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

Math 数学帮助:3d建模/Three.js-动态旋转图形,math,3d,geometry,three.js,computational-geometry,Math,3d,Geometry,Three.js,Computational Geometry,这对任何数学/3d几何爱好者来说都是一个大问题。先谢谢你 概述 我有一个图形是通过在空间中扭曲样条曲线周围挤出面创建的。我试图在给定的曲线段上放置一个沿样条曲线路径定向的环形,以便它与样条曲线对齐。我的意思是,圆环体的宽度平行于给定拉伸段的样条线路径,其高度垂直于所选的面,如下图所示 我知道的数据: 我得到了这个图形的一个面,从中我还可以收集该面的质心中心点、组成它的顶点、周围的面以及面的法向量 当前非工作解决方案成果: 我可以围绕单击的面质心正确创建一个环面循环。但是,它无法正确旋转以与面对齐

这对任何数学/3d几何爱好者来说都是一个大问题。先谢谢你

概述

我有一个图形是通过在空间中扭曲样条曲线周围挤出面创建的。我试图在给定的曲线段上放置一个沿样条曲线路径定向的环形,以便它与样条曲线对齐。我的意思是,圆环体的宽度平行于给定拉伸段的样条线路径,其高度垂直于所选的面,如下图所示

我知道的数据:

我得到了这个图形的一个面,从中我还可以收集该面的质心中心点、组成它的顶点、周围的面以及面的法向量

当前非工作解决方案成果:

我可以围绕单击的面质心正确创建一个环面循环。但是,它无法正确旋转以与面对齐。看看下面他们看起来有点不对劲

这是一张图片,周围有材料:

这是一张线框模式的图片。您可以非常清楚地看到拉伸段

目前的非工作方法:

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

公式:

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

法向量1和法向量2的点积=向量1的大小*向量2的大小*Cosθ

或:

n1n2=| | n1 | |*| | n2 | |*余弦θ

或:

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

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

各分量之和的平方根

或:

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

此外,我将以下内容用于原点平面的法向量:

水平面的法向量: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;
}

我发现我使用的方法不正确。我本应该按轴旋转,而不是试图计算每个角度并进行旋转X和旋转Y。肯定是想得太多了

旋转轴;是内置于three.js中的函数