기타/수학적 개념
Direction to Quaternion 방향벡터를 로테이션 (회전) 전환
SpiritLink
2018. 8. 3. 21:07
Vector3 Direction to Quaternion (Rotation)
방향 벡터를 이용해서 쿼터니언 (로테이션) 구하기
this.front.subVectors( this.finalTarget, this.resultPos );
this.front.normalize();
현재 좌표에서 바라볼 대상의 좌표를 뺀다.
정규화 (Normalize) 하면 대상을 바라보는 Look Vector (front)가 생긴다.
this.up.set( 0, 1, 0);
Up vector를 설정한다. (일반적으로 0, 1, 0인 상황)
만약 지구와 같은 구체주변을 맴돈다면
this.up.copy( this.object.position );
this.up.normalize();
자신의 좌표를 이용해서 Up벡터를 구한다. (지구의 중점이 0, 0, 0 이라는 기준으로)
this.right.crossVectors( this.up, this.front );
this.right.normalize();
up벡터와 front벡터를 Cross 시켜서 Right 벡터를 구한다.
this.up.crossVectors( this.front, this.right );
this.up.normalize();
front와 right를 이용해서 다시 Up벡터를 구한다.
일반적으론 이렇게 나온 right, up, front에 적용시키면 로테이션이 적용된다.
이번은 Matrix를 이용해서 Quaternion을 구해보자.
Matrix mBasis = new Matrix(vRight.X, vRight.Y, vRight.Z, 0.0f,
vUp.X, vUp.Y, vUp.Z, 0.0f,
vDirection.X, vDirection.Y, vDirection.Z, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
Quaternion qrot = new Quaternion();
qrot.W = (float)Math.Sqrt(1.0f + mBasis.M11 + mBasis.M22 + mBasis.M33) / 2.0f;
double dfWScale = qrot.W * 4.0;
qrot.X = (float)((mBasis.M32 - mBasis.M23) / dfWScale);
qrot.Y = (float)((mBasis.M13 - mBasis.M31) / dfWScale);
qrot.Z = (float)((mBasis.M21 - mBasis.M12) / dfWScale);
이렇게 나온 쿼터니언 (Quaternion)을 이용해서 Rotation을 적용시키면 된다.