마우스 드래그 동작을 객체의 3D 회전으로 변환하는 가장 좋은 방법

StackOverflow https://stackoverflow.com/questions/107413

  •  01-07-2019
  •  | 
  •  

문제

3D로 회전할 수 있는 3D 개체가 있습니다.가장 쉬운 방법은 X 및 Y 마우스 모션을 Y 및 X축에 대한 회전으로 직접 변환하는 것입니다. 그러나 두 축을 따라 약간의 회전이 있는 경우 모델이 회전하는 방식은 매우 반직관적이 ​​됩니다(예:한 축을 기준으로 개체를 180도 뒤집으면 다른 축을 따른 동작이 반전됩니다.

위의 방법을 간단하게 수행할 수 있지만 두 축을 기준으로 회전할 양을 저장하는 대신 전체 회전 행렬을 저장하고 각 마우스 드래그에 대해 동일한 축을 따라 추가로 회전할 수 있지만 그렇게 되면 걱정됩니다. 신속하게 정밀도 문제가 발생합니다.

도움이 되었습니까?

해결책

누산기 행렬을 만들고 항등원으로 초기화합니다.

각 프레임에서는 객체를 그리기 전에 모델 뷰/월드 매트릭스 상태에 이를 적용합니다.

마우스 움직임 시, Sensitivity_constant * delta_x를 사용하여 X축에 대한 회전 행렬을 구성합니다.다른 구성요소에 대해 Y축을 중심으로 또 다른 회전 행렬을 구성합니다.하나를 곱한 다음 다른 하나를 누산기에 곱합니다.

마우스를 움직이면 누산기가 변경됩니다.그릴 때 예상대로 개체의 방향이 지정됩니다.

또한 쿼터니언에 대해 말하는 사람이 옳습니다.이는 작은 증분 변경에만 적합해 보입니다.대각선으로 빠르게 드래그하면 예상한 대로 회전하지 않습니다.

다른 팁

각 마우스 동작에 따라 증분적으로 또는 드래그 시작 위치를 기준으로 현재 드래그 방향에 수직인 축을 중심으로 개체를 회전하는 것이 아마도 가장 직관적일 것입니다.두 가지 옵션은 각각 장단점이 있는 약간 다른 사용자 상호 작용을 제공합니다.

이있다 비교적 간단하다 회전하는 축을 나타내는 각도와 3D 벡터를 회전 행렬로 변환하는 방법입니다.

증분 회전을 통해 원시 회전 행렬을 업데이트하면 행렬이 더 이상 순수한 회전 행렬이 되지 않는다는 점은 맞습니다.이는 3x3 회전 행렬이 회전을 표현하는 데 필요한 것보다 3배 많은 데이터를 갖기 때문입니다.

회전을 표현하는 보다 간단한 방법은 다음과 같습니다. 오일러 각도, 최소 3개의 값 벡터를 갖습니다.현재 회전을 오일러 각도 벡터로 가져와 이를 행렬로 변환하고 회전(증분 또는 기타)을 적용한 다음 행렬을 다시 오일러 각도 벡터로 변환할 수 있습니다.마지막 단계에서는 자연스럽게 행렬의 비회전 구성 요소를 제거하므로 다시 한 번 다음 상태에 대한 순수한 회전 행렬이 생성됩니다.

오일러 각도는 개념적으로는 훌륭하지만 앞뒤로 변환하는 데는 많은 작업이 필요합니다.

좀 더 실용적인 선택은 쿼터니언 (또한), 이는 4개의 요소 벡터입니다.4개의 요소는 회전과 균등 스케일을 지정하며, 벡터를 단위 길이로 정규화하면 스케일 인수가 1.0이 됩니다.각도축 값은 다음과 같이 매우 쉽게 쿼터니언 값으로 변환될 수 있음이 밝혀졌습니다.

q.x = sin(0.5*angle) * axis.x;
q.y = sin(0.5*angle) * axis.y;
q.z = sin(0.5*angle) * axis.z;
q.w = cos(0.5*angle);

그런 다음 현재 회전 쿼터니언과 증분 회전 쿼터니언의 쿼터니언 곱(간단한 곱셈과 덧셈만 사용)을 취하여 두 회전 수행을 나타내는 새 쿼터니언을 얻을 수 있습니다.이 시점에서 길이를 정규화하여 순수한 회전을 보장할 수 있지만, 그렇지 않은 경우 계속해서 반복적으로 회전을 결합할 수 있습니다.

전통적인 그래픽 API를 사용하여 모델을 회전된 상태로 표시하려는 경우 쿼터니언을 회전 행렬로 변환하는 것은 매우 간단합니다(곱셈과 덧셈만 사용).

내 컴퓨터 그래픽 과정에서 우리는 바퀴를 재발명하지 않도록 허용하는 다음 코드를 받았습니다.

트랙볼.h

트랙볼.c

3개 행 각각이 다시 수직이 되도록 회전 행렬을 다시 정규화하여 정밀도 손실을 처리할 수 있습니다.또는 객체에 대한 기존 정보를 기반으로 수정하려는 회전 행렬을 다시 생성할 수 있으며 이렇게 하면 재정규화가 필요하지 않습니다.

또는 다음을 사용할 수 있습니다. 쿼터니언, 이는 회전을 처리하기 위한 오일러 각도의 대안입니다.

나는 초창기에 이것에 대해 많은 것을 배웠습니다. 이 자주 묻는 질문, 이 문제를 다루고 있습니다(다른 응용 프로그램의 경우에도). 오일러는 악마다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top