2010-12-14 10 views
13

Ich habe ein Modell um eine Quaternion gedreht. Ich kann nur die Rotation einstellen, ich kann nichts hinzufügen oder subtrahieren. Ich muss den Wert einer Achse erhalten und dann einen Winkel (vielleicht einen Grad oder Bogenmaß?) Hinzufügen und dann die modifizierte Quaternion hinzufügen.rotieren eine Quaternion auf 1 Achse?

Wie kann ich das tun? (Antwort auf jeder Achse).

+1

Ich glaube, Sie brauchen ein bisschen weiter zu klären. Sie sagen, Sie können nur die Rotation einstellen ... Eine Quaternion dient dem gleichen Zweck wie eine Rotationsmatrix. Der Unterschied liegt darin, dass die Quaternion numerisch stabil ist, aber für die 3D-Geometrie teurer ist, aber für die Verkettung weniger teuer ist ... Sie werden typischerweise verwendet, wenn lange Rotationsreihen angewendet werden müssen und dann wieder in Rotation umgewandelt werden Matrizen vor der Anwendung. Bitte klären Sie, was Sie meinen, Antwort auf jeder Achse, vielleicht wollen Sie Quaternion -> drei Rotations-Matrix, wo jeder über eine Achse ist? – Quaternion

Antwort

29

Sie können zwei Quaternionen miteinander multiplizieren, um eine dritte Quaternion zu erhalten, die das Ergebnis der zwei Rotationen ist. Beachten Sie, dass die Quaternion-Multiplikation nicht kommutativ ist, was bedeutet, dass die Reihenfolge wichtig ist (wenn Sie dies einige Male in Ihrem Kopf tun, können Sie sehen, warum).

Sie können eine quaternion erzeugen, die sich um eine bestimmte Achse mit so etwas wie dies (entschuldigen Sie die Tatsache, dass es C++, nicht Java), die eine Drehung um einen bestimmten Winkel darstellt:

Quaternion Quaternion::create_from_axis_angle(const double &xx, const double &yy, const double &zz, const double &a) 
{ 
    // Here we calculate the sin(theta/2) once for optimization 
    double factor = sin(a/2.0); 

    // Calculate the x, y and z of the quaternion 
    double x = xx * factor; 
    double y = yy * factor; 
    double z = zz * factor; 

    // Calcualte the w value by cos(theta/2) 
    double w = cos(a/2.0); 

    return Quaternion(x, y, z, w).normalize(); 
} 

So um das zu drehen B. x-Achse, können Sie eine Quaternion mit createFromAxisAngle(1, 0, 0, M_PI/2) erstellen und sie mit der aktuellen Rotationsquaternion Ihres Modells multiplizieren.

+3

Das hat funktioniert. Vielen Dank!^_^^ – William

+0

@William - keine Sorgen – sje397

+2

Also, wenn ich eine Quaternion mit einer Rotation von -15 Grad auf der X-Achse erstellen möchte, sollte ich createFromAxisAngle (1, 0, 0, -15 * PI/180) aufrufen? Vielen Dank! – VladN

2

Haben einen lauffähigen Code von sje397 Post zum Testen anderer Details später gemacht, dachte ich würde teilen. Schließlich benutze C den Grund für keine Quaternion-Klasse.

#include <iostream> 
#include <math.h> 
using namespace std; 

struct float4{ 
    float x; 
    float y; 
    float z; 
    float w; 
}; 
float4 make_float4(float x, float y, float z, float w){ 
    float4 quat = {x,y,z,w}; 
    return quat; 
} 
float dot(float4 a) 
{ 
    return (((a.x * a.x) + (a.y * a.y)) + (a.z * a.z)) + (a.w * a.w); 
} 
float4 normalize(float4 q) 
{ 
    float num = dot(q); 
    float inv = 1.0f/(sqrtf(num)); 
    return make_float4(q.x * inv, q.y * inv, q.z * inv, q.w * inv); 
} 
float4 create_from_axis_angle(const float &xx, const float &yy, const float &zz, const float &a) 
{ 
    // Here we calculate the sin(theta/2) once for optimization 
    float factor = sinf(a/2.0f); 

    float4 quat; 
    // Calculate the x, y and z of the quaternion 
    quat.x = xx * factor; 
    quat.y = yy * factor; 
    quat.z = zz * factor; 

    // Calcualte the w value by cos(theta/2) 
    quat.w = cosf(a/2.0f); 
    return normalize(quat); 
} 
int main() 
{ 
    float degrees = 10.0f; 
    float4 quat = create_from_axis_angle(1, 0, 0, degrees*(3.14159f/180.0f)); 
    cout << "> (" << quat.x << ", " <<quat.y << ", " <<quat.z << ", " <<quat.w << ")" << endl; 
    return 0; 
} 

Ausgabe

(0,0871557, 0, 0, 0,996195)