2012-05-19 3 views
5

오일 회전 각 및 쿼터니온을 사용하여 3D 회전을 제한하는 올바른 방법은 무엇입니까?3D 회전을 제한하는 방법 (오일러)

내 방식에 문제가있는 것처럼 보입니다. 회전을 골격 구조의 뼈대에 애니메이션으로 적용하고 뼈가 시각적으로 잘못된 방향으로 "점프"하고 개별 오일러 구성 요소가 범위의 반대쪽 끝으로 감싸고 있습니다.

저는 오일러 각을 사용하여 현재 방향을 나타내고 쿼터니언으로 변환하여 각 오일러 각도 축을 독립적으로 클램핑합니다.

Euler min = ...; 
Euler max = ...; 

Quat rotation = ...; 
Euler eCurrent = ...; 

// do rotation 
Quat qCurrent = eCurrent.toQuat(); 
qCurrent = qCurrent * rotation; 
eCurrent = qCurrent.toEuler(); 

// constrain 
for (unsigned int i = 0; i < 3; i++) 
    eCurrent[i] = clamp(eCurrent[i], min[i], max[i]); 
+0

일반적으로 쿼터니언을 사용하는 것이 좋습니다. 오히려 오일러 각도의 한계 (예 : 짐발 잠금과 같은 문제)가 발생하지 않기 때문입니다. 복잡한 회전 (예 : 3 축)이 필요할 때마다 쿼터니언을 사용하십시오. 오일러 각은 간단한 것들만으로도 충분합니다. –

+0

오일러 앵글을 사용하는 이유는 내가 그들을 제약 할 수 있기 때문입니다. 나는 쿼터니언을 제한하는 방법을 모른다. – KTC

+0

http://www.geometrictools.com/Documentation/ConstrainedQuaternions.pdf –

답변

0

여기서 문제는 당신이 적용하는 제약이 회전 전혀 관련 적용이 없다는 것입니다 : 여기에 내가 뭘하는지 기본적으로 보여주는 C++ 의사 코드이다. 개념적 관점에서 볼 때 이것은 달성하고자하는 목표입니다.

  • 뼈는 제한되지 않은 상태에 있다고 가정합니다.
  • 회전 적용
  • 에는 뼈가 초과되었습니다. 예인 경우 더 이상 구속되지 않은 위치로 회전하십시오.

오일러 회전을 고정시키는 코드는 뼈를 뒤로 돌리는 부분입니다. 그러나이 코드는 원래 본 회전을 무시하므로 사용자가보고있는 스냅과 같은 이상한 동작을 보게됩니다.

이 함께 작동하는 간단한 방법 대신이 작업을 수행하는 것입니다

  • 이 뼈는 뼈 제약
  • 예 경우를 초과하는 경우
  • 회전을
  • 테스트를 적용 구속되지 않은 상태에있는 가정, 우리는 구속 조건이 움직이는 곳을 찾아야합니다.
    1. 가 회전을 절반, 그것은 뼈가 제약을 초과 역
    2. 적용? 예인 경우 1로 이동합니다.
    3. 아니요 인 경우 회전을 반으로 줄이고 정방향으로 적용하십시오. 고토 2
  • 킵 당신이 당신의 구속의 허용 오차 이내가 될 때까지이

지금이 작동 각도 것으로하고 있지만 회전 quarternions 모든 각도에 적용되고 있기 때문에, 회전 때 어떤 중지됩니다 그러한 제한 중 하나는 자유가있는 경우에도 그물입니다.

대신에 서로 독립적으로 회전을 적용하는 경우 제한을 존중하기 위해 클램핑 또는 위의 기술을 안정적으로 사용할 수 있으며 가능하면 대상과 최대한 근접하게 회전 할 수 있습니다. -

+0

쿼터니온과 오일러 각을 변환하면이 해법을 벗어나는 것처럼 보입니다. 쿼터니언을 사용하면서 회전을 독립적으로 적용하는 방법을 잘 모르겠습니다. – KTC

+0

짧은 대답은 당신이하지 않는다는 것입니다. 독립적으로 회전을 적용해야하는 경우 내부 데이터 구조는 오일러 회전을 별도로 유지해야하며 회전 순서를 적용해야합니다. –

+0

나는 그것을 할 수 없을 것이다. 키 프레임 사이를 보간하기 위해 쿼터니언을 사용하고 싶습니다. – KTC

0

오일러 각도의 한 가지 문제는 동일한 회전을 나타내는 여러 가지 방법이 있으므로 원활하게 회전 순서를 쉽게 만들 수 있지만 회전을 나타내는 각도가 점프 할 수 있다는 것입니다. 각도가 제한된 범위를 벗어났다면 설명하는 것과 같은 효과가 나타납니다.

X 회전 만 관련되어 있다고 가정하고 X 회전을 0도에서 180도 사이로 제한했습니다. 또한 쿼터니온을 오일러 각으로 변환하는 함수가 -180도에서 180도까지의 각도를 부여했다고 상상해보십시오.

그런 다음 회전의 순서를 가지고 :

당신은 변환 기능은 그 결과를 강제하기 때문에 회전이 원활하게 변화하는 경우에도, 결과는 갑자기 한 쪽에서 다른쪽으로 이동합니다 것을 알 수 있습니다
True rotation After conversion After constraint 
179    179     179 
180    180     180 
181    -179     0 

특정 범위 내에서 표현 될 수있다.

쿼터니언을 오일러 각으로 변환 할 때 이전 결과와 가장 가까운 각도를 찾으십시오. 예를 들어 :

eCurrent = closestAngles(qCurrent.toEuler(),eCurrent); 
eConstrained = clampAngles(eCurrent,min,max); 

는 다음의 eCurrent 값을 기억하고 골격에 eConstrained 회전을 적용합니다.

+0

이해가 안됩니다. "closestAngles"라는 용어로 문제를 다시 작성한 것처럼 보입니다. – KTC

+0

요점은 오일러 각으로 변환 할 때 이전 각도를 고려해야하므로 회전의 오일러 표현이 부드럽게 나타납니다. –

+0

자, 무슨 뜻인지 알 겠어. 그래도 각 축에 대해 독립적으로 그렇게 할 수 있다고 확신합니까? 나는 그것을 시도하고 작동하도록 할 수 없었다. 그것은 "점프"를 수정했지만 뼈는 여전히 유효하지 않은 방향으로 끝났습니다. 나는 오일러와 쿼터니언 사이를 앞뒤로 변환하는 것은 각도를 감싸는 것 외에 다른 문제가 있다고 생각합니다. – KTC

관련 문제