根据Three.js中的法线旋转向量

时间:2019-07-16 10:11:02

标签: javascript math vector three.js

我有一个像这样的载体

{x: 0, y: 0, z: 1}

然后我有另一个向量,法线是这样的方向

{x: 1, y: 0, z: 0}

如何根据法线方向旋转向量,使其看起来像这样?

{x: 1, y: 0, z: 0}

我正在使用Three.js

2 个答案:

答案 0 :(得分:1)

虽然自动回答正确,但以下是有关轮换的一些一般要点:

如果仅给出两个向量,即ab,则存在无限旋转将a转换为b。上面的答案是最短的旋转,但是需要通过叉积确定旋转轴。第二种解决方案是将等分线作为旋转轴并旋转Pi。在这里,您将归一化为a_nb_n并围绕(a_n + b_n)旋转。

旋转之间的差异只会影响非旋转对称对象。

如果所有矢量都已经归一化,那么它应该简单到

var a = new THREE.Vector3( 0, 0, 1 );
var b = new THREE.Vector3( 1, 0, 0 );
var c = new THREE.Vector3( x, y, z );
var quaternion = new THREE.Quaternion();
quaternion.setFromAxisAngle( a + b, Math.PI );
c.applyQuaternion( quaternion );

如果c==a则将c旋转到b上,如果c==b则将c旋转到a上。

答案 1 :(得分:0)

深入研究此答案后,我想出了一个似乎可行的解决方案 https://github.com/mrdoob/three.js/issues/1486

rotateVectorWithNormal(toRotate: Vector3, normal: Vector3) {

    const newVector: Vector3 = new Vector3().copy(toRotate);

    // set up direction
    let up = new Vector3(0, 1, 0);
    let axis: Vector3;
    // we want the vector to point in the direction of the face normal
    // determine an axis to rotate around
    // cross will not work if vec == +up or -up, so there is a special case
    if (normal.y == 1 || normal.y == -1) {
        axis = new Vector3(1, 0, 0);
    } else {
        axis = new Vector3().cross(up, normal);
    }

    // determine the amount to rotate
    let radians = Math.acos(normal.dot(up));
    const quat = new Quaternion().setFromAxisAngle(axis, radians);
    newVector.applyQuaternion(quat);

    return newVector;

}

打字稿中的代码