Three.js 學習筆記(1)--座標體系和旋轉

前言

JavaScript 3D libraryhtml

The aim of the project is to create an easy to use, lightweight, 3D library. The library provides <canvas>, <svg>, CSS3D and WebGL renderers.(該項目的目標是建立一個易於使用,輕量級的3D庫。該庫提供了<canvas>,<svg>,CSS3D和WebGL渲染器。git

示例 - 文檔 - Wiki - 遷移 - 幫助github

官網:https://threejs.orgcanvas

Github:https://github.com/mrdoob/three.jside

學習THREE.JS,能夠從《three.js開發指南》開始,有中文電子文檔PDF。電子文檔代碼:https://github.com/josdirksen/learning-threejssvg

一、3D空間的座標體系

  在threejs中,xyz軸的座標如圖所示,X軸紅色,Y軸綠色,Z軸藍色。函數

http://www.cnblogs.com/silent-stranger/p/6307372.html學習

1.相機座標系(Camera Space)

         有一個比較特殊的物體座標系就是相機座標系,這個座標系是咱們的視點用來渲染看到的場景所用的座標系。在相機座標系中,相機一直處於相機座標系的原點,+x的方向是向右的,+z的方向是向前的(向屏幕裏的方向,由於使用的是左手座標系),+y的方向是向上。這裏的像上不是世界座標的正上,而是一個相機的上方向。能夠來看一下這個相機座標系的圖片。ui

  這裏要注意一些細節,相機的座標是三維空間,而咱們在屏幕上看到的是二維的。
由於咱們是作了一個映射,把三維空間的東西映射到了一個二維的平面上,這個映射就是你們知道的「投影」了。this

 

 

二、二維平面旋轉公式

1 x1=Math.cos(angle)*x-Math.sin(angle)*y;
2 y1=Math.cos(angle)*y+Math.sin(angle)*x;
3 //其中x,y表示物體相對於旋轉點旋轉angle的角度以前的座標,
4 //  x1,y1表示物體旋轉angle後相對於旋轉點的座標

從數學上來講,此公式能夠用來計算某個點繞另一點旋轉必定角度後的座標,

例如:A(x,y)繞B(a,b)旋轉β度後的位置爲C(c,d),則x,y,a,b,β,c,d有以下關係式:

1。設A點旋轉前的角度爲δ,則旋轉(逆時針)到C點后角度爲δ+β

2。求A,B兩點的距離:dist1=|AB|=y/sin(δ)=x/cos(δ)

3。求C,B兩點的距離:dist2=|CB|=d/sin(δ+β)=c/cos(δ+β)

4。顯然dist1=dist2,設dist1=r因此:

  r=x/cos(δ)=y/sin(δ)=d/sin(δ+β)=c/cos(δ+β)

5。由三角函數兩角和差公式知:

  sin(δ+β)=sin(δ)cos(β)+cos(δ)sin(β)

  cos(δ+β)=cos(δ)cos(β)-sin(δ)sin(β)

  因此得出:

  c=r*cos(δ+β)=r*cos(δ)cos(β)-r*sin(δ)sin(β)=x*cos(β)-y*sin(β)

  d=r*sin(δ+β)=r*sin(δ)cos(β)+r*cos(δ)sin(β)=y*cos(β)+x*sin(β)

即旋轉後的座標c,d只與旋轉前的座標x,y及旋轉的角度β有關

 從圖中能夠很容易理解出A點旋轉後的C點老是在圓周上運動,圓周的半徑爲|AB|,利用這點就可使物體繞圓周運動,即旋轉物體。

三、三維空間旋轉公式

【轉】https://www.cnblogs.com/silent-stranger/p/6027266.html

  三維空間中主要有兩種幾何變換,一種是位置的變換,位置變換和二維空間的是同樣的。假設一點P(X1,Y1,Z1) 移動到Q(X2,Y2,Z2)只要簡單的讓P點的座標值加上偏移值就能夠了。可是三維空間的旋轉變換就不能簡單的使用二維空間的變換了。下面詳細介紹一下三維空間的旋轉。

  二維空間的旋轉能夠看做是圍繞點的旋轉,只有一個自由度。而三維空間的旋轉是圍繞一條線旋轉的。當旋轉的軸是Z軸時,旋轉能夠看做是在二維平面XY平面的旋轉,旋轉的中心點是P(x=0,y=0)。按照右手法則,讓拇指指向Z軸的正方向,四指指向爲旋轉的正方向。按照Y軸和X軸的旋轉也相似。按照不一樣的軸的旋轉能夠進行組合。好比,先按照Z軸旋轉45度,再按照Y軸旋轉45度。可是每個朝向均可以當作是物體在原始位置處圍繞某一個軸轉動了一個角度造成的。

                 

 

      三維空間的旋轉有多種方式,如旋轉矩陣,歐拉角,四元數:

 

1.歐拉角(Euler Angle)

      歐拉角這種旋轉方式是最直觀的,由於這種方式是將旋轉表示爲物體按座標系的三個軸X(1,0,0) ,Y(0,1,0),Z(0,0,1)的旋轉組合成的。這裏首先要明確兩個概念,1參考系:相似於物理中的參考系,是靜止不動的,好比北極星,無論在那裏,那就是北。2座標系:座標系是固定於物體的,隨着物體的轉動而發生變化,最簡單的例子就是左右,人所說的左邊一直是根據人所面對的方向來決定的。在下圖中藍色爲參考系的三個軸,而紅色是物體的座標系的三個軸。雖說歐拉角表示的旋轉是有多個沿座標軸的旋轉組合而成的。可是旋轉的順序不一樣旋轉就不一樣,因此,歐拉角中旋轉的順序要註明。這裏的三個角是zxz順規的歐拉角。物體先繞Z軸旋轉了α°,而後物體座標系的x軸的位置變化到了圖中N的位置,而後繞這個N軸(X軸)旋轉β°,最後再沿Z軸旋轉γ°。

                                                                      

 

      歐拉角的旋轉雖然是最直觀的,可是卻存在一個很是致命的問題--萬向節鎖,大體是指。按某一個旋轉了90°的時候會使另外兩個軸重合,從而喪失一個自由度。沒法很好的追蹤物體。具體的能夠看一下這個視頻萬向節鎖。講得很是清楚,這裏也就再也不贅述了。

      歐拉角旋轉應用於不少第一人稱3D遊戲中,雖然萬向節鎖是沒法避免的,但能夠將觸發的機率減至最小。只有當人物視線徹底朝上或者朝下的時候纔會觸發萬向節鎖。

 

2.旋轉矩陣(Rotation Matrix)

      三維空間的旋轉使用旋轉矩陣的方式表示比較容易,旋轉矩陣是一個3x3的矩陣。能夠看做物體沿空間中的某一個軸(x,y,z)旋轉了θ°。三維的旋轉矩陣能夠表示爲:

      

其中:c=cos(θ) , s=sin(θ),t=1-cos(θ)

假設物體在初始位置的旋轉矩陣爲A ,通過旋轉以後的旋轉矩陣爲A` ,那麼A,A`以及R之間的關係能夠表示爲 A` = AR。

3.四元數(Quaternion

      四元數是一種高階複數,四元數q表示爲:=(x,,,w)=xi+j+k+w  能夠將四元數寫成一個向量和一個實數的組合。=(v  ⃗    +w)=((x,,),w)  ,四元數也可用矩陣表示。

能夠證實這個矩陣和旋轉矩陣是一個矩陣。

在數學上四元數來表示的旋轉要好一些,可是在程序設計裏,旋轉矩陣更方便。在Three.js中使用四元數的方式也是將四元數換成了旋轉矩陣使用的。

 

四、Three.JS中的旋轉實現

      three.js支持上面所說的三種旋轉方式。

1.歐拉角

     three.js中場景裏的物體都屬於Object3D這個類。這個類中有表示物體朝向的一個屬性–rotation,這是一個歐拉類型的值,有三個軸旋轉的角度,單位是π,還有一個旋轉的順序組成。要使物體旋轉能夠改動這個rotation的值。好比讓物體按Y軸正方向旋轉45°能夠寫成 object3D.rotation.y+=0.25*Math.PI。這裏的旋轉順序默認使用的是‘XYZ’順序。另外Object3D 還提供了幾個方法來進行旋轉,rotateX(angle),rotateY(angle),rotateZ(angle),分別是按照X,Y,Z軸的正反向旋轉一個角度。但具體使用的時候和 object3D.rotation.y+=0.25*Math.PI 這種方式仍是有一些區別的。另外還有一個方法是rotateOnAxis(axis,angle) 能夠指定旋轉的軸,這裏的axis是一個Vector3類型的值。

2.矩陣

    three.js裏的矩陣和以前介紹的不太同樣,由於three.js裏的矩陣式一個4x4的複合的矩陣(Transform Matrix),將位置信息放在了矩陣的最後一行。能夠很容易的從這個矩陣裏分解出旋轉矩陣(Rotation Matrix),和位置矩陣(Translation Matrix)。Matrix4的主要方法有:

 

mutiply():矩陣的乘法。
transpose() :矩陣轉置。
getInverse(m) :求逆矩陣。
makeRotationFromEuler(euler) :經過一個歐拉類型的值來設置矩陣的值。
makeRotationFromQuaternion(q):經過一個四元數類型的值來設置矩陣。
makeRotationonAxis(axis,theta):按一個軸旋轉θ°,而後設置矩陣的值。
makeRotationonAxis(axis,theta) 的源碼爲:

 1 makeRotationAxis: function ( axis, angle ) {
 2     var c = Math.cos( angle );
 3      var s = Math.sin( angle );
 4     var t = 1 - c;
 5     var x = axis.x, y = axis.y, z = axis.z;
 6     var tx = t * x, ty = t * y;
 7     this.set(
 8         tx * x + c, tx * y - s * z, tx * z + s * y, 0,
 9         tx * y + s * z, ty * y + c, ty * z - s * x, 0,
10         tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
11         0, 0, 0, 1
12     );
13      return this;
14 }

經過源碼,能夠看出,調用這個方法就能夠獲得一個旋轉矩陣了。而後,讓物體的矩陣乘旋轉矩陣就能夠獲得物體轉動後的矩陣了。

    下面是一段我使用旋轉矩陣來旋轉物體的代碼。

function rotateAroundWorldAxis(object, axis, radians) {
    rotWorldMatrix = new THREE.Matrix4();
    rotWorldMatrix.makeRotationAxis(axis.normalize(), radians);
    rotWorldMatrix.multiply(object.matrix);                // pre-multiply
    object.matrix = rotWorldMatrix;
    object.rotation.setFromRotationMatrix(object.matrix);
}

經過這樣的方法,就可讓物體沿參考系中的肯定的一個軸進行旋轉了。

3.四元數

      沒有使用四元數,因此沒有研究,在object3D中設置rotation能夠經過Matrix ,也能夠經過Quaternion ,不過setFromRotationQuaternion的內部也是用的Matrix。

 

座標體系:http://www.cnblogs.com/silent-stranger/p/6307372.html

三維空間旋轉:http://www.javashuo.com/article/p-uzfkwzbj-by.html

三維旋轉矩陣:https://wenku.baidu.com/view/6dac0c22915f804d2b16c17c.html

參考資料

https://www.fastgraph.com/makegames/3drotation/

http://www.essentialmath.com/GDC2012/GDC2012_JMV_Rotations.pdf

http://www.gamedev.net/page/resources/_/technical/math-and-physics/do-we-really-need-quaternions-r1199

https://threejs.org/docs/

相關文章
相關標籤/搜索