나는 세계 공간에 어떤 물체를 가지고 있는데, (0,0,0)이라고 말하고 얼굴을 (10,10,10) 회전시키고 싶다.쿼터니온 (Quaternion) - 회전 할 곳
쿼터니언을 사용하면 어떻게 할 수 있습니까?
나는 세계 공간에 어떤 물체를 가지고 있는데, (0,0,0)이라고 말하고 얼굴을 (10,10,10) 회전시키고 싶다.쿼터니온 (Quaternion) - 회전 할 곳
쿼터니언을 사용하면 어떻게 할 수 있습니까?
을이 질문은 아주 이해가되지 않습니다. 당신은 어떤 대상이 특정 지점에 "직면"하기를 원하지만 충분한 정보를주지는 않는다고 말했습니다.
먼저, 방향이 이면 그 의미는 무엇입니까? OpenGL에서 로컬 참조 프레임의 -z 축이 일부 외부 참조 프레임에서 지정된 방향으로 정렬됨을 의미합니다. 이러한 정렬이 일어나기 위해서는 객체의 관련 축이 현재 "향하고있는"방향을 알아야합니다.
그러나 여전히 고유 한 변환을 정의하지는 않습니다. -z 축 포인트를 만들 방향을 알고 있더라도 개체는 해당 축의 축을 중심으로 주위로 자유롭게 회전 할 수 있습니다. 따라서 gluLookAt()
함수는 'at'방향으로 및 방향을 'up'방향으로 제공해야합니다.
다음으로 알아야 할 사항은 최종 결과가 어떤 형식이어야하는지입니다. 객체의 방향은 종종 쿼터니온 형식으로 저장됩니다. 그러나 그래픽으로 바꾸려면 개체를 회전시킨 다음 회전 행렬이 필요할 수 있습니다.
그래서 몇 가지 가정을합니다. 나는 여러분의 물체가 세계의 중심점 인 c을 중심에두고 기본 정렬을한다고 가정합니다. 즉, 객체의 X, Y 및 Z 축은 세계X, Y 및 Z 축으로 정렬된다. 즉, 세계에 대한 객체의 방향을 항등 행렬 또는 신원 쿼터니언 ([1 0 0 0]
) (w이 먼저 오는 쿼터니언 규칙을 사용)으로 나타낼 수 있습니다.
는 점 페이지와 객체의 -z 축 정렬됩니다 짧은 회전하려면 : = [p.x의 p.y의 p.z]을, 당신은 축 주위 φ에 의해 회전합니다. 이제 우리는 그 값들을 발견 할 것입니다. 먼저 우리는 벡터 PC을 정상화하고 단위 길이 -z 벡터 크로스 제품을 복용 한 후 다시 정상화하여축 찾습니다
= 정규화 (벡터 곱 (를 - z, 정규화 (pc)));
그 내적의 역 코사인 취함으로써 발견되는 두 개의 단위 벡터의 최단 각도 :
φ = ACOS (dotProduct (-z는 정규화 (P-C)));
불행히도, 이것은 두 벡터에 의해 형성된 각도의 절대 값을 측정 한 것입니다. 인 경우 일 때 양수인지 음수인지 알아야합니다. 보다 세련된 방법이 있어야하지만, 가장 먼저 떠오르는 방법은 과 및 -z에 수직 인 세 번째 축을 찾은 다음 목표 축을 사용하여 내적 제품의 부호를 가져 오는 것입니다. 비스 :
B = 벡터 곱 (, -z);
경우
(dotProduct (B 는 정규화 ( P-C)) < 0) = φ -φ;우리 쿼터니온으로 돌리면, 우리 축과의 각도를 일단은 간단하다
Q = COS (φ/2) 죄 (φ/2) ];
이 새로운 쿼터니언은 객체의 새로운 방향을 나타냅니다. 렌더링을 위해 행렬로 변환하거나 쿼터니언 곱셈 규칙을 사용하여 원하는 경우 객체의 정점을 직접 회전 할 수 있습니다.
큰 설명에 감사드립니다. – PeeS
SLERP (Spherical Linear Interpolation)을 사용할 수 있습니다. 이것을 article을 참조하여 C++에서 수행하는 방법을 참조하십시오.
두 벡터 사이의 회전을 나타내는 쿼터니언을 계산하는 예는 Ogre::Vector3 class의 OGRE 소스 코드에서 찾을 수 있습니다.
당신의 설명에 대답하고 이것에 대답하기 위해, 전에 보지 못했던 두 가지 벡터 사이의 퀘스트를 찾기 위해 뻔뻔스럽게 매우 흥미롭고 깔끔한 알고리즘을 복사했습니다. here. 수학적으로, 그것은 유효하고, 당신의 질문이 그것의 배후에 관한 것이기 때문에, 당신이이 의사 코드를 C++로 변환 할 수있을 것이라고 확신합니다.
quaternion q;
vector3 c = cross(v1,v2);
q.v = c;
if (vectors are known to be unit length) {
q.w = 1 + dot(v1,v2);
} else {
q.w = sqrt(v1.length_squared() * v2.length_squared()) + dot(v1,v2);
}
q.normalize();
return q;
해당 의사 코드의 비트를 명확히하는 데 도움이 필요하면 알려주십시오. 그래도 간단해야합니다.
dot(a,b) = a1*b1 + a2*b2 + ... + an*bn
및
cross(a,b) = well, the cross product. it's annoying to type out and
can be found anywhere.
설명해 주셔서 감사합니다. 귀하의 설명과 JCooper 덕분에 제 문제가 해결되었습니다. – PeeS
Quaternion 회전의 수학이나 구현 방법에 대해 묻고 있습니까? 쿼터니언이 어떻게 작동하는지 이해한다면, C++로 구현하는 것은 매우 간단하며 한 번만하는 것이냐 아니냐에 따라 몇 줄의 mathy 코드에서 수행 할 수 있습니다. 당신이 쿼터니언을 이해하지 못한다면, 이것은 틀린 장소에 있습니다. –
@ AK4749 - 안녕하세요, 저는 여기 뒤에서 서있는 수학을 abouth에게 요청하고 있습니다. 두 Vector3을 가졌습니다. 여기서 (1)은 객체 후퇴이고 (2)는이 객체가 회전하려는 위치입니다.이 회전을 나타내는 쿼터니언을 어떻게 계산합니까? – PeeS
쿼터니온은 벡터가 아닌 행렬을 보간하는 데 적합합니다. 두 개의 행렬 (즉, 위치 + 회전)을 만들기 위해서는 적어도 두 세트의 벡터 (위치 + 방향)가 필요합니다. 그런 다음이 행렬을 쿼터니언으로 변환하고, 행렬을 보간하고, 행렬로 다시 변환합니다. –