Empirical
Angle2D.h
Go to the documentation of this file.
1 // This file is part of Empirical, https://github.com/devosoft/Empirical
2 // Copyright (C) Michigan State University, 2016-2018.
3 // Released under the MIT Software license; see doc/LICENSE
4 //
5 // emp::Angle maintains an angle on a 2D surface.
6 //
7 // The internal representation uses an int to represent angles.
8 // First two bytes are number of full circles.
9 // Last two bytes represent angle angles.
10 //
11 
12 #ifndef EMP_ANGLE_2D_H
13 #define EMP_ANGLE_2D_H
14 
15 
16 #include <cmath>
17 
18 #include "../tools/const.h"
19 #include "Point2D.h"
20 
21 namespace emp {
22 
23  constexpr const int32_t sin_chart_1K[] =
24  { 0, 25, 50, 75, 100, 125, 150, 175, 200, 224, 249, 273, 297, 321, 345, 369,
25  392, 415, 438, 460, 483, 505, 526, 548, 569, 590, 610, 630, 650, 669, 688, 706,
26  724, 742, 759, 775, 792, 807, 822, 837, 851, 865, 878, 891, 903, 915, 926, 936,
27  946, 955, 964, 972, 980, 987, 993, 999, 1004, 1009, 1013, 1016, 1019, 1021, 1023, 1024,
28  1024, 1024, 1023, 1021, 1019, 1016, 1013, 1009, 1004, 999, 993, 987, 980, 972, 964, 955,
29  946, 936, 926, 915, 903, 891, 878, 865, 851, 837, 822, 807, 792, 775, 759, 742,
30  724, 706, 688, 669, 650, 630, 610, 590, 569, 548, 526, 505, 483, 460, 438, 415,
31  392, 369, 345, 321, 297, 273, 249, 224, 200, 175, 150, 125, 100, 75, 50, 25,
32  0, -24, -49, -74, -99, -124, -149, -174, -199, -223, -248, -272, -296, -320, -344, -368,
33  -391, -414, -437, -459, -482, -504, -525, -547, -568, -589, -609, -629, -649, -668, -687, -705,
34  -723, -741, -758, -774, -791, -806, -821, -836, -850, -864, -877, -890, -902, -914, -925, -935,
35  -945, -954, -963, -971, -979, -986, -992, -998,-1003,-1008,-1012,-1015,-1018,-1020,-1022,-1023,
36  -1023,-1023,-1022,-1020,-1018,-1015,-1012,-1008,-1003, -998, -992, -986, -979, -971, -963, -954,
37  -945, -935, -925, -914, -902, -890, -877, -864, -850, -836, -821, -806, -791, -774, -758, -741,
38  -723, -705, -687, -668, -649, -629, -609, -589, -568, -547, -525, -504, -482, -459, -437, -414,
39  -391, -368, -344, -320, -296, -272, -248, -223, -199, -174, -149, -124, -99, -74, -49, -24
40  };
41  constexpr const int32_t cos_chart_1K[] =
42  { 1024, 1024, 1023, 1021, 1019, 1016, 1013, 1009, 1004, 999, 993, 987, 980, 972, 964, 955,
43  946, 936, 926, 915, 903, 891, 878, 865, 851, 837, 822, 807, 792, 775, 759, 742,
44  724, 706, 688, 669, 650, 630, 610, 590, 569, 548, 526, 505, 483, 460, 438, 415,
45  392, 369, 345, 321, 297, 273, 249, 224, 200, 175, 150, 125, 100, 75, 50, 25,
46  0, -24, -49, -74, -99, -124, -149, -174, -199, -223, -248, -272, -296, -320, -344, -368,
47  -391, -414, -437, -459, -482, -504, -525, -547, -568, -589, -609, -629, -649, -668, -687, -705,
48  -723, -741, -758, -774, -791, -806, -821, -836, -850, -864, -877, -890, -902, -914, -925, -935,
49  -945, -954, -963, -971, -979, -986, -992, -998,-1003,-1008,-1012,-1015,-1018,-1020,-1022,-1023,
50  -1023,-1023,-1022,-1020,-1018,-1015,-1012,-1008,-1003, -998, -992, -986, -979, -971, -963, -954,
51  -945, -935, -925, -914, -902, -890, -877, -864, -850, -836, -821, -806, -791, -774, -758, -741,
52  -723, -705, -687, -668, -649, -629, -609, -589, -568, -547, -525, -504, -482, -459, -437, -414,
53  -391, -368, -344, -320, -296, -272, -248, -223, -199, -174, -149, -124, -99, -74, -49, -24,
54  0, 25, 50, 75, 100, 125, 150, 175, 200, 224, 249, 273, 297, 321, 345, 369,
55  392, 415, 438, 460, 483, 505, 526, 548, 569, 590, 610, 630, 650, 669, 688, 706,
56  724, 742, 759, 775, 792, 807, 822, 837, 851, 865, 878, 891, 903, 915, 926, 936,
57  946, 955, 964, 972, 980, 987, 993, 999, 1004, 1009, 1013, 1016, 1019, 1021, 1023, 1024
58  };
59  constexpr const int32_t tan_chart_1K[] =
60  { 0, 25, 50, 76, 101, 126, 152, 178, 204, 230, 256, 283, 311, 338, 366, 395,
61  424, 454, 484, 515, 547, 580, 614, 648, 684, 721, 759, 799, 840, 883, 928, 975,
62  1024, 1076, 1130, 1187, 1248, 1312, 1381, 1454, 1533, 1617, 1708, 1808, 1916, 2034, 2165, 2310,
63  2472, 2655, 2862, 3100, 3376, 3700, 4088, 4560, 5148, 5901, 6903, 8302,10397,13882,20844,41713,
64  MIN_INT, -41712, -20843, -13881, -10396, -8301, -6902, -5900, -5147, -4559, -4087, -3699, -3375, -3099, -2861, -2654,
65  -2471,-2309,-2164,-2033,-1915,-1807,-1707,-1616,-1532,-1453,-1380,-1311,-1247,-1186,-1129,-1075,
66  -1023, -974, -927, -882, -839, -798, -758, -720, -683, -647, -613, -579, -546, -514, -483, -453,
67  -423, -394, -365, -337, -310, -282, -255, -229, -203, -177, -151, -125, -100, -75, -49, -24,
68  0, 25, 50, 76, 101, 126, 152, 178, 204, 230, 256, 283, 311, 338, 366, 395,
69  424, 454, 484, 515, 547, 580, 614, 648, 684, 721, 759, 799, 840, 883, 928, 975,
70  1024, 1076, 1130, 1187, 1248, 1312, 1381, 1454, 1533, 1617, 1708, 1808, 1916, 2034, 2165, 2310,
71  2472, 2655, 2862, 3100, 3376, 3700, 4088, 4560, 5148, 5901, 6903, 8302,10397,13882,20844,41713,
72  MIN_INT, -41712, -20843, -13881, -10396, -8301, -6902, -5900, -5147, -4559, -4087, -3699, -3375, -3099, -2861, -2654,
73  -2471,-2309,-2164,-2033,-1915,-1807,-1707,-1616,-1532,-1453,-1380,-1311,-1247,-1186,-1129,-1075,
74  -1023, -974, -927, -882, -839, -798, -758, -720, -683, -647, -613, -579, -546, -514, -483, -453,
75  -423, -394, -365, -337, -310, -282, -255, -229, -203, -177, -151, -125, -100, -75, -49, -24,
76  };
77 
78  class Angle {
79  private:
80  uint32_t angle; // Int representation of an angle
81 
82  static constexpr double ANGLE_CAP = 65536.0;
83  static constexpr uint32_t UP = 0;
84  static constexpr uint32_t RIGHT = 16384;
85  static constexpr uint32_t DOWN = 32768;
86  static constexpr uint32_t LEFT = 49152;
87 
88  public:
89  constexpr Angle() : angle(0) { ; }
90  constexpr Angle(const Angle & in_angle) : angle(in_angle.angle) { ; }
91  constexpr Angle(double radians) : angle((uint32_t)(radians * ANGLE_CAP / (2.0*PI))) { ; }
92  constexpr Angle(uint32_t in_angle, bool) : angle(in_angle) { ; } // directly set internal value
93 
94  constexpr double AsPortion() const { return ((double) (angle % 0xFFFF)) / ANGLE_CAP; }
95  constexpr double AsRadians() const { return ((double) angle) * 2.0 * PI / ANGLE_CAP; }
96  constexpr double AsDegrees() const { return ((double) angle) * 360.0 / ANGLE_CAP; }
97 
98  Angle & SetPortion(double portion) {
99  angle = (uint32_t) (portion * ANGLE_CAP);
100  return *this;
101  }
102  Angle & SetRadians(double radians) {
103  angle = (uint32_t) (radians * ANGLE_CAP / (2.0 * PI));
104  return *this;
105  }
106  Angle & SetDegrees(double degrees) {
107  angle = (uint32_t) (degrees * ANGLE_CAP / 360.0);
108  return *this;
109  }
110  Angle & PointUp() { angle = UP; return *this; }
111  Angle & PointRight() { angle = RIGHT; return *this; }
112  Angle & PointDown() { angle = DOWN; return *this; }
113  Angle & PointLeft() { angle = LEFT; return *this; }
114 
115  // Chop off full circles
116  Angle & Truncate() { angle &= 0xFFFF; return *this; }
117 
118  // Count full circles
119  uint32_t CountFullCircles() { return angle >> 16; }
120 
121  // Some basic rotations...
122  Angle & RotateRight() { angle += RIGHT; return *this; }
123  Angle & RotateLeft() { angle -= RIGHT; return *this; }
124  Angle & RotateUTurn() { angle += DOWN; return *this; }
125  Angle & RotateFull(uint32_t turns=1) { angle += turns << 16; return *this; }
126 
127  Angle & RotateRadians(double radians) {
128  angle += (uint32_t) (radians * ANGLE_CAP / (2.0 * PI));
129  return *this;
130  }
131  Angle & RotateDegrees(double degrees) {
132  angle += (uint32_t) (degrees * ANGLE_CAP / 360.0);
133  return *this;
134  }
135 
136  Angle & operator=(const Angle & _in) { angle = _in.angle; return *this; }
137 
138  constexpr bool operator==(const Angle & _in) const { return angle == _in.angle; }
139  constexpr bool operator!=(const Angle & _in) const { return angle != _in.angle; }
140  constexpr bool operator<(const Angle & _in) const { return angle < _in.angle; }
141  constexpr bool operator<=(const Angle & _in) const { return angle <= _in.angle; }
142  constexpr bool operator>(const Angle & _in) const { return angle > _in.angle; }
143  constexpr bool operator>=(const Angle & _in) const { return angle >= _in.angle; }
144 
145  constexpr Angle operator+(const Angle & _in) const { return Angle(angle + _in.angle, true); }
146  constexpr Angle operator-(const Angle & _in) const { return Angle(angle - _in.angle, true); }
147 
148  constexpr Angle operator*(double _in) const { return Angle((uint32_t) (angle * _in), true); }
149  constexpr Angle operator/(double _in) const { return Angle((uint32_t) (angle / _in), true); }
150  // constexpr Angle operator*(int _in) const { return Angle(angle * _in, true); }
151  // constexpr Angle operator/(int _in) const { return Angle(angle / _in, true); }
152 
153  Angle & operator+=(const Angle & _in) { angle += _in.angle; return *this; }
154  Angle & operator-=(const Angle & _in) { angle -= _in.angle; return *this; }
155  Angle & operator*=(double _in) { angle = (uint32_t) (angle * _in); return *this; }
156  Angle & operator/=(double _in) { angle = (uint32_t) (angle / _in); return *this; }
157 
158  double Sin() const { return sin(AsRadians()); }
159  double Cos() const { return cos(AsRadians()); }
160  double Tan() const { return tan(AsRadians()); }
161 
162  // Quicker version of sin/cos/tan -- these are low precision and return an int: result * 1024
163  constexpr int Sin_Quick1K() const { return emp::sin_chart_1K[ (angle >> 8) & 255 ]; }
164  constexpr int Cos_Quick1K() const { return emp::cos_chart_1K[ (angle >> 8) & 255 ]; }
165  constexpr int Tan_Quick1K() const { return emp::tan_chart_1K[ (angle >> 8) & 255 ]; }
166 
167  Point GetPoint(double distance=1.0) const {
168  return Point(Sin() * distance, Cos() * distance);
169  }
170  Point GetPoint(const Point & start_point, double distance=1.0) const {
171  return start_point.GetOffset(Sin() * distance, Cos() * distance);
172  }
173  };
174 
175 }
176 
177 
178 #endif
constexpr double AsPortion() const
Definition: Angle2D.h:94
Angle & RotateDegrees(double degrees)
Definition: Angle2D.h:131
Angle & SetPortion(double portion)
Definition: Angle2D.h:98
Angle & RotateRight()
Definition: Angle2D.h:122
Angle & SetDegrees(double degrees)
Definition: Angle2D.h:106
Angle & PointDown()
Definition: Angle2D.h:112
constexpr double AsDegrees() const
Definition: Angle2D.h:96
constexpr Point2D GetOffset(TYPE off_x, TYPE off_y) const
Definition: Point2D.h:55
Angle & operator=(const Angle &_in)
Definition: Angle2D.h:136
constexpr double AsRadians() const
Definition: Angle2D.h:95
Angle & RotateFull(uint32_t turns=1)
Definition: Angle2D.h:125
Angle & RotateLeft()
Definition: Angle2D.h:123
Angle & operator-=(const Angle &_in)
Definition: Angle2D.h:154
constexpr const int32_t sin_chart_1K[]
Definition: Angle2D.h:23
uint32_t CountFullCircles()
Definition: Angle2D.h:119
constexpr int Sin_Quick1K() const
Definition: Angle2D.h:163
constexpr Angle operator*(double _in) const
Definition: Angle2D.h:148
constexpr const double PI
pi
Definition: const.h:20
constexpr bool operator==(const Angle &_in) const
Definition: Angle2D.h:138
constexpr Angle operator-(const Angle &_in) const
Definition: Angle2D.h:146
Angle & PointUp()
Definition: Angle2D.h:110
Angle & PointRight()
Definition: Angle2D.h:111
Angle & RotateRadians(double radians)
Definition: Angle2D.h:127
Point2D<> Point
Definition: Point2D.h:99
constexpr bool operator>=(const Angle &_in) const
Definition: Angle2D.h:143
constexpr Angle(uint32_t in_angle, bool)
Definition: Angle2D.h:92
Angle & PointLeft()
Definition: Angle2D.h:113
Angle & SetRadians(double radians)
Definition: Angle2D.h:102
constexpr Angle operator+(const Angle &_in) const
Definition: Angle2D.h:145
constexpr Angle(double radians)
Definition: Angle2D.h:91
constexpr const int32_t MIN_INT
(- 2^31)
Definition: const.h:30
constexpr Angle(const Angle &in_angle)
Definition: Angle2D.h:90
constexpr const int32_t tan_chart_1K[]
Definition: Angle2D.h:59
Angle & RotateUTurn()
Definition: Angle2D.h:124
constexpr bool operator<=(const Angle &_in) const
Definition: Angle2D.h:141
double Cos() const
Definition: Angle2D.h:159
Angle & operator*=(double _in)
Definition: Angle2D.h:155
double Sin() const
Definition: Angle2D.h:158
constexpr const int32_t cos_chart_1K[]
Definition: Angle2D.h:41
constexpr bool operator<(const Angle &_in) const
Definition: Angle2D.h:140
If we are in emscripten, make sure to include the header.
Definition: array.h:37
Definition: Angle2D.h:78
Angle & operator/=(double _in)
Definition: Angle2D.h:156
constexpr bool operator!=(const Angle &_in) const
Definition: Angle2D.h:139
Angle & Truncate()
Definition: Angle2D.h:116
Angle & operator+=(const Angle &_in)
Definition: Angle2D.h:153
constexpr bool operator>(const Angle &_in) const
Definition: Angle2D.h:142
constexpr Angle()
Definition: Angle2D.h:89
Point GetPoint(const Point &start_point, double distance=1.0) const
Definition: Angle2D.h:170
constexpr int Tan_Quick1K() const
Definition: Angle2D.h:165
double Tan() const
Definition: Angle2D.h:160
constexpr int Cos_Quick1K() const
Definition: Angle2D.h:164
constexpr Angle operator/(double _in) const
Definition: Angle2D.h:149
Point GetPoint(double distance=1.0) const
Definition: Angle2D.h:167