2013-06-27 80 views
1

我在空間中給出了一個矩形(一個face4)。 face4可以在任何角度/空間位置。Three.js對齊和旋轉

我在它的質心處創建一個圓環。

然後我試圖對準我的圓環用以下標準:

1)平面水平地平分了環面(使得半圓出現在平面的任一側)

2 )環面與平面垂直

3)環面與矩形面的兩個(「較短」)邊的中點對齊,以便環面平分矩形面的「較長」邊, face4。

例如,它應該是這樣的:

enter image description here

我覺得我需要做的這兩個不同的軸旋轉。一個將它對準臉部,另一個使其垂直。

現在,我只是嘗試的第一部分(它對準的face4,擔心的不是垂直的),而我這樣做:

1)計算兩個矢量集中的兩個中點從臉上

2)通過從另一箇中點減去一箇中點來確定結束環面軸以獲得我的軸。

3)尋找通過執行#2的橫產物和起始花托

4)尋找旋轉角度與Math.cos(endAxis的(0,1,0)軸的旋轉軸線。點(rotationAxis))

5)旋轉圓環

6)翻譯其

不幸的是,它不是 「對齊」 兩個點作爲我希望看到的照片)。

我在嘗試不同的方法(每當我嘗試新的東西時反轉theta等),但它仍然沒有像我預期的那樣工作。我的方法或想法有什麼問題嗎?

我使用的代碼如下。 (我特意將它保留在很長的形式中,並附有許多評論以幫助我的思考)。

this.createTorus = function (tubeMeshParams) { 

    var torusRadius = 5; 
    var torus = new THREE.TorusGeometry(torusRadius, 1.5, segments/10, 50); 
    fIndex = this.calculateFaceIndex(); 

    //Determine midpoint of line AB on Face 
    var v1 = geometry.vertices[geometry.faces[fIndex].a]; 
    var v2 = geometry.vertices[geometry.faces[fIndex].b]; 
    var xMidAB = (v1.x + v2.x)/2; 
    var yMidAB = (v1.y + v2.y)/2; 
    var zMidAB = (v1.z + v2.z)/2; 
    var midpointAB = new THREE.Vector3(xMidAB, yMidAB, zMidAB); 

    //Determine midpoint of line CD on Face 
    var v3 = geometry.vertices[geometry.faces[fIndex].c]; 
    var v4 = geometry.vertices[geometry.faces[fIndex].d]; 
    var xMidCD = (v3.x + v4.x)/2; 
    var yMidCD = (v3.y + v4.y)/2; 
    var zMidCD = (v3.z + v4.z)/2; 
    var midpointCD = new THREE.Vector3(xMidCD, yMidCD, zMidCD); 

    //Determine Ending Torus axis 
    var endTorusAxis = new THREE.Vector3(); 
    endTorusAxis.subVectors(midpointCD, midpointAB); 
    endTorusAxis.normalize(); 

    //Direction vector of Torus (Y = 1) 
    var torusAxis = new THREE.Vector3(0, 1, 0); 

    //Find the axis of rotation through Cross Product 
    var rotationAxis = new THREE.Vector3(); 
    rotationAxis.crossVectors(endTorusAxis, torusAxis); 

    if (rotationAxis.length() == 0) // Acounting for special case where the axis are aligned 
    { 
     rotationAxis.set(1, 0, 0); 
    } 
    rotationAxis.normalize(); 

    //Now that we have the needed data, determine angle of rotation 
    var theta = Math.acos(endTorusAxis.dot(rotationAxis)); 
    theta = -theta; 

    //Don't use position, rotate, scale 
    torus.matrixAutoUpdate = false; 

    //Rotate it 
    torus.applyMatrix(new THREE.Matrix4().makeRotationAxis(rotationAxis, theta)); 

    // Create mesh and scale 
    torusLoop = new THREE.Mesh(torus, this.m); 
    torusLoop.scale.x = torusLoop.scale.y = torusLoop.scale.z = tubeMeshParams['Scale']; 

    //Determine Face centroid positions 
    var cenPosX = geometry.faces[fIndex].centroid.x; 
    var cenPosY = geometry.faces[fIndex].centroid.y; 
    var cenPosZ = geometry.faces[fIndex].centroid.z; 

    //Move the rotated torus around the centroid 
    torusLoop.geometry.applyMatrix(new THREE.Matrix4().makeTranslation(cenPosX, cenPosY, cenPosZ)); 
    torusLoop.geometry.computeCentroids(); 
    torusLoop.geometry.computeFaceNormals(); 
    torusLoop.geometry.computeVertexNormals(); 

    return torusLoop; 
} 

回答

0

已解決。我使用了Matrix.lookAT()命令,它基於兩個正交矢量(而不是從makeRotationAxis中的一個非正交矢量)創建旋轉矩陣。更具體地說,它需要三個輸入:眼睛,中心和上,並從這些輸入生成正交向量。

詳細信息可以在這裏找到:

http://threejs.org/docs/58/#Reference/Math/Matrix4function