plane equation
. 然后,确定
quaternion
它表示
normal to the z axis
通过从“w”=0的向量创建四元数,可以通过四元数旋转向量:
v=(x,y,z)
按q2旋转,
rv=q2*q*q2^-1
若要将rv转换为点,请删除w(即0)。
要再次旋转,请使用
其中q2^-1是q2的逆或共轭。
class Vector3d {
//...
double x, y, z;
//...
// functions here e.g. dot (dot product), cross (cross product)
};
class Quaternion {
//...
double w, x, y, z;
//...
Quaternion inverse() const { // also equal to conjugate for unit quaternions
return Quaternion (w, -x, -y, -z);
}
static Quaternion align(const Vector3d v1, const Vector3d v2) {
Vector3d bisector = (v1 + v2).normalize();
double cosHalfAngle = v1.dot(bisector);
Vector3d cross;
if(cosHalfAngle == 0.0) {
cross = v1.cross(bisector);
} else {
cross = v1.cross(Vector3d(v2.z, v2.x, v2.y)).normalize();
}
return Quaternion(cosHalfAngle, cross.x, cross.y, cross.z);
}
Quaternion operator *(const Quaternion &q) const {
Quaternion r;
r.w = w * q.w - x * q.x - y * q.y - z * q.z;
r.x = w * q.x + x * q.w + y * q.z - z * q.y;
r.y = w * q.y + y * q.w + z * q.x - x * q.z;
r.z = w * q.z + z * q.w + x * q.y - y * q.x;
return r;
}
};
利用这种数学方法,我们的想法是用“对齐”方法创建一个四元数,表示从平面法线到z轴的旋转(即v1是平面法线[标准化],v2是z轴单位向量)-让我们称之为Q。要旋转每个点,p,你要为点创建一个四元数,Q,旋转它,qr,然后将q转换回点p2,如下所示:
q = Quaternion(0, p.x, p.y, p.z);
qr = Q * q * Q.inverse();
p2 = Vector3d(qr.x, qr.y, qr.z);
要再次旋转p2,请执行以下操作:
q = Quaternion(0, p2.x, p2.y, p2.z);
qr = Q.inverse() * q * Q;
p = Vector3d(qr.x, qr.y, qr.z);