00001 #pragma once
00002
00003 #include "common.h"
00004 #include <math.h>
00005 #include "Vector.h"
00006
00007
00008 class Quaternion
00009 {
00010 public:
00011
00015 Quaternion()
00016 {
00017 Set(Vector(0.0f,0.0f,0.0f),0.0f);
00018 };
00019
00020
00026 Quaternion(const Vector &vecV, const float fS)
00027 {
00028 Set(vecV,fS);
00029 };
00030
00031
00036 Quaternion(const Vector &vecV)
00037 {
00038 Set(vecV,0.0f);
00039 };
00040
00041
00047 Quaternion(const float fAngle, const Vector &vecAxis)
00048 {
00049 float fD = fAngle * 0.5f;
00050 Set(vecAxis.GetNormalized() * sinf(fD),cosf(fD));
00051 };
00052
00053
00059 Quaternion(const Vector &vecFrom, const Vector &vecTo)
00060 {
00061 const float fAngle = acosf(vecFrom.GetNormalized().GetDot(vecTo.GetNormalized()));
00062 const Vector vecAxis = vecFrom.GetNormalized().GetCross(vecTo.GetNormalized());
00063 (*this) = Quaternion(fAngle,vecAxis);
00064 };
00065
00066
00070 ~Quaternion()
00071 {
00072 };
00073
00074
00080 void Set(const Vector &vecV, const float fS)
00081 {
00082 m_vecVector = vecV;
00083 m_fScalar = fS;
00084 normalize();
00085 };
00086
00087
00092 void SetVector(const Vector &vecV)
00093 {
00094 Set(vecV,GetScalar());
00095 };
00096
00097
00102 void SetScalar(const float fS)
00103 {
00104 Set(GetVector(),fS);
00105 };
00106
00107
00112 const Vector & GetVector() const
00113 {
00114 return m_vecVector;
00115 };
00116
00117
00122 const float & GetScalar() const
00123 {
00124 return m_fScalar;
00125 };
00126
00127
00132 const float GetMagnitude() const
00133 {
00134 return sqrtf( GetScalar()*GetScalar() + GetVector().GetMagnitude() * GetVector().GetMagnitude());
00135 };
00136
00137
00142 const Quaternion GetNormalized() const
00143 {
00144 Quaternion quaNew = *this;
00145 float fMagnitude = quaNew.GetMagnitude();
00146
00147 if (fMagnitude > 0.0f)
00148 {
00149 quaNew.m_vecVector /= fMagnitude;
00150 quaNew.m_fScalar /= fMagnitude;
00151 }
00152
00153 return quaNew;
00154 };
00155
00156
00161 const Quaternion GetInverse() const
00162 {
00163 return Quaternion(GetVector()*-1.0f,GetScalar()).GetNormalized();
00164 };
00165
00166
00170 void normalize()
00171 {
00172 (*this) = GetNormalized();
00173 };
00174
00175
00179 void invert()
00180 {
00181 (*this) = GetInverse();
00182 };
00183
00184 const bool operator==(const Quaternion & quaOther) const
00185 {
00186 return (GetVector() == quaOther.GetVector()) && (GetScalar() == quaOther.GetScalar());
00187 };
00188
00189 const bool operator!=(const Quaternion & quaOther) const
00190 {
00191 return !(*this == quaOther);
00192 };
00193
00194 const Quaternion & operator*=(const float & fOther)
00195 {
00196 Set(GetVector() * fOther,GetScalar() * fOther);
00197 return *this;
00198 };
00199
00200 const Quaternion & operator/=(const float & fOther)
00201 {
00202 Set(GetVector() / fOther,GetScalar() / fOther);
00203 return *this;
00204 };
00205
00206 const Quaternion & operator+=(const Quaternion & quaOther)
00207 {
00208 Set(GetVector() + quaOther.GetVector(),GetScalar() + quaOther.GetScalar());
00209 return *this;
00210 };
00211
00212 const Quaternion & operator-=(const Quaternion & quaOther)
00213 {
00214 Set(GetVector() - quaOther.GetVector(),GetScalar() - quaOther.GetScalar());
00215 return *this;
00216 };
00217
00218 const Quaternion & operator*=(const Quaternion& quaOther)
00219 {
00220 Set(
00221 GetVector().GetCross(quaOther.GetVector()) + GetVector() * quaOther.GetScalar() + quaOther.GetVector() * GetScalar(),
00222 GetScalar() * quaOther.GetScalar() - GetVector().GetDot(quaOther.GetVector()));
00223 return *this;
00224 };
00225
00226 const Quaternion operator*(const float fOther) const
00227 {
00228 Quaternion quaNew = *this;
00229 quaNew *= fOther;
00230 return quaNew;
00231 };
00232
00233 const Quaternion operator/(const float fOther) const
00234 {
00235 Quaternion quaNew = *this;
00236 quaNew *= fOther;
00237 return quaNew;
00238 };
00239
00240 const Quaternion operator+(const Quaternion & quaOther) const
00241 {
00242 Quaternion quaNew = *this;
00243 quaNew += quaOther;
00244 return quaNew;
00245 };
00246
00247 const Quaternion operator-(const Quaternion & quaOther) const
00248 {
00249 Quaternion quaNew = *this;
00250 quaNew += quaOther;
00251 return quaNew;
00252 };
00253
00254 const Quaternion operator*(const Quaternion & quaOther) const
00255 {
00256 Quaternion quaNew = *this;
00257 quaNew *= quaOther;
00258 return quaNew;
00259 };
00260
00261 const Vector operator*(const Vector &vecOther) const
00262 {
00263 Quaternion quaRotated = (*this * Quaternion(vecOther) * GetInverse());
00264 return quaRotated.GetVector() * vecOther.GetMagnitude();
00265 };
00266
00267 private:
00269 Vector m_vecVector;
00271 float m_fScalar;
00272 };
00273
00274
00275 inline std::ostream & operator << (std::ostream & os, const Quaternion & quaQuaternion)
00276 {
00277 os << "(" << quaQuaternion.GetVector() << ";" << quaQuaternion.GetScalar() << ")";
00278 return os;
00279 }
00280
00281 inline std::istream & operator>> (std::istream & is, Quaternion & quaQuaternion)
00282 {
00283 Vector vecV;
00284 float fS;
00285
00286 if (is >> eat("(") >> vecV >> eat(";") >> fS >> eat(")"))
00287 quaQuaternion.Set(vecV,fS);
00288
00289 return is;
00290 }