我有两个描述任意旋转的旋转矩阵。 (4x4 opengl兼容)
现在我想在它们之间进行插值,以便它遵循从一个旋转到另一个旋转的径向路径。想到三脚架上的相机,然后转向。然后旋转。
如果我插入每个组件我得到一个压缩结果,所以我认为我只需要插入矩阵的某些组件。但是哪些?
答案 0 :(得分:14)
您必须将SLERP用于矩阵的旋转部分,并将线性用于其他部分。最好的方法是将矩阵转换为四元数并使用(更简单的)四元数SLERP:http://en.wikipedia.org/wiki/Slerp。
我建议阅读Graphic Gems II或III,特别是关于将矩阵分解为更简单的转换的部分。这是Spencer W. Thomas本章的来源:
http://tog.acm.org/resources/GraphicsGems/gemsii/unmatrix.c
当然,我建议你自己学习如何做到这一点。这真的不是那么难,只是很烦人的代数。最后,这是一篇关于如何通过Id软件将矩阵转换为四元数的好文章:http://www.mrelusive.com/publications/papers/SIMD-From-Quaternion-to-Matrix-and-Back.pdf
编辑:这是几乎每个人都引用的公式,它来自1985年的SIGGRAPH论文。
其中:
- qm = interpolated quaternion
- qa = quaternion a (first quaternion to be interpolated between)
- qb = quaternion b (second quaternion to be interpolated between)
- t = a scalar between 0.0 (at qa) and 1.0 (at qb)
- θ is half the angle between qa and qb
代码:
quat slerp(quat qa, quat qb, double t) {
// quaternion to return
quat qm = new quat();
// Calculate angle between them.
double cosHalfTheta = qa.w * qb.w + qa.x * qb.x + qa.y * qb.y + qa.z * qb.z;
// if qa=qb or qa=-qb then theta = 0 and we can return qa
if (abs(cosHalfTheta) >= 1.0){
qm.w = qa.w;qm.x = qa.x;qm.y = qa.y;qm.z = qa.z;
return qm;
}
// Calculate temporary values.
double halfTheta = acos(cosHalfTheta);
double sinHalfTheta = sqrt(1.0 - cosHalfTheta*cosHalfTheta);
// if theta = 180 degrees then result is not fully defined
// we could rotate around any axis normal to qa or qb
if (fabs(sinHalfTheta) < 0.001){ // fabs is floating point absolute
qm.w = (qa.w * 0.5 + qb.w * 0.5);
qm.x = (qa.x * 0.5 + qb.x * 0.5);
qm.y = (qa.y * 0.5 + qb.y * 0.5);
qm.z = (qa.z * 0.5 + qb.z * 0.5);
return qm;
}
double ratioA = sin((1 - t) * halfTheta) / sinHalfTheta;
double ratioB = sin(t * halfTheta) / sinHalfTheta;
//calculate Quaternion.
qm.w = (qa.w * ratioA + qb.w * ratioB);
qm.x = (qa.x * ratioA + qb.x * ratioB);
qm.y = (qa.y * ratioA + qb.y * ratioB);
qm.z = (qa.z * ratioA + qb.z * ratioB);
return qm;
}
来自:http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
答案 1 :(得分:1)
您需要将矩阵转换为不同的表示 - 四元数适用于此,插值四元数是一个定义明确的操作。