2010-12-14 9 views
13

Tengo un modelo girado por un cuaternión. Solo puedo configurar la rotación, no puedo sumar ni restar de nada. Necesito obtener el valor de un eje, y luego agregarle un ángulo (¿tal vez un grado o radianes?) Y luego volver a agregar el cuaternión modificado.girando un cuaternión en 1 eje?

¿Cómo puedo hacer esto? (respuesta en cada eje).

+1

creo que es necesario aclarar un poco más lejos. Usted dice que solo puede establecer la rotación ... Un cuaternión tiene el mismo propósito que una matriz de rotación. La diferencia es que el cuaternión es numéricamente estable, son más caros de aplicar a la geometría 3D pero son menos costosos para la concatenación ... Por lo tanto, se usan normalmente cuando se deben aplicar series largas de rotaciones y luego se vuelven a transformar en rotación matrices antes de la aplicación. Por favor, aclare lo que quiere decir con respuesta en cada eje, tal vez desee cuaternión -> tres matriz de rotación donde cada uno tiene más o menos un eje. – Quaternion

Respuesta

29

Puede multiplicar dos cuaterniones para producir un tercer cuaternión que es el resultado de las dos rotaciones. Tenga en cuenta que la multiplicación del cuaternión no es conmutativa, lo que significa que el orden importa (si hace esto en su cabeza varias veces, puede ver por qué).

Puede producir un cuaternión que representa una rotación en un ángulo dado en torno a un eje determinado con algo como esto (excusa el hecho de que es C++, no java):

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

Así que para girar alrededor del eje x, por ejemplo, puede crear un cuaternión con createFromAxisAngle(1, 0, 0, M_PI/2) y multiplicarlo por el cuaternión de rotación actual de su modelo.

+3

Eso funcionó. ¡Muchas gracias!^_^ – William

+0

@William - no hay preocupaciones – sje397

+2

Entonces, si quiero crear un cuaternión con una rotación de -15 grados en el eje X, debería llamar a createFromAxisAngle (1, 0, 0, -15 * PI/180)? ¡Gracias! – VladN

2

Hice un código de la publicación de sje397 para probar otros detalles más tarde, pensé que compartiría. Eventualmente usando C el motivo de ninguna clase de Quaternion.

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

salida

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

Cuestiones relacionadas