我有一个像这样的载体
{x: 0, y: 0, z: 1}
然后我有另一个向量,法线是这样的方向
{x: 1, y: 0, z: 0}
如何根据法线方向旋转向量,使其看起来像这样?
{x: 1, y: 0, z: 0}
我正在使用Three.js
答案 0 :(得分:1)
虽然自动回答正确,但以下是有关轮换的一些一般要点:
如果仅给出两个向量,即a
和b
,则存在无限旋转将a
转换为b
。上面的答案是最短的旋转,但是需要通过叉积确定旋转轴。第二种解决方案是将等分线作为旋转轴并旋转Pi
。在这里,您将归一化为a_n
和b_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;
}
打字稿中的代码