NDEVR
API Documentation
Bounds.hpp
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: Bounds
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include <NDEVR/BaseValues.h>
34#include <NDEVR/Vertex.h>
35#include <NDEVR/LineSegment.h>
36#include <NDEVR/Triangle.h>
37#include <NDEVR/RadialObject.h>
38namespace NDEVR
39{
40
52 template<uint01 t_dims, class t_type, class t_vertex = Vertex<t_dims, t_type>>
53 class Bounds : public Vector<2, t_vertex>
54 {
55 public:
56 constexpr Bounds()
57 {}
58
63 constexpr Bounds(const t_vertex& vertex)
64 : Vector<2, t_vertex>(vertex, vertex)
65 {}
66
74 constexpr Bounds(const t_vertex& center, t_type size)
75 : Vector<2, t_vertex>(center - size, center + size)
76 {}
77 constexpr Bounds(const t_vertex& min, const t_vertex& max)
78 : Vector<2, t_vertex>(min, max)
79 {}
80 constexpr Bounds(const t_type& min_scaler, const t_type& max_scaler)
81 : Vector<2, t_vertex>(t_vertex(min_scaler), t_vertex(max_scaler))
82 {}
83
84 constexpr Bounds(const Vector<2, t_vertex>& bounds)
85 : Vector<2, t_vertex>(bounds)
86 {}
87
88 constexpr Bounds(const Bounds& bounds_a, const Bounds& bounds_b)
89 : Vector<2, t_vertex>(getMin(bounds_a[MIN], bounds_b[MIN]), getMax(bounds_a[MAX], bounds_b[MAX]))
90 {}
91
92 constexpr Bounds(const Bounds& bounds, const t_vertex& vector)
93 : Vector<2, t_vertex>(getMin(bounds[MIN], vector), getMax(bounds[MAX], vector))
94 {}
95 constexpr Bounds(const LineSegment<t_dims, t_type, t_vertex>& line)
96 : Vector<2, t_vertex>(getMin(line.vertex(A), line.vertex(B)), getMax(line.vertex(A), line.vertex(B)))
97 {}
98
99 constexpr Bounds(const Triangle<t_dims, t_type, t_vertex>& tri)
100 : Vector<2, t_vertex>(
101 getMin(tri.vertex(A), tri.vertex(B), tri.vertex(C))
102 , getMax(tri.vertex(A), tri.vertex(B), tri.vertex(C)))
103 {}
104
105 constexpr Bounds(const RadialObject<t_dims, t_type, t_vertex>& radial)
106 : Vector<2, t_vertex>(radial.center() - radial.radius(), radial.center() + radial.radius())
107 {}
108
113 constexpr Ray<t_dims, t_type> span() const
114 {
115 return Ray<t_dims, t_type>(Vector<2, t_vertex>::m_values[1] - Vector<2, t_vertex>::m_values[0]);
116 }
117
121 constexpr t_type span(uint01 dim) const
122 {
124 }
125
129 constexpr t_vertex center() const
130 {
132 }
133
137 constexpr t_type center(uint01 dim) const
138 {
140 }
141
145
146 constexpr t_type volume() const
147 {
148 return span().product();
149 }
150
154 constexpr t_type surfaceArea() const
155 {
156 t_type area = 0;
157 t_vertex side_lengths = span();
158 for (uint01 dim_a = 0; dim_a < t_dims; dim_a++)
159 {
160 for (uint01 dim_b = 0; dim_b < t_dims; dim_b++)
161 {
162 if (dim_b != dim_a)
163 {
164 area += side_lengths[dim_a] * side_lengths[dim_b];
165 }
166 }
167 }
168 return area;
169 }
170
176
177 constexpr void expand(const t_type& expansion_scaler)
178 {
179 (*this)[MIN] -= expansion_scaler;
180 (*this)[MAX] += expansion_scaler;
181 }
182
188
189 constexpr void expand(const t_vertex& expansion_vector)
190 {
191 Vector<2, t_vertex>::m_values[MIN] -= expansion_vector;
192 Vector<2, t_vertex>::m_values[MAX] += expansion_vector;
193 }
194
201 constexpr Bounds<t_dims, t_type> scale(const Vector<t_dims, t_type>& scale, const Vector<t_dims, t_type>& center) const
202 {
203 t_vertex scale_a = Vector<2, t_vertex>::m_values[MIN].scale(scale, center);
204 t_vertex scale_b = Vector<2, t_vertex>::m_values[MAX].scale(scale, center);
205 return Bounds<t_dims, t_type>(getMin(scale_a, scale_b), getMax(scale_a, scale_b));
206 }
207 constexpr Bounds<t_dims, t_type> scale(const Vector<t_dims, t_type>& center_scale) const
208 {
209 return scale(center_scale, center());
210 }
211
212 constexpr Bounds<t_dims, t_type> scale(const t_type& scale, const Vector<t_dims, t_type>& center) const
213 {
214 t_vertex scale_a = Vector<2, t_vertex>::m_values[MIN].scale(scale, center);
215 t_vertex scale_b = Vector<2, t_vertex>::m_values[MAX].scale(scale, center);
216 return Bounds<t_dims, t_type>(getMin(scale_a, scale_b), getMax(scale_a, scale_b));
217 }
218
219 constexpr Bounds<t_dims, t_type> scale(const t_type& center_scale) const
220 {
221 auto point = center();
222 t_vertex scale_a = Vector<2, t_vertex>::m_values[MIN].scale(center_scale, point);
223 t_vertex scale_b = Vector<2, t_vertex>::m_values[MAX].scale(center_scale, point);
224 if(center_scale > 0)
225 return Bounds<t_dims, t_type>(scale_a, scale_b);
226 else
227 return Bounds<t_dims, t_type>(scale_b, scale_a);
228 }
229
235 template<uint01 t_new_dims, class t_new_type, class t_new_vertex = Vertex<t_new_dims, t_new_type>>
236 constexpr decltype(auto) as(t_new_type extra_fill_value = t_new_type(0)) const
237 {
238 if constexpr (t_new_dims == t_dims
239 && std::is_same_v<t_new_type, t_type>
240 && std::is_same_v<t_new_vertex, t_vertex>)
241 {
242 return static_cast<const Bounds&>(*this);
243 }
244 else
245 {
246 return Bounds<t_new_dims, t_new_type, t_new_vertex>(
247 t_new_vertex((*this)[MIN].template as<t_new_dims, t_new_type>(extra_fill_value))
248 , t_new_vertex((*this)[MAX].template as<t_new_dims, t_new_type>(extra_fill_value)));
249 }
250 }
251
260 template<bool t_allow_bounds = true, uint01 tdims = t_dims
261 , typename = typename std::enable_if<tdims == 1>::type>
262 constexpr bool contains(const t_type & value) const
263 {
264 if (t_allow_bounds)
265 {
266 return !(!(value >= (*this)[MIN][0]) || !(value <= (*this)[MAX][0]));
267 }
268 else
269 {
270 return !(!(value > (*this)[MIN][0]) || !(value < (*this)[MAX][0]));
271 }
272 }
273
282 template<bool t_allow_bounds = true>
283 constexpr bool contains(const t_vertex& vector) const
284 {
285 if (t_allow_bounds)
286 {
287 for (uint01 dim = 0; dim < t_dims; ++dim)
288 {
289 if (!(vector[dim] >= (*this)[MIN][dim]) || !(vector[dim] <= (*this)[MAX][dim]))
290 return false;
291 }
292 }
293 else
294 {
295 for (uint01 dim = 0; dim < t_dims; ++dim)
296 {
297 if (!(vector[dim] > (*this)[MIN][dim]) || !(vector[dim] < (*this)[MAX][dim]))
298 return false;
299 }
300 }
301 return true;
302 }
303
318 template<bool t_allow_bounds = true>
319 constexpr bool contains(const Bounds& bounds) const
320 {
321 if (t_allow_bounds)
322 {
323 for (uint01 dim = 0; dim < t_dims; ++dim)
324 {
325 if (!(bounds[MIN][dim] >= (*this)[MIN][dim]))
326 return false;
327 if (!(bounds[MAX][dim] <= (*this)[MAX][dim]))
328 return false;
329 }
330 }
331 else
332 {
333 for (uint01 dim = 0; dim < t_dims; ++dim)
334 {
335 if (!(bounds[MIN][dim] >(*this)[MIN][dim]))
336 return false;
337 if (!(bounds[MAX][dim] < (*this)[MAX][dim]))
338 return false;
339 }
340 }
341 return true;
342 }
343
356 template<bool t_allow_bounds = true>
357 constexpr bool contains(const LineSegment<t_dims, t_type, t_vertex>& line) const
358 {
359 if (t_allow_bounds)
360 {
361 for (uint01 dim = 0; dim < t_dims; ++dim)
362 {
363 if (!(line.vertex(A)[dim] >= (*this)[MIN][dim] && line.vertex(B)[dim] >= (*this)[MIN][dim]))
364 return false;
365 if (!(line.vertex(A)[dim] <= (*this)[MAX][dim] && line.vertex(B)[dim] <= (*this)[MAX][dim]))
366 return false;
367 }
368 }
369 else
370 {
371 for (uint01 dim = 0; dim < t_dims; ++dim)
372 {
373 if (!(line.vertex(A)[dim] > (*this)[MIN][dim] && line.vertex(B)[dim] > (*this)[MIN][dim]))
374 return false;
375 if (!(line.vertex(A)[dim] < (*this)[MAX][dim] && line.vertex(B)[dim] < (*this)[MAX][dim]))
376 return false;
377 }
378 }
379 return true;
380 }
381
382
395 template<bool t_allow_bounds = true>
396 constexpr bool contains(const Triangle<t_dims, t_type, t_vertex>& tri) const
397 {
398 for (uint01 tri_index = A; tri_index <= C; tri_index++)
399 if (!contains<t_allow_bounds>(tri.vertex(tri_index)))
400 return false;
401 return true;
402 }
403
414
415 constexpr void addToBounds(const t_vertex& vector)
416 {
417 for (uint01 dim = 0; dim < t_dims; ++dim)
418 {
419 if ((*this)[MAX][dim] < vector[dim])
420 (*this)[MAX][dim] = vector[dim];
421 if ((*this)[MIN][dim] > vector[dim])
422 (*this)[MIN][dim] = vector[dim];
423 }
424 }
425 template<uint01 tdims = t_dims>
426 constexpr void addToBounds(typename std::enable_if<tdims == 1, const t_type&>::type scaler)
427 {
428 for (uint01 dim = 0; dim < tdims; ++dim)
429 {
430 if ((*this)[MAX][dim] < scaler)
431 (*this)[MAX][dim] = scaler;
432 if ((*this)[MIN][dim] > scaler)
433 (*this)[MIN][dim] = scaler;
434 }
435 }
436
448
449 constexpr void addToBounds(const Bounds& bounds)
450 {
451 for (uint01 dim = 0; dim < t_dims; ++dim)
452 {
453 if ((*this)[MAX][dim] < bounds[MAX][dim])
454 (*this)[MAX][dim] = bounds[MAX][dim];
455 if ((*this)[MIN][dim] > bounds[MIN][dim])
456 (*this)[MIN][dim] = bounds[MIN][dim];
457 }
458 }
459
471
472 constexpr void addToBounds(const LineSegment<t_dims, t_type, t_vertex>& line_segment)
473 {
474 addToBounds(line_segment.vertex(A));
475 addToBounds(line_segment.vertex(B));
476 }
477
489
490 constexpr void addToBounds(const Triangle<t_dims, t_type, t_vertex>& triangle)
491 {
492 addToBounds(triangle.vertex(A));
493 addToBounds(triangle.vertex(B));
494 addToBounds(triangle.vertex(C));
495 }
496
509 template<bool t_allow_bounds = true>
510 constexpr bool contains(const RadialObject<t_dims, t_type>& radial_object) const
511 {
512 if (t_allow_bounds)
513 return distanceSquared(closestEdge(radial_object.center()), radial_object.center()) <= radial_object.radius() * radial_object.radius();
514 else
515 return distanceSquared(closestEdge(radial_object.center()), radial_object.center()) < radial_object.radius() * radial_object.radius();
516 }
517
531
532 constexpr t_vertex closestEdge(const t_vertex& vertex) const
533 {
534 t_vertex closest_edge;
535 for(uint01 dim = 0; dim < t_dims; ++dim)
536 closest_edge[dim] = abs(vertex[dim] - (*this)[MIN][dim]) > abs(vertex[dim] - (*this)[MAX][dim]) ? (*this)[MAX][dim] : (*this)[MIN][dim];
537 return closest_edge;
538 }
539
553
554 constexpr t_vertex closestValue(const t_vertex& vertex) const
555 {
556 t_vertex closest_vertex;
557 for(uint01 dim = 0; dim < t_dims; ++dim)
558 closest_vertex[dim] = (vertex[dim] < (*this)[MIN][dim]) ? (*this)[MIN][dim] : (vertex[dim] > (*this)[MAX][dim]) ? (*this)[MAX][dim] : vertex[dim];
559 return closest_vertex;
560 }
561
575
576 constexpr t_vertex furthestValue(const t_vertex& vertex) const
577 {
578 t_vertex furthest_vertex;
579 for(uint01 dim = 0; dim < t_dims; ++dim)
580 furthest_vertex[dim] = abs(vertex[dim] - (*this)[MIN][dim]) > abs(vertex[dim] - (*this)[MAX][dim]) ? (*this)[MIN][dim] : (*this)[MAX][dim];
581 return furthest_vertex;
582 }
583
601
602 constexpr bool doesIntersect(t_type distance_a, t_type distance_b, const t_vertex& origin, const Vector<t_dims, t_type>& ray, uint01 exclusion_axis) const
603 {
604 if(!((distance_a * distance_b) < cast<t_type>(0)))
605 return false;
606
607 t_type unit_value = (-distance_a / (distance_b - distance_a));
608 for (uint01 dim = 0; dim < exclusion_axis; ++dim)
609 {
610 t_type hit_location = origin[dim] + ray[dim] * unit_value;
611 if (hit_location < (*this)[MIN][dim] || hit_location > (*this)[MAX][dim])
612 return false;
613 }
614 for (uint01 dim = exclusion_axis + 1; dim < t_dims; ++dim)
615 {
616 t_type hit_location = origin[dim] + ray[dim] * unit_value;
617 if (hit_location < (*this)[MIN][dim] || hit_location > (*this)[MAX][dim])
618 return false;
619 }
620 return true;
621 }
622
635 template<class t_other_vertex_type>
636 constexpr bool intersects(const Bounds<t_dims, t_type, t_other_vertex_type>& bounds) const
637 {
638 for (uint01 dim = 0; dim < t_dims; ++dim)
639 {
640 if (!((*this)[MAX][dim] > bounds[MIN][dim] && (*this)[MIN][dim] < bounds[MAX][dim]))
641 return false;
642 }
643 return true;
644 }
645
646
647 template<class t_other_vertex_type>
648 constexpr bool intersects(const LineSegment<t_dims, t_type, t_other_vertex_type>& seg) const
649 {
650 if (contains(seg))
651 {
652 return true;
653 }
654 const Vector<t_dims, t_type> ray = seg.ray();
655 for (uint01 i = 0; i < t_dims; ++i)
656 {
657 if ( doesIntersect(seg.vertex(A)[i] - (*this)[MIN][i], seg.vertex(B)[i] - (*this)[MIN][i], seg.vertex(A), ray, i)
658 || doesIntersect(seg.vertex(A)[i] - (*this)[MAX][i], seg.vertex(B)[i] - (*this)[MAX][i], seg.vertex(A), ray, i))
659 return true;
660 }
661 return false;
662 }
663
669 template<bool t_allow_bounds = true>
670 constexpr bool intersects(const RadialObject<t_dims, t_type>& circle) const
671 {
672 t_type dist_squared = circle.radius() * circle.radius();
673 for (uint01 dim = 0; dim < t_dims; ++dim)
674 {
675 if (circle.getCenter()[dim] < (*this)[MIN][dim])
676 {
677 t_type value = circle.center()[dim] - (*this)[MIN][dim];
678 dist_squared -= (value * value);
679 }
680 else if (circle.getCenter()[dim] > (*this)[MAX][dim])
681 {
682 t_type value = circle.center()[dim] - (*this)[MAX][dim];
683 dist_squared -= (value * value);
684 }
685 if (t_allow_bounds)
686 {
687 if (dist_squared < 0)
688 return false;
689 }
690 else
691 {
692 if (dist_squared <= 0)
693 return false;
694 }
695 }
696 return true;
697 }
698
704 [[nodiscard]] constexpr bool validate() const
705 {
706 if (getMin((*this)[MIN], (*this)[MAX]) != (*this)[MIN])
707 return false;
708 if (getMax((*this)[MIN], (*this)[MAX]) != (*this)[MAX])
709 return false;
710 return true;
711 }
712
718 {
719 t_vertex min = (*this)[MIN];
720 t_vertex max = (*this)[MAX];
721 (*this)[MIN] = getMin(min, max);
722 (*this)[MAX] = getMax(min, max);
723 }
724 Bounds<t_dims, t_type>& operator-=(const t_type& center_scale)
725 {
726 (*this)[MAX] -= center_scale;
727 (*this)[MIN] -= center_scale;
728 return *this;
729 }
730 };
731
732
733
734 template<uint01 t_dims, class t_type, class t_vertex>
735 struct Constant<Bounds<t_dims, t_type, t_vertex>>
736 {
737 constexpr static Bounds<t_dims, t_type, t_vertex> Invalid{ Constant<t_type>::Invalid, Constant<t_type>::Invalid };
738 constexpr static Bounds<t_dims, t_type, t_vertex> Min{ Constant<t_type>::Max, Constant<t_type>::Min };
739 constexpr static Bounds<t_dims, t_type, t_vertex> Max{ Constant<t_type>::Min, Constant<t_type>::Max };
740 };
741
742 template<uint01 t_dims, class t_type, class t_vertex>
743 static constexpr bool IsInvalid(const Bounds<t_dims, t_type, t_vertex>& value)
744 {
745 for (uint01 dim = 0; dim < 2; ++dim)
746 {
747 if (IsInvalid(value[dim]))
748 return true;
749 }
750 return false;
751 }
752 template<uint01 t_dims, class t_type, class t_vertex>
753 static constexpr bool IsValid(const Bounds<t_dims, t_type, t_vertex>& value)
754 {
755 for (uint01 dim = 0; dim < 2; ++dim)
756 {
757 if (IsInvalid(value[dim]))
758 return false;
759 }
760 return true;
761 }
762
763};
764
A specification of upper and lower bounds in N-dimensions.
Definition Bounds.hpp:54
constexpr void expand(const t_type &expansion_scaler)
Expands the given expansion scaler.
Definition Bounds.hpp:177
constexpr Bounds(const t_vertex &vertex)
Given the vector, creates bounds of size 0 where max and min are both equal to the vertex.
Definition Bounds.hpp:63
constexpr void expand(const t_vertex &expansion_vector)
Expands the given expansion scaler.
Definition Bounds.hpp:189
constexpr bool intersects(const Bounds< t_dims, t_type, t_other_vertex_type > &bounds) const
Definition Bounds.hpp:636
constexpr t_type span(uint01 dim) const
The side length of one axis of the bounds.
Definition Bounds.hpp:121
constexpr t_type surfaceArea() const
The surface area of the shape.
Definition Bounds.hpp:154
constexpr bool contains(const Triangle< t_dims, t_type, t_vertex > &tri) const
Definition Bounds.hpp:396
constexpr t_type volume() const
Returns the volume of the bounds.
Definition Bounds.hpp:146
constexpr void addToBounds(const t_vertex &vector)
Definition Bounds.hpp:415
constexpr void addToBounds(const Bounds &bounds)
Definition Bounds.hpp:449
constexpr bool contains(const LineSegment< t_dims, t_type, t_vertex > &line) const
Author: Tyler Parke.
Definition Bounds.hpp:357
constexpr void addToBounds(const LineSegment< t_dims, t_type, t_vertex > &line_segment)
Definition Bounds.hpp:472
constexpr t_type center(uint01 dim) const
Returns the center of the bounds in a single dimention.
Definition Bounds.hpp:137
constexpr t_vertex furthestValue(const t_vertex &vertex) const
Definition Bounds.hpp:576
constexpr bool doesIntersect(t_type distance_a, t_type distance_b, const t_vertex &origin, const Vector< t_dims, t_type > &ray, uint01 exclusion_axis) const
Checks for intersection of the ray from a given distance, excluding one axis.
Definition Bounds.hpp:602
constexpr Bounds< t_dims, t_type > scale(const Vector< t_dims, t_type > &scale, const Vector< t_dims, t_type > &center) const
Scales this geometry about a center point.
Definition Bounds.hpp:201
constexpr bool contains(const Bounds &bounds) const
Definition Bounds.hpp:319
constexpr decltype(auto) as(t_new_type extra_fill_value=t_new_type(0)) const
Casts this object into an object of different dimension or precision.
Definition Bounds.hpp:236
constexpr void addToBounds(const Triangle< t_dims, t_type, t_vertex > &triangle)
Definition Bounds.hpp:490
void ensureValid()
Ensures that this is a valid bounds object.
Definition Bounds.hpp:717
constexpr bool validate() const
Validates this object.
Definition Bounds.hpp:704
constexpr Bounds(const t_vertex &center, t_type size)
Given the center, creates bounds of size where max and min are both equal to the vertex + size and.
Definition Bounds.hpp:74
constexpr Vertex< t_dims, fltp08 > center() const
Definition Bounds.hpp:129
constexpr bool contains(const RadialObject< t_dims, t_type > &radial_object) const
Definition Bounds.hpp:510
constexpr bool intersects(const RadialObject< t_dims, t_type > &circle) const
Query if this object contains the given circle.
Definition Bounds.hpp:670
constexpr t_vertex closestEdge(const t_vertex &vertex) const
Definition Bounds.hpp:532
constexpr Ray< t_dims, t_type > span() const
The side lengths of these bounds.
Definition Bounds.hpp:113
constexpr bool contains(const t_vertex &vector) const
Query if this object contains the given vector.
Definition Bounds.hpp:283
constexpr bool contains(const t_type &value) const
Query if this object contains the given value.
Definition Bounds.hpp:262
constexpr t_vertex closestValue(const t_vertex &vertex) const
Definition Bounds.hpp:554
Class: LineSegment.
Definition Line.hpp:52
constexpr const t_vertex & vertex(uint01 index) const
Definition Line.hpp:155
constexpr t_vertex ray() const
Definition Line.hpp:123
A radial object.
constexpr const t_vertex & center() const
constexpr t_type radius() const
A three-vertex polygon representing a triangle in N-dimensional space.
Definition Triangle.hpp:142
constexpr t_vertex & vertex(TriangleLocation triangle_node)
Vertices the given triangle node.
Definition Triangle.hpp:172
A fixed-size array with N dimensions used as the basis for geometric and mathematical types.
Definition Vector.hpp:62
t_type m_values[t_dims]
The values[t dims].
Definition Vector.hpp:630
The primary namespace for the NDEVR SDK.
static constexpr Angle< t_angle_type > & operator-=(Angle< t_angle_type > &angle, const Angle< t_angle_type > &sub)
Subtraction assignment operator for Angles.
constexpr t_type getMin(const t_type &left, const t_type &right)
Finds the minimum of the given arguments based on the < operator Author: Tyler Parke Date: 2017-11-05...
constexpr t_type getMax(const t_type &left, const t_type &right)
Finds the max of the given arguments using the > operator The only requirement is that t_type have > ...
static constexpr bool IsValid(const Angle< t_type > &value)
Checks whether the given Angle holds a valid value.
Definition Angle.h:398
constexpr Angle< t_angle_type > abs(const Angle< t_angle_type > &value)
Changes an input with a negative sign, to a positive sign.
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
static constexpr bool IsInvalid(const Angle< t_type > &value)
Checks whether the given Angle holds an invalid value.
Definition Angle.h:388
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
Definition Angle.h:408
Defines for a given type (such as sint04, fltp08, UUID, etc) a maximum, minimum, and reserved 'invali...