三維空間旋轉和Three.JS中的實現

[toc]html

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

三維空間的旋轉方法論

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

歐拉角(Euler Angle)

將旋轉表示爲物體按座標系的三個軸X(1,0,0) ,Y(0,1,0),Z(0,0,1)的旋轉組合成的。code

這裏首先要明確兩個概念,orm

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

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

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

旋轉矩陣(Rotation Matrix)

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

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

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

Three.js中旋轉的實際運用

歐拉角

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類型的值(向量)。

矩陣

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) 的源碼爲:

makeRotationAxis: function ( axis, angle ) {
        var c = Math.cos( angle );
        var s = Math.sin( angle );
        var t = 1 - c;
        var x = axis.x, y = axis.y, z = axis.z;
        var tx = t * x, ty = t * y;
        this.set(
            tx * x + c, tx * y - s * z, tx * z + s * y, 0,
            tx * y + s * z, ty * y + c, ty * z - s * x, 0,
            tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
            0, 0, 0, 1
        );
         return this;
    }

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

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

var rotWorldMatrix;
 function rotateAroundWorldAxis(object, axis, radians) {
 //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);
    }

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

利用組合物體中心軸

three.js中的旋轉中心點默認是自身集合中心點,當要讓一個物體繞在某個軸運動時,能夠先將該物體(暫稱子元素)與一個旋轉中心點(自身座標軸)與該物體須要旋轉軸中心點重合的物體(暫稱父元素)。這個時候讓父元素繞自身的某條座標軸運動,就實現了子元素繞某條軸運動。

相關文章
相關標籤/搜索