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