数学帮助:3d Modeling / Three.js - 动态旋转图形

时间:2013-06-27 00:34:45

标签: math 3d geometry three.js computational-geometry

对于任何数学/三维几何爱好者来说,这是一个很大的问题。提前谢谢。

概述

我有一个通过在空间中扭曲样条曲线周围挤出面来创建的图形。我试图在曲线的给定段上沿着样条曲线路径定位“环”(圆环),以便它与样条曲线“对齐”。我的意思是圆环的宽度与给定挤出段的样条路径平行,并且它的高度垂直于所选择的面(见下图)。

我知道的数据:

我得到了这个人物的一张脸。从那里我也可以收集那个面部的质心(中心点),构成它的顶点,周围的面部以及面部的法线向量。

当前(非工作)解决方案结果:

我可以在点击的脸的质心周围正确创建圆环。但是,它无法正确旋转以与脸部“对齐”。看看它们在下面看起来有点像“关闭”。

这是一张周围材料的图片:

enter image description here

这是在线框模式下的图片。您可以非常清楚地看到挤出段。

enter image description here

当前(非工作)方法:

我正在尝试做两次计算。首先,我正在计算两个平面(选定的面和原点的水平面)之间的角度。其次,我正在计算原点处面部和垂直平面之间的角度。有了这两个角度,我就做了两次旋转 - 圆环上的X和Y旋转到我希望正确的方向。它以可变的量旋转圆环,但不在我想要的位置。

公式:

在执行上述操作时,我使用以下方法使用它们的法线向量计算两个平面之间的角度:

法向量1和法向量的点积2 =向量的大小1 *向量的大小2 * Cos(theta)

或者:

(n1)(n2)= || n1 || * || n2 || * cos(theta)

或者:

角度= ArcCos {(n1 * n2)/(|| n1 || * || n2 ||)}

要确定向量的大小,公式为:

组件总和的平方根。

或者:

Sqrt {n1.x ^ 2 + n1.y ^ 2 + n1.z ^ 2}

另外,我使用以下内容作为“origin”平面的法向量:

水平面的法线向量:(1,0,0)

垂直平面的法向量:(0,1,0)

我已经考虑了几次上面的法向量...我认为(?)他们是对的?

当前实施:

以下是我目前用于实现它的代码。任何想法将不胜感激。我有一种沉闷的感觉,我在尝试计算飞机之间的角度时采取了错误的方法。任何建议/想法/建议将不胜感激。非常感谢您提出任何建议。

计算角度的函数:

this.toRadians = function (face, isX)
{
    //Normal of the face
    var n1 = face.normal;

    //Normal of the vertical plane
    if (isX)
        var n2 = new THREE.Vector3(1, 0, 0); // Vector normal for vertical plane. Use for Y rotation.
    else
        var n2 = new THREE.Vector3(0, 1, 0); // Vector normal for horizontal plane. Use for X rotation.

    //Equation to find the cosin of the angle. (n1)(n2) = ||n1|| * ||n2|| (cos theta)

    //Find the dot product of n1 and n2.
    var dotProduct = (n1.x * n2.x) + (n1.y * n2.y) + (n1.z * n2.z);

    // Calculate the magnitude of each vector
    var mag1 = Math.sqrt (Math.pow(n1.x, 2) + Math.pow(n1.y, 2) + Math.pow(n1.z, 2));
    var mag2 = Math.sqrt (Math.pow(n2.x, 2) + Math.pow(n2.y, 2) + Math.pow(n2.z, 2));

    //Calculate the angle of the two planes. Returns value in radians. 
    var a = (dotProduct)/(mag1 * mag2);

    var result = Math.acos(a);

    return result;
}

创建和旋转环面循环的功能:

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

    //run the equation twice to calculate the angles
    var xRadian = this.toRadians(geometry.faces[fIndex], false);
    var yRadian = this.toRadians(geometry.faces[fIndex], true);

    //Rotate the Torus 
    torus.applyMatrix(new THREE.Matrix4().makeRotationX(xRadian));
    torus.applyMatrix(new THREE.Matrix4().makeRotationY(yRadian));
    torusLoop = new THREE.Mesh(torus, this.m);

    torusLoop.scale.x = torusLoop.scale.y = torusLoop.scale.z = tubeMeshParams['Scale'];

    //Create the torus around the centroid
    posx = geometry.faces[fIndex].centroid.x;
    posy = geometry.faces[fIndex].centroid.y;
    posz = geometry.faces[fIndex].centroid.z;

    torusLoop.geometry.applyMatrix(new THREE.Matrix4().makeTranslation(posx, posy, posz));
    torusLoop.geometry.computeCentroids();
    torusLoop.geometry.computeFaceNormals();
    torusLoop.geometry.computeVertexNormals();

    return torusLoop;
}

1 个答案:

答案 0 :(得分:0)

我发现我使用的方法不正确。我应该按轴进行旋转,而不是尝试计算每个角度并执行RotationX和RotationY。绝对是在思考它。

makeRotationAxis();是一个内置于three.js的函数。