1

我在空间中取了一个给定的矩形(a face4)。face4 可以在空间中的任何角度/位置。

我正在它的质心处创建一个圆环。

然后,我尝试将我的环面与以下标准对齐:

1) 平面将圆环水平二等分(使平面两侧出现半圆)

2)环面垂直于平面

3)圆环与矩形面的两个(“较短”)边的中点对齐,因此圆环将矩形/面的“较长”边一分为二。

例如,它看起来像这样:

在此处输入图像描述

我觉得我需要为此做两个不同的轴旋转。一个使其与脸部对齐,另一个使其垂直。

现在,我只是在尝试第一部分(将它与 face4 对齐,而不是担心垂直),我正在这样做:

1)从人脸计算两组向量的两个中点

2)通过从另一个中点减去一个中点来确定结束圆环轴以获得我的轴。

3)通过做#2和起始圆环的(0,1,0)轴的叉积来找到旋转轴

4) 用 Math.cos( endAxis.dot (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;
}
4

1 回答 1

0

解决了。我使用了 Matrix.lookAT() 命令,它本质上是基于两个正交向量(而不是仅来自 makeRotationAxis 的一个非正交向量)创建旋转矩阵。更具体地说,它需要三个输入:eye、center 和 up,并从中生成正交向量。

详细信息可以在这里找到:

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

于 2013-07-09T01:06:32.510 回答