2013-09-16 5 views
2

내 자신의 쿼터니언 클래스를 만들려고하고 있는데 이상한 결과가납니다. 회전하려고하는 큐브가 미친 듯이 깜박이거나 뒤 틀릴 수 있습니다.쿼터니언이 뒤틀 리거나 깜박임

entity->Quat.AddRotation(vec4(1.0f, 1.0f, 0.0f, 45.f)); 

그리고 작은 금액으로 추가하여 회전하려고 각 프레임 : 내가 엔티티를 생성 할 때 나는 그것을 사원 수를 줄

void Quaternion::AddRotation(vec4 v) 
{ 
    Quaternion temp(v.x, v.y, v.z, v.w); 
    *this = temp * (*this); 
} 

mat4 Quaternion::GenerateMatrix(Quaternion &q) 
{ 
    q.Normalize(); 

    //Row order 
    mat4 m(1 - 2*q.y*q.y - 2*q.z*q.z, 2*q.x*q.y - 2*q.w*q.z, 2*q.x*q.z + 2*q.w*q.y, 0, 
      2*q.x*q.y + 2*q.w*q.z, 1 - 2*q.x*q.x - 2*q.z*q.z, 2*q.y*q.z + 2*q.w*q.x, 0, 
      2*q.x*q.z - 2*q.w*q.y, 2*q.y*q.z - 2*q.w*q.x, 1 - 2*q.x*q.x - 2*q.y*q.y, 0, 
      0, 0, 0, 1); 

    //Col order 
    // mat4 m(1 - 2*q.y*q.y - 2*q.z*q.z,2*q.x*q.y + 2*q.w*q.z,2*q.x*q.z - 2*q.w*q.y,0, 
    //   2*q.x*q.y - 2*q.w*q.z,1 - 2*q.x*q.x - 2*q.z*q.z,2*q.y*q.z - 2*q.w*q.x,0, 
    //   2*q.x*q.z + 2*q.w*q.y,2*q.y*q.z + 2*q.w*q.x,1 - 2*q.x*q.x - 2*q.y*q.y,0, 
    //   0,0,0,1); 

    return m; 
} 

:

내 코드입니다

for (int i = 0; i < Entities.size(); i++) 
{ 
    if (Entities[i] != NULL) 
    { 
     Entities[i]->Quat.AddRotation(vec4(0.5f, 0.2f, 1.0f, 0.000005f)); 
     Entities[i]->DrawModel(); 
    } 
    else 
     break; 
} 

마지막으로 각 큐브를 그립니다.

void Entity::DrawModel() 
{ 
    glPushMatrix(); 

    //Rotation 
    mat4 RotationMatrix; 
    RotationMatrix = this->Quat.GenerateMatrix(this->Quat); 

    //Position 
    mat4 TranslationMatrix = glm::translate(mat4(1.0f), this->Pos); 

    this->Trans = TranslationMatrix * RotationMatrix; 

    glMultMatrixf(value_ptr(this->Trans)); 

    if (this->shape != NULL) 
     this->shape->DrawShape(); 

    glPopMatrix(); 
} 

EDIT 0 :이 내가 쿼터니온을 학습하는 데 사용하는 튜토리얼입니다 : 결국에 회전 행렬을 공부하지 않고 http://www.cprogramming.com/tutorial/3d/quaternions.html

+0

그러면 코드가 어딘가 잘못되었습니다. 테스트 케이스를 단순화하고 각각의 쿼터니언 방식을 단위 테스트 할 수 있습니까? 손으로 간단한 케이스를 전달하고 가장자리 케이스의 정확성을 확인하십시오. 안타깝게도 체계적이고 합리적인 코딩 이외에는 아마도 앞서 언급 한 TDD가있는 것은 아닙니다. –

+0

예, 코드가 올바르지 않습니다. 나는 당신의 답을 이해할 수 있는지 100 % 확신하지 못했습니다. 제 영어는 최고가 아닙니다. 나는 간단한 큐브를 렌더링하는 것만으로 가능한 한 기본으로 유지하려고 노력했습니다. 더 쉬운 테스트 케이스를 설정하는 방법을 모르겠습니다. 미안합니다. 이것은 쿼터니언에 관해서 제가 사용하고있는 모든 코드입니다. 응답 해 주셔서 감사합니다! – Edvin

+0

더 간단한 코드는 아무 것도 렌더링하지 않으며 매우 간단한 데이터에서 숫자를 계산하고 출력하여 직접 확인할 수 있습니다. 행렬 및 쿼터니언 (또는 더 신뢰할 수있는 다른 쿼터니언 라이브러리)을 사용하여 동등한 변환을 시도한 다음 결과가 동일한 지 확인할 수 있습니다. 희망을 조금 지워줍니다. –

답변

0

, 내가 생각할 수있는 두 가지 버그가 있습니다. 첫 번째는 회전 행렬 R이 직각이 아니므로 R의 역수가 전치 행렬과 같지 않다는 것입니다. 이로 인해 오브젝트가 뒤틀릴 수 있습니다. 버그를 숨기는 두 번째 장소는 쿼터니언의 곱셈입니다.

+0

확인했습니다. inverse! = 전치. 나에게 상기시켜 줘서 고마워, 나는 그 문제를 조사하고 해결책을 찾는다. – Edvin

0

회전 행렬에 실수가 있습니다. 요소 (2,3)를 요소 (3,2)와 교환 해보십시오.

+0

내 깜빡 거리는 문제를 해결했습니다! 감사! 하지만 이제 다른 문제가 생겼습니다 ... 객체는 Y 축을 중심으로 회전합니다. 나는 그 문제를 더 조사 할 것이다. 적어도 이것은 깜박 거림을 디버그하는 것이 더 쉽습니다 ... – Edvin