如何將3D投影至2D平面--3D初探


前一段時間,組里分享一個關於3D投影至2D平面上的主題,一直沒有時間細細的咀嚼一下。

每天的代碼大部分都是在寫業務邏輯,細想一下,自從畢業上班以來,一直沒有去寫過關於圖形展示方面的東東,所以決定先入個門,以后要是有需求了也可以快速上手,也當補充一下高中的數學知識。

1,旋轉

處理旋轉需要用到一個旋轉變換公式:

http://zh.wikipedia.org/wiki/%E5%8F%98%E6%8D%A2%E7%9F%A9%E9%98%B5#.E9.80.8F.E8.A7.86.E6.8A.95.E5.BD.B1

繞原點逆時針旋轉 θ 度角的變換公式是 x' = x \cos \theta - y \sin \thetay' = x \sin \theta + y \cos \theta,用矩陣表示為:


\begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} \cos \theta & - \sin\theta \\ \sin \theta & \cos \theta \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix}

由於是x,y,z的三維坐標系,所以根據上面的公式,可以得到如下的轉換公式:

//向量旋轉
function rotateX(x, y, z, a) {//繞X軸旋轉
	return {
		x: x,
		y: y * Math.cos(a) - z * Math.sin(a),
		z: y * Math.sin(a) + z * Math.cos(a)
	};
}
function rotateY(x, y, z, a) {//繞Y軸旋轉
	return {
		x: x * Math.cos(a) + z * Math.sin(a),
		y: y,
		z: z * Math.cos(a) - x * Math.sin(a)
	};
}
function rotateZ(x, y, z, a) {//繞Z軸旋轉
	return {
		x: x * Math.cos(a) - y * Math.sin(a),
		y: x * Math.sin(a) + y * Math.cos(a),
		z: z
	};
}

2,球面坐標系轉直角坐標系:

http://zh.wikipedia.org/wiki/%E5%9D%90%E6%A0%87%E7%B3%BB

球坐標系是用一個角度 \phi表示位置和xy-面的相對關系。如P 點的球坐標為(r,\ \theta,\ \phi)

  • r是原點至P點之間的距離。
  • \phi是線 OP 在 xy-面的投影線與正 x-軸之間的夾角。
  • \theta為原點到點 P 的連線與正 z-軸之間的天頂角。

用球坐標 (r,\ \theta,\ \phi) 來表示一個點的位置

而根據上面的介紹,可以寫出下面的轉換公式:

/*
 * 球面坐標系轉直角坐標系
 * @param {Number} a 仰角的余角
 * @param {Number} b 轉角
 * @param {Number} r 半徑
 */
function spherical(a, b, r) {
	return {
		x: r * Math.sin(a) * Math.cos(b),
		y: r * Math.sin(a) * Math.sin(b),
		z: r * Math.cos(a)
	};
}

3,透視投影:

以上方的三維坐標系(x, y, z)為例,假設觀察點設置在(1000, 0, 0)的A點上,而目標點B設置在(x < 0, y > 0, z >0)的區域內,並且設B點的坐標為Xb, Yb, Zb;設B點在YOZ平面上的投影的坐標是(0, Y’b. Z’b),那么通過畫圖,可以得到一個公式:

1000 / (1000 - Xb) = Z’b / Zb (Xb < 0)  == >>  這樣就得到了Z’b(投影點的z坐標)和目標點B的原始Zb坐標之間和Xb坐標之間的關系;

同理:

1000 / ( - Xb) = Y’b / (Yb – Y’b) (Xb < 0)

根據以上投影原理,可以列出以下代碼片段:

image

主需要注意第二個紅框,第一個紅框是純粹的平行投影(就像影子一樣),第二個是透視投影,只是和上面說明的坐標系使用的不一樣,但是原理是一樣的。

----------

下面來看下整體代碼吧:(不是原創,只是用來學習分享下)

不貼整體代碼了,直接點擊下方鏈接,太占地兒,直接新標簽打開鏈接,查看源代碼..

猛擊這里!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM