NDEVR
API Documentation
Vector.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: Vector
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include <NDEVR/BaseValues.h>
34#include <NDEVR/LibAssert.h>
35#include <type_traits>
36#include <cmath>
37#include <type_traits>
38namespace NDEVR
39{
60 template<uint01 t_dims, class t_type>
61 class Vector
62 {
63 public:
64 constexpr Vector() noexcept
65 : m_values()
66 {}
67
78 template<class t_vec_type>
79 constexpr explicit Vector(const Vector<t_dims, t_vec_type>& vector) noexcept
80 : m_values()
81 {
82 for (uint01 dim = 0; dim < t_dims; ++dim)
83 m_values[dim] = cast<t_type>(vector[dim]);
84 }
85
96
97 constexpr explicit Vector(const t_type& scaler) noexcept
98 : m_values()
99 {
100 for(uint01 dim = 0; dim < t_dims; ++dim)
101 m_values[dim] = scaler;
102 }
103
116 template<uint01 tdims = t_dims>
117 constexpr Vector(const t_type& x, typename std::enable_if<tdims == 2, const t_type&>::type y)
118 : m_values{x, y}
119 {
120 static_assert(t_dims == 2, "Unexpected Number of Dimensions. Vector Size Required: 2");
121 }
122
136 template<uint01 tdims = t_dims>
137 constexpr Vector(const t_type& x, const t_type& y, const typename std::enable_if<tdims == 3, const t_type&>::type z)
138 : m_values{x, y, z}
139 {
140 static_assert(t_dims == 3, "Unexpected Number of Dimensions. Vector Size Required: 3");
141 }
142
157 template<uint01 tdims = t_dims>
158 constexpr Vector(const t_type& x, const t_type& y, const t_type& z, typename std::enable_if<tdims == 4, const t_type&>::type w)
159 : m_values{ x, y, z, w }
160 {
161 static_assert(t_dims == 4, "Unexpected Number of Dimensions. Vector Size Required: 4");
162 }
163
164 template<uint01 tdims = t_dims>
165 constexpr Vector(const t_type& x, const t_type& y, const t_type& z, const t_type& w, typename std::enable_if<tdims == 5, const t_type&>::type v)
166 : m_values{ x, y, z, w, v }
167 {
168 static_assert(t_dims == 5, "Unexpected Number of Dimensions. Vector Size Required: 5");
169 }
170
171 template<uint01 tdims = t_dims>
172 constexpr Vector(const t_type& x, const t_type& y, const t_type& z, const t_type& w, const t_type& v, typename std::enable_if<tdims == 6, const t_type&>::type u)
173 : m_values{ x, y, z, w, v, u }
174 {
175 static_assert(t_dims == 6, "Unexpected Number of Dimensions. Vector Size Required: 6");
176 }
177 template<uint01 tdims = t_dims>
178 constexpr Vector(const t_type& x, const t_type& y, const t_type& z, const t_type& w, const t_type& v, const t_type& u, const t_type& t, const t_type& s, typename std::enable_if<tdims == 9, const t_type&>::type r)
179 : m_values{ x, y, z, w, v, u, t, s, r }
180 {
181 static_assert(t_dims == 9, "Unexpected Number of Dimensions. Vector Size Required: 9");
182 }
193 constexpr explicit Vector(const t_type(&vector)[t_dims])
194 : m_values{}
195 {
196 for (uint01 dim = 0; dim < t_dims; dim++)
197 m_values[dim] = vector[dim];
198 }
199
211 template<uint01 tdims = t_dims>
212 constexpr Vector(const Vector<tdims - 1, t_type>& vector, typename std::enable_if<tdims >= 2, const t_type&>::type suffix)
213 : m_values{}
214 {
215 static_assert(t_dims >= 2, "Unexpected Number of Dimensions. Vector Size Required: >= 2");
216 for(uint01 dim = 0; dim < t_dims - 1; ++dim)
217 m_values[dim] = vector[dim];
218 m_values[t_dims - 1] = suffix;
219 }
220
233 template<uint01 tdims = t_dims>
234 constexpr Vector(const Vector<getMax(tdims - 2, 0), t_type>& vector, const t_type& suffix_a, typename std::enable_if<tdims >= 3, const t_type&>::type suffix_b)
235 : m_values{}
236 {
237 static_assert(t_dims >= 3, "Unexpected Number of Dimensions. Vector Size Required: >= 3");
238 for(uint01 dim = 0; dim < t_dims - 2; ++dim)
239 m_values[dim] = vector[dim];
240 m_values[t_dims - 2] = suffix_a;
241 m_values[t_dims - 1] = suffix_b;
242 }
243
255 template<uint01 tdims = t_dims>
256 constexpr Vector(const t_type& prefix, typename std::enable_if<tdims >= 2, const Vector<t_dims - 1, t_type>&>::type vector)
257 : m_values{}
258 {
259 static_assert(t_dims >= 2, "Unexpected Number of Dimensions. Vector Size Required: >= 2");
260 m_values[X] = prefix;
261 for(uint01 dim = Y; dim < t_dims; ++dim)
262 m_values[dim] = vector[dim - 1];
263 }
264
276 template<uint01 tdims = t_dims>
277 constexpr Vector(const t_type& prefix_a, const t_type& prefix_b, typename std::enable_if<tdims >= 3, const Vector<tdims - 1, t_type>&>::type vector)
278 : m_values{}
279 {
280 static_assert(t_dims >= 3, "Unexpected Number of Dimensions. Vector Size Required: >= 3");
281 m_values[X] = prefix_a;
282 m_values[Y] = prefix_b;
283 for (uint01 dim = Z; dim < t_dims; ++dim)
284 m_values[dim] = vector[dim - 1];
285 }
286
300 template<class t_new_type>
301 constexpr decltype(auto) as() const
302 {
303 if constexpr (std::is_same_v<t_new_type, t_type>)
304 {
305 return static_cast<const Vector<t_dims, t_type>&>(*this);
306 }
307 else
308 {
309 Vector<t_dims, t_new_type> vec;
310 for (uint01 dim = 0; dim < t_dims; ++dim)
311 vec[dim] = cast<t_new_type>(m_values[dim]);
312 return vec;
313 }
314 }
315 template<uint01 t_new_dim, class t_new_type>
316 constexpr decltype(auto) as() const
317 {
318 if constexpr (t_new_dim == t_dims && std::is_same_v<t_new_type, t_type>)
319 {
320 return static_cast<const Vector<t_dims, t_type>&>(*this);
321 }
322 else
323 {
324 Vector<t_new_dim, t_new_type> vec;
325 constexpr uint01 min = getMin(t_new_dim, t_dims);
326 for (uint01 dim = 0; dim < min; ++dim)
327 vec[dim] = cast<t_new_type>(m_values[dim]);
328 return vec;
329 }
330 }
331 template<uint01 t_new_dim, class t_new_type>
332 constexpr decltype(auto) as(t_new_type extra_fill_value) const
333 {
334 if constexpr (t_new_dim == t_dims && std::is_same_v<t_new_type, t_type>)
335 {
336 return static_cast<const Vector<t_dims, t_type>&>(*this);
337 }
338 else
339 {
340 Vector<t_new_dim, t_new_type> vec;
341 uint01 dim = 0;
342 constexpr uint01 min = getMin(t_new_dim, t_dims);
343 for (; dim < min; dim++)
344 vec[dim] = cast<t_new_type>(m_values[dim]);
345 for (; dim < t_new_dim; dim++)
346 vec[dim] = extra_fill_value;
347 return vec;
348 }
349 }
350
361 template<LocationValues t_max_min>
362 [[nodiscard]] constexpr t_type dimensionalValue() const
363 {
364 t_type value = m_values[0];
365 for(uint01 dim = 1; dim < t_dims; ++dim)
366 {
367 if constexpr(t_max_min == MAX)
368 {
369 if(m_values[dim] > value)
370 value = m_values[dim];
371 }
372 else
373 {
374 if(m_values[dim] < value)
375 value = m_values[dim];
376 }
377 }
378 return value;
379 }
380
391 template<LocationValues t_max_min>
392 [[nodiscard]] constexpr uint01 dimensionalIndex() const
393 {
394 uint01 dimension = 0;
395 for(uint01 dim = 1; dim < t_dims; ++dim)
396 {
397 if constexpr (t_max_min == MAX)
398 {
399 if (m_values[dim] > m_values[dimension])
400 dimension = dim;
401 }
402 else
403 {
404 if(m_values[dim] < m_values[dimension])
405 dimension = dim;
406 }
407 }
408 return dimension;
409 }
410
421 template<uint01 tdims = t_dims
422 , typename = typename std::enable_if<tdims == 1>::type>
423 constexpr operator t_type&()
424 {
425 return m_values[0];
426 }
427
428 template<uint01 tdims = t_dims
429 , typename = typename std::enable_if<tdims == 1>::type>
430 constexpr operator const t_type &() const
431 {
432 return m_values[0];
433 }
434
448 [[nodiscard]] constexpr t_type magnitudeSquared() const
449 {
450 t_type magnitude(0);
451 for(uint01 dim = 0; dim < t_dims; ++dim)
452 magnitude += m_values[dim] * m_values[dim];
453 return magnitude;
454 }
455
469 template<class t_magnitude_type = t_type>
470 constexpr t_magnitude_type magnitude() const
471 {
473 }
474
475
485 template<class t_norm_type = t_type>
486 constexpr Vector<t_dims, t_norm_type> normalized(Vector<t_dims, t_norm_type> value_if_nan = Constant<Vector<t_dims, t_norm_type>>::Invalid) const
487 {
489 if(magnitude == 0)
490 return value_if_nan;
492 Vector<t_dims, t_norm_type> normalized;
493 for (uint01 dim = 0; dim < t_dims; dim++)
494 {
496 }
497 return normalized;
498 }
499
500
510 [[nodiscard]] constexpr t_type product() const
511 {
512 t_type value = m_values[0];
513 for(uint01 dim = 1; dim < t_dims; ++dim)
514 value *= m_values[dim];
515 return value;
516 }
517
527 [[nodiscard]] constexpr t_type sum() const
528 {
529 t_type value = m_values[0];
530 for (uint01 dim = 1; dim < t_dims; ++dim)
531 value += m_values[dim];
532 return value;
533 }
534
547
548 constexpr t_type& operator[](uint01 dimension_index)
549 {
550 #if defined(__clang__) || defined(__GNUC__)
551 if constexpr (__builtin_constant_p(dimension_index))
552 static_assert(dimension_index < t_dims, "Dimension requested Exceeded maximum vector dimension");
553 #endif
554 lib_assert(dimension_index < t_dims, "Dimension requested Exceeded maximum vector dimension");
555 return m_values[dimension_index];
556 }
557 constexpr const t_type& operator[](const uint01 dimension_index) const
558 {
559 #if defined(__clang__) || defined(__GNUC__)
560 if constexpr (__builtin_constant_p(dimension_index))
561 static_assert(dimension_index < t_dims, "Dimension requested Exceeded maximum vector dimension");
562 #endif
563 lib_assert(dimension_index < t_dims, "Dimension requested Exceeded maximum vector dimension");
564 return m_values[dimension_index];
565 }
566
576 constexpr Vector<t_dims, t_type> operator-() const
577 {
578 Vector<t_dims, t_type> value;
579 for(uint01 dim = 0; dim < t_dims; ++dim)
580 value[dim] = -m_values[dim];
581 return value;
582 }
583
596
597 constexpr Vector<t_dims, t_type>& operator=(const t_type& scaler)
598 {
599 for (uint01 dim = 0; dim < t_dims; ++dim)
600 m_values[dim] = scaler;
601 return *this;
602 }
603
613
614 constexpr static uint01 NumberOfDimensions() { return t_dims; }
615
626 constexpr static t_type Type() { return t_type(); }
627
628 protected:
630 t_type m_values[t_dims];
631 };
632
633 static_assert(sizeof(Vector<3, fltp08>) == 24, "Bad Vector<3, fltp08> size");
634 static_assert(sizeof(Vector<4, Vector<4, fltp08>>) == 128, "Bad Vector<4, Vector<4, fltp08>> size");
648 template<uint01 t_dims, class t_type>
649 constexpr bool operator==(const Vector<t_dims, t_type>& vec_a, const Vector<t_dims, t_type>& vec_b)
650 {
651 for (uint01 dim = 0; dim < t_dims; ++dim)
652 {
653 if (vec_a[dim] != vec_b[dim])
654 return false;
655 }
656 return true;
657 }
658
672 template<uint01 t_dims, class t_type>
673 constexpr bool operator!=(const Vector<t_dims, t_type>& vec_a, const Vector<t_dims, t_type>& vec_b)
674 {
675 for (uint01 dim = 0; dim < t_dims; ++dim)
676 {
677 if (vec_a[dim] != vec_b[dim])
678 return true;
679 }
680 return false;
681 }
682
683
698 template<uint01 t_dims, class t_type>
700 {
701 return (((value.template as<t_dims, fltp08>() / cast<fltp08>(d) + 0.5).template as<t_dims, sint08>()).template as<t_dims, fltp08>() * cast<fltp08>(d)).template as<t_dims, t_type>();
702 }
703
707 template<uint01 t_dims, class t_type>
709 {
710 return (((value.template as<t_dims, fltp08>()
711 / d.template as<t_dims, fltp08>() + 0.5).template as<t_dims, uint08>()).template as<t_dims, fltp08>()
712 * d.template as<t_dims, fltp08>()).template as<t_dims, t_type>();
713 }
714 template<uint01 t_dims, class t_type>
715 struct Constant<Vector<t_dims, t_type>>
716 {
718 constexpr const static Vector<t_dims, t_type> Invalid{ Constant<t_type>::Invalid };
720 constexpr const static Vector<t_dims, t_type> Min{ Constant<t_type>::Min };
722 constexpr const static Vector<t_dims, t_type> Max{ Constant<t_type>::Max };
723 };
724
725 template<uint01 t_dims, class t_type>
726 static constexpr bool IsInvalid(const Vector<t_dims, t_type>& value)
727 {
728 for (uint01 dim = 0; dim < t_dims; ++dim)
729 {
730 if (IsInvalid(value[dim]))
731 return true;
732 }
733 return false;
734 }
735 template<uint01 t_dims, class t_type>
736 static constexpr bool IsValid(const Vector<t_dims, t_type>& value)
737 {
738 for (uint01 dim = 0; dim < t_dims; ++dim)
739 {
740 if (IsInvalid(value[dim]))
741 return false;
742 }
743 return true;
744 }
745 template < template <uint01 t_dims, class t_type> class base, typename derived>
746 struct is_base_of_template_impl
747 {
748 template<uint01 t_dims, class t_type>
749 static constexpr std::true_type test(const base<t_dims, t_type>*);
750 static constexpr std::false_type test(...);
751 using type = decltype(test(std::declval<derived*>()));
752 };
753
754 template < template <uint01 t_dims, class t_type> class base, typename derived>
755 using is_base_of_template = typename is_base_of_template_impl<base, derived>::type;
756
757 template<class t_type>
758 struct IsVec
759 {
760 static constexpr bool value = is_base_of_template<Vector, t_type>::value;
761 };
762 template<class t_type_a, class t_type_b>
763 struct IsSameType
764 {
765 static constexpr bool value = false;
766 };
767 template<class t_type_a>
768 struct IsSameType<t_type_a, t_type_a>
769 {
770 static constexpr bool value = true;
771 };
772 template<class t_type_a, class t_type_b>
773 struct IsVecType
774 {
775 private:
776 template<class t = t_type_a, std::enable_if_t<!IsVec<t>::value, int> = 0>
777 static constexpr bool internalValue()
778 {
779 return false;
780 }
781 template<class t = t_type_a, std::enable_if_t<IsVec<t>::value, int> = 0>
782 static constexpr bool internalValue()
783 {
784 return IsSameType<decltype(t::Type()), t_type_b>::value;
785 }
786 public:
787 static constexpr bool value = internalValue();
788 };
789};
790namespace std//Define things to allow use within std libs
791{
792 template <>
793 struct hash<Vector<2, uint04>>
794 {
795 std::size_t operator()(const Vector<2, uint04>& s) const noexcept
796 {
797 std::size_t h = 0, g = 0;
798 const uint01* bytes = reinterpret_cast<const uint01*>(&s[0]);
799 for (size_t i = 0; i < 2 * sizeof(uint04); i++)
800 {
801 h = (h << 4) + bytes[i];
802 g = h & 0xF0000000L;
803 if (g)
804 h ^= g >> 24;
805 h &= ~g;
806 }
807 return h;
808 }
809 };
810 template <>
811 struct hash<Vector<3, uint04>>
812 {
813 std::size_t operator()(const Vector<3, uint04>& s) const noexcept
814 {
815 std::size_t h = 0, g = 0;
816 const uint01* bytes = reinterpret_cast<const uint01*>(&s[0]);
817 for (size_t i = 0; i < 3 * sizeof(uint04); i++)
818 {
819 h = (h << 4) + bytes[i];
820 g = h & 0xF0000000L;
821 if (g)
822 h ^= g >> 24;
823 h &= ~g;
824 }
825 return h;
826 }
827 };
828 template <>
829 struct hash<Vector<3, fltp08>>
830 {
831 std::size_t operator()(const Vector<3, fltp08>& s) const noexcept
832 {
833 std::size_t h = 0, g = 0;
834 const uint01* bytes = reinterpret_cast<const uint01*>(&s[0]);
835 for (size_t i = 0; i < 3 * sizeof(fltp08); i++)
836 {
837 h = (h << 4) + bytes[i];
838 g = h & 0xF0000000L;
839 if (g)
840 h ^= g >> 24;
841 h &= ~g;
842 }
843 return h;
844 }
845 };
846 template <>
847 struct hash<Vector<3, fltp04>>
848 {
849 std::size_t operator()(const Vector<3, fltp04>& s) const noexcept
850 {
851 std::size_t h = 0, g = 0;
852 const uint01* bytes = reinterpret_cast<const uint01*>(&s[0]);
853 for (uint04 i = 0; i < 3 * sizeof(fltp04); i++)
854 {
855 h = (h << 4) + bytes[i];
856 g = h & 0xF0000000L;
857 if (g)
858 h ^= g >> 24;
859 h &= ~g;
860 }
861 return h;
862 }
863 };
864};
865#include "BoolVector.hpp"
A fixed-size array with N dimensions used as the basis for geometric and mathematical types.
Definition Vector.hpp:62
constexpr t_type sum() const
Returns the sum, or value of each dimension added together.
Definition Vector.hpp:527
constexpr Vector(const t_type &prefix, typename std::enable_if< tdims >=2, const Vector< t_dims - 1, t_type > & >::type vector)
Creates a vector where the prefix scaler is combined with the suffix vector.
Definition Vector.hpp:256
constexpr t_type product() const
Returns the product, or value of each dimension multiplied together.
Definition Vector.hpp:510
constexpr Vector(const Vector< tdims - 1, t_type > &vector, typename std::enable_if< tdims >=2, const t_type & >::type suffix)
Creates a vector where the prefix vector is combined with the suffix scalers.
Definition Vector.hpp:212
constexpr Vector(const t_type(&vector)[t_dims])
Given a container of statically determined array, transforms it to a vector.
Definition Vector.hpp:193
constexpr Vector(const t_type &scaler) noexcept
Definition Vector.hpp:97
t_type m_values[t_dims]
The values[t dims].
Definition Vector.hpp:630
constexpr decltype(auto) as() const
Returns the vector as a new time of vector.
Definition Vector.hpp:301
constexpr Vector< t_dims, t_norm_type > normalized(Vector< t_dims, t_norm_type > value_if_nan=Constant< Vector< t_dims, t_norm_type > >::Invalid) const
Gets the normalized, or unit length representation of this vector.
Definition Vector.hpp:486
constexpr t_type magnitudeSquared() const
Vectors are commonly used to model forces such as wind, sea current, gravity, and electromagnetism.
Definition Vector.hpp:448
constexpr Vector(const t_type &x, const t_type &y, const typename std::enable_if< tdims==3, const t_type & >::type z)
Sets values in each dimension to the respective value in the passed in scaler.
Definition Vector.hpp:137
constexpr Vector(const t_type &prefix_a, const t_type &prefix_b, typename std::enable_if< tdims >=3, const Vector< tdims - 1, t_type > & >::type vector)
Creates a vector where the prefix scaler values are combined with the suffix vector.
Definition Vector.hpp:277
constexpr Vector< t_dims, t_type > & operator=(const t_type &scaler)
Assignment operator.
Definition Vector.hpp:597
constexpr Vector(const Vector< getMax(tdims - 2, 0), t_type > &vector, const t_type &suffix_a, typename std::enable_if< tdims >=3, const t_type & >::type suffix_b)
Creates a vector where the prefix vector is combined with the suffix scalers.
Definition Vector.hpp:234
constexpr Vector< t_dims, t_type > operator-() const
Negation operator.
Definition Vector.hpp:576
constexpr Vector(const t_type &x, typename std::enable_if< tdims==2, const t_type & >::type y)
Sets values in each dimension to the respective value in the passed in scaler.
Definition Vector.hpp:117
constexpr Vector(const t_type &x, const t_type &y, const t_type &z, typename std::enable_if< tdims==4, const t_type & >::type w)
Sets values in each dimension to the respective value in the passed in scaler.
Definition Vector.hpp:158
constexpr t_type dimensionalValue() const
Used with template arguments MAX or MIN, Gets the dimensional value for the value that is either max ...
Definition Vector.hpp:362
constexpr t_type & operator[](uint01 dimension_index)
Accesses the value of a certain dimension.
Definition Vector.hpp:548
static constexpr uint01 NumberOfDimensions()
Number of dimensions in this vector class.
Definition Vector.hpp:614
static constexpr t_type Type()
Returns the type of this class.
Definition Vector.hpp:626
constexpr t_magnitude_type magnitude() const
Vectors are commonly used to model forces such as wind, sea current, gravity, and electromagnetism.
Definition Vector.hpp:470
constexpr uint01 dimensionalIndex() const
Used with template arguments MAX or MIN, Gets the dimensional index for the value that is either max ...
Definition Vector.hpp:392
constexpr Vector(const Vector< t_dims, t_vec_type > &vector) noexcept
Definition Vector.hpp:79
The primary namespace for the NDEVR SDK.
@ type
The type identifier string for this model node.
Definition Model.h:58
constexpr bool operator!=(const Vector< t_dims, t_type > &vec_a, const Vector< t_dims, t_type > &vec_b)
Inequality operator.
Definition Vector.hpp:673
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...
float fltp04
Defines an alias representing a 4 byte floating-point number Bit layout is as follows: -Sign: 1 bit a...
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 HSLColor Constant< HSLColor >::Invalid
The invalid HSLColor constant with all components set to invalid.
Definition HSLColor.h:264
constexpr Vector< t_dims, Angle< t_angle_type > > quantize(const Vector< t_dims, Angle< t_angle_type > > &value, Angle< t_angle_type > d=Angle< t_angle_type >(DEGREES, 1.0))
Quantizes a Vector of Angles to the nearest multiple of a given step size.
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
double fltp08
Defines an alias representing an 8 byte floating-point number.
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
t_type sqrt(const t_type &value)
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
Definition Angle.h:408
STL namespace.
Defines for a given type (such as sint04, fltp08, UUID, etc) a maximum, minimum, and reserved 'invali...