00001 #pragma once
00002
00003 #include "Vector.h"
00004
00005
00006 class Quaternion
00007 {
00008 public:
00009 Quaternion()
00010 {
00011 Set(Vector(0.0f,0.0f,0.0f),0.0f);
00012 };
00013
00014 Quaternion(const Vector &vecV, const float fS)
00015 {
00016 Set(vecV,fS);
00017 };
00018
00019 Quaternion(const Vector &vecV)
00020 {
00021 Set(vecV,0.0f);
00022 };
00023
00024 Quaternion(const float fAngle, const Vector &vecAxis)
00025 {
00026 float fD = fAngle * 0.5f;
00027 Set(vecAxis.GetNormalized() * sinf(fD),cosf(fD));
00028 };
00029
00030 Quaternion(const Vector &vecFrom, const Vector &vecTo)
00031 {
00032 const float fAngle = acosf(vecFrom.GetNormalized().GetDot(vecTo.GetNormalized()));
00033 const Vector vecAxis = vecFrom.GetNormalized().GetCross(vecTo.GetNormalized());
00034 (*this) = Quaternion(fAngle,vecAxis);
00035 };
00036
00037 ~Quaternion()
00038 {
00039 };
00040
00041 void Set(const Vector &vecV, const float fS)
00042 {
00043 m_vecVector = vecV;
00044 m_fScalar = fS;
00045 normalize();
00046 };
00047
00048 void SetVector(const Vector &vecV)
00049 {
00050 Set(vecV,GetScalar());
00051 };
00052
00053 void SetScalar(const float fS)
00054 {
00055 Set(GetVector(),fS);
00056 };
00057
00058 const Vector & GetVector() const
00059 {
00060 return m_vecVector;
00061 };
00062
00063 const float & GetScalar() const
00064 {
00065 return m_fScalar;
00066 };
00067
00068 const float GetMagnitude() const
00069 {
00070 return sqrtf( GetScalar()*GetScalar() + GetVector().GetMagnitude() * GetVector().GetMagnitude());
00071 };
00072
00073 const Quaternion GetNormalized() const
00074 {
00075 Quaternion quaNew = *this;
00076 float fMagnitude = quaNew.GetMagnitude();
00077
00078 if (fMagnitude > 0.0f)
00079 {
00080 quaNew.m_vecVector /= fMagnitude;
00081 quaNew.m_fScalar /= fMagnitude;
00082 }
00083
00084 return quaNew;
00085 };
00086
00087 const Quaternion GetInverse() const
00088 {
00089 return Quaternion(GetVector()*-1.0f,GetScalar()).GetNormalized();
00090 };
00091
00092 void normalize()
00093 {
00094 (*this) = GetNormalized();
00095 };
00096
00097 void invert()
00098 {
00099 (*this) = GetInverse();
00100 };
00101
00102 const bool operator==(const Quaternion & quaOther) const
00103 {
00104 return (GetVector() == quaOther.GetVector()) && (GetScalar() == quaOther.GetScalar());
00105 };
00106
00107 const bool operator!=(const Quaternion & quaOther) const
00108 {
00109 return !(*this == quaOther);
00110 };
00111
00112 const Quaternion & operator*=(const float & fOther)
00113 {
00114 Set(GetVector() * fOther,GetScalar() * fOther);
00115 return *this;
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 Quaternion & quaOther)
00125 {
00126 Set(GetVector() + quaOther.GetVector(),GetScalar() + quaOther.GetScalar());
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(
00139 GetVector().GetCross(quaOther.GetVector()) + GetVector() * quaOther.GetScalar() + quaOther.GetVector() * GetScalar(),
00140 GetScalar() * quaOther.GetScalar() - GetVector().GetDot(quaOther.GetVector()));
00141 return *this;
00142 };
00143
00144 const Quaternion operator*(const float fOther) const
00145 {
00146 Quaternion quaNew = *this;
00147 quaNew *= fOther;
00148 return quaNew;
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 Quaternion & quaOther) const
00159 {
00160 Quaternion quaNew = *this;
00161 quaNew += quaOther;
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 Vector operator*(const Vector &vecOther) const
00180 {
00181 Quaternion quaRotated = (*this * Quaternion(vecOther) * GetInverse());
00182 return quaRotated.GetVector() * vecOther.GetMagnitude();
00183 };
00184
00185 private:
00186 Vector m_vecVector;
00187 float m_fScalar;
00188 };
00189
00190
00191 inline std::ostream & operator << (std::ostream & os, const Quaternion & quaQuaternion)
00192 {
00193 os << "(" << quaQuaternion.GetVector() << ";" << quaQuaternion.GetScalar() << ")";
00194 return os;
00195 }
00196
00197 inline std::istream & operator>> (std::istream & is, Quaternion & quaQuaternion)
00198 {
00199 Vector vecV;
00200 float fS;
00201
00202 if (is >> eat("(") >> vecV >> eat(";") >> fS >> eat(")"))
00203 quaQuaternion.Set(vecV,fS);
00204
00205 return is;
00206 }