수양버들's | 수양버들
http://blog.naver.com/egohim/70004640696 데브피아 에서 인용한 글입니다.
방식 1-1. 두 벡터의 Radian값을 구하고
1-2. 두 벡터의 외적을 구해 나온 값을 Axis의 x, y, z를 기준으로
1-3. 쿼터니언 공식에 대입
http://blog.naver.com/egohim/70004640696 데브피아 에서 인용한 글입니다.
방식 1-1. 두 벡터의 Radian값을 구하고
1-2. 두 벡터의 외적을 구해 나온 값을 Axis의 x, y, z를 기준으로
1-3. 쿼터니언 공식에 대입
inline void __Quaternion::RotationSetFromVectorAToVectorB(const __Vector3& vA, const __Vector3& vB)
{
//vA와 vB의 사이각을 구한다.
float fRadian = acosf(vA.Dot(vB) / (vA.Magnitude() * vB.Magnitude()));
//완전히 정반대벡터이면 외적 축을 구할수 없기때문에 보정한다.
__Vector3 vA2(vA);
if(D3DX_PI - fRadian < 0.0005f) vA2 += 0.0005f;
//vA와 vB에 직교하는 벡터를 구한다.(cross)
__Vector3 vCross;
vCross.Cross(vA2, vB);
vCross.Normalize();
//vCross를 기준으로 fRadian만큼 회전하는 행렬을 만든다.
this->RotationAxis(vCross, fRadian);
}
inline void __Quaternion::RotationAxis(const __Vector3& v, float fRadian)
{
//D3DXQuaternionRotationAxis(this, &v, fRadian);
this->RotationAxis(v.x, v.y, v.z, fRadian);
}
inline void __Quaternion::RotationAxis(float fX, float fY, float fZ, float fRadian)
{
float fTheta = sinf(fRadian/2.0f);
x = fX * fTheta;
y = fY * fTheta;
z = fZ * fTheta;
w = cosf(fRadian/2.0f);
}
위 공식을 더 간단화 하면 아래와 같다./// 벡터 v0에서 v1까지 호를 그리는 회전 사원수
/// 주의: v0, v1는 단위 벡터
void quatRotationArc(quat* p, const vec3& v0, const vec3& v1)
{
vec3 c;
cross(&c, v0, v1); // 외적값으로 나온 c 벡터
real s = sqrtf((1.0f+dot(v0,v1))*2.0f);
// 중요..
// 외적 결과를 쿼터니언의 Axis값으로 산출
p->x = c.x/s;
p->y = c.y/s;
p->z = c.z/s;
p->w = s/2.0f;
}
댓글
댓글 쓰기