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