#pragma once #include "scalar.h" class Degree; class SinCosPair; class Radian { public: Scalar angle; #if defined(USE_SIGNATURE) friend int Is_Signature_Bad(const volatile Radian *); #endif Radian() {} Radian(Scalar angle) { this->angle = angle; } Radian& operator=(Scalar angle) { Check_Pointer(this); this->angle = angle; return *this; } Radian& operator=(const Radian &radian) { Check_Pointer(this); Check(&radian); angle = radian.angle; return *this; } Radian& operator=(const Degree °ree); Radian& operator=(const SinCosPair &pair); operator Scalar() const { Check(this); return angle; } // // These comparator functions are not designed to make exact comparisons // of Scalaring point numbers, but rather to compare them to within some // specified error threshold // Logical operator!() const { return Small_Enough(angle); } Logical operator==(const Radian &r) const { return Close_Enough(angle, r.angle); } Logical operator==(float r) const { return Close_Enough(angle, r); } Logical operator!=(const Radian &r) const { return !Close_Enough(angle, r.angle); } Logical operator!=(float r) const { return !Close_Enough(angle, r); } Radian& Negate(Scalar r) { Check_Pointer(this); angle = -r; return *this; } Radian& Add(Scalar r1, Scalar r2) { Check_Pointer(this); angle = r1 + r2; return *this; } Radian& operator+=(Scalar r) { Check(this); angle += r; return *this; } Radian& Subtract(Scalar r1, Scalar r2) { Check_Pointer(this); angle = r1 - r2; return *this; } Radian& operator-=(Scalar r) { Check(this); angle -= r; return *this; } Radian& Multiply(Scalar r1, Scalar r2) { Check_Pointer(this); angle = r1 * r2; return *this; } Radian& operator*=(Scalar r) { Check(this); angle *= r; return *this; } Radian& Divide(Scalar r1, Scalar r2) { Check_Pointer(this); Verify(!Small_Enough(r2)); angle = r1 / r2; return *this; } Radian& operator/=(Scalar r) { Check(this); Verify(!Small_Enough(r)); angle /= r; return *this; } Radian& Lerp(const Radian &a, const Radian &b, Scalar t); static Scalar Normalize(Scalar value); Radian& Normalize(); friend std::ostream& operator<<(std::ostream& stream, const Radian &radian); Logical TestInstance() const; static Logical TestClass(); }; class Degree { public: Scalar angle; #if defined(USE_SIGNATURE) friend int Is_Signature_Bad(const volatile Degree *); #endif // // constructors // Degree() {} Degree(Scalar angle) { this->angle = angle; } // // Assignment operators // Degree& operator=(const Degree °ree) { Check(this); Check(°ree); angle = degree.angle; return *this; } Degree& operator=(Scalar angle) { Check(this); this->angle = angle; return *this; } Degree& operator=(const Radian &radian) { Check(this); Check(&radian); angle = radian.angle * DEG_PER_RAD; return *this; } // // Support functions // friend std::ostream& operator<<(std::ostream& stream, const Degree &angle); Logical TestInstance() const; static Logical TestClass(); }; inline Radian& Radian::operator=(const Degree& degree) { Check_Pointer(this); Check(°ree); angle = degree.angle * RAD_PER_DEG; return *this; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SinCosPair ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class SinCosPair { public: Scalar sine, cosine; #if defined(USE_SIGNATURE) friend int Is_Signature_Bad(const volatile SinCosPair *); #endif // // Constructors // SinCosPair() {} SinCosPair(Scalar sin, Scalar cos) { Check_Pointer(this); sine = sin; cosine = cos; Check(this); } // // Assignment operators // SinCosPair& operator=(const SinCosPair &pair) { Check_Pointer(this); Check(&pair); sine = pair.sine; cosine = pair.cosine; return *this; } SinCosPair& operator=(const Radian &radian); // // Support functions // friend std::ostream& operator<<(std::ostream& stream, const SinCosPair &pair); Logical TestInstance() const; static Logical TestClass(); }; inline Radian& Radian::operator=(const SinCosPair& pair) { Check_Pointer(this); Check(&pair); angle = Arctan(pair.sine, pair.cosine); return *this; }