mal-math
C++20 mathematics library.
All Classes Namespaces Files Functions Variables Typedefs Concepts
vec_math.inl
Go to the documentation of this file.
1#pragma once
2#include "vec_math.hpp"
3namespace mal_math
4{
5 template <AnyVec U>
6 constexpr std::istream &operator>>(std::istream &is, U &vec)
7 {
8 for (size_t i = 0; i < U::size; i++)
9 {
10 is >> vec[i];
11 }
12 return is;
13 }
14 template <AnyVec U>
15 constexpr std::ostream &operator<<(std::ostream &os, U const &vec)
16 {
17 for (size_t i = 0; i < U::size; i++)
18 {
19 os << vec[i] << " ";
20 }
21 return os;
22 }
23 template <AnyVec U>
24 constexpr std::ostream &operator<<(std::ostream &os, U &vec)
25 {
26 for (size_t i = 0; i < U::size; i++)
27 {
28 os << vec[i] << " ";
29 }
30 return os;
31 }
32
33 template <size_t n, Primitive U, AnyVec Vector>
34 [[nodiscard]] constexpr vec<n, U> as_vec(Vector const &v) noexcept requires(n >= 2 && n <= Vector::size)
35 {
36 vec<n, U> rv;
37 for (size_t i = 0; i < n; i++)
38 {
39 rv.data[i] = static_cast<U>(v.data[i]);
40 }
41 return rv;
42 }
43
44 template <size_t n, AnyVec Vector>
45 [[nodiscard]] constexpr vec<n, std::remove_const_t<typename Vector::type>> as_vec(Vector const &v) noexcept requires(n >= 2 && n <= Vector::size)
46 {
48 }
49
50 template <AnyVec Vector>
55 template <size_t n, AnyVec Vector>
56 [[nodiscard]] constexpr vec<n, typename Vector::type> &as_rvec(Vector &v) noexcept requires(n >= 2 && n <= Vector::size)
57 {
58 return reinterpret_cast<vec<n, typename Vector::type> &>(v);
59 }
60 template <AnyVec Vector>
61 [[nodiscard]] constexpr vec<Vector::size, typename Vector::type> &as_rvec(Vector &v) noexcept
62 {
63 return as_rvec<Vector::size>(v);
64 }
65
66 template <size_t n, AnyVec Vector>
67 [[nodiscard]] constexpr vec<n, typename Vector::type> const &as_crvec(Vector const &v) noexcept requires(n >= 2 && n <= Vector::size)
68 {
69 return reinterpret_cast<vec<n, typename Vector::type> const &>(v);
70 }
71 template <AnyVec Vector>
72 [[nodiscard]] constexpr vec<Vector::size, typename Vector::type> const &as_crvec(Vector const &v) noexcept
73 {
74 return as_rvec<Vector::size>(v);
75 }
76
77 template <size_t size, Primitive T, Primitive U>
78 [[nodiscard]] constexpr vec<size, T> operator+(vec<size, T> const &vector, U const value) noexcept
79 {
80 return vec<size, T>(vector) += value;
81 }
82 template <size_t size, Primitive T, Primitive U>
83 [[nodiscard]] constexpr vec<size, T> operator-(vec<size, T> const &vector, U const value) noexcept
84 {
85 return vec<size, T>(vector) -= value;
86 }
87 template <size_t size, Primitive T, Primitive U>
88 [[nodiscard]] constexpr vec<size, T> operator*(vec<size, T> const &vector, U const value) noexcept
89 {
90 return vec<size, T>(vector) *= value;
91 }
92 template <size_t size, Primitive T, Primitive U>
93 [[nodiscard]] constexpr vec<size, T> operator/(vec<size, T> const &vector, U const value) noexcept
94 {
95 return vec<size, T>(vector) /= value;
96 }
97 template <size_t size, Primitive T, Primitive U>
98 [[nodiscard]] constexpr vec<size, T> operator*(U const value, vec<size, T> const &vector) noexcept
99 {
100 return vec<size, T>(vector) *= value;
101 }
102 template <size_t size, Primitive T, Primitive U>
103 [[nodiscard]] constexpr vec<size, T> operator/(U const value, vec<size, T> const &vector) noexcept
104 {
105 return vec<size, T>(value) /= vector;
106 }
107 template <size_t size, Primitive T, Primitive U>
108 [[nodiscard]] constexpr vec<size, T> operator+(U const value, vec<size, T> const &vector) noexcept
109 {
110 return vec<size, T>(vector) += value;
111 }
112 template <size_t size, Primitive T, Primitive U>
113 [[nodiscard]] constexpr vec<size, T> operator-(U const value, vec<size, T> const &vector) noexcept
114 {
115 return vec<size, T>(-vector) += value;
116 }
117
118 template <size_t size, Primitive T, Primitive U>
119 [[nodiscard]] constexpr vec<size, T> operator+(vec<size, T> const &left, vec<size, U> const &right) noexcept
120 {
121 return vec<size, T>(left) += right;
122 }
123 template <size_t size, Primitive T, Primitive U>
124 [[nodiscard]] constexpr vec<size, T> operator-(vec<size, T> const &left, vec<size, U> const &right) noexcept
125 {
126 return vec<size, T>(left) -= right;
127 }
128 template <size_t size, Primitive T, Primitive U>
129 [[nodiscard]] constexpr vec<size, T> operator*(vec<size, T> const &left, vec<size, U> const &right) noexcept
130 {
131 return vec<size, T>(left) *= right;
132 }
133 template <size_t size, Primitive T, Primitive U>
134 [[nodiscard]] constexpr vec<size, T> operator/(vec<size, T> const &left, vec<size, U> const &right) noexcept
135 {
136 return vec<size, T>(left) /= right;
137 }
138 template <size_t size, Primitive T, Primitive U>
139 [[nodiscard]] constexpr vec<size, T> operator%(vec<size, T> const &left, U const value) noexcept
140 {
141 return vec<size, T>(left) %= value;
142 }
143 template <size_t size, Primitive T, Primitive U>
144 [[nodiscard]] constexpr vec<size, T> operator%(vec<size, T> const &left, vec<size, U> const &right) noexcept
145 {
146 return vec<size, T>(left) %= right;
147 }
148
149 template <size_t size, Primitive T, Primitive U>
150 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator*(U const value, _detail::rvec<size, T> const &vector) noexcept
151 {
152 return vec<size, std::remove_const_t<T>>(vector) *= value;
153 }
154 template <size_t size, Primitive T, Primitive U>
155 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator+(U const value, _detail::rvec<size, T> const &vector) noexcept
156 {
157 return vec<size, std::remove_const_t<T>>(vector) += value;
158 }
159 template <size_t size, Primitive T, Primitive U>
160 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator-(U const value, _detail::rvec<size, T> const &vector) noexcept
161 {
162 return vec<size, std::remove_const_t<T>>(-vector) += value;
163 }
164 template <size_t size, Primitive T, Primitive U>
165 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator+(_detail::rvec<size, T> const &vector, U const value) noexcept
166 {
167 return vec<size, std::remove_const_t<T>>(vector) += value;
168 }
169 template <size_t size, Primitive T, Primitive U>
170 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator-(_detail::rvec<size, T> const &vector, U const value) noexcept
171 {
172 return vec<size, std::remove_const_t<T>>(vector) -= value;
173 }
174 template <size_t size, Primitive T, Primitive U>
175 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator*(_detail::rvec<size, T> const &vector, U const value) noexcept
176 {
177 return vec<size, std::remove_const_t<T>>(vector) *= value;
178 }
179 template <size_t size, Primitive T, Primitive U>
180 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator/(_detail::rvec<size, T> const &vector, U const value) noexcept
181 {
182 return vec<size, std::remove_const_t<T>>(vector) /= value;
183 }
184 template <size_t size, Primitive T, Primitive U>
185 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator+(_detail::rvec<size, T> const &left, vec<size, U> const &right) noexcept
186 {
187 return vec<size, std::remove_const_t<T>>(left) += right;
188 }
189 template <size_t size, Primitive T, Primitive U>
190 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator-(_detail::rvec<size, T> const &left, vec<size, U> const &right) noexcept
191 {
192 return vec<size, std::remove_const_t<T>>(left) -= right;
193 }
194 template <size_t size, Primitive T, Primitive U>
195 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator*(_detail::rvec<size, T> const &left, vec<size, U> const &right) noexcept
196 {
197 return vec<size, std::remove_const_t<T>>(left) *= right;
198 }
199 template <size_t size, Primitive T, Primitive U>
200 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator/(_detail::rvec<size, T> const &left, vec<size, U> const &right) noexcept
201 {
202 return vec<size, std::remove_const_t<T>>(left) /= right;
203 }
204 template <size_t size, Primitive T, Primitive U>
205 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator%(_detail::rvec<size, T> const &left, U const value) noexcept
206 {
207 return vec<size, std::remove_const_t<T>>(left) %= value;
208 }
209 template <size_t size, Primitive T, Primitive U>
210 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator%(_detail::rvec<size, T> const &left, vec<size, U> const &right) noexcept
211 {
212 return vec<size, std::remove_const_t<T>>(left) %= right;
213 }
214
215 template <size_t size, Primitive T, Primitive U>
216 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator+(_detail::rvec<size, T> const &left, _detail::rvec<size, U> const &right) noexcept
217 {
218 return vec<size, std::remove_const_t<T>>(left) += right;
219 }
220 template <size_t size, Primitive T, Primitive U>
221 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator-(_detail::rvec<size, T> const &left, _detail::rvec<size, U> const &right) noexcept
222 {
223 return vec<size, std::remove_const_t<T>>(left) -= right;
224 }
225 template <size_t size, Primitive T, Primitive U>
226 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator*(_detail::rvec<size, T> const &left, _detail::rvec<size, U> const &right) noexcept
227 {
228 return vec<size, std::remove_const_t<T>>(left) *= right;
229 }
230 template <size_t size, Primitive T, Primitive U>
231 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator/(_detail::rvec<size, T> const &left, _detail::rvec<size, U> const &right) noexcept
232 {
233 return vec<size, std::remove_const_t<T>>(left) /= right;
234 }
235 template <size_t size, Primitive T, Primitive U>
236 [[nodiscard]] constexpr vec<size, std::remove_const_t<T>> operator%(_detail::rvec<size, T> const &left, _detail::rvec<size, U> const &right) noexcept
237 {
238 return vec<size, std::remove_const_t<T>>(left) %= right;
239 }
240
241 template <size_t size, Primitive T, Primitive U>
242 [[nodiscard]] constexpr vec<size, T> operator+(vec<size, T> const &left, _detail::rvec<size, U> const &right) noexcept
243 {
244 return vec<size, T>(left) += right;
245 }
246 template <size_t size, Primitive T, Primitive U>
247 [[nodiscard]] constexpr vec<size, T> operator-(vec<size, T> const &left, _detail::rvec<size, U> const &right) noexcept
248 {
249 return vec<size, T>(left) -= right;
250 }
251 template <size_t size, Primitive T, Primitive U>
252 [[nodiscard]] constexpr vec<size, T> operator*(vec<size, T> const &left, _detail::rvec<size, U> const &right) noexcept
253 {
254 return vec<size, T>(left) *= right;
255 }
256 template <size_t size, Primitive T, Primitive U>
257 [[nodiscard]] constexpr vec<size, T> operator/(vec<size, T> const &left, _detail::rvec<size, U> const &right) noexcept
258 {
259 return vec<size, T>(left) /= right;
260 }
261 template <size_t size, Primitive T, Primitive U>
262 [[nodiscard]] constexpr vec<size, T> operator%(vec<size, T> const &left, _detail::rvec<size, U> const &right) noexcept
263 {
264 return vec<size, T>(left) %= right;
265 }
266
267 template <AnyVec T, AnyVec U>
268 [[nodiscard]] constexpr bool operator==(T const &left, U const &right) noexcept requires(T::size == U::size)
269 {
270 bool rv = true;
271 for (size_t i = 0; i < T::size; i++)
272 {
273 rv = rv && (left.data[i] == right.data[i]);
274 }
275 return rv;
276 }
277
278 template <AnyVec T, AnyVec U>
279 [[nodiscard]] constexpr bool operator!=(T const &left, U const &right) noexcept requires(T::size == U::size)
280 {
281 return !(left == right);
282 }
283 template <AnyVec T>
284 [[nodiscard]] constexpr std::remove_const_t<typename T::type> squared_length(T const &vector) noexcept
285 {
286 std::remove_const_t<typename T::type> return_value = 0;
287 for (size_t i = 0; i < T::size; i++)
288 {
289 return_value += vector.data[i] * vector.data[i];
290 }
291 return return_value;
292 }
293 template <AnyVec T>
294 [[nodiscard]] constexpr auto length(T const &vector) noexcept
295 {
296 return sqrt(squared_length(vector));
297 }
298
299 template <AnyVec T>
300 [[nodiscard]] constexpr vec<T::size, std::remove_const_t<typename T::type>> unit_vector(T const &vector) noexcept
301 {
302 return vector / length(vector);
303 }
304 template <AnyVec T>
305 [[nodiscard]] constexpr vec<T::size, std::remove_const_t<typename T::type>> normalize(T const &vector) noexcept
306 {
307 return vector / length(vector);
308 }
309
310 template <AnyVec T, AnyVec U>
311 constexpr std::remove_const_t<typename T::type> dot(T const &left, U const &right) noexcept requires(T::size == U::size)
312 {
313 std::remove_const_t<typename T::type> return_value = 0;
314 auto const temp = left * right;
315 for (size_t i = 0; i < T::size; i++)
316 {
317 return_value += temp[i];
318 }
319 return return_value;
320 }
321
322 template <AnyVec T, AnyVec U>
323 constexpr typename std::remove_const_t<typename T::type> angle(T const &left, U const &right) noexcept requires(T::size == U::size)
324 {
325 return acos(clamp(dot(left, right), typename T::type(-1), typename T::type(1)));
326 }
327
328 template <AnyVec T>
329 constexpr vec<T::size, std::remove_const_t<typename T::type>> cos(T const &vector) noexcept
330 {
332 for (size_t i = 0; i < T::size; i++)
333 {
334 return_value[i] = cos(vector[i]);
335 }
336 return return_value;
337 }
338
339 template <AnyVec T>
340 constexpr vec<T::size, std::remove_const_t<typename T::type>> sin(T const &vector) noexcept
341 {
343 for (size_t i = 0; i < T::size; i++)
344 {
345 return_value[i] = sin(vector[i]);
346 }
347 return return_value;
348 }
349 template <AnyVec T>
350 constexpr vec<T::size, std::remove_const_t<typename T::type>> tan(T const &vector) noexcept
351 {
353 for (size_t i = 0; i < T::size; i++)
354 {
355 return_value[i] = tan(vector[i]);
356 }
357 return return_value;
358 }
359 template <AnyVec T>
360 constexpr vec<T::size, std::remove_const_t<typename T::type>> acos(T const &vector) noexcept
361 {
363 for (size_t i = 0; i < T::size; i++)
364 {
365 return_value[i] = acos(vector[i]);
366 }
367 return return_value;
368 }
369 template <AnyVec T>
370 constexpr vec<T::size, std::remove_const_t<typename T::type>> asin(T const &vector) noexcept
371 {
373 for (size_t i = 0; i < T::size; i++)
374 {
375 return_value[i] = asin(vector[i]);
376 }
377 return return_value;
378 }
379 template <AnyVec T>
380 constexpr vec<T::size, std::remove_const_t<typename T::type>> atan(T const &vector) noexcept
381 {
383 for (size_t i = 0; i < T::size; i++)
384 {
385 return_value[i] = atan(vector[i]);
386 }
387 return return_value;
388 }
389 template <AnyVec T, AnyVec U>
390 constexpr vec<T::size, std::remove_const_t<typename T::type>> atan(T const &left, U const &right) noexcept requires(T::size == U::size)
391 {
393 for (size_t i = 0; i < T::size; i++)
394 {
395 return_value[i] = atan2(left[i], right[i]);
396 }
397 return return_value;
398 }
399 template <AnyVec T, AnyVec U>
400 constexpr vec<T::size, std::remove_const_t<typename T::type>> atan2(T const &left, U const &right) noexcept requires(T::size == U::size)
401 {
402 return atan(left, right);
403 }
404 template <AnyVec T>
405 constexpr vec<T::size, std::remove_const_t<typename T::type>> sinh(T const &vector) noexcept
406 {
408 for (size_t i = 0; i < T::size; i++)
409 {
410 return_value[i] = sinh(vector[i]);
411 }
412 return return_value;
413 }
414 template <AnyVec T>
415 constexpr vec<T::size, std::remove_const_t<typename T::type>> cosh(T const &vector) noexcept
416 {
418 for (size_t i = 0; i < T::size; i++)
419 {
420 return_value[i] = cosh(vector[i]);
421 }
422 return return_value;
423 }
424 template <AnyVec T>
425 constexpr vec<T::size, std::remove_const_t<typename T::type>> tanh(T const &vector) noexcept
426 {
428 for (size_t i = 0; i < T::size; i++)
429 {
430 return_value[i] = tanh(vector[i]);
431 }
432 return return_value;
433 }
434 template <AnyVec T>
436 {
438 for (size_t i = 0; i < T::size; i++)
439 {
440 return_value[i] = asinh(vector[i]);
441 }
442 return return_value;
443 }
444 template <AnyVec T>
446 {
448 for (size_t i = 0; i < T::size; i++)
449 {
450 return_value[i] = acosh(vector[i]);
451 }
452 return return_value;
453 }
454 template <AnyVec T>
456 {
458 for (size_t i = 0; i < T::size; i++)
459 {
460 return_value[i] = atanh(vector[i]);
461 }
462 return return_value;
463 }
464 template <AnyVec T>
465 constexpr vec<T::size, std::remove_const_t<typename T::type>> exp(T const &vector) noexcept
466 {
468 for (size_t i = 0; i < T::size; i++)
469 {
470 return_value[i] = exp(vector[i]);
471 }
472 return return_value;
473 }
474 template <AnyVec T>
475 constexpr vec<T::size, std::remove_const_t<typename T::type>> exp2(T const &vector) noexcept
476 {
478 for (size_t i = 0; i < T::size; i++)
479 {
480 return_value[i] = exp2(vector[i]);
481 }
482 return return_value;
483 }
484 template <AnyVec T>
486 {
488 for (size_t i = 0; i < T::size; i++)
489 {
490 return_value[i] = expm1(vector[i]);
491 }
492 return return_value;
493 }
494 template <AnyVec T>
495 constexpr vec<T::size, std::remove_const_t<typename T::type>> log(T const &vector) noexcept
496 {
498 for (size_t i = 0; i < T::size; i++)
499 {
500 return_value[i] = log(vector[i]);
501 }
502 return return_value;
503 }
504 template <AnyVec T>
505 constexpr vec<T::size, std::remove_const_t<typename T::type>> log2(T const &vector) noexcept
506 {
508 for (size_t i = 0; i < T::size; i++)
509 {
510 return_value[i] = log2(vector[i]);
511 }
512 return return_value;
513 }
514 template <AnyVec T>
516 {
518 for (size_t i = 0; i < T::size; i++)
519 {
520 return_value[i] = log10(vector[i]);
521 }
522 return return_value;
523 }
524 template <AnyVec T>
526 {
528 for (size_t i = 0; i < T::size; i++)
529 {
530 return_value[i] = log1p(vector[i]);
531 }
532 return return_value;
533 }
534 template <AnyVec T>
535 constexpr vec<T::size, std::remove_const_t<typename T::type>> logb(T const &vector) noexcept
536 {
538 for (size_t i = 0; i < T::size; i++)
539 {
540 return_value[i] = logb(vector[i]);
541 }
542 return return_value;
543 }
544 template <AnyVec T>
545 constexpr vec<T::size, std::remove_const_t<typename T::type>> sqrt(T const &vector) noexcept
546 {
548 for (size_t i = 0; i < T::size; i++)
549 {
550 return_value[i] = sqrt(vector[i]);
551 }
552 return return_value;
553 }
554 template <AnyVec T>
556 {
558 for (size_t i = 0; i < T::size; i++)
559 {
560 return_value[i] = inversesqrt(vector[i]);
561 }
562 return return_value;
563 }
564 template <AnyVec T>
565 constexpr vec<T::size, std::remove_const_t<typename T::type>> abs(T const &vector) noexcept
566 {
568 for (size_t i = 0; i < T::size; i++)
569 {
570 return_value[i] = abs(vector[i]);
571 }
572 return return_value;
573 }
574 template <AnyVec T>
575 constexpr vec<T::size, std::remove_const_t<typename T::type>> sign(T const &vector) noexcept
576 {
578 for (size_t i = 0; i < T::size; i++)
579 {
580 return_value[i] = static_cast<typename T::type>(sign(vector[i]));
581 }
582 return return_value;
583 }
584 template <AnyVec T>
586 {
588 for (size_t i = 0; i < T::size; i++)
589 {
590 return_value[i] = floor(vector[i]);
591 }
592 return return_value;
593 }
594 template <AnyVec T>
595 constexpr vec<T::size, std::remove_const_t<typename T::type>> ceil(T const &vector) noexcept
596 {
598 for (size_t i = 0; i < T::size; i++)
599 {
600 return_value[i] = ceil(vector[i]);
601 }
602 return return_value;
603 }
604 template <AnyVec T>
606 {
608 for (size_t i = 0; i < T::size; i++)
609 {
610 return_value[i] = trunc(vector[i]);
611 }
612 return return_value;
613 }
614 template <AnyVec T>
616 {
618 for (size_t i = 0; i < T::size; i++)
619 {
620 return_value[i] = round(vector[i]);
621 }
622 return return_value;
623 }
624 template <AnyVec T>
626 {
628 for (size_t i = 0; i < T::size; i++)
629 {
630 return_value[i] = roundEven(vector[i]);
631 }
632 return return_value;
633 }
634 template <AnyVec T>
636 {
638 for (size_t i = 0; i < T::size; i++)
639 {
640 return_value[i] = fract(vector[i]);
641 }
642 return return_value;
643 }
644 template <AnyVec T>
645 constexpr vec<T::size, std::remove_const_t<typename T::type>> mod(T const &vector, typename T::type const &scalar) noexcept
646 {
648 for (size_t i = 0; i < T::size; i++)
649 {
650 return_value[i] = mod(vector[i], scalar);
651 }
652 return return_value;
653 }
654 template <AnyVec T, AnyVec U>
655 constexpr vec<T::size, std::remove_const_t<typename T::type>> mod(T const &left, U const &right) noexcept requires(T::size == U::size)
656 {
658 for (size_t i = 0; i < T::size; i++)
659 {
660 return_value[i] = mod(left[i], right[i]);
661 }
662 return return_value;
663 }
664
665 template <AnyVec T, Primitive U>
666 constexpr vec<T::size, std::remove_const_t<typename T::type>> pow(T const &vector, U const value) noexcept
667 {
669 for (size_t i = 0; i < T::size; i++)
670 {
671 return_value[i] = pow(vector[i], value);
672 }
673 return return_value;
674 }
675 template <AnyVec T, AnyVec U>
676 constexpr vec<T::size, std::remove_const_t<typename T::type>> pow(T const &vector1, U const &vector2) noexcept
677 {
679 for (size_t i = 0; i < T::size; i++)
680 {
681 return_value[i] = pow(vector1[i], vector2[i]);
682 }
683 return return_value;
684 }
685
686 template <AnyVec T, AnyVec U>
687 constexpr vec<3, std::remove_const_t<typename T::type>> cross(T const &left, U const &right) noexcept requires(T::size == U::size && T::size == 3)
688 {
689 return vec<3, std::remove_const_t<typename T::type>>{left.y *right.z - left.z * right.y,
690 left.x *right.z - left.z * right.x,
691 left.x *right.y - left.y * right.x};
692 }
693
694 template <Primitive T, Primitive U>
695 constexpr void rclamp(T &left, U const min, U const max) noexcept
696 {
697 if (left < min)
698 left = static_cast<T>(min);
699 else if (left > max)
700 left = static_cast<T>(max);
701 }
702
703 template <AnyVec T, Primitive U>
704 constexpr void rclamp(T &left, U const min, U const max) noexcept
705 {
706 for (size_t i = 0; i < T::size; i++)
707 {
708 if (left[i] < static_cast<typename T::type>(min))
709 {
710 left[i] = min;
711 }
712 else if (left[i] > static_cast<typename T::type>(max))
713 {
714 left[i] = max;
715 }
716 }
717 }
718 template <AnyVec T, AnyVec U>
719 constexpr void rclamp(T &left, U const min, U const max) noexcept requires(T::size == U::size)
720 {
721 for (size_t i = 0; i < T::size; i++)
722 {
723 if (left[i] < static_cast<typename T::type>(min[i]))
724 {
725 left[i] = min[i];
726 }
727 else if (left[i] > static_cast<typename T::type>(max[i]))
728 {
729 left[i] = max[i];
730 }
731 }
732 }
733 template <AnyVec T, Primitive U>
734 [[nodiscard]] constexpr vec<T::size, std::remove_const_t<typename T::type>> clamp(T const &left, U const min, U const max) noexcept
735 {
737
738 for (size_t i = 0; i < T::size; i++)
739 {
740 if (left[i] < static_cast<std::remove_const_t<typename T::type>>(min))
741 {
742 rvec[i] = static_cast<std::remove_const_t<typename T::type>>(min);
743 }
744 else if (left[i] > static_cast<std::remove_const_t<typename T::type>>(max))
745 {
746 rvec[i] = static_cast<std::remove_const_t<typename T::type>>(max);
747 }
748 else
749 {
750 rvec[i] = left[i];
751 }
752 }
753 return rvec;
754 }
755 template <AnyVec T, AnyVec U>
756 [[nodiscard]] constexpr vec<T::size, std::remove_const_t<typename T::type>> clamp(T const &left, U const &min, U const &max) noexcept requires(T::size == U::size)
757 {
759 for (size_t i = 0; i < T::size; i++)
760 {
761 if (left[i] < static_cast<std::remove_const_t<typename T::type>>(min[i]))
762 {
763 rvec[i] = static_cast<std::remove_const_t<typename T::type>>(min[i]);
764 }
765 else if (left[i] > static_cast<std::remove_const_t<typename T::type>>(max[i]))
766 {
767 rvec[i] = static_cast<std::remove_const_t<typename T::type>>(max[i]);
768 }
769 else
770 {
771 rvec[i] = left[i];
772 }
773 }
774 return rvec;
775 }
776 template <Primitive T, Primitive U>
777 [[nodiscard]] constexpr T clamp(T left, U const min, U const max) noexcept
778 {
779 if (left < min)
780 return min;
781 if (left > max)
782 return max;
783 return left;
784 }
785
786 template <AnyVec T, Primitive U>
787 [[nodiscard]] constexpr vec<T::size, std::remove_const_t<typename T::type>> min(T const &left, U const max) noexcept
788 {
790 for (size_t i = 0; i < T::size; i++)
791 {
792 rv[i] = std::min(left[i], static_cast<typename T::type>(max));
793 }
794 return rv;
795 }
796
797 template <AnyVec T, Primitive U>
798 [[nodiscard]] constexpr vec<T::size, std::remove_const_t<typename T::type>> max(T const &left, U const min) noexcept
799 {
801 for (size_t i = 0; i < T::size; i++)
802 {
803 rv[i] = std::max(left[i], static_cast<typename T::type>(min));
804 }
805 return rv;
806 }
807
808 template <AnyVec T, AnyVec U>
809 [[nodiscard]] constexpr vec<T::size, std::remove_const_t<typename T::type>> min(T const &left, U const &right) noexcept requires(T::size == U::size)
810 {
812 for (size_t i = 0; i < T::size; i++)
813 {
814 rv[i] = std::min(left[i], static_cast<typename T::type>(right[i]));
815 }
816 return rv;
817 }
818
819 template <AnyVec T, AnyVec U>
820 [[nodiscard]] constexpr vec<T::size, std::remove_const_t<typename T::type>> max(T const &left, U const &right) noexcept requires(T::size == U::size)
821 {
823 for (size_t i = 0; i < T::size; i++)
824 {
825 rv[i] = std::max(left[i], static_cast<typename T::type>(right[i]));
826 }
827 return rv;
828 }
829 template <AnyVec T, AnyVec U>
830 constexpr void rmin(T &left, U const &max) noexcept requires(T::size == U::size)
831 {
832 for (size_t i = 0; i < T::size; i++)
833 {
834 left[i] = std::min(left[i], static_cast<typename T::type>(max[i]));
835 }
836 }
837
838 template <AnyVec T, AnyVec U>
839 constexpr void rmax(T &left, U const &min) noexcept requires(T::size == U::size)
840 {
841 for (size_t i = 0; i < T::size; i++)
842 {
843 left[i] = std::max(left[i], static_cast<typename T::type>(min[i]));
844 }
845 }
846
847 template <AnyVec T, Primitive U>
848 constexpr void rmin(T &left, U const max) noexcept
849 {
850 for (size_t i = 0; i < T::size; i++)
851 {
852 left[i] = std::min(left[i], static_cast<typename T::type>(max));
853 }
854 }
855
856 template <AnyVec T, Primitive U>
857 constexpr void rmax(T &left, U const min) noexcept
858 {
859 for (size_t i = 0; i < T::size; i++)
860 {
861 left[i] = std::max(left[i], static_cast<typename T::type>(min));
862 }
863 }
864
865 template <Primitive T, Primitive U>
866 constexpr void rmin(T &left, U const max) noexcept
867 {
868 left = left < max ? left : max;
869 }
870
871 template <Primitive T, Primitive U>
872 constexpr void rmax(T &left, U const min) noexcept
873 {
874 left = left > min ? left : min;
875 }
876 template <AnyVec T>
877 [[nodiscard]] constexpr std::remove_const_t<typename T::type> distance(T const &left, T const &right) noexcept
878 {
879 return length(left - right);
880 }
881 template <typename T, Primitive U>
882 [[nodiscard]] constexpr auto lerp(T const &from, T const &to, U const param) noexcept
883 {
884 return from * (1 - param) + to * param;
885 }
886 template <typename T, Primitive U>
887 [[nodiscard]] constexpr auto mix(T const &from, T const &to, U const param) noexcept
888 {
889 return lerp(from, to, param);
890 }
891} // namespace mal_math
Contains mathematical utility functions and classes.
constexpr auto lerp(T const &from, T const &to, U const param) noexcept
Linearly interpolate between two values.
Definition vec_math.inl:882
float atanh(T x) noexcept
float cos(T x) noexcept
constexpr vec< T::size, std::remove_const_t< typename T::type > > max(T const &left, U const max) noexcept
Returns a new vector with each element being the maximum of the corresponding element in left and min...
Definition vec_math.inl:798
float atan2(T x, T y) noexcept
float asin(T x) noexcept
float sin(T x) noexcept
float log1p(T x) noexcept
float acos(T x) noexcept
float acosh(T x) noexcept
float log2(T x) noexcept
constexpr T length(qua< T > const &q) noexcept
Computes the length (or magnitude) of a quaternion.
float expm1(T x) noexcept
float atan(T x) noexcept
float log10(T x) noexcept
constexpr void rmin(T &left, U const &max) noexcept
Modifies left in-place, setting each element to the minimum of itself and the corresponding element i...
Definition vec_math.inl:830
float exp(T x) noexcept
constexpr vec< n, typename Vector::type > const & as_crvec(Vector const &v) noexcept
Convert a given const vector to a const reference of vec with specified size and type.
Definition vec_math.inl:67
float mod(T x, U y) noexcept
constexpr T clamp(T x, T min, T max) noexcept
Function to clamp a value between a minimum and maximum.
float tanh(T x) noexcept
constexpr mat< T::size.x, T::size.y, std::remove_const_t< typename T::type > > operator-(T const &left, U const right)
Subtracts a matrix from a primitive.
Definition mat_math.inl:100
constexpr T angle(qua< T > const &quaternion) noexcept
Computes the angle (or magnitude) of a quaternion.
T roundEven(T x) noexcept
float inversesqrt(T x) noexcept
constexpr auto operator*(U const &lhs, V const &rhs)
Multiplies two matrices.
Definition mat_math.inl:33
float log(T x) noexcept
float exp2(T x) noexcept
T abs(T x) noexcept
constexpr std::remove_const_t< typename T::type > distance(T const &left, T const &right) noexcept
Compute the distance between two vectors.
Definition vec_math.inl:877
constexpr bool operator==(T const &left, U const &right) noexcept
Definition vec_math.inl:268
T trunc(T x) noexcept
float sinh(T x) noexcept
constexpr vec< n, U > as_vec(Vector const &v) noexcept
Create a new vector of a specified size and type from the given vector.
Definition vec_math.inl:34
float sqrt(T x) noexcept
T ceil(T x) noexcept
constexpr std::remove_const_t< typename T::type > squared_length(T const &vector) noexcept
Compute the squared length of the given vector.
Definition vec_math.inl:284
constexpr std::istream & operator>>(std::istream &is, U &matrix)
Reads a matrix from an input stream.
Definition mat_math.inl:8
int sign(T x) noexcept
constexpr std::ostream & operator<<(std::ostream &os, U const &matrix)
Writes a matrix to an output stream.
Definition mat_math.inl:20
constexpr void rclamp(T &left, U const min, U const max) noexcept
Clamp the value of left between min and max in-place.
Definition vec_math.inl:695
T floor(T x) noexcept
float asinh(T x) noexcept
constexpr T dot(qua< T > const &left, qua< U > const &right) noexcept
Computes the dot product of two quaternions.
constexpr void rmax(T &left, U const &min) noexcept
Modifies left in-place, setting each element to the maximum of itself and the corresponding element i...
Definition vec_math.inl:839
float pow(T x, U y) noexcept
constexpr bool operator!=(T const &left, U const &right) noexcept
Definition vec_math.inl:279
constexpr qua< T > normalize(qua< T > const &q) noexcept
Normalizes a quaternion.
constexpr vec< T::size, std::remove_const_t< typename T::type > > unit_vector(T const &vector) noexcept
Compute the unit vector (normalized vector) of the given vector.
Definition vec_math.inl:300
constexpr mat< T::size.x, T::size.y, std::remove_const_t< typename T::type > > operator+(U const left, T const &right)
Adds a matrix to a primitive.
Definition mat_math.inl:105
T round(T x) noexcept
float tan(T x) noexcept
constexpr vec< n, typename Vector::type > & as_rvec(Vector &v) noexcept
Convert a given vector to a reference of vec with specified size and type.
Definition vec_math.inl:56
float cosh(T x) noexcept
constexpr auto mix(T const &from, T const &to, U const param) noexcept
Mix between two values (same as lerp).
Definition vec_math.inl:887
float logb(T x) noexcept
constexpr vec< size, std::remove_const_t< T > > operator%(_detail::rvec< size, T > const &left, U const value) noexcept
Definition vec_math.inl:205
constexpr vec< T::size, std::remove_const_t< typename T::type > > min(T const &left, U const min) noexcept
Returns a new vector with each element being the minimum of the corresponding element in left and max...
Definition vec_math.inl:787
constexpr qua< T > operator/(U const value, qua< T > const &vector) noexcept
Scalar-quaternion division.
constexpr vec< 3, T > cross(qua< T > const &left, vec< 3, U > const &right) noexcept
Cross product between quaternion and vector.
T fract(T x) noexcept
Internal detail definition of a reference vector with fixed size L and type T
Definition of the mathematical vector with fixed size L and type T
Definition vecn.hpp:22
std::array< T, size > data
The underlying data of the vector.
Definition vecn.hpp:101
Contains a collection of mathematical operations and utility functions for vector objects.