È necessario utilizzare SLERP per le parti rotazionali delle matrici e lineare per le altre parti. Il modo migliore è trasformare le matrici in quaternioni e utilizzare lo SLERP (più semplice) quaternario: http://en.wikipedia.org/wiki/Slerp.
Suggerisco di leggere Graphic Gems II o III, in particolare le sezioni relative alla scomposizione delle matrici in trasformazioni più semplici. Ecco fonte Spencer W. Thomas' per questo capitolo:
http://tog.acm.org/resources/GraphicsGems/gemsii/unmatrix.c
Naturalmente, vi consiglio di imparare a fare da soli. Non è poi così difficile, solo un sacco di algebra fastidiosa. E, infine, ecco una grande carta su come trasformare una matrice in un quaternione, e ritorno, dal software Id: http://cache-www.intel.com/cd/00/00/29/37/293748_293748.pdf
Edit: Questa è la formula più o meno tutti cita, è da un 1985 SIGGRAPH carta.
Dove:
- 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
Codice:
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;
}
Da: http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
fonte
2010-11-04 17:29:46
grazie! quindi, come posso convertire una matrice in un quaternion? – clamp
Ti suggerisco di iniziare leggendo questo: http://en.wikipedia.org/wiki/Quaternion – tdammers