📄 wm4quaternion.inl
字号:
// Wild Magic Source Code
// David Eberly
// http://www.geometrictools.com
// Copyright (c) 1998-2007
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or (at
// your option) any later version. The license is available for reading at
// either of the locations:
// http://www.gnu.org/copyleft/lgpl.html
// http://www.geometrictools.com/License/WildMagicLicense.pdf
//
// Version: 4.0.1 (2007/03/07)
//----------------------------------------------------------------------------
template <class Real>
Quaternion<Real>::Quaternion ()
{
// uninitialized for performance in array construction
}
//----------------------------------------------------------------------------
template <class Real>
Quaternion<Real>::Quaternion (Real fW, Real fX, Real fY, Real fZ)
{
m_afTuple[0] = fW;
m_afTuple[1] = fX;
m_afTuple[2] = fY;
m_afTuple[3] = fZ;
}
//----------------------------------------------------------------------------
template <class Real>
Quaternion<Real>::Quaternion (const Quaternion& rkQ)
{
m_afTuple[0] = rkQ.m_afTuple[0];
m_afTuple[1] = rkQ.m_afTuple[1];
m_afTuple[2] = rkQ.m_afTuple[2];
m_afTuple[3] = rkQ.m_afTuple[3];
}
//----------------------------------------------------------------------------
template <class Real>
Quaternion<Real>::Quaternion (const Matrix3<Real>& rkRot)
{
FromRotationMatrix(rkRot);
}
//----------------------------------------------------------------------------
template <class Real>
Quaternion<Real>::Quaternion (const Vector3<Real>& rkAxis, Real fAngle)
{
FromAxisAngle(rkAxis,fAngle);
}
//----------------------------------------------------------------------------
template <class Real>
Quaternion<Real>::Quaternion (const Vector3<Real> akRotColumn[3])
{
FromRotationMatrix(akRotColumn);
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real>::operator const Real* () const
{
return m_afTuple;
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real>::operator Real* ()
{
return m_afTuple;
}
//----------------------------------------------------------------------------
template <class Real>
inline Real Quaternion<Real>::operator[] (int i) const
{
return m_afTuple[i];
}
//----------------------------------------------------------------------------
template <class Real>
inline Real& Quaternion<Real>::operator[] (int i)
{
return m_afTuple[i];
}
//----------------------------------------------------------------------------
template <class Real>
inline Real Quaternion<Real>::W () const
{
return m_afTuple[0];
}
//----------------------------------------------------------------------------
template <class Real>
inline Real& Quaternion<Real>::W ()
{
return m_afTuple[0];
}
//----------------------------------------------------------------------------
template <class Real>
inline Real Quaternion<Real>::X () const
{
return m_afTuple[1];
}
//----------------------------------------------------------------------------
template <class Real>
inline Real& Quaternion<Real>::X ()
{
return m_afTuple[1];
}
//----------------------------------------------------------------------------
template <class Real>
inline Real Quaternion<Real>::Y () const
{
return m_afTuple[2];
}
//----------------------------------------------------------------------------
template <class Real>
inline Real& Quaternion<Real>::Y ()
{
return m_afTuple[2];
}
//----------------------------------------------------------------------------
template <class Real>
inline Real Quaternion<Real>::Z () const
{
return m_afTuple[3];
}
//----------------------------------------------------------------------------
template <class Real>
inline Real& Quaternion<Real>::Z ()
{
return m_afTuple[3];
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real>& Quaternion<Real>::operator= (const Quaternion& rkQ)
{
m_afTuple[0] = rkQ.m_afTuple[0];
m_afTuple[1] = rkQ.m_afTuple[1];
m_afTuple[2] = rkQ.m_afTuple[2];
m_afTuple[3] = rkQ.m_afTuple[3];
return *this;
}
//----------------------------------------------------------------------------
template <class Real>
int Quaternion<Real>::CompareArrays (const Quaternion& rkQ) const
{
return memcmp(m_afTuple,rkQ.m_afTuple,4*sizeof(Real));
}
//----------------------------------------------------------------------------
template <class Real>
bool Quaternion<Real>::operator== (const Quaternion& rkQ) const
{
return CompareArrays(rkQ) == 0;
}
//----------------------------------------------------------------------------
template <class Real>
bool Quaternion<Real>::operator!= (const Quaternion& rkQ) const
{
return CompareArrays(rkQ) != 0;
}
//----------------------------------------------------------------------------
template <class Real>
bool Quaternion<Real>::operator< (const Quaternion& rkQ) const
{
return CompareArrays(rkQ) < 0;
}
//----------------------------------------------------------------------------
template <class Real>
bool Quaternion<Real>::operator<= (const Quaternion& rkQ) const
{
return CompareArrays(rkQ) <= 0;
}
//----------------------------------------------------------------------------
template <class Real>
bool Quaternion<Real>::operator> (const Quaternion& rkQ) const
{
return CompareArrays(rkQ) > 0;
}
//----------------------------------------------------------------------------
template <class Real>
bool Quaternion<Real>::operator>= (const Quaternion& rkQ) const
{
return CompareArrays(rkQ) >= 0;
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real> Quaternion<Real>::operator+ (
const Quaternion& rkQ) const
{
Quaternion kSum;
for (int i = 0; i < 4; i++)
{
kSum.m_afTuple[i] = m_afTuple[i] + rkQ.m_afTuple[i];
}
return kSum;
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real> Quaternion<Real>::operator- (
const Quaternion& rkQ) const
{
Quaternion kDiff;
for (int i = 0; i < 4; i++)
{
kDiff.m_afTuple[i] = m_afTuple[i] - rkQ.m_afTuple[i];
}
return kDiff;
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real> Quaternion<Real>::operator* (
const Quaternion& rkQ) const
{
// NOTE: Multiplication is not generally commutative, so in most
// cases p*q != q*p.
Quaternion kProd;
kProd.m_afTuple[0] =
m_afTuple[0]*rkQ.m_afTuple[0] -
m_afTuple[1]*rkQ.m_afTuple[1] -
m_afTuple[2]*rkQ.m_afTuple[2] -
m_afTuple[3]*rkQ.m_afTuple[3];
kProd.m_afTuple[1] =
m_afTuple[0]*rkQ.m_afTuple[1] +
m_afTuple[1]*rkQ.m_afTuple[0] +
m_afTuple[2]*rkQ.m_afTuple[3] -
m_afTuple[3]*rkQ.m_afTuple[2];
kProd.m_afTuple[2] =
m_afTuple[0]*rkQ.m_afTuple[2] +
m_afTuple[2]*rkQ.m_afTuple[0] +
m_afTuple[3]*rkQ.m_afTuple[1] -
m_afTuple[1]*rkQ.m_afTuple[3];
kProd.m_afTuple[3] =
m_afTuple[0]*rkQ.m_afTuple[3] +
m_afTuple[3]*rkQ.m_afTuple[0] +
m_afTuple[1]*rkQ.m_afTuple[2] -
m_afTuple[2]*rkQ.m_afTuple[1];
return kProd;
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real> Quaternion<Real>::operator* (Real fScalar) const
{
Quaternion kProd;
for (int i = 0; i < 4; i++)
{
kProd.m_afTuple[i] = fScalar*m_afTuple[i];
}
return kProd;
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real> Quaternion<Real>::operator/ (Real fScalar) const
{
Quaternion kQuot;
int i;
if (fScalar != (Real)0.0)
{
Real fInvScalar = ((Real)1.0)/fScalar;
for (i = 0; i < 4; i++)
{
kQuot.m_afTuple[i] = fInvScalar*m_afTuple[i];
}
}
else
{
for (i = 0; i < 4; i++)
{
kQuot.m_afTuple[i] = Math<Real>::MAX_REAL;
}
}
return kQuot;
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real> Quaternion<Real>::operator- () const
{
Quaternion kNeg;
for (int i = 0; i < 4; i++)
{
kNeg.m_afTuple[i] = -m_afTuple[i];
}
return kNeg;
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real> operator* (Real fScalar, const Quaternion<Real>& rkQ)
{
Quaternion<Real> kProd;
for (int i = 0; i < 4; i++)
{
kProd[i] = fScalar*rkQ[i];
}
return kProd;
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real>& Quaternion<Real>::operator+= (const Quaternion& rkQ)
{
for (int i = 0; i < 4; i++)
{
m_afTuple[i] += rkQ.m_afTuple[i];
}
return *this;
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real>& Quaternion<Real>::operator-= (const Quaternion& rkQ)
{
for (int i = 0; i < 4; i++)
{
m_afTuple[i] -= rkQ.m_afTuple[i];
}
return *this;
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real>& Quaternion<Real>::operator*= (Real fScalar)
{
for (int i = 0; i < 4; i++)
{
m_afTuple[i] *= fScalar;
}
return *this;
}
//----------------------------------------------------------------------------
template <class Real>
inline Quaternion<Real>& Quaternion<Real>::operator/= (Real fScalar)
{
int i;
if (fScalar != (Real)0.0)
{
Real fInvScalar = ((Real)1.0)/fScalar;
for (i = 0; i < 4; i++)
{
m_afTuple[i] *= fInvScalar;
}
}
else
{
for (i = 0; i < 4; i++)
{
m_afTuple[i] = Math<Real>::MAX_REAL;
}
}
return *this;
}
//----------------------------------------------------------------------------
template <class Real>
Quaternion<Real>& Quaternion<Real>::FromRotationMatrix (
const Matrix3<Real>& rkRot)
{
// Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
// article "Quaternion Calculus and Fast Animation".
Real fTrace = rkRot(0,0) + rkRot(1,1) + rkRot(2,2);
Real fRoot;
if (fTrace > (Real)0.0)
{
// |w| > 1/2, may as well choose w > 1/2
fRoot = Math<Real>::Sqrt(fTrace + (Real)1.0); // 2w
m_afTuple[0] = ((Real)0.5)*fRoot;
fRoot = ((Real)0.5)/fRoot; // 1/(4w)
m_afTuple[1] = (rkRot(2,1)-rkRot(1,2))*fRoot;
m_afTuple[2] = (rkRot(0,2)-rkRot(2,0))*fRoot;
m_afTuple[3] = (rkRot(1,0)-rkRot(0,1))*fRoot;
}
else
{
// |w| <= 1/2
int i = 0;
if ( rkRot(1,1) > rkRot(0,0) )
{
i = 1;
}
if ( rkRot(2,2) > rkRot(i,i) )
{
i = 2;
}
int j = ms_iNext[i];
int k = ms_iNext[j];
fRoot = Math<Real>::Sqrt(rkRot(i,i)-rkRot(j,j)-rkRot(k,k)+(Real)1.0);
Real* apfQuat[3] = { &m_afTuple[1], &m_afTuple[2], &m_afTuple[3] };
*apfQuat[i] = ((Real)0.5)*fRoot;
fRoot = ((Real)0.5)/fRoot;
m_afTuple[0] = (rkRot(k,j)-rkRot(j,k))*fRoot;
*apfQuat[j] = (rkRot(j,i)+rkRot(i,j))*fRoot;
*apfQuat[k] = (rkRot(k,i)+rkRot(i,k))*fRoot;
}
return *this;
}
//----------------------------------------------------------------------------
template <class Real>
void Quaternion<Real>::ToRotationMatrix (Matrix3<Real>& rkRot) const
{
Real fTx = ((Real)2.0)*m_afTuple[1];
Real fTy = ((Real)2.0)*m_afTuple[2];
Real fTz = ((Real)2.0)*m_afTuple[3];
Real fTwx = fTx*m_afTuple[0];
Real fTwy = fTy*m_afTuple[0];
Real fTwz = fTz*m_afTuple[0];
Real fTxx = fTx*m_afTuple[1];
Real fTxy = fTy*m_afTuple[1];
Real fTxz = fTz*m_afTuple[1];
Real fTyy = fTy*m_afTuple[2];
Real fTyz = fTz*m_afTuple[2];
Real fTzz = fTz*m_afTuple[3];
rkRot(0,0) = (Real)1.0-(fTyy+fTzz);
rkRot(0,1) = fTxy-fTwz;
rkRot(0,2) = fTxz+fTwy;
rkRot(1,0) = fTxy+fTwz;
rkRot(1,1) = (Real)1.0-(fTxx+fTzz);
rkRot(1,2) = fTyz-fTwx;
rkRot(2,0) = fTxz-fTwy;
rkRot(2,1) = fTyz+fTwx;
rkRot(2,2) = (Real)1.0-(fTxx+fTyy);
}
//----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -