23 #include <type_traits> 29 #include <boost/math/constants/constants.hpp> 46 constexpr T
zero =
static_cast<T
>(0.0);
48 constexpr T
one =
static_cast<T
>(1.0);
50 constexpr T
two =
static_cast<T
>(2.0);
53 template <
typename T,
typename SFINAE = std::enable_if_t<std::is_scalar_v<T>, sfinae>>
54 inline T
lerp(T aX1, T aX2,
double aAmount)
58 return static_cast<T
>((x2 - x1) * aAmount + x1);
63 return aDegrees / 180.0 * pi<angle>();
68 return aRadians * 180.0 / pi<angle>();
74 template <typename T, uint32_t Size, typename Type = column_vector, bool IsScalar = std::is_scalar<T>::value>
78 template <
typename T, u
int32_t _Size,
typename Type>
86 enum : uint32_t {
Size = _Size };
94 typedef typename array_type::iterator
iterator;
99 template <
typename SFINAE =
int>
100 explicit basic_vector(value_type x,
typename std::enable_if_t<Size == 1, SFINAE> = 0) : base_type{ {x} } {}
101 template <
typename SFINAE =
int>
102 explicit basic_vector(value_type x, value_type y,
typename std::enable_if_t<Size == 2, SFINAE> = 0) : base_type{ {x, y} } {}
103 template <
typename SFINAE =
int>
104 explicit basic_vector(value_type x, value_type y, value_type z,
typename std::enable_if_t<Size == 3, SFINAE> = 0) : base_type{ {x, y, z} } {}
105 template <
typename SFINAE =
int>
106 explicit basic_vector(value_type x, value_type y, value_type z, value_type w,
typename std::enable_if_t<Size == 4, SFINAE> = 0) : base_type{ { x, y, z, w } } {}
107 template <
typename... Arguments>
108 explicit basic_vector(
const value_type& value, Arguments&&... aArguments) : base_type{ {value, std::forward<Arguments>(aArguments)...} } {}
109 template <
typename... Arguments>
110 explicit basic_vector(value_type&& value, Arguments&&... aArguments) : base_type{ {std::move(value), std::forward<Arguments>(aArguments)...} } {}
112 template <
typename V,
typename A, uint32_t S, uint32_t... Indexes>
116 template <
typename T2>
118 template <
typename T2, u
int32_t Size2,
typename SFINAE =
int>
119 basic_vector(
const basic_vector<T2, Size2, Type>& other,
typename std::enable_if_t<Size2 < Size, SFINAE> = 0) : base_type{} { std::transform(other.begin(), other.end(), v.begin(), [](T2 source) {
return static_cast<value_type
>(source); }); }
120 self_type&
operator=(
const self_type& other) { v = other.
v;
return *
this; }
121 self_type&
operator=(self_type&& other) { v = std::move(other.v);
return *
this; }
122 self_type&
operator=(std::initializer_list<value_type> values) {
if (values.size() >
Size)
throw std::out_of_range(
"neogfx::basic_vector: initializer list too big"); std::copy(values.begin(), values.end(), v.begin()); std::uninitialized_fill(v.begin() + (values.end() - values.begin()), v.end(), value_type{});
return *
this; }
125 value_type
operator[](uint32_t aIndex)
const {
return v[aIndex]; }
126 value_type&
operator[](uint32_t aIndex) {
return v[aIndex]; }
127 const_iterator
begin()
const {
return v.begin(); }
128 const_iterator
end()
const {
return v.end(); }
129 iterator
begin() {
return v.begin(); }
130 iterator
end() {
return v.end(); }
131 operator const array_type&()
const {
return v; }
133 template <
typename T2>
139 bool operator==(
const self_type& right)
const {
return v == right.
v; }
140 bool operator!=(
const self_type& right)
const {
return v != right.
v; }
141 self_type&
operator+=(value_type value) {
for (uint32_t index = 0; index <
Size; ++index) v[index] += value;
return *
this; }
142 self_type&
operator-=(value_type value) {
for (uint32_t index = 0; index <
Size; ++index) v[index] -= value;
return *
this; }
143 self_type&
operator*=(value_type value) {
for (uint32_t index = 0; index <
Size; ++index) v[index] *= value;
return *
this; }
144 self_type&
operator/=(value_type value) {
for (uint32_t index = 0; index <
Size; ++index) v[index] /= value;
return *
this; }
145 self_type&
operator+=(
const self_type& right) {
for (uint32_t index = 0; index <
Size; ++index) v[index] += right.
v[index];
return *
this; }
146 self_type&
operator-=(
const self_type& right) {
for (uint32_t index = 0; index <
Size; ++index) v[index] -= right.
v[index];
return *
this; }
147 self_type&
operator*=(
const self_type& right) {
for (uint32_t index = 0; index <
Size; ++index) v[index] *= right.
v[index];
return *
this; }
148 self_type&
operator/=(
const self_type& right) {
for (uint32_t index = 0; index <
Size; ++index) v[index] /= right.
v[index];
return *
this; }
149 self_type
operator-()
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result.
v[index] = -v[index];
return result; }
150 self_type
scale(
const self_type& right)
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result[index] = v[index] * right[index];
return result; }
151 value_type
magnitude()
const { value_type ss = constants::zero<value_type>;
for (uint32_t index = 0; index <
Size; ++index) ss += (v[index] * v[index]);
return std::sqrt(ss); }
152 self_type
normalized()
const { self_type result; value_type im = constants::one<value_type> / magnitude();
for (uint32_t index = 0; index <
Size; ++index) result.
v[index] = v[index] * im;
return result; }
153 self_type
min(
const self_type& right)
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result[index] = std::min(v[index], right.
v[index]);
return result; }
154 self_type
max(
const self_type& right)
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result[index] = std::max(v[index], right.
v[index]);
return result; }
155 value_type
min()
const { value_type result = v[0];
for (uint32_t index = 1; index <
Size; ++index) result = std::min(v[index], result);
return result; }
156 self_type
ceil()
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result[index] = std::ceil(v[index]);
return result; }
157 self_type
floor()
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result[index] = std::floor(v[index]);
return result; }
158 self_type
round()
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result[index] = std::round(v[index]);
return result; }
159 value_type
distance(
const self_type& right)
const { value_type total = 0;
for (uint32_t index = 0; index <
Size; ++index) total += ((v[index] - right.
v[index]) * (v[index] - right.
v[index]));
return std::sqrt(total); }
160 value_type
dot(
const self_type& right)
const 162 value_type result = constants::zero<value_type>;
163 for (uint32_t index = 0; index <
Size; ++index)
164 result += (v[index] * right[index]);
167 template <
typename SFINAE = self_type>
168 std::enable_if_t<Size == 3, SFINAE>
cross(
const self_type& right)
const 171 base_type::y * right.base_type::z - base_type::z * right.base_type::y,
172 base_type::z * right.base_type::x - base_type::x * right.base_type::z,
173 base_type::x * right.base_type::y - base_type::y * right.base_type::x };
177 self_type result = *
this;
185 template <
typename T, u
int32_t _Size,
typename Type>
192 enum : uint32_t {
Size = _Size };
205 template <
typename SFINAE =
int>
206 explicit basic_vector(value_type x,
typename std::enable_if_t<Size == 1, SFINAE> = 0) : v{ { x } } {}
207 template <
typename SFINAE =
int>
208 explicit basic_vector(value_type x, value_type y,
typename std::enable_if_t<Size == 2, SFINAE> = 0) : v{ { x, y } } {}
209 template <
typename SFINAE =
int>
210 explicit basic_vector(value_type x, value_type y, value_type z,
typename std::enable_if_t<Size == 3, SFINAE> = 0) : v{ { x, y, z } } {}
211 template <
typename SFINAE =
int>
212 explicit basic_vector(value_type x, value_type y, value_type z, value_type w,
typename std::enable_if_t<Size == 4, SFINAE> = 0) : v{ { x, y, z, w } } {}
213 template <
typename... Arguments>
214 explicit basic_vector(
const value_type& value, Arguments&&... aArguments) : v{ {value, std::forward<Arguments>(aArguments)...} } {}
215 template <
typename... Arguments>
216 explicit basic_vector(value_type&& value, Arguments&&... aArguments) : v{ {std::move(value), std::forward<Arguments>(aArguments)...} } {}
220 template <
typename T2>
222 template <
typename T2, u
int32_t Size2,
typename SFINAE =
int>
223 basic_vector(
const basic_vector<T2, Size2, Type>& other,
typename std::enable_if_t<Size2 < Size, SFINAE> = 0) : v{} { std::transform(other.begin(), other.end(), v.begin(), [](T2 source) {
return static_cast<value_type
>(source); }); }
224 self_type&
operator=(
const self_type& other) { v = other.
v;
return *
this; }
225 self_type&
operator=(self_type&& other) { v = std::move(other.v);
return *
this; }
226 self_type&
operator=(std::initializer_list<value_type> values) {
if (values.size() >
Size)
throw std::out_of_range(
"neogfx::basic_vector: initializer list too big"); std::copy(values.begin(), values.end(), v.begin()); std::uninitialized_fill(v.begin() + (values.end() - values.begin()), v.end(), value_type{});
return *
this; }
229 const value_type&
operator[](uint32_t aIndex)
const {
return v[aIndex]; }
230 value_type&
operator[](uint32_t aIndex) {
return v[aIndex]; }
231 const_iterator
begin()
const {
return v.begin(); }
232 const_iterator
end()
const {
return v.end(); }
233 iterator
begin() {
return v.begin(); }
234 iterator
end() {
return v.end(); }
235 operator const array_type&()
const {
return v; }
237 template <
typename T2>
245 self_type&
operator+=(value_type value) {
for (uint32_t index = 0; index <
Size; ++index) v[index] += value;
return *
this; }
246 self_type&
operator-=(value_type value) {
for (uint32_t index = 0; index <
Size; ++index) v[index] -= value;
return *
this; }
247 self_type&
operator*=(value_type value) {
for (uint32_t index = 0; index <
Size; ++index) v[index] *= value;
return *
this; }
248 self_type&
operator/=(value_type value) {
for (uint32_t index = 0; index <
Size; ++index) v[index] /= value;
return *
this; }
249 self_type&
operator+=(
const self_type& right) {
for (uint32_t index = 0; index <
Size; ++index) v[index] += right.
v[index];
return *
this; }
250 self_type&
operator-=(
const self_type& right) {
for (uint32_t index = 0; index <
Size; ++index) v[index] -= right.
v[index];
return *
this; }
251 self_type&
operator*=(
const self_type& right) {
for (uint32_t index = 0; index <
Size; ++index) v[index] *= right.
v[index];
return *
this; }
252 self_type&
operator/=(
const self_type& right) {
for (uint32_t index = 0; index <
Size; ++index) v[index] /= right.
v[index];
return *
this; }
253 self_type
operator-()
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result.
v[index] = -v[index];
return result; }
254 self_type
scale(
const self_type& right)
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result[index] = v[index] * right[index];
return result; }
255 value_type
magnitude()
const { value_type ss = constants::zero<value_type>;
for (uint32_t index = 0; index <
Size; ++index) ss += (v[index] * v[index]);
return std::sqrt(ss); }
256 self_type
normalized()
const { self_type result; value_type im = constants::one<value_type> / magnitude();
for (uint32_t index = 0; index <
Size; ++index) result.
v[index] = v[index] * im;
return result; }
257 self_type
min(
const self_type& right)
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result[index] = std::min(v[index], right.
v[index]);
return result; }
258 self_type
max(
const self_type& right)
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result[index] = std::max(v[index], right.
v[index]);
return result; }
259 self_type
ceil()
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result[index] = std::ceil(v[index]);
return result; }
260 self_type
floor()
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result[index] = std::floor(v[index]);
return result; }
261 self_type
round()
const { self_type result;
for (uint32_t index = 0; index <
Size; ++index) result[index] = std::round(v[index]);
return result; }
262 value_type
distance(
const self_type& right)
const { value_type total = constants::zero<value_type>;
for (uint32_t index = 0; index <
Size; ++index) total += ((v[index] - right.
v[index]) * (v[index] - right.
v[index]));
return std::sqrt(total); }
263 value_type
dot(
const self_type& right)
const 265 value_type result = constants::zero<value_type>;
266 for (uint32_t index = 0; index <
Size; ++index)
267 result += ((*
this)[index] * right[index]);
270 std::enable_if_t<Size == 3, self_type>
cross(
const self_type& right)
const 272 auto const& x = v[0];
273 auto const& y = v[1];
274 auto const& z = v[2];
275 auto const& xx = right.
v[0];
276 auto const& yy = right.
v[1];
277 auto const& zz = right.
v[2];
278 return self_type{ y * zz - z * yy, z * xx - x * zz, x * yy - y * xx };
282 self_type result = *
this;
290 template <
typename T, u
int32_t Size,
typename Type>
293 return aLhs.v < aRhs.v;
296 template <
typename T, u
int32_t Size,
typename Type>
299 return aLhs.v <= aRhs.v;
302 template <
typename T, u
int32_t Size,
typename Type>
305 return aLhs.v > aRhs.v;
308 template <
typename T, u
int32_t Size,
typename Type>
311 return aLhs.v >= aRhs.v;
314 template <
typename T, u
int32_t Size,
typename Type>
317 return aLhs.v == aRhs.v;
320 template <
typename T, u
int32_t Size,
typename Type>
323 return aLhs.v != aRhs.v;
408 template <std::
size_t VertexCount>
411 template <std::
size_t VertexCount>
415 typedef std::array<vec3, 4>
quad;
420 template <
typename T, u
int32_t D,
typename Type,
bool IsScalar>
421 inline basic_vector<T, D, Type, IsScalar> operator+(
const basic_vector<T, D, Type, IsScalar>& left,
const basic_vector<T, D, Type, IsScalar>& right)
428 template <
typename T, u
int32_t D,
typename Type,
bool IsScalar>
429 inline basic_vector<T, D, Type, IsScalar> operator-(
const basic_vector<T, D, Type, IsScalar>& left,
const basic_vector<T, D, Type, IsScalar>& right)
436 template <
typename T, u
int32_t D,
typename Type,
bool IsScalar>
440 for (uint32_t i = 0; i <
D; ++i)
445 template <
typename T, u
int32_t D,
typename Type,
bool IsScalar>
449 for (uint32_t i = 0; i <
D; ++i)
454 template <
typename T, u
int32_t D,
typename Type,
bool IsScalar>
458 for (uint32_t i = 0; i <
D; ++i)
463 template <
typename T, u
int32_t D,
typename Type,
bool IsScalar>
467 for (uint32_t i = 0; i <
D; ++i)
468 result[i] = left - right[i];
472 template <
typename T, u
int32_t D,
typename Type,
bool IsScalar>
476 for (uint32_t i = 0; i <
D; ++i)
481 template <
typename T, u
int32_t D,
typename Type,
bool IsScalar>
485 for (uint32_t i = 0; i <
D; ++i)
490 template <
typename T, u
int32_t D,
typename Type,
bool IsScalar>
494 for (uint32_t i = 0; i <
D; ++i)
499 template <
typename T, u
int32_t D,
typename Type,
bool IsScalar>
503 for (uint32_t i = 0; i <
D; ++i)
504 result[i] = left / right[i];
508 template <
typename T, u
int32_t D,
typename Type,
bool IsScalar>
512 for (uint32_t i = 0; i <
D; ++i)
513 result[i] = std::fmod(left[i], right);
517 template <
typename T, u
int32_t D,
bool IsScalar>
521 for (uint32_t index = 0; index <
D; ++index)
522 result += (left[index] * right[index]);
526 template <
typename T,
typename Type,
bool IsScalar>
527 inline basic_vector<T, 3, Type, IsScalar> operator+(
const basic_vector<T, 3, Type, IsScalar>& left,
const basic_vector<T, 3, Type, IsScalar>& right)
532 template <
typename T,
typename Type,
bool IsScalar>
533 inline basic_vector<T, 3, Type, IsScalar> operator-(
const basic_vector<T, 3, Type, IsScalar>& left,
const basic_vector<T, 3, Type, IsScalar>& right)
538 template <
typename T,
typename Type,
bool IsScalar>
544 template <
typename T,
typename Type,
bool IsScalar>
550 template <
typename T,
typename Type,
bool IsScalar>
556 template <
typename T,
typename Type,
bool IsScalar>
562 template <
typename T,
typename Type,
bool IsScalar>
568 template <
typename T,
typename Type,
bool IsScalar>
574 template <
typename T,
typename Type,
bool IsScalar>
580 template <
typename T,
typename Type,
bool IsScalar>
586 template <
typename T,
bool IsScalar>
589 return left[0] * right[0] + left[1] * right[1] + left[2] * right[2];
592 template <
typename T,
typename Type,
bool IsScalar>
593 inline basic_vector<T, 3, Type, IsScalar> midpoint(
const basic_vector<T, 3, Type, IsScalar>& left,
const basic_vector<T, 3, Type, IsScalar>& right)
595 return (left + right) / constants::two<T>;
598 template <
typename T, u
int32_t Size,
typename Type,
bool IsScalar>
599 inline basic_vector<T, Size, Type, IsScalar> lerp(
const basic_vector<T, Size, Type, IsScalar>& aV1,
const basic_vector<T, Size, Type, IsScalar>& aV2,
double aAmount)
602 for (uint32_t i = 0; i <
Size; ++i)
606 result[i] =
static_cast<T
>((x2 - x1) * aAmount + x1);
612 template <
typename T, u
int32_t Rows, u
int32_t Columns>
624 template <
typename T2>
628 basic_matrix(std::initializer_list<std::initializer_list<value_type>> aColumns) { std::copy(aColumns.begin(), aColumns.end(), m.begin()); }
631 template <
typename T2>
634 for (uint32_t column = 0; column < Columns; ++column)
635 for (uint32_t row = 0; row < Rows; ++row)
636 (*
this)[column][row] =
static_cast<value_type
>(other[column][row]);
638 self_type&
operator=(
const self_type& other) { m = other.m;
return *
this; }
639 self_type&
operator=(self_type&& other) { m = std::move(other.m);
return *
this; }
641 template <
typename T2>
648 const column_type&
operator[](uint32_t aColumn)
const {
return m[aColumn]; }
649 column_type&
operator[](uint32_t aColumn) {
return m[aColumn]; }
650 const value_type*
data()
const {
return &m[0].v[0]; }
652 bool operator==(
const self_type& right)
const {
return m == right.m; }
653 bool operator!=(
const self_type& right)
const {
return m != right.m; }
654 self_type&
operator+=(
const self_type& right) {
for (uint32_t column = 0; column < Columns; ++column) m[column] += right.m[column];
return *
this; }
655 self_type&
operator-=(
const self_type& right) {
for (uint32_t column = 0; column < Columns; ++column) m[column] -= right.m[column];
return *
this; }
659 for (uint32_t column = 0; column < Columns; ++column)
660 for (uint32_t row = 0; row < Rows; ++row)
661 for (uint32_t index = 0; index < Columns; ++index)
662 result[column][row] += (m[index][row] * right[column][index]);
668 self_type result = *
this;
669 for (uint32_t column = 0; column < Columns; ++column)
670 for (uint32_t row = 0; row < Rows; ++row)
671 result[column][row] = -result[column][row];
677 for (uint32_t column = 0; column < Columns; ++column)
678 for (uint32_t row = 0; row < Rows; ++row)
680 std::modf((*
this)[column][row] / aEpsilon + 0.5, &result[column][row]);
681 result[column][row] *= aEpsilon;
688 for (uint32_t column = 0; column < Columns; ++column)
689 for (uint32_t row = 0; row < Rows; ++row)
690 result[row][column] = m[column][row];
693 template <
typename SFINAE = self_type>
694 static const std::enable_if_t<Rows == Columns, SFINAE>&
identity()
696 auto make_identity = []()
699 for (uint32_t diag = 0; diag < Rows; ++diag)
700 result[diag][diag] = static_cast<value_type>(1.0);
703 static self_type
const sIdentity = make_identity();
708 return this == &identity();
885 template <
typename T, u
int32_t Rows, u
int32_t Columns>
893 template <
typename T, u
int32_t Rows, u
int32_t Columns>
901 template <
typename T, u
int32_t Rows, u
int32_t Columns>
909 template <
typename T, u
int32_t Rows, u
int32_t Columns>
917 template <
typename T, u
int32_t Rows, u
int32_t Columns>
925 template <
typename T, u
int32_t Rows, u
int32_t Columns>
928 return -right + left;
931 template <
typename T, u
int32_t Rows, u
int32_t Columns>
939 template <
typename T, u
int32_t Rows, u
int32_t Columns>
947 template <
typename T, u
int32_t Rows, u
int32_t Columns>
955 template <
typename T, u
int32_t D1, u
int32_t D2>
963 for (uint32_t column = 0; column < D1; ++column)
964 for (uint32_t row = 0; row < D1; ++row)
965 for (uint32_t index = 0; index < D2; ++index)
966 result[column][row] += (left[index][row] * right[column][index]);
970 template <
typename T, u
int32_t D,
bool IsScalar>
974 for (uint32_t row = 0; row <
D; ++row)
975 for (uint32_t index = 0; index < D; ++index)
976 result[row] += (left[index][row] * right[index]);
980 template <
typename T, u
int32_t D,
bool IsScalar>
984 for (uint32_t column = 0; column <
D; ++column)
985 for (uint32_t index = 0; index < D; ++index)
986 result[column] += (left[index] * right[column][index]);
990 template <
typename T, u
int32_t D,
bool IsScalar>
994 for (uint32_t column = 0; column <
D; ++column)
995 for (uint32_t row = 0; row < D; ++row)
996 result[column][row] = (left[row] * right[column]);
1000 template <
typename T, u
int32_t D>
1003 auto result = matrix;
1004 for (uint32_t row = 0; row <
D - 1; ++row)
1005 result[D - 1][row] = 0.0;
1009 template <
typename Elem,
typename Traits,
typename T, u
int32_t Size,
typename Type,
bool IsScalar>
1013 for (uint32_t i = 0; i <
Size; ++i)
1017 aStream << aVector[i];
1023 template <
typename Elem,
typename Traits,
typename T, u
int32_t Rows, u
int32_t Columns>
1027 for (uint32_t row = 0; row < Rows; ++row)
1032 for (uint32_t column = 0; column < Columns; ++column)
1036 aStream << aMatrix[column][row];
1044 template <
typename Elem,
typename Traits,
typename T, u
int32_t Rows, u
int32_t Columns>
1045 inline std::basic_ostream<Elem, Traits>& operator<<(std::basic_ostream<Elem, Traits>& aStream,
const std::optional<basic_matrix<T, Rows, Columns>>& aMatrix)
1047 if (aMatrix != std::nullopt)
1048 aStream << *aMatrix;
1050 aStream <<
"[null]";
1059 aabb(
const vec3& aMin,
const vec3& aMax) : min{ aMin }, max{ aMax } {}
1069 return !(left == right);
1074 return std::tie(left.
min.z, left.
min.y, left.
min.x, left.
max.z, left.
max.y, left.
max.x) <
1075 std::tie(right.
min.z, right.
min.y, right.
min.x, right.
max.z, right.
max.y, right.
max.x);
1087 auto extents = a.
max - a.
min;
1088 return extents.x * extents.y * (extents.z != 0.0 ? extents.z : 1.0);
1093 return inner.
min >= outer.
min && inner.
max <= outer.
max;
1098 return point >= outer.
min && point <= outer.
max;
1103 if (first.
max.x < second.
min.x)
1105 if (first.
min.x > second.
max.x)
1107 if (first.
max.y < second.
min.y)
1109 if (first.
min.y > second.
max.y)
1111 if (first.
max.z < second.
min.z)
1113 if (first.
min.z > second.
max.z)
1123 aabb_2d(
const vec2& aMin,
const vec2& aMax) : min{ aMin }, max{ aMax } {}
1130 for (
auto const& v : vertices)
1132 result.
min = result.
min.min(v.xy);
1133 result.
max = result.
max.max(v.xy);
1145 return !(left == right);
1150 return std::tie(left.
min.y, left.
min.x, left.
max.y, left.
max.x) <
1151 std::tie(right.
min.y, right.
min.x, right.
max.y, right.
max.x);
1163 auto extents = a.
max - a.
min;
1164 return extents.x * extents.y;
1169 return inner.
min >= outer.
min && inner.
max <= outer.
max;
1174 return point >= outer.
min && point <= outer.
max;
1179 if (first.
max.x < second.
min.x)
1181 if (first.
min.x > second.
max.x)
1183 if (first.
max.y < second.
min.y)
1185 if (first.
min.y > second.
max.y)
1192 template <
typename T,
bool IsScalar>
1198 template <
typename T,
bool IsScalar>
1201 std::vector<basic_vector<T, 3, column_vector, IsScalar>> result;
1202 result.reserve(right.size());
1203 for (
auto const& v : right)
1204 result.push_back(left * v);
1210 if (std::abs(angle) <= epsilon)
1212 else if (std::abs(angle - boost::math::constants::pi<scalar>()) <= epsilon)
1214 scalar
const s = std::sin(angle);
1215 scalar
const c = std::cos(angle);
1216 scalar
const a = 1.0 - c;
1217 scalar
const ax = a * axis.x;
1218 scalar
const ay = a * axis.y;
1219 scalar
const az = a * axis.z;
1221 { ax * axis.x + c, ax * axis.y + axis.z * s, ax * axis.z - axis.y * s },
1222 { ay * axis.x - axis.z * s, ay * axis.y + c, ay * axis.z + axis.x * s },
1223 { az * axis.x + axis.y * s, az * axis.y - axis.x * s, az * axis.z + c } }.round_to(epsilon);
1226 inline mat33
rotation_matrix(
const vec3& vectorA,
const vec3& vectorB, scalar epsilon = 0.00001)
1228 auto const nva = vectorA.normalized();
1229 auto const nvb = vectorB.normalized();
1230 return rotation_matrix(nva.cross(nvb).normalized(), std::acos(nva.dot(nvb)), epsilon);
1235 scalar ax = angles.x;
1236 scalar ay = angles.y;
1237 scalar az = angles.z;
1238 if (ax != 0.0 || ay != 0.0)
1240 mat33 rx = { { 1.0, 0.0, 0.0 },{ 0.0, std::cos(ax), std::sin(ax) },{ 0.0, -std::sin(ax), std::cos(ax) } };
1241 mat33 ry = { { std::cos(ay), 0.0, -std::sin(ay) },{ 0.0, 1.0, 0.0 },{ std::sin(ay), 0.0, std::cos(ay) } };
1242 mat33 rz = { { std::cos(az), std::sin(az), 0.0 },{ -std::sin(az), std::cos(az), 0.0 },{ 0.0, 0.0, 1.0 } };
1243 return rz * ry * rx;
1247 return mat33{ { std::cos(az), std::sin(az), 0.0 },{ -std::sin(az), std::cos(az), 0.0 },{ 0.0, 0.0, 1.0 } };
1253 scalar ax = angles.x;
1254 scalar ay = angles.y;
1255 scalar az = angles.z;
1256 if (ax != 0.0 || ay != 0.0)
1258 mat44 rx = { { 1.0, 0.0, 0.0, 0.0 },{ 0.0, std::cos(ax), std::sin(ax), 0.0 },{ 0.0, -std::sin(ax), std::cos(ax), 0.0 },{0.0, 0.0, 0.0, 1.0} };
1259 mat44 ry = { { std::cos(ay), 0.0, -std::sin(ay), 0.0 },{ 0.0, 1.0, 0.0, 0.0 },{ std::sin(ay), 0.0, std::cos(ay), 0.0 },{0.0, 0.0, 0.0, 1.0} };
1260 mat44 rz = { { std::cos(az), std::sin(az), 0.0, 0.0 },{ -std::sin(az), std::cos(az), 0.0, 0.0 },{ 0.0, 0.0, 1.0, 0.0 },{0.0, 0.0, 0.0, 1.0} };
1261 return rz * ry * rx;
1265 return mat44{ { std::cos(az), std::sin(az), 0.0, 0.0 },{ -std::sin(az), std::cos(az), 0.0, 0.0 },{ 0.0, 0.0, 1.0, 0.0 },{0.0, 0.0, 0.0, 1.0} };
1270 using namespace math;
basic_matrix< double, 2, 2 > matrix22
std::optional< matrix23f > optional_matrix23f
basic_vector< uint32_t, 4 > vector4u32
const value_type & operator[](uint32_t aIndex) const
value_type dot(const self_type &right) const
self_type & operator*=(const self_type &right)
self_type & operator=(const self_type &other)
aabb_2d to_aabb_2d(const vertices &vertices)
array_type::iterator iterator
T lerp(T aX1, T aX2, double aAmount)
self_type & operator+=(value_type value)
self_type & operator-=(const self_type &right)
basic_vector< float, 3 > vector3f
basic_matrix< double, 1, 2 > matrix12
self_type & operator*=(value_type value)
std::optional< matrix42 > optional_matrix42
std::optional< col_vec3 > optional_col_vec3
mat33 rotation_matrix(const vec3 &axis, scalar angle, scalar epsilon=0.00001)
std::optional< mat22 > optional_mat22
std::optional< vector2 > optional_vector2
basic_vector(const value_type &value, Arguments &&... aArguments)
self_type & operator-=(value_type value)
bool operator>(const basic_vector< T, Size, Type > &aLhs, const basic_vector< T, Size, Type > &aRhs)
std::optional< matrix12 > optional_matrix12
basic_matrix< double, 1, 3 > matrix13
std::optional< matrix43f > optional_matrix43f
bool operator!=(const basic_vector &right) const
std::optional< matrix33 > optional_matrix33
const_iterator end() const
bool operator>=(const basic_vector< T, Size, Type > &aLhs, const basic_vector< T, Size, Type > &aRhs)
std::enable_if_t< Size==3, self_type > cross(const self_type &right) const
basic_vector< float, 4 > vector4f
value_type distance(const self_type &right) const
self_type max(const self_type &right) const
basic_matrix< double, 4, 3 > matrix43
std::optional< mat23f > optional_mat23f
basic_matrix< float, 4, 4 > matrix44f
basic_vector< double, 1 > vector1
self_type & operator*=(value_type value)
std::optional< mat34 > optional_mat34
self_type & operator*=(const self_type &right)
basic_vector(self_type &&other)
basic_matrix(std::initializer_list< std::initializer_list< value_type >> aColumns)
optional_vec2_list optional_vertices_2d_t
basic_vector< int32_t, 2 > vector2i32
std::optional< mat41 > optional_mat41
std::optional< matrix33 > optional_matrix3
std::optional< mat14 > optional_mat14
basic_matrix< float, 1, 3 > matrix13f
value_type dot(const self_type &right) const
basic_matrix< double, 2, 1 > matrix21
basic_matrix< float, 3, 1 > matrix31f
self_type & operator+=(const self_type &right)
angle to_rad(angle aDegrees)
basic_vector(self_type &&other)
std::optional< mat32 > optional_mat32
self_type & operator-=(value_type value)
std::optional< matrix13f > optional_matrix13f
basic_vector< float, 2 > vector2f
std::optional< mat21f > optional_mat21f
basic_matrix< double, 4, 1 > matrix41
self_type & operator-=(const self_type &right)
std::array< value_type, Size > array_type
self_type & operator=(const self_type &other)
basic_vector< int32_t, 3 > vector3i32
std::optional< col_vec2 > optional_col_vec2
value_type distance(const self_type &right) const
std::optional< vec2 > optional_vec2
std::optional< mat11f > optional_mat1f
basic_matrix< float, 1, 4 > matrix14f
bool aabb_intersects(const aabb &first, const aabb &second)
basic_vector(value_type x, value_type y, value_type z, typename std::enable_if_t< Size==3, SFINAE >=0)
std::optional< mat22f > optional_mat22f
std::optional< vec2_list > optional_vec2_list
std::optional< mat43f > optional_mat43f
aabb_2d(const vec2 &aMin, const vec2 &aMax)
basic_vector(const self_type &other)
std::optional< matrix13 > optional_matrix13
optional_vec3_list optional_vertices_t
std::optional< matrix44 > optional_matrix44
basic_vector< T, D, Type, IsScalar > operator-(const basic_vector< T, D, Type, IsScalar > &left, const basic_vector< T, D, Type, IsScalar > &right)
basic_matrix< float, 2, 3 > matrix23f
std::optional< mat11f > optional_mat11f
basic_vector< T2, Size, Type > as() const
std::optional< mat41f > optional_mat41f
basic_matrix< double, 1, 1 > matrix11
basic_vector< double, 2, row_vector > row_vec2
std::optional< matrix14f > optional_matrix14f
basic_matrix< float, 4, 1 > matrix41f
mat44 affine_rotation_matrix(const vec3 &angles)
std::optional< matrix11 > optional_matrix1
self_type & operator/=(value_type value)
basic_matrix< double, 3, 1 > matrix31
std::optional< mat33f > optional_mat3f
bool operator==(const basic_vector &right) const
self_type max(const self_type &right) const
value_type magnitude() const
std::optional< vec1 > optional_vec1
std::optional< mat24 > optional_mat24
basic_matrix< double, 2, 4 > matrix24
std::optional< vec3_list > optional_vec3_list
const value_type * data() const
std::optional< matrix34f > optional_matrix34f
std::optional< row_vec3 > optional_row_vec3
std::optional< mat13 > optional_mat13
self_type normalized() const
std::array< vec2, 4 > quad_2d
array_type::const_iterator const_iterator
std::optional< matrix43 > optional_matrix43
std::optional< matrix44f > optional_matrix4f
basic_matrix< float, 2, 2 > matrix22f
basic_vector(const array_type &v)
std::optional< mat11 > optional_mat11
std::optional< matrix24 > optional_matrix24
basic_vector< value_type, Size, Type > vector_type
angle to_deg(angle aRadians)
basic_matrix< double, 3, 3 > matrix33
value_type & operator[](uint32_t aIndex)
std::optional< mat13f > optional_mat13f
std::optional< mat44f > optional_mat4f
basic_matrix< T2, Rows, Columns > type
bool operator<(const basic_vector< T, Size, Type > &aLhs, const basic_vector< T, Size, Type > &aRhs)
aabb_2d(const aabb &aAabb)
basic_matrix< float, 4, 2 > matrix42f
basic_vector< float, 1 > vector1f
self_type & operator/=(const self_type &right)
basic_matrix< T, Columns, Rows > transposed() const
basic_vector< uint32_t, 3 > vector3u32
self_type & operator*=(const self_type &right)
const column_type & operator[](uint32_t aColumn) const
basic_vector(const basic_vector< T2, Size, Type > &other)
std::optional< matrix31f > optional_matrix31f
std::optional< mat22 > optional_mat2
std::array< vec3, 3 > triangle
std::optional< matrix11f > optional_matrix1f
basic_matrix< double, 4, 2 > matrix42
basic_vector< T, 3, Type, IsScalar > midpoint(const basic_vector< T, 3, Type, IsScalar > &left, const basic_vector< T, 3, Type, IsScalar > &right)
std::optional< mat31f > optional_mat31f
self_type hadamard_product(const self_type &right) const
scalar aabb_volume(const aabb &a)
value_type & operator[](uint32_t aIndex)
self_type operator-() const
std::optional< matrix42f > optional_matrix42f
self_type hadamard_product(const self_type &right) const
std::optional< matrix32 > optional_matrix32
basic_matrix(const basic_matrix< T2, Rows, Columns > &other)
basic_vector< T, D, Type, IsScalar > operator%(const basic_vector< T, D, Type, IsScalar > &left, const T &right)
array_type::iterator iterator
basic_matrix< double, 3, 2 > matrix32
std::array< value_type, Size > array_type
std::optional< vector1 > optional_vector1
std::optional< vec4 > optional_vec4
basic_vector(const basic_vector< T2, Size2, Type > &other, typename std::enable_if_t< Size2< Size, SFINAE >=0)
self_type & operator=(self_type &&other)
std::optional< matrix11f > optional_matrix11f
std::optional< mat42 > optional_mat42
self_type normalized() const
array_type::const_iterator const_iterator
self_type operator-() const
basic_matrix(const self_type &other)
basic_vector(value_type x, typename std::enable_if_t< Size==1, SFINAE >=0)
std::optional< row_vec1 > optional_row_vec1
self_type & operator+=(const self_type &right)
std::optional< mat33f > optional_mat33f
basic_vector(const array_type &v)
basic_matrix< float, 2, 1 > matrix21f
basic_vector(value_type x, typename std::enable_if_t< Size==1, SFINAE >=0)
std::optional< mat31 > optional_mat31
std::optional< matrix34 > optional_matrix34
self_type & operator+=(value_type value)
std::optional< matrix31 > optional_matrix31
bool operator==(const self_type &right) const
basic_matrix(self_type &&other)
basic_matrix< float, 4, 3 > matrix43f
self_type round_to(value_type aEpsilon) const
std::optional< mat43 > optional_mat43
basic_matrix< T, D, D > without_translation(const basic_matrix< T, D, D > &matrix)
std::array< vec3, 4 > quad
basic_vector(const basic_vector< T2, Size, Type > &other)
std::optional< matrix44f > optional_matrix44f
bool operator!=(const self_type &right) const
std::optional< vector4 > optional_vector4
basic_vector< T, D, Type, IsScalar > operator*(const basic_vector< T, D, Type, IsScalar > &left, const T &right)
value_type operator[](uint32_t aIndex) const
aabb(const vec3 &aMin, const vec3 &aMax)
basic_vector< T, Columns, row_vector > row_type
std::optional< matrix21f > optional_matrix21f
std::optional< matrix32f > optional_matrix32f
std::optional< mat34f > optional_mat34f
std::optional< vector3 > optional_vector3
basic_vector< double, 4 > vector4
self_type & operator-=(const self_type &right)
self_type min(const self_type &right) const
std::optional< mat12f > optional_mat12f
std::optional< mat21 > optional_mat21
basic_vector< T, Size2, Type > type
basic_vector(value_type x, value_type y, typename std::enable_if_t< Size==2, SFINAE >=0)
self_type min(const self_type &right) const
basic_vector< uint32_t, 2 > vector2u32
const_iterator begin() const
std::optional< mat23 > optional_mat23
basic_vector(value_type &&value, Arguments &&... aArguments)
std::optional< matrix33f > optional_matrix33f
std::pair< uint32_t, uint32_t > size() const
std::optional< col_vec4 > optional_col_vec4
basic_vector(value_type x, value_type y, value_type z, typename std::enable_if_t< Size==3, SFINAE >=0)
std::optional< matrix41 > optional_matrix41
basic_matrix< float, 3, 4 > matrix34f
std::optional< matrix44 > optional_matrix4
std::optional< mat11 > optional_mat1
basic_vector< uint32_t, 1 > vector1u32
std::optional< mat24f > optional_mat24f
std::optional< matrix24f > optional_matrix24f
std::optional< matrix21 > optional_matrix21
std::optional< mat44 > optional_mat4
std::optional< matrix12f > optional_matrix12f
std::optional< aabb > optional_aabb
basic_matrix< double, 4, 4 > matrix44
basic_matrix< T2, Rows, Columns > as() const
std::optional< col_vec1 > optional_col_vec1
basic_vector< double, 3, row_vector > row_vec3
basic_matrix< float, 2, 4 > matrix24f
self_type & operator=(std::initializer_list< value_type > values)
std::optional< matrix11 > optional_matrix11
std::optional< matrix33f > optional_matrix3f
self_type & operator/=(const self_type &right)
basic_vector(value_type x, value_type y, typename std::enable_if_t< Size==2, SFINAE >=0)
std::optional< matrix22f > optional_matrix22f
self_type operator-() const
basic_vector(value_type &&value, Arguments &&... aArguments)
basic_vector< value_type, Size, Type > vector_type
basic_matrix< float, 1, 1 > matrix11f
bool operator!=(const self_type &right) const
self_type & operator/=(value_type value)
basic_vector< T, D, Type, IsScalar > operator+(const basic_vector< T, D, Type, IsScalar > &left, const basic_vector< T, D, Type, IsScalar > &right)
basic_matrix< float, 1, 2 > matrix12f
const_iterator begin() const
basic_matrix< double, 1, 4 > matrix14
std::enable_if_t< Size==3, SFINAE > cross(const self_type &right) const
bool operator!=(const basic_vector< T, Size, Type > &aLhs, const basic_vector< T, Size, Type > &aRhs)
self_type & operator=(const self_type &other)
self_type scale(const self_type &right) const
std::optional< matrix22 > optional_matrix22
std::optional< mat44f > optional_mat44f
std::optional< aabb_2d > optional_aabb_2d
self_type & operator=(std::initializer_list< value_type > values)
basic_matrix< double, 2, 3 > matrix23
std::optional< matrix41f > optional_matrix41f
basic_vector(const basic_vector< T2, Size2, Type > &other, typename std::enable_if_t< Size2< Size, SFINAE >=0)
std::optional< mat14f > optional_mat14f
std::optional< mat44 > optional_mat44
basic_vector< T, Size2, Type > type
const_iterator end() const
std::array< column_type, Columns > array_type
static const std::enable_if_t< Rows==Columns, SFINAE > & identity()
std::optional< vec3 > optional_vec3
self_type & operator=(self_type &&other)
basic_vector(const swizzle< V, A, S, Indexes... > &aSwizzle)
std::optional< row_vec4 > optional_row_vec4
basic_vector< double, 3 > vector3
basic_vector(const self_type &other)
std::optional< matrix22 > optional_matrix2
basic_vector(value_type x, value_type y, value_type z, value_type w, typename std::enable_if_t< Size==4, SFINAE >=0)
self_type scale(const self_type &right) const
basic_vector< T2, Size, Type > as() const
std::array< vec2, 3 > triangle_2d
bool aabb_contains(const aabb &outer, const aabb &inner)
std::optional< mat33 > optional_mat33
basic_matrix< float, 3, 3 > matrix33f
column_type & operator[](uint32_t aColumn)
basic_vector< double, 1, row_vector > row_vec1
bool operator==(const self_type &right) const
std::optional< row_vec2 > optional_row_vec2
bool operator==(const basic_vector< T, Size, Type > &aLhs, const basic_vector< T, Size, Type > &aRhs)
std::optional< matrix23 > optional_matrix23
std::optional< mat12 > optional_mat12
std::optional< mat42f > optional_mat42f
basic_vector< T, Rows, column_vector > column_type
basic_matrix< float, 3, 2 > matrix32f
std::vector< vec3 > vec3_list
std::optional< matrix22f > optional_matrix2f
basic_vector(const value_type &value, Arguments &&... aArguments)
basic_vector(value_type x, value_type y, value_type z, value_type w, typename std::enable_if_t< Size==4, SFINAE >=0)
std::optional< mat33 > optional_mat3
value_type magnitude() const
basic_matrix< double, 3, 4 > matrix34
basic_vector< int32_t, 1 > vector1i32
basic_vector< double, 2 > vector2
aabb aabb_union(const aabb &left, const aabb &right)
basic_vector< double, 4, row_vector > row_vec4
std::vector< vec2 > vec2_list
self_type & operator+=(const self_type &right)
basic_vector< int32_t, 4 > vector4i32
std::optional< mat22f > optional_mat2f
std::optional< mat32f > optional_mat32f
basic_vector< T, D, Type, IsScalar > operator/(const basic_vector< T, D, Type, IsScalar > &left, const T &right)
std::optional< matrix14 > optional_matrix14
pair< std::decay_t< T1 >, std::decay_t< T2 > > make_pair(T1 &&aFirst, T2 &&aSecond)
self_type & operator=(self_type &&other)