API Documentation
Loading...
Searching...
No Matches
Angle.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------------------------------
2Copyright (c) 2019, NDEVR LLC
3tyler.parke@ndevr.org
4 __ __ ____ _____ __ __ _______
5 | \ | | | __ \ | ___|\ \ / / | __ \
6 | \ | | | | \ \ | |___ \ \ / / | |__) |
7 | . \| | | |__/ / | |___ \ V / | _ /
8 | |\ |_|_____/__|_____|___\_/____| | \ \
9 |__| \__________________________________| \__\
10
11Subject to the terms of the Enterprise+ Agreement, NDEVR hereby grants
12Licensee a limited, non-exclusive, non-transferable, royalty-free license
13(without the right to sublicense) to use the API solely for the purpose of
14Licensee's internal development efforts to develop applications for which
15the API was provided.
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
23FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25DEALINGS IN THE SOFTWARE.
26
27Library: Base
28File: Angle
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include <NDEVR/BaseValues.h>
34#include <NDEVR/ObjectInfo.h>
35#include <cmath>
36
37namespace NDEVR
38{
39 /**--------------------------------------------------------------------------------------------------
40 \brief Values that represent euler angles.
41 These are typically used in Vector<3, Angle> to classify an orientation of an object.
42 **/
49
50 /**--------------------------------------------------------------------------------------------------
51 \brief The possible units that can be used by the angle class.
52 These are returned and used for real world angle representation.
53 INTERNAL_ANGLE is the angle internally used by the angle class.
54 **/
56 {
59 , INTERNAL_ANGLE//The angle internally used by the angle class.
61 };
62
63 /**--------------------------------------------------------------------------------------------------
64 \brief Values that represent angle format modes.
65 Used in classes for printing angle in a given format
66 **/
75 /**--------------------------------------------------------------------------------------------------
76 \brief Returns the value of PI to a given precision.
77 \return The value of PI (~3.1415...).
78 **/
79 template<class t_float_type>
80 static constexpr t_float_type PI()
81 {
82 return cast<t_float_type>(3.14159265358979323846264338327950288419716939937510);
83 }
84 /**--------------------------------------------------------------------------------------------------
85 \brief The primary angle storage class for this API. Stores an angle in an optimized format.
86
87 Since all angles are from 0-360 degrees it is possible to make certain optimizations that
88 make use of defined overflow that traditional floating point angles would not be able to achieve.
89 In addition space can be saved and expensive sin, cos, tan functions can be precomputed.
90 **/
91 template<class t_type = fltp08>
92 class Angle
93 {
94 public:
95
96 /**
97 \brief Default constructor, creates an angle with 0 degrees.
98 **/
99 constexpr Angle()
100 : m_index_angle(0)
101 {}
102
103 /**
104 \brief Default copy constructor
105 **/
106 constexpr Angle(const Angle& angle)
108 {}
109
110 /**
111 \brief Explicit conversion of an angle from one container type to another.
112 **/
113 template<class t_other_type>
114 explicit constexpr Angle(const Angle<t_other_type>& angle)
115 : m_index_angle(cast<t_type>(angle.template internal<false>()))
116 {}
117
118 /**
119 \brief Angle Constructor.
120 \param[in] type The type of the angle given (Example: radians, degrees, percent)
121 \param[in] value The value of the angle in the units specified by type.
122 **/
123 constexpr explicit Angle(AngleType type, fltp04 value)
124 : m_index_angle(0)
125 {
126 switch (type)
127 {
128 case INTERNAL_ANGLE: break;
129 case RADIANS: value = (value / PI<fltp04>()) * INDEX_PI; break;
130 case DEGREES: value = (value / 180.0f) * INDEX_PI; break;
131 case PERCENT: value = value * 2.0f * INDEX_PI; break;
132 }
134 }
135
136 /**
137 \brief Angle Constructor.
138 \param[in] type The type of the angle given (Example: radians, degrees, percent)
139 \param[in] value The value of the angle in the units specified by type.
140 **/
141 constexpr explicit Angle(AngleType type, fltp08 value)
142 : m_index_angle(0)
143 {
144 switch (type)
145 {
146 case INTERNAL_ANGLE: break;
147 case RADIANS: value = (value / PI<fltp08>()) * INDEX_PI; break;
148 case DEGREES: value = (value / 180.0) * INDEX_PI; break;
149 case PERCENT: value = value * 2.0 * INDEX_PI; break;
150 }
152 }
153
154 /**
155 \brief Constructor.
156 \param[in] value the optimized input where INDEX_PI is 180 degrees
157 **/
158 constexpr explicit Angle(t_type value)
159 : m_index_angle(value)
160 {}
161
162 /**
163 \brief Returns a form of this angle as a given type (Radian, Degree, Percent, etc)
164 The template t_type provides the AngleType of the angle to return (Example: radians, degrees, percent)
165 \param[in] t_is_signed Whether the given type should be signed or not (-180 - 180 vs 0 to 360)
166 \return A fltp08 representing this angle as the given type.
167 **/
168 template<AngleType t_angle_type>
169 [[nodiscard]] constexpr fltp08 as() const
170 {
171 switch (t_angle_type)
172 {
173 case INTERNAL_ANGLE:
174 if (IsInvalid(m_index_angle))
176 else
178 case DEGREES:
179 return as<INTERNAL_ANGLE>() * INV_INDEX_PI * 180.0;
180 case RADIANS:
181 return as<INTERNAL_ANGLE>() * INV_INDEX_PI * PI<fltp08>();
182 case PERCENT:
183 return as<INTERNAL_ANGLE>() * INV_INDEX_PI * 0.5;
184 }
186 }
187
188 /**
189 \brief Returns a form of this angle as a given type (Radian, Degree, Percent, etc)
190 \param[in] type - The AngleType of the angle to return (Example: radians, degrees, percent).
191 \return A fltp04 representing this angle as the given type.
192 **/
193 [[nodiscard]] constexpr fltp08 as(AngleType type) const
194 {
195 switch (type)
196 {
197 case DEGREES: return as<DEGREES>();
198 case RADIANS: return as<RADIANS>();
199 case PERCENT: return as<PERCENT>();
200 case INTERNAL_ANGLE: return as<INTERNAL_ANGLE>();
201 }
203 }
204 public:
205 /**
206 \brief Gets the internal index angle which is the default storage unit for the angle data.
207 \return The internal index angle, or the angle represented by 0 - Constant<t_type>::Max representing
208 0 to 2 PI radians
209 **/
210 template<bool t_normalized>
211 [[nodiscard]] constexpr t_type internal() const
212 {
213 if constexpr(t_normalized)
214 {
215 return Angle<t_type>::template NormalizeInternal<t_type>(m_index_angle);
216 }
217 else
218 {
219 return m_index_angle;
220 }
221 }
222 /**
223 \brief Explicit conversion of an angle from one container type to another.
224 **/
225 template<class t_new_type>
227 {
229 return angle;
230 }
231 /**
232 \brief returns the normalized angle which lies from 0 to 360 degrees.
233 **/
234 [[nodiscard]] constexpr Angle normalized() const
235 {
236 return Angle(internal<true>());
237 }
238 /**
239 \brief returns the normalized angle which lies from -180 to 180 degrees.
240 **/
241 [[nodiscard]] constexpr Angle normalizedOffset() const
242 {
243 Angle value = normalized();
244 if (value > Angle(DEGREES, 180.0))
245 value -= Angle(DEGREES, 360.0);
246 return value;
247 }
248 /**
249 \param[in] angle - The value to assign.
250 \return A shallow copy of this object.
251 **/
252 constexpr Angle& operator=(const Angle& angle)
253 {
254 m_index_angle = angle.m_index_angle;
255 return (*this);
256 }
257
258 /**
259 \brief Equality operator.
260 \param[in] angle - The value to check comparison.
261 \return true if the left and right are considered equivalent.
262 **/
263 constexpr bool operator==(const Angle& angle) const
264 {
265 return internal<false>() == angle.internal<false>();
266 }
267
268 /**
269 \brief Inequality operator.
270 \param[in] angle The value to check inequality against.
271 \return true if the left and right are not considered equivalent.
272 **/
273 constexpr bool operator!=(const Angle& angle) const
274 {
275 return internal<false>() != angle.internal<false>();
276 }
277
278 /**
279 \brief negates the angle
280 \return The result of the operation.
281 **/
283 {
284 return Angle(-m_index_angle);
285 }
286 public:
287
288 /**
289 \brief Computes the principal value of the arc cosine of the given value
290 \param[in] value - The value to perform arc cos.
291 \return the arc cosine of the given value as an Angle.
292 **/
293 template<class t_value_type>
294 static Angle acos(t_value_type value)
295 {
296 return Angle(RADIANS, ::acos(value));
297 }
298
299 /**
300 \brief Computes the principal value of the arc sine of the given value
301 \param[in] value - The value to perform arc sine.
302 \return the arc sine of the given value as an Angle.
303 **/
304 template<class t_value_type>
305 static Angle asin(t_value_type value)
306 {
307 return Angle(RADIANS, ::asin(value));
308 }
309
310 /**
311 \brief Computes the principal value of the arc tangent of the given value
312 \param[in] value - The value to perform arc tangent.
313 \return the arc tangent of the given value as an Angle.
314 **/
315 template<class t_value_type>
316 static Angle atan(t_value_type value)
317 {
318 return Angle(RADIANS, ::atan(value));
319 }
320
321 /**
322 \brief measures the counterclockwise angle between the positive x-axis and the point (x, y)
323 \param[in] x - the numerator or x value of atan
324 \param[in] y - the denomenator or y value of atan
325 \return the arc tangent of the given value as an Angle.
326 **/
327 template<class t_value_type>
328 static Angle atan2(t_value_type x, t_value_type y)
329 {
330 return Angle(RADIANS, ::atan2(x, y));
331 }
332 public:
333 static constexpr sint04 INDEX_PI = 32768;//optimized angle that allows integers to store angles to some degree of accuracy
334 static constexpr fltp08 INV_INDEX_PI = { 1.0 / Angle<t_type>::INDEX_PI };
335 private:
336 template<class t_normal_type>
337 static constexpr typename std::enable_if<!ObjectInfo<t_normal_type>::Float, t_normal_type>::type NormalizeInternal(t_normal_type value)
338 {
339 const t_normal_type angle = (value >= 0 ? value : -value) % (2 * INDEX_PI);
340 if (value >= 0)
341 return angle;
342 else
343 return (2 * INDEX_PI) - angle;
344 }
345
346 template<class t_normal_type>
347 static constexpr typename std::enable_if<ObjectInfo<t_normal_type>::Float, t_normal_type>::type NormalizeInternal(t_normal_type value)
348 {
349 const t_normal_type angle = fmod(std::abs(value), (2 * INDEX_PI));
350 if (value >= 0)
351 return angle;
352 else
353 return 2 * cast<t_normal_type>(INDEX_PI) - angle;
354 }
355
356 protected:
357 /** The index angle. */
359 };
363
367
368 template<class t_type>
369 static constexpr bool IsInvalid(const Angle<t_type>& value)
370 {
371 return IsInvalid(value.template internal<false>());
372 }
373
374 template<class t_to, class t_from>
375 constexpr t_to cast(const Angle<t_from>& value)
376 {
377 return t_to(INTERNAL_ANGLE, cast<fltp08>(value.template internal<false>()));
378 }
379 /**
380 \brief Information about an Angle object backed by a signed 4 byte integer.
381 **/
382 template<>
383 struct ObjectInfo<Angle<sint04>, false, false>
384 {
385 static const uint01 Dimensions = 0;
386 static const bool Vector = false;
387 static const bool Primitive = true;
388 static const bool Pointer = false;
389 static const bool Unsigned = false;
390 static const bool Float = true;
391 static const bool Integer = false;
392 static const bool Number = true;
393 static const bool String = false;
394 static const bool Color = false;
395 static const bool Buffer = false;
396 static const bool Boolean = false;
397 static constexpr ObjectInfo<Angle<sint04>, false, false> VectorSub() { return ObjectInfo<Angle<sint04>, false, false>(); }
398 };
399 /**
400 \brief Information about an Angle object backed by a 8 byte floating point number.
401 **/
402 template<>
403 struct ObjectInfo<Angle<fltp08>, false, false>
404 {
405 static const uint01 Dimensions = 0;
406 static const bool Vector = false;
407 static const bool Primitive = true;
408 static const bool Pointer = false;
409 static const bool Unsigned = false;
410 static const bool Float = true;
411 static const bool Integer = false;
412 static const bool Number = true;
413 static const bool String = false;
414 static const bool Color = false;
415 static const bool Buffer = false;
416 static const bool Boolean = false;
417 static constexpr ObjectInfo<Angle<fltp08>, false, false> VectorSub() { return ObjectInfo<Angle<fltp08>, false, false>(); }
418 };
419 /**
420 \brief Information about an Angle object backed by a 4 byte floating point number.
421 **/
422 template<>
423 struct ObjectInfo<Angle<fltp04>, false, false>
424 {
425 static const uint01 Dimensions = 0;
426 static const bool Vector = false;
427 static const bool Primitive = true;
428 static const bool Pointer = false;
429 static const bool Unsigned = false;
430 static const bool Float = true;
431 static const bool Integer = false;
432 static const bool Number = true;
433 static const bool String = false;
434 static const bool Color = false;
435 static const bool Buffer = false;
436 static const bool Boolean = false;
437 static constexpr ObjectInfo<Angle<fltp04>, false, false> VectorSub() { return ObjectInfo<Angle<fltp04>, false, false>(); }
438 };
439};
440
The primary angle storage class for this API. Stores an angle in an optimized format.
Definition StringStream.h:540
t_type m_index_angle
Definition Angle.h:358
static Angle asin(t_value_type value)
Computes the principal value of the arc sine of the given value.
Definition Angle.h:305
constexpr t_type internal() const
Gets the internal index angle which is the default storage unit for the angle data.
Definition Angle.h:211
constexpr Angle(AngleType type, fltp04 value)
Angle Constructor.
Definition Angle.h:123
constexpr Angle< t_new_type > toTypeAngle() const
Explicit conversion of an angle from one container type to another.
Definition Angle.h:226
constexpr Angle normalizedOffset() const
returns the normalized angle which lies from -180 to 180 degrees.
Definition Angle.h:241
constexpr Angle()
Default constructor, creates an angle with 0 degrees.
Definition Angle.h:99
constexpr Angle(const Angle &angle)
Default copy constructor.
Definition Angle.h:106
static Angle atan2(t_value_type x, t_value_type y)
measures the counterclockwise angle between the positive x-axis and the point (x, y)
Definition Angle.h:328
constexpr Angle normalized() const
returns the normalized angle which lies from 0 to 360 degrees.
Definition Angle.h:234
constexpr Angle & operator=(const Angle &angle)
Definition Angle.h:252
constexpr Angle(const Angle< t_other_type > &angle)
Explicit conversion of an angle from one container type to another.
Definition Angle.h:114
static constexpr fltp08 INV_INDEX_PI
Definition Angle.h:334
static Angle acos(t_value_type value)
Computes the principal value of the arc cosine of the given value.
Definition Angle.h:294
Angle operator-() const
negates the angle
Definition Angle.h:282
constexpr bool operator!=(const Angle &angle) const
Inequality operator.
Definition Angle.h:273
constexpr fltp08 as(AngleType type) const
Returns a form of this angle as a given type (Radian, Degree, Percent, etc)
Definition Angle.h:193
static Angle atan(t_value_type value)
Computes the principal value of the arc tangent of the given value.
Definition Angle.h:316
constexpr bool operator==(const Angle &angle) const
Equality operator.
Definition Angle.h:263
constexpr Angle(AngleType type, fltp08 value)
Angle Constructor.
Definition Angle.h:141
static constexpr sint04 INDEX_PI
Definition Angle.h:333
constexpr Angle(t_type value)
Constructor.
Definition Angle.h:158
constexpr fltp08 as() const
Returns a form of this angle as a given type (Radian, Degree, Percent, etc) The template t_type provi...
Definition Angle.h:169
Definition ACIColor.h:37
int32_t sint04
-Defines an alias representing a 4 byte, signed integer. -Can represent exact integer values -2147483...
Definition BaseValues.hpp:64
float fltp04
Defines an alias representing a 4 byte floating-point number Bit layout is as follows: -Sign: 1 bit a...
Definition BaseValues.hpp:127
EulerPosition
Values that represent euler angles. These are typically used in Vector<3, Angle> to classify an orien...
Definition Angle.h:44
@ ROLL
Definition Angle.h:45
@ YAW
Definition Angle.h:47
@ PITCH
Definition Angle.h:46
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:80
AngleType
The possible units that can be used by the angle class. These are returned and used for real world an...
Definition Angle.h:56
@ PERCENT
Definition Angle.h:60
@ RADIANS
Definition Angle.h:57
@ DEGREES
Definition Angle.h:58
@ INTERNAL_ANGLE
Definition Angle.h:59
AngleFormatMode
Values that represent angle format modes. Used in classes for printing angle in a given format.
Definition Angle.h:68
@ MODE_DEGREES_MINUTES_SECONDS
Definition Angle.h:70
@ MODE_GRADIANS
Definition Angle.h:71
@ MODE_RADIANS
Definition Angle.h:72
@ MODE_SURVEYOR_UNITS
Definition Angle.h:73
@ MODE_DECIMAL_DEGREES
Definition Angle.h:69
constexpr t_to cast(const Angle< t_from > &value)
Definition Angle.h:375
double fltp08
Defines an alias representing an 8 byte floating-point number.
Definition BaseValues.hpp:149
Defines for a given type (such as sint04, fltp08, UUID, etc) a maximum, minimum, and reserved 'invali...
Definition BaseValues.hpp:233