2010-12-14 5 views
13

저는 쿼터니온에 의해 회전 된 모델을 가지고 있습니다. 회전 만 설정할 수 있으며, 아무것도 추가하거나 뺄 수 없습니다. 나는 축의 가치를 알아야하고, 각도를 추가하거나 (아마도 또는 라디안일까요?) 수정 된 쿼터니온을 다시 추가하는 것보다 필요합니다.1 축에 쿼터니온을 회전 시키시겠습니까?

어떻게하면됩니까? (각 축에 대한 답).

+1

난 당신이 조금 더 명확히 할 필요가 있다고 생각합니다. 여러분은 회전만을 설정할 수 있다고 말합니다 ... 쿼터니온은 회전 행렬과 같은 목적을합니다. 차이점은 쿼터니언은 수치 적으로 안정적이며 3d 형상에 적용하는 데 더 많은 비용이 들지만 연결에는 비용이 덜 듭니다 ... 따라서 일반적으로 일련의 회전을 적용해야 할 때 사용되며 회전으로 다시 변환됩니다 행렬을 적용하기 전에. 각 축에 대한 대답으로 무엇을 의미하는지 명확히하십시오. 아마도 쿼터니언 -> 회전 행렬 3 개가 각각 축에 대해 하나씩 필요하겠습니까? – Quaternion

답변

29

두 개의 쿼터니온을 곱하여 두 개의 회전의 결과 인 세 번째 쿼터니온을 생성 할 수 있습니다. 쿼터니온 곱셈은 교환 적 (commutative)이 아니므로, 순서가 중요하다는 것을 의미합니다 (머리에서 몇 번 이렇게하면 왜 볼 수 있습니다).

당신은 이런 일에 특정 축을 중심으로 특정 각도로 회전 (는 C++이 아닌 자바 사실 변명) 나타내는 사원 수 생산할 수 :

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

그래서 주위에 회전을 예를 들어 x 축을 사용하면 createFromAxisAngle(1, 0, 0, M_PI/2)의 쿼터니언을 만들고 모델의 현재 회전 쿼터니언을 곱할 수 있습니다.

+3

그게 효과가있다. 고마워요!^_^ – William

+0

@William - 걱정하지 마십시오 – sje397

+2

X 축에서 -15도 회전하는 쿼터니언을 만들려면 createFromAxisAngle (1, 0, 0, -15 * PI/180)을 호출해야합니까? 감사! – VladN

2

나중에 다른 세부 정보를 테스트하기 위해 sje397의 게시물에서 실행 가능한 코드를 작성했습니다. 공유 할 것으로 생각됩니다. 결국 Quaternion 클래스가없는 이유를 C 언어를 사용합니다.

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

출력

(0.0871557, 0, 0, 0.996195)

관련 문제