#pragma once #include "angle.h" class Quaternion; class Origin; class YawPitchRoll; class UnitVector; class LinearMatrix; class Vector3D; //########################################################################## //############################ Hinge ################################# //########################################################################## class Hinge { public: int axisNumber; Radian rotationAmount; // // Constructors // Hinge() {} Hinge(int axis, const Radian &angle) : axisNumber(axis), rotationAmount(angle) {} #if defined(USE_SIGNATURE) friend int Is_Signature_Bad(const volatile Hinge *); #endif // // Assignment operators // Hinge& operator=(const Hinge &hinge) { Check_Pointer(this); Check(&hinge); axisNumber = hinge.axisNumber; rotationAmount = hinge.rotationAmount; return *this; } // // "Close-enough" comparators // friend Logical Small_Enough(const Hinge &a, Scalar e = SMALL) { Check(&a); return Small_Enough(a, e); } Logical operator!() const { return Small_Enough(*this,SMALL); } friend Logical Close_Enough(const Hinge &a1, const Hinge &a2, Scalar e = SMALL); Logical operator==(const Hinge& a) const { return Close_Enough(*this, a, SMALL); } Logical operator!=(const Hinge& a) const { return !Close_Enough(*this, a, SMALL); } // // Template support // Hinge& Lerp(const Hinge& v1, const Hinge& v2, Scalar t); // // Support functions // friend std::ostream& operator<<(std::ostream& stream, const Hinge& angles); Logical TestInstance() const; }; //########################################################################## //######################### EulerAngles ############################# //########################################################################## class EulerAngles { public: Radian pitch, yaw, roll; static const EulerAngles Identity; #if defined(USE_SIGNATURE) friend int Is_Signature_Bad(const volatile EulerAngles *); #endif // // Constructors // EulerAngles() {} EulerAngles(const Radian &pitch, const Radian &yaw, const Radian &roll) { this->pitch = pitch; this->yaw = yaw; this->roll = roll; } // // Assignment operators // EulerAngles& operator=(const EulerAngles &angles); EulerAngles& operator=(const YawPitchRoll &angles); EulerAngles& operator=(const Hinge &hinge); EulerAngles& operator=(const Quaternion &quaternion); EulerAngles& operator=(const LinearMatrix &matrix); EulerAngles& operator=(const Origin &p); // // "Close-enough" comparators // friend Logical Small_Enough(const EulerAngles &a, Scalar e = SMALL); Logical operator!() const { return Small_Enough(*this); } friend Logical Close_Enough(const EulerAngles &a1, const EulerAngles &a2, Scalar e = SMALL); Logical operator==(const EulerAngles& a) const { return Close_Enough(*this, a, SMALL); } Logical operator!=(const EulerAngles& a) const { return !Close_Enough(*this, a, SMALL); } // // Axis index operators // const Radian& operator[](size_t index) const { Check_Pointer(this); Warn(index>Z_Axis); return (&pitch)[index]; } Radian& operator[](size_t index) { Check_Pointer(this); Warn(index>Z_Axis); return (&pitch)[index]; } // // Multiplication operators // EulerAngles& Multiply(const EulerAngles &q1, const EulerAngles &q2); EulerAngles& Multiply(const EulerAngles &q, Scalar scale); EulerAngles& MultiplyScaled(const EulerAngles &q1, const EulerAngles &q2, Scalar t); // // Template support // EulerAngles& Lerp(const EulerAngles& v1, const EulerAngles& v2, Scalar t); // // Support functions // EulerAngles& Normalize(); friend std::ostream& operator<<(std::ostream& stream, const EulerAngles& angles); // // Test functions // Logical TestInstance() const; static Logical TestClass(); }; //########################################################################## //######################### YawPitchRoll ############################ //########################################################################## class YawPitchRoll { public: Radian yaw, pitch, roll; static const YawPitchRoll Identity; #if defined(USE_SIGNATURE) friend int Is_Signature_Bad(const volatile YawPitchRoll *); #endif // // Constructors // YawPitchRoll() {} YawPitchRoll(const Radian &yaw, const Radian &pitch, const Radian &roll) { this->pitch = pitch; this->yaw = yaw; this->roll = roll; } // // Assignment operators // YawPitchRoll& operator=(const Hinge &hinge); YawPitchRoll& operator=(const YawPitchRoll &angles); YawPitchRoll& operator=(const EulerAngles &angles); YawPitchRoll& operator=(const Quaternion &quaternion); YawPitchRoll& operator=(const LinearMatrix &matrix); YawPitchRoll& operator=(const Origin &p); // // "Close-enough" comparators // friend Logical Small_Enough(const YawPitchRoll &a, Scalar e = SMALL); Logical operator!() const { return Small_Enough(*this); } friend Logical Close_Enough(const YawPitchRoll &a1, const YawPitchRoll &a2, Scalar e = SMALL); Logical operator==(const YawPitchRoll& a) const { return Close_Enough(*this, a); } Logical operator!=(const YawPitchRoll& a) const { return !Close_Enough(*this, a); } // // Support functions // YawPitchRoll& Normalize(); friend std::ostream& operator<<(std::ostream& stream, const YawPitchRoll& angles); // // Test functions // Logical TestInstance() const; }; //########################################################################## //######################### Quaternion ############################### //########################################################################## class Quaternion { public: static const Quaternion Identity; #if defined(USE_SIGNATURE) friend int Is_Signature_Bad(const volatile Quaternion *); #endif Scalar x, y, z, w; // // Constructors // Quaternion() {} Quaternion(Scalar x, Scalar y, Scalar z, Scalar w); // // Assignment operators // Quaternion& operator=(const Quaternion &q); Quaternion& operator=(const Hinge &hinge); Quaternion& operator=(const EulerAngles &angles); Quaternion& operator=(const YawPitchRoll &angles); Quaternion& operator=(const LinearMatrix &matrix); Quaternion& operator=(const Origin &p); // // "Close-enough" comparators // friend Logical Small_Enough(const Quaternion &q, Scalar e = SMALL) { Check(&q); return Close_Enough(q.w, 1.0f, e); } Logical operator!() const { return Small_Enough(*this, SMALL); } // // Axis index operators // const Scalar& operator[](size_t index) const { Check_Pointer(this); Warn(index>W_Axis); return (&x)[index]; } Scalar& operator[](size_t index) { Check_Pointer(this); Warn(index>W_Axis); return (&x)[index]; } Scalar GetAngle(); void GetAxis(UnitVector *axis); // // Multiplication operators // Quaternion& Multiply(const Quaternion &q1, const Quaternion &q2); Quaternion& Multiply(const Quaternion &q, Scalar scale); Quaternion& MultiplyScaled(const Quaternion &q1, const Quaternion &q2, Scalar t); Quaternion& Add(const Quaternion &source, const Vector3D &delta); Quaternion& AddScaled(const Quaternion &source, const Vector3D &delta, Scalar t); // // Transform functions // Quaternion& Multiply(const Quaternion &q, const LinearMatrix &m); Quaternion& operator*=(const LinearMatrix &m); // // Template support // Quaternion& Lerp(const Quaternion& v1, const Quaternion& v2, Scalar t); // // Miscellaneous functions // Quaternion& Normalize(); Quaternion& Subtract(const Quaternion &end, const Quaternion &start); Quaternion& Subtract(const UnitVector &end, const UnitVector &start); Quaternion& Subtract(const Vector3D &end, const Vector3D &start); // // Support functions // friend std::ostream& operator<<(std::ostream& stream, const Quaternion& quaternion); Logical TestInstance() const; static Logical TestClass(); };