2010-11-04 14 views
12

Ich habe zwei Rotationsmatrizen, die beliebige Rotationen beschreiben. (4x4 Opengl kompatibel)interpolieren zwischen Rotationsmatrizen

jetzt interpoliere ich zwischen ihnen, so dass es einen radialen Weg von einer Rotation zur anderen folgt. Denken Sie an eine Kamera auf einem Stativ, die in eine Richtung schaut und dann rotiert.

Wenn ich jede Komponente interpoliere, bekomme ich ein Quetschergebnis, also denke ich, dass ich nur bestimmte Komponenten der Matrix interpolieren muss. aber welche?

Antwort

1

Sie müssen die Matrix in eine andere Darstellung konvertieren - Quaternionen funktionieren dafür gut, und das Interpolieren von Quaternionen ist eine wohldefinierte Operation.

+0

Dank! Wie kann ich eine Matrix in eine Quaternion umwandeln? – clamp

+0

Ich schlage vor, Sie beginnen mit dem Lesen dieser: http://en.wikipedia.org/wiki/Quaternion – tdammers

14

Sie müssen SLERP für die rotierenden Teile der Matrizen und linear für die anderen Teile verwenden. Der beste Weg ist, Ihre Matrizen in Quaternionen umzuwandeln und das (einfachere) Quaternion SLERP zu verwenden: http://en.wikipedia.org/wiki/Slerp.

Ich empfehle Grafik Edelsteine ​​II oder III, insbesondere die Abschnitte über die Zerlegung von Matrizen in einfachere Transformationen zu lesen. Hier ist Spencer W. Thomas Quelle für dieses Kapitel:

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

Natürlich, ich schlage vor, Sie lernen, wie man dies selbst zu tun. Es ist wirklich nicht so schwer, nur eine Menge nerviger Algebra. Und schließlich ist hier ein großes Papier, wie eine Matrix in eine Quaternion drehen und zurück, von Id Software: http://cache-www.intel.com/cd/00/00/29/37/293748_293748.pdf


bearbeiten: Dies ist die Formel so ziemlich jeder zitiert, es ist von einem 1985 SIGGRAPH Papier.

alt text

Wo:

- 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 

Code:

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

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

+0

ok, danke sagen wir, dass ich stattdessen Quaternions verwenden. interpoliere ich einfach jede der 4 Komponenten, um einen reibungslosen Übergang zu erhalten? – clamp

+0

Bearbeitete meine Antwort mit der Formel und etwas einfacherem Code zu verdauen. –

+0

Ihr erstes Bündel von Links funktioniert nicht mehr :( – Narfanator

Verwandte Themen