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 Enum: EulerPosition
41
42 \brief Values that represent euler angles.
43 These are typically used in Vector<3, Angle> to classify an orientation of an object.
44 *-----------------------------------------------------------------------------------------------**/
51
52 /**--------------------------------------------------------------------------------------------------
53 \brief The possible units that can be used by the angle class.
54
55 These are returned and used for real world angle representation.
56
57 INTERNAL_ANGLE is the angle internally used by the angle class.
58 *-----------------------------------------------------------------------------------------------**/
66
67 /**--------------------------------------------------------------------------------------------------
68 \brief Values that represent angle format modes.
69 Used in classes for printing angle in a given format
70 *-----------------------------------------------------------------------------------------------**/
79 /**--------------------------------------------------------------------------------------------------
80 \brief Returns the value of PI to a given precision.
81 \return The value of PI (~3.1415...).
82 *-----------------------------------------------------------------------------------------------**/
83 template<class t_float_type>
84 static constexpr t_float_type PI()
85 {
86 return cast<t_float_type>(3.14159265358979323846264338327950288419716939937510);
87 }
88 /**--------------------------------------------------------------------------------------------------
89 \brief The primary angle storage class for this API. Stores an angle in an optimized format.
90
91 Since all angles are from 0-360 degrees it is possible to make certain optimizations that
92 make use of defined overflow that traditional floating point angles would not be able to achieve.
93 In addition space can be saved and expensive sin, cos, tan functions can be precomputed.
94 *-----------------------------------------------------------------------------------------------**/
95 template<class t_type = fltp08>
96 class Angle
97 {
98 public:
99
100 /**--------------------------------------------------------------------------------------------------
101 \brief Default constructor, creates an angle with 0 degrees.
102 *-----------------------------------------------------------------------------------------------**/
103 constexpr Angle()
104 : m_index_angle(0)
105 {}
106
107 /**--------------------------------------------------------------------------------------------------
108 \brief Default copy constructor
109 *-----------------------------------------------------------------------------------------------**/
110 constexpr Angle(const Angle& angle)
112 {}
113
114 /**--------------------------------------------------------------------------------------------------
115 \brief Explicit conversion of an angle from one container type to another.
116 *-----------------------------------------------------------------------------------------------**/
117 template<class t_other_type>
118 explicit constexpr Angle(const Angle<t_other_type>& angle)
119 : m_index_angle(cast<t_type>(angle.template internal<false>()))
120 {}
121
122 /**--------------------------------------------------------------------------------------------------
123 \brief Angle Constructor.
124 \param[in] type The type of the angle given (Example: radians, degrees, percent)
125 \param[in] value The value of the angle in the units specified by type.
126 *-----------------------------------------------------------------------------------------------**/
127 constexpr explicit Angle(AngleType type, fltp04 value)
128 : m_index_angle(0)
129 {
130 switch (type)
131 {
132 case INTERNAL_ANGLE: break;
133 case RADIANS: value = (value / PI<fltp04>()) * INDEX_PI; break;
134 case DEGREES: value = (value / 180.0f) * INDEX_PI; break;
135 case PERCENT: value = value * 2.0f * INDEX_PI; break;
136 }
138 }
139
140 /**--------------------------------------------------------------------------------------------------
141 \brief Angle Constructor.
142 \param[in] type The type of the angle given (Example: radians, degrees, percent)
143 \param[in] value The value of the angle in the units specified by type.
144 *-----------------------------------------------------------------------------------------------**/
145 constexpr explicit Angle(AngleType type, fltp08 value)
146 : m_index_angle(0)
147 {
148 switch (type)
149 {
150 case INTERNAL_ANGLE: break;
151 case RADIANS: value = (value / PI<fltp08>()) * INDEX_PI; break;
152 case DEGREES: value = (value / 180.0) * INDEX_PI; break;
153 case PERCENT: value = value * 2.0 * INDEX_PI; break;
154 }
156 }
157
158 /**--------------------------------------------------------------------------------------------------
159 \brief Constructor.
160 \param[in] value - the optimized input where INDEX_PI is 180 degrees
161 *-----------------------------------------------------------------------------------------------**/
162 constexpr explicit Angle(t_type value)
163 : m_index_angle(value)
164 {}
165
166 /**--------------------------------------------------------------------------------------------------
167 \brief Returns a form of this angle as a given type (Radian, Degree, Percent, etc)
168 \param[in] t_type The type of the angle to return (Example: radians, degrees, percent)
169 \param[in] t_is_signed Whether the given type should be signed or not (-180 - 180 vs 0 to 360)
170 \return A fltp08 representing this angle as the given type.
171 *-----------------------------------------------------------------------------------------------**/
172 template<AngleType t_angle_type>
173 [[nodiscard]] constexpr fltp08 as() const
174 {
175 switch (t_angle_type)
176 {
177 case INTERNAL_ANGLE:
178 if (IsInvalid(m_index_angle))
180 else
182 case DEGREES:
183 return as<INTERNAL_ANGLE>() * INV_INDEX_PI * 180.0;
184 case RADIANS:
185 return as<INTERNAL_ANGLE>() * INV_INDEX_PI * PI<fltp08>();
186 case PERCENT:
187 return as<INTERNAL_ANGLE>() * INV_INDEX_PI * 0.5;
188 }
190 }
191
192 /**--------------------------------------------------------------------------------------------------
193 \brief Returns a form of this angle as a given type (Radian, Degree, Percent, etc)
194 \param[in] type - The type of the angle to return (Example: radians, degrees, percent).
195 \return A fltp04 representing this angle as the given type.
196 *-----------------------------------------------------------------------------------------------**/
197 [[nodiscard]] constexpr fltp08 as(AngleType type) const
198 {
199 switch (type)
200 {
201 case DEGREES: return as<DEGREES>();
202 case RADIANS: return as<RADIANS>();
203 case PERCENT: return as<PERCENT>();
204 case INTERNAL_ANGLE: return as<INTERNAL_ANGLE>();
205 }
207 }
208 public:
209 /**--------------------------------------------------------------------------------------------------
210 \brief Gets the internal index angle which is the default storage unit for the angle data.
211 \return The internal index angle, or the angle represented by 0 - Constant<t_type>::Max representing
212 0 to 2 PI radians
213 *-----------------------------------------------------------------------------------------------**/
214 template<bool t_normalized>
215 [[nodiscard]] constexpr t_type internal() const
216 {
217 if constexpr(t_normalized)
218 {
219 return Angle<t_type>::template NormalizeInternal<t_type>(m_index_angle);
220 }
221 else
222 {
223 return m_index_angle;
224 }
225 }
226 /**--------------------------------------------------------------------------------------------------
227 \brief Explicit conversion of an angle from one container type to another.
228 *-----------------------------------------------------------------------------------------------**/
229 template<class t_new_type>
231 {
233 return angle;
234 }
235 /**--------------------------------------------------------------------------------------------------
236 \brief returns the normalized angle which lies from 0 to 360 degrees.
237 *-----------------------------------------------------------------------------------------------**/
238 [[nodiscard]] constexpr Angle normalized() const
239 {
240 return Angle(internal<true>());
241 }
242 /**--------------------------------------------------------------------------------------------------
243 \brief returns the normalized angle which lies from -180 to 180 degrees.
244 *-----------------------------------------------------------------------------------------------**/
245 [[nodiscard]] constexpr Angle normalizedOffset() const
246 {
247 Angle value = normalized();
248 if (value > Angle(DEGREES, 180.0))
249 value -= Angle(DEGREES, 360.0);
250 return value;
251 }
252 /**--------------------------------------------------------------------------------------------------
253 \param[in] angle - The value to assign.
254 \return A shallow copy of this object.
255 *-----------------------------------------------------------------------------------------------**/
256 constexpr Angle& operator=(const Angle& angle)
257 {
258 m_index_angle = angle.m_index_angle;
259 return (*this);
260 }
261
262 /**--------------------------------------------------------------------------------------------------
263 \brief Equality operator.
264 \param[in] angle - The value to check comparison.
265 \return true if the left and right are considered equivalent.
266 *-----------------------------------------------------------------------------------------------**/
267 constexpr bool operator==(const Angle& angle) const
268 {
269 return internal<false>() == angle.internal<false>();
270 }
271
272 /**--------------------------------------------------------------------------------------------------
273 \brief Inequality operator.
274 \param[in] angle The value to check inequality against.
275 \return true if the left and right are not considered equivalent.
276 *-----------------------------------------------------------------------------------------------**/
277 constexpr bool operator!=(const Angle& angle) const
278 {
279 return internal<false>() != angle.internal<false>();
280 }
281
282 /**--------------------------------------------------------------------------------------------------
283 \brief negates the angle
284 \return The result of the operation.
285 *-----------------------------------------------------------------------------------------------**/
287 {
288 return Angle(-m_index_angle);
289 }
290 public:
291
292 /**--------------------------------------------------------------------------------------------------
293 \brief Computes the principal value of the arc cosine of the given value
294 \param[in] value - The value to perform arc cos.
295 \return the arc cosine of the given value as an Angle.
296 *-----------------------------------------------------------------------------------------------**/
297 template<class t_value_type>
298 static Angle acos(t_value_type value)
299 {
300 return Angle(RADIANS, ::acos(value));
301 }
302
303 /**--------------------------------------------------------------------------------------------------
304 \brief Computes the principal value of the arc sine of the given value
305 \param[in] value - The value to perform arc sine.
306 \return the arc sine of the given value as an Angle.
307 *-----------------------------------------------------------------------------------------------**/
308 template<class t_value_type>
309 static Angle asin(t_value_type value)
310 {
311 return Angle(RADIANS, ::asin(value));
312 }
313
314 /**--------------------------------------------------------------------------------------------------
315 \brief Computes the principal value of the arc tangent of the given value
316 \param[in] value - The value to perform arc tangent.
317 \return the arc tangent of the given value as an Angle.
318 *-----------------------------------------------------------------------------------------------**/
319 template<class t_value_type>
320 static Angle atan(t_value_type value)
321 {
322 return Angle(RADIANS, ::atan(value));
323 }
324
325 /**--------------------------------------------------------------------------------------------------
326 \brief measures the counterclockwise angle between the positive x-axis and the point (x, y)
327 \param[in] x - the numerator or x value of atan
328 \param[in] y - the denomenator or y value of atan
329 \return the arc tangent of the given value as an Angle.
330 *-----------------------------------------------------------------------------------------------**/
331 template<class t_value_type>
332 static Angle atan2(t_value_type x, t_value_type y)
333 {
334 return Angle(RADIANS, ::atan2(x, y));
335 }
336 public:
337 static constexpr sint04 INDEX_PI = 32768;//optimized angle that allows integers to store angles to some degree of accuracy
338 static constexpr fltp08 INV_INDEX_PI = { 1.0 / Angle<t_type>::INDEX_PI };
339 private:
340 template<class t_normal_type>
341 static constexpr typename std::enable_if<!ObjectInfo<t_normal_type>::Float, t_normal_type>::type NormalizeInternal(t_normal_type value)
342 {
343 const t_normal_type angle = (value >= 0 ? value : -value) % (2 * INDEX_PI);
344 if (value >= 0)
345 return angle;
346 else
347 return (2 * INDEX_PI) - angle;
348 }
349
350 template<class t_normal_type>
351 static constexpr typename std::enable_if<ObjectInfo<t_normal_type>::Float, t_normal_type>::type NormalizeInternal(t_normal_type value)
352 {
353 const t_normal_type angle = fmod(std::abs(value), (2 * INDEX_PI));
354 if (value >= 0)
355 return angle;
356 else
357 return 2 * cast<t_normal_type>(INDEX_PI) - angle;
358 }
359
360 protected:
361 /** The index angle. */
363 };
367
371
372 template<class t_type>
373 static constexpr bool IsInvalid(const Angle<t_type>& value)
374 {
375 return IsInvalid(value.template internal<false>());
376 }
377
378 template<class t_to, class t_from>
379 constexpr t_to cast(const Angle<t_from>& value)
380 {
381 return t_to(INTERNAL_ANGLE, cast<fltp08>(value.template internal<false>()));
382 }
383 /**--------------------------------------------------------------------------------------------------
384 \brief Information about an Angle object backed by a signed 4 byte integer.
385 *-----------------------------------------------------------------------------------------------**/
386 template<>
387 struct ObjectInfo<Angle<sint04>, false, false>
388 {
389 static const uint01 Dimensions = 0;
390 static const bool Vector = false;
391 static const bool Primitive = true;
392 static const bool Pointer = false;
393 static const bool Unsigned = false;
394 static const bool Float = true;
395 static const bool Integer = false;
396 static const bool Number = true;
397 static const bool String = false;
398 static const bool Color = false;
399 static const bool Buffer = false;
400 static const bool Boolean = false;
401 static constexpr ObjectInfo<Angle<sint04>, false, false> VectorSub() { return ObjectInfo<Angle<sint04>, false, false>(); }
402 };
403 /**--------------------------------------------------------------------------------------------------
404 \brief Information about an Angle object backed by a 8 byte floating point number.
405 *-----------------------------------------------------------------------------------------------**/
406 template<>
407 struct ObjectInfo<Angle<fltp08>, false, false>
408 {
409 static const uint01 Dimensions = 0;
410 static const bool Vector = false;
411 static const bool Primitive = true;
412 static const bool Pointer = false;
413 static const bool Unsigned = false;
414 static const bool Float = true;
415 static const bool Integer = false;
416 static const bool Number = true;
417 static const bool String = false;
418 static const bool Color = false;
419 static const bool Buffer = false;
420 static const bool Boolean = false;
421 static constexpr ObjectInfo<Angle<fltp08>, false, false> VectorSub() { return ObjectInfo<Angle<fltp08>, false, false>(); }
422 };
423 /**--------------------------------------------------------------------------------------------------
424 \brief Information about an Angle object backed by a 4 byte floating point number.
425 *-----------------------------------------------------------------------------------------------**/
426 template<>
427 struct ObjectInfo<Angle<fltp04>, false, false>
428 {
429 static const uint01 Dimensions = 0;
430 static const bool Vector = false;
431 static const bool Primitive = true;
432 static const bool Pointer = false;
433 static const bool Unsigned = false;
434 static const bool Float = true;
435 static const bool Integer = false;
436 static const bool Number = true;
437 static const bool String = false;
438 static const bool Color = false;
439 static const bool Buffer = false;
440 static const bool Boolean = false;
441 static constexpr ObjectInfo<Angle<fltp04>, false, false> VectorSub() { return ObjectInfo<Angle<fltp04>, false, false>(); }
442 };
443};
444
The primary angle storage class for this API. Stores an angle in an optimized format.
Definition StringStream.h:408
t_type m_index_angle
Definition Angle.h:362
static Angle asin(t_value_type value)
Computes the principal value of the arc sine of the given value.
Definition Angle.h:309
constexpr t_type internal() const
Gets the internal index angle which is the default storage unit for the angle data.
Definition Angle.h:215
constexpr Angle(AngleType type, fltp04 value)
Angle Constructor.
Definition Angle.h:127
constexpr Angle< t_new_type > toTypeAngle() const
Explicit conversion of an angle from one container type to another.
Definition Angle.h:230
constexpr Angle normalizedOffset() const
returns the normalized angle which lies from -180 to 180 degrees.
Definition Angle.h:245
constexpr Angle()
Default constructor, creates an angle with 0 degrees.
Definition Angle.h:103
constexpr Angle(const Angle &angle)
Default copy constructor.
Definition Angle.h:110
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:332
constexpr Angle normalized() const
returns the normalized angle which lies from 0 to 360 degrees.
Definition Angle.h:238
constexpr Angle & operator=(const Angle &angle)
Definition Angle.h:256
constexpr Angle(const Angle< t_other_type > &angle)
Explicit conversion of an angle from one container type to another.
Definition Angle.h:118
static constexpr fltp08 INV_INDEX_PI
Definition Angle.h:338
static Angle acos(t_value_type value)
Computes the principal value of the arc cosine of the given value.
Definition Angle.h:298
Angle operator-() const
negates the angle
Definition Angle.h:286
constexpr bool operator!=(const Angle &angle) const
Inequality operator.
Definition Angle.h:277
constexpr fltp08 as(AngleType type) const
Returns a form of this angle as a given type (Radian, Degree, Percent, etc)
Definition Angle.h:197
static Angle atan(t_value_type value)
Computes the principal value of the arc tangent of the given value.
Definition Angle.h:320
constexpr bool operator==(const Angle &angle) const
Equality operator.
Definition Angle.h:267
constexpr Angle(AngleType type, fltp08 value)
Angle Constructor.
Definition Angle.h:145
static constexpr sint04 INDEX_PI
Definition Angle.h:337
constexpr Angle(t_type value)
Constructor.
Definition Angle.h:162
constexpr fltp08 as() const
Returns a form of this angle as a given type (Radian, Degree, Percent, etc)
Definition Angle.h:173
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:62
float fltp04
Defines an alias representing a 4 byte floating-point number.
Definition BaseValues.hpp:125
EulerPosition
Values that represent euler angles.
Definition Angle.h:46
@ ROLL
Definition Angle.h:47
@ YAW
Definition Angle.h:49
@ PITCH
Definition Angle.h:48
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:78
AngleType
The possible units that can be used by the angle class.
Definition Angle.h:60
@ PERCENT
Definition Angle.h:64
@ RADIANS
Definition Angle.h:61
@ DEGREES
Definition Angle.h:62
@ INTERNAL_ANGLE
Definition Angle.h:63
AngleFormatMode
Values that represent angle format modes.
Definition Angle.h:72
@ MODE_DEGREES_MINUTES_SECONDS
Definition Angle.h:74
@ MODE_GRADIANS
Definition Angle.h:75
@ MODE_RADIANS
Definition Angle.h:76
@ MODE_SURVEYOR_UNITS
Definition Angle.h:77
@ MODE_DECIMAL_DEGREES
Definition Angle.h:73
constexpr t_to cast(const Angle< t_from > &value)
Definition Angle.h:379
double fltp08
Defines an alias representing an 8 byte floating-point number.
Definition BaseValues.hpp:146
Defines for a given type (such as sint04, fltp08, UUID, etc) a maximum, minimum, and reserved.
Definition BaseValues.hpp:230