TurtleBrains  0.3.5
High quality, portable, C++ framework for rapid 2D game development.
tb_angle.hpp
1 
9 #ifndef TurtleBrains_Angle_hpp
10 #define TurtleBrains_Angle_hpp
11 
12 #include <turtle_brains/core/tb_error.hpp>
13 #include <turtle_brains/math/tb_constants.hpp>
14 #include <turtle_brains/math/tb_math.hpp>
15 
16 #include <iostream>
17 
18 namespace TurtleBrains
19 {
20  namespace Math
21  {
22 
26  enum class AngleUnit
27  {
28  Degrees,
29  Radians
30  };
31 
37  template<typename Type> class TypedAngle
38  {
39  public:
43  inline static TypedAngle Degrees(const Type angleInDegrees)
44  {
45  return TypedAngle(angleInDegrees, AngleUnit::Degrees);
46  }
47 
51  inline static TypedAngle Radians(const Type angleInRadians)
52  {
53  return TypedAngle(angleInRadians, AngleUnit::Radians);
54  }
55 
56  inline static TypedAngle Zero(void)
57  {
58  return TypedAngle(Type(0.0), AngleUnit::Degrees);
59  }
60 
62 
66  inline TypedAngle(void) :
67  mAngle(0)
68  {
69  }
70 
72 
79  inline explicit TypedAngle(const Type& angle, const AngleUnit units) :
80  mAngle((AngleUnit::Radians == units) ? angle : tbMath::Convert::DegreesToRadians(angle))
81  {
82  }
83 
87  inline Type AsRadians(void) const { return mAngle; }
88 
92  inline Type AsDegrees(void) const { return tbMath::Convert::RadiansToDegrees(mAngle); }
93 
97  inline Type As(const AngleUnit& angleUnits) const
98  {
99  switch (angleUnits)
100  {
101  case AngleUnit::Degrees: return AsDegrees();
102  case AngleUnit::Radians: return AsRadians();
103  };
104 
105  // 2024-09-22: Mostly to stop the compiler warnings.
106  tb_error("Expected not to reach this point...");
107  return Type(0.0);
108  }
109 
110 
114  //This is untested, written 2022-08-28
115  inline void Normalize(void)
116  {
117  mAngle = std::fmod(mAngle, tbMath::Pi<Type>());
118  }
119 
124  bool operator==(const TypedAngle& other) const
125  {
126  return tbMath::IsEqual(mAngle, other.mAngle);
127  }
128 
133  bool operator!=(const TypedAngle& other) const
134  {
135  return !tbMath::IsEqual(mAngle, other.mAngle);
136  }
137 
139  bool operator<(const TypedAngle& other) const
140  {
141  return mAngle < other.mAngle;
142  }
143 
144  bool operator<=(const TypedAngle& other) const
145  {
146  return mAngle <= other.mAngle;
147  }
148 
149  bool operator>(const TypedAngle& other) const
150  {
151  return mAngle > other.mAngle;
152  }
153 
154  bool operator>=(const TypedAngle& other) const
155  {
156  return mAngle >= other.mAngle;
157  }
159 
163  template<typename ToType> explicit operator TypedAngle<ToType>(void) const
164  {
165  return TypedAngle<ToType>(static_cast<ToType>(mAngle), AngleUnit::Radians);
166  }
167 
171  TypedAngle operator-() const { return Radians(-mAngle); }
172 
173 
175  TypedAngle operator+(const TypedAngle& other) const { return Radians(mAngle + other.mAngle); }
176  TypedAngle& operator+=(const TypedAngle& other) { mAngle += other.mAngle; return *this; }
177  TypedAngle operator-(const TypedAngle& other) const { return Radians(mAngle - other.mAngle); }
178  TypedAngle& operator-=(const TypedAngle& other) { mAngle -= other.mAngle; return *this; }
179 
180  TypedAngle operator*(const TypedAngle& other) const { return Radians(mAngle * other.mAngle); }
181  TypedAngle operator*(const Type& scalar) const { return Radians(mAngle * scalar); }
182  friend TypedAngle operator*(const Type& scalar, const TypedAngle& rhs) { return Radians(scalar * rhs.mAngle); }
183  TypedAngle& operator*=(const Type& scalar) { mAngle *= scalar; return *this; }
184 
185  TypedAngle operator/(const TypedAngle& other) const { return Radians(mAngle / other.mAngle); }
186  TypedAngle operator/(const Type& scalar) const { return Radians(mAngle / scalar); }
187  //Left out the scalar / Angle because it doesn't seem like a useful construct. 5 / 4radians ... ???
188  TypedAngle& operator/=(const Type& scalar) { mAngle /= scalar; return *this; }
190 
191  private:
192  Type mAngle; //Stored as radians.
193  };
194 
199 
203  template<typename Type> std::ostream& operator<<(std::ostream& output, const tbMath::TypedAngle<Type>& angle)
204  {
205  output << angle.AsDegrees() << " degrees";
206  return output;
207  }
208 
209  }; /* namespace Math */
210 }; /* namespace TurtleBrains */
211 
212 namespace tbMath = TurtleBrains::Math;
213 
214 //
215 // @note Visual Studio 2015 (at least) requires the literal operator to be either a 'long double' or 'const char*', this defeats the ability
216 // to use the templated versions above, and thus may lose some precision - but at least we get it working for floats?
217 //
218 //template<typename Type> tbMath::TypedAngle<Type> operator "" _radians (Type value) { return tbMath::TypedAngle<Type>(value, tbMath::AngleUnit::Radians); }
219 //template<typename Type> tbMath::TypedAngle<Type> operator "" _degrees (Type value) { return tbMath::TypedAngle<Type>(value, tbMath::AngleUnit::Degrees); }
220 //
221 
225 inline tbMath::Angle operator ""_radians(long double value) { return tbMath::Angle::Radians(static_cast<float>(value)); }
226 
230 inline tbMath::Angle operator ""_degrees(long double value) { return tbMath::Angle::Degrees(static_cast<float>(value)); }
231 
232 #endif /* TurtleBrains_Angle_hpp */
Definition: tb_angle.hpp:38
TypedAngle operator-() const
Definition: tb_angle.hpp:171
static TypedAngle Radians(const Type angleInRadians)
Definition: tb_angle.hpp:51
TypedAngle(const Type &angle, const AngleUnit units)
Definition: tb_angle.hpp:79
Type AsRadians(void) const
Definition: tb_angle.hpp:87
bool operator==(const TypedAngle &other) const
Definition: tb_angle.hpp:124
void Normalize(void)
Definition: tb_angle.hpp:115
Type AsDegrees(void) const
Definition: tb_angle.hpp:92
static TypedAngle Degrees(const Type angleInDegrees)
Definition: tb_angle.hpp:43
TypedAngle(void)
Definition: tb_angle.hpp:66
bool operator!=(const TypedAngle &other) const
Definition: tb_angle.hpp:133
#define tb_error(message,...)
Definition: tb_error.hpp:23
Contains objects and functions for dealing with Vector and Matrix math.
std::ostream & operator<<(std::ostream &output, const tbMath::TypedAngle< Type > &angle)
Definition: tb_angle.hpp:203
bool IsEqual(const Type &leftValue, const Type &rightValue, const Type tolerance=tbMath::kTolerance)
Definition: tb_math.hpp:56
TypedAngle< float > Angle
Definition: tb_angle.hpp:198
AngleUnit
Definition: tb_angle.hpp:27
@ Radians
Specifies the angle input value is in units of Radians.
@ Degrees
Specifies the angle input value is in units of Degrees.
Here is some information about the primary namespace.
Definition: tb_application_dialog.hpp:22