xyz una transformación rotación rotacion matriz matrices las identificar explicacion encontrar ejes desplazamiento derivada demostracion coordenadas cartesianas matrix rotation 3d

matrix - una - interpolar entre matrices de rotación



rotacion de coordenadas cartesianas (2)

Tengo dos matrices de rotación que describen rotaciones arbitrarias. (4x4 compatible con OpenGL)

ahora quiero interpolar entre ellos, de modo que siga un camino radial de una rotación a la otra. piense en una cámara en un trípode mirando hacia un lado y luego girando.

si interpolo cada componente obtengo un resultado de compresión, entonces creo que necesito interpolar solo ciertos componentes de la matriz. pero cuales?


Necesita convertir la matriz en una representación diferente: los cuaterniones funcionan bien para esto, y la interpolación de cuaterniones es una operación bien definida.


Debe usar SLERP para las partes rotacionales de las matrices, y lineal para las otras partes. La mejor manera es convertir sus matrices en cuaterniones y usar el SLERP cuaternario (más simple): http://en.wikipedia.org/wiki/Slerp .

Sugiero leer Graphic Gems II o III, específicamente las secciones sobre matrices en descomposición en transformaciones más simples. Aquí está la fuente de Spencer W. Thomas para este capítulo:

http://tog.acm.org/resources/GraphicsGems/gemsii/unmatrix.c

Por supuesto, te sugiero que aprendas cómo hacerlo tú mismo. Realmente no es tan difícil, solo un montón de álgebra molesta. Y, por último, aquí hay un documento excelente sobre cómo convertir una matriz en un cuaternión, y viceversa, mediante el software Id: http://cache-www.intel.com/cd/00/00/29/37/293748_293748.pdf

Editar : Esta es la fórmula que casi todo el mundo cita, es de un documento de SIGGRAPH de 1985.

Donde :

- 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

Código:

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; }

De: http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/