| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- $#include "Quaternion.h"
- /// Rotation represented as a four-dimensional normalized vector.
- class Quaternion
- {
- public:
- /// Construct identity quaternion.
- Quaternion() :
- w_(1.0f),
- x_(0.0f),
- y_(0.0f),
- z_(0.0f)
- {
- }
-
- /// Copy-construct from another quaternion.
- Quaternion(const Quaternion& quat) :
- w_(quat.w_),
- x_(quat.x_),
- y_(quat.y_),
- z_(quat.z_)
- {
- }
-
- /// Construct from values.
- Quaternion(float w, float x, float y, float z) :
- w_(w),
- x_(x),
- y_(y),
- z_(z)
- {
- }
-
- /// Construct from an angle (in degrees) and axis.
- Quaternion(float angle, const Vector3& axis)
- {
- FromAngleAxis(angle, axis);
- }
-
- /// Construct from Euler angles (in degrees.)
- Quaternion(float x, float y, float z)
- {
- FromEulerAngles(x, y, z);
- }
-
- /// Construct from the rotation difference between two vectors.
- Quaternion(const Vector3& start, const Vector3& end)
- {
- FromRotationTo(start, end);
- }
-
- /// Construct from orthonormal axes.
- Quaternion(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis)
- {
- FromAxes(xAxis, yAxis, zAxis);
- }
- /// Construct from a rotation matrix.
- Quaternion(const Matrix3& matrix)
- {
- FromRotationMatrix(matrix);
- }
-
- /// Test for equality with another quaternion without epsilon.
- bool operator == (const Quaternion& rhs) const;
-
- /// Multiply with a scalar.
- Quaternion operator * (float rhs) const;
-
- /// Return negation.
- Quaternion operator - () const;
-
- /// Test for equality with another quaternion without epsilon.
- bool operator == (const Quaternion& rhs) const { return w_ == rhs.w_ && x_ == rhs.x_ && y_ == rhs.y_ && z_ == rhs.z_; }
- /// Multiply with a scalar.
- Quaternion operator * (float rhs) const { return Quaternion(w_ * rhs, x_ * rhs, y_ * rhs, z_ * rhs); }
- /// Return negation.
- Quaternion operator - () const { return Quaternion(-w_, -x_, -y_, -z_); }
- /// Add a quaternion.
- Quaternion operator + (const Quaternion& rhs) const { return Quaternion(w_ + rhs.w_, x_ + rhs.x_, y_ + rhs.y_, z_ + rhs.z_); }
- /// Subtract a quaternion.
- Quaternion operator - (const Quaternion& rhs) const { return Quaternion(w_ - rhs.w_, x_ - rhs.x_, y_ - rhs.y_, z_ - rhs.z_); }
-
- /// Multiply a quaternion.
- Quaternion operator * (const Quaternion& rhs) const
- {
- return Quaternion(
- w_ * rhs.w_ - x_ * rhs.x_ - y_ * rhs.y_ - z_ * rhs.z_,
- w_ * rhs.x_ + x_ * rhs.w_ + y_ * rhs.z_ - z_ * rhs.y_,
- w_ * rhs.y_ + y_ * rhs.w_ + z_ * rhs.x_ - x_ * rhs.z_,
- w_ * rhs.z_ + z_ * rhs.w_ + x_ * rhs.y_ - y_ * rhs.x_
- );
- }
-
- /// Multiply a Vector3.
- Vector3 operator * (const Vector3& rhs) const
- {
- Vector3 qVec(x_,y_,z_);
- Vector3 cross1(qVec.CrossProduct(rhs));
- Vector3 cross2(qVec.CrossProduct(cross1));
-
- return rhs + 2.0f * (cross1 * w_ + cross2);
- }
-
- /// Define from an angle (in degrees) and axis.
- void FromAngleAxis(float angle, const Vector3& axis);
- /// Define from Euler angles (in degrees.)
- void FromEulerAngles(float x, float y, float z);
- /// Define from the rotation difference between two vectors.
- void FromRotationTo(const Vector3& start, const Vector3& end);
- /// Define from orthonormal axes.
- void FromAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
- /// Define from a rotation matrix.
- void FromRotationMatrix(const Matrix3& matrix);
-
- /// Normalize to unit length and return the previous length.
- float Normalize()
- {
- float len = sqrtf(LengthSquared());
- if (len >= M_EPSILON)
- *this *= (1.0f / len);
- return len;
- }
-
- /// Return normalized to unit length.
- Quaternion Normalized() const
- {
- float lenSquared = LengthSquared();
- if (lenSquared >= M_EPSILON * M_EPSILON)
- return *this * (1.0f / sqrtf(lenSquared));
- else
- return IDENTITY;
- }
-
- /// Return inverse.
- Quaternion Inverse() const
- {
- float lenSquared = LengthSquared();
- if (lenSquared == 1.0f)
- return Conjugate();
- else if (lenSquared >= M_EPSILON)
- return Conjugate() * (1.0f / lenSquared);
- else
- return IDENTITY;
- }
-
- /// Return squared length.
- float LengthSquared() const { return w_ * w_ + x_ * x_ + y_ * y_ + z_ * z_; }
- /// Calculate dot product.
- float DotProduct(const Quaternion& rhs) const { return w_ * rhs.w_ + x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_; }
- /// Test for equality with another quaternion with epsilon.
- bool Equals(const Quaternion& rhs) const { return Urho3D::Equals(w_, rhs.w_) && Urho3D::Equals(x_, rhs.x_) && Urho3D::Equals(y_, rhs.y_) && Urho3D::Equals(z_, rhs.z_); }
- /// Return conjugate.
- Quaternion Conjugate() const { return Quaternion(w_, -x_, -y_, -z_); }
-
- /// Return Euler angles in degrees.
- Vector3 EulerAngles() const;
- /// Return yaw angle in degrees.
- float YawAngle() const;
- /// Return pitch angle in degrees.
- float PitchAngle() const;
- /// Return roll angle in degrees.
- float RollAngle() const;
- /// Return the rotation matrix that corresponds to this quaternion.
- Matrix3 RotationMatrix() const;
- /// Spherical interpolation with another quaternion.
- Quaternion Slerp(Quaternion rhs, float t) const;
- /// Return as string.
- String ToString() const;
-
- /// W coordinate.
- float w_ @ w;
- /// X coordinate.
- float x_ @ x;
- /// Y coordinate.
- float y_ @ y;
- /// Z coordinate.
- float z_ @ z;
-
- /// Identity quaternion.
- static const Quaternion IDENTITY;
- };
|