2013-06-27 84 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