00001 #pragma once
00002
00003 #include "common.h"
00004 #include <math.h>
00005 #include "Vector.h"
00006
00008
00012 class Quaternion
00013 {
00014 public:
00015 Quaternion()
00016 {
00017 Set(Vector(0.0f,0.0f,0.0f),0.0f);
00018 };
00019
00020 Quaternion(const Vector &vecV, const float fS)
00021 {
00022 Set(vecV,fS);
00023 };
00024
00025 Quaternion(const Vector &vecV)
00026 {
00027 Set(vecV,0.0f);
00028 };
00029
00030 Quaternion(const float fAngle, const Vector &vecAxis)
00031 {
00032 float fD = fAngle * 0.5f;
00033 Set(vecAxis.GetNormalized() * sinf(fD),cosf(fD));
00034 };
00035
00036 Quaternion(const Vector &vecFrom, const Vector &vecTo)
00037 {
00038 const float fAngle = acosf(vecFrom.GetNormalized().GetDot(vecTo.GetNormalized()));
00039 const Vector vecAxis = vecFrom.GetNormalized().GetCross(vecTo.GetNormalized());
00040 (*this) = Quaternion(fAngle,vecAxis);
00041 };
00042
00043 ~Quaternion()
00044 {
00045 };
00046
00047 void Set(const Vector &vecV, const float fS)
00048 {
00049 m_vecVector = vecV;
00050 m_fScalar = fS;
00051 normalize();
00052 };
00053
00054 void SetVector(const Vector &vecV)
00055 {
00056 Set(vecV,GetScalar());
00057 };
00058
00059 void SetScalar(const float fS)
00060 {
00061 Set(GetVector(),fS);
00062 };
00063
00064 const Vector & GetVector() const
00065 {
00066 return m_vecVector;
00067 };
00068
00069 const float & GetScalar() const
00070 {
00071 return m_fScalar;
00072 };
00073
00074 const float GetMagnitude() const
00075 {
00076 return sqrtf( GetScalar()*GetScalar() + GetVector().GetMagnitude() * GetVector().GetMagnitude());
00077 };
00078
00079 const Quaternion GetNormalized() const
00080 {
00081 Quaternion quaNew = *this;
00082 float fMagnitude = quaNew.GetMagnitude();
00083
00084 if (fMagnitude > 0.0f)
00085 {
00086 quaNew.m_vecVector /= fMagnitude;
00087 quaNew.m_fScalar /= fMagnitude;
00088 }
00089
00090 return quaNew;
00091 };
00092
00093 const Quaternion GetInverse() const
00094 {
00095 return Quaternion(GetVector()*-1.0f,GetScalar()).GetNormalized();
00096 };
00097
00098 void normalize()
00099 {
00100 (*this) = GetNormalized();
00101 };
00102
00103 void invert()
00104 {
00105 (*this) = GetInverse();
00106 };
00107
00108 const bool operator==(const Quaternion & quaOther) const
00109 {
00110 return (GetVector() == quaOther.GetVector()) && (GetScalar() == quaOther.GetScalar());
00111 };
00112
00113 const bool operator!=(const Quaternion & quaOther) const
00114 {
00115 return !(*this == quaOther);
00116 };
00117
00118 const Quaternion & operator*=(const float & fOther)
00119 {
00120 Set(GetVector() * fOther,GetScalar() * fOther);
00121 return *this;
00122 };
00123
00124 const Quaternion & operator/=(const float & fOther)
00125 {
00126 Set(GetVector() / fOther,GetScalar() / fOther);
00127 return *this;
00128 };
00129
00130 const Quaternion & operator+=(const Quaternion & quaOther)
00131 {
00132 Set(GetVector() + quaOther.GetVector(),GetScalar() + quaOther.GetScalar());
00133 return *this;
00134 };
00135
00136 const Quaternion & operator-=(const Quaternion & quaOther)
00137 {
00138 Set(GetVector() - quaOther.GetVector(),GetScalar() - quaOther.GetScalar());
00139 return *this;
00140 };
00141
00142 const Quaternion & operator*=(const Quaternion& quaOther)
00143 {
00144 Set(
00145 GetVector().GetCross(quaOther.GetVector()) + GetVector() * quaOther.GetScalar() + quaOther.GetVector() * GetScalar(),
00146 GetScalar() * quaOther.GetScalar() - GetVector().GetDot(quaOther.GetVector()));
00147 return *this;
00148 };
00149
00150 const Quaternion operator*(const float fOther) const
00151 {
00152 Quaternion quaNew = *this;
00153 quaNew *= fOther;
00154 return quaNew;
00155 };
00156
00157 const Quaternion operator/(const float fOther) const
00158 {
00159 Quaternion quaNew = *this;
00160 quaNew *= fOther;
00161 return quaNew;
00162 };
00163
00164 const Quaternion operator+(const Quaternion & quaOther) const
00165 {
00166 Quaternion quaNew = *this;
00167 quaNew += quaOther;
00168 return quaNew;
00169 };
00170
00171 const Quaternion operator-(const Quaternion & quaOther) const
00172 {
00173 Quaternion quaNew = *this;
00174 quaNew += quaOther;
00175 return quaNew;
00176 };
00177
00178 const Quaternion operator*(const Quaternion & quaOther) const
00179 {
00180 Quaternion quaNew = *this;
00181 quaNew *= quaOther;
00182 return quaNew;
00183 };
00184
00185 const Vector operator*(const Vector &vecOther) const
00186 {
00187 Quaternion quaRotated = (*this * Quaternion(vecOther) * GetInverse());
00188 return quaRotated.GetVector() * vecOther.GetMagnitude();
00189 };
00190
00191 private:
00192 Vector m_vecVector;
00193 float m_fScalar;
00194 };
00195
00196
00197 inline std::ostream & operator << (std::ostream & os, const Quaternion & quaQuaternion)
00198 {
00199 os << "(" << quaQuaternion.GetVector() << ";" << quaQuaternion.GetScalar() << ")";
00200 return os;
00201 }
00202
00203 inline std::istream & operator>> (std::istream & is, Quaternion & quaQuaternion)
00204 {
00205 Vector vecV;
00206 float fS;
00207
00208 if (is >> eat("(") >> vecV >> eat(";") >> fS >> eat(")"))
00209 quaQuaternion.Set(vecV,fS);
00210
00211 return is;
00212 }