46#if defined(_MSC_VER) && (_MSC_VER <= 1900)
47#define LINALG_CONSTEXPR14
49#define LINALG_CONSTEXPR14 constexpr
55template <
class T,
int M>
60template <
class T,
int M,
int N>
65template <
class T,
class U>
68template <
class T,
class U>
69using conv_t =
typename std::enable_if<!std::is_same<T, U>::value,
71 std::declval<U>()))>::type;
76template <
class T,
int M>
80template <
class T,
int M,
int N>
92constexpr bool operator==(
const ord<T>& o, std::nullptr_t) {
96constexpr bool operator!=(
const ord<T>& o, std::nullptr_t) {
100constexpr bool operator<(
const ord<T>& o, std::nullptr_t) {
104constexpr bool operator>(
const ord<T>& o, std::nullptr_t) {
108constexpr bool operator<=(
const ord<T>& o, std::nullptr_t) {
112constexpr bool operator>=(
const ord<T>& o, std::nullptr_t) {
117template <
class A,
class B>
130 return !(a.x == b.x) ?
ord<T>{a.x, b.x} :
ord<T>{a.y, b.y};
137 return !(a.x == b.x) ?
ord<T>{a.x, b.x}
138 : !(a.y == b.y) ?
ord<T>{a.y, b.y}
146 return !(a.x == b.x) ?
ord<T>{a.x, b.x}
147 : !(a.y == b.y) ?
ord<T>{a.y, b.y}
148 : !(a.z == b.z) ?
ord<T>{a.z, b.z}
152template <
class T,
int M>
157 return compare(a.x, b.x);
160template <
class T,
int M>
165 return a.x != b.x ? compare(a.x, b.x) : compare(a.y, b.y);
168template <
class T,
int M>
173 return a.x != b.x ? compare(a.x, b.x)
174 : a.y != b.y ? compare(a.y, b.y)
178template <
class T,
int M>
183 return a.x != b.x ? compare(a.x, b.x)
184 : a.y != b.y ? compare(a.y, b.y)
185 : a.z != b.z ? compare(a.z, b.z)
197 constexpr auto operator()(A& a)
const ->
decltype(a.x) {
204 constexpr auto operator()(A& a)
const ->
decltype(a.y) {
211 constexpr auto operator()(A& a)
const ->
decltype(a.z) {
218 constexpr auto operator()(A& a)
const ->
decltype(a.w) {
226template <
int A,
int N>
248template <
int A,
int B>
250template <
class T,
int M,
int... I>
254template <
class T,
int M,
int N,
int... I,
int... J>
255mat<T,
sizeof...(I),
sizeof...(J)>
constexpr swizzle(
const mat<T, M, N>& m,
261template <
class F,
class... T>
262using ret_t =
decltype(std::declval<F>()(std::declval<T>()...));
272template <
class T,
class... U>
273struct scalars<T, U...> : std::conditional<std::is_arithmetic<T>::value,
274 scalars<U...>, empty>::type {};
276using scalars_t =
typename scalars<T...>::type;
280template <
class F,
class Void,
class... T>
282template <
class F,
int M,
class A>
285 enum { size = M, mm = 0 };
291template <
class F,
int M,
class A,
class B>
294 enum { size = M, mm = 0 };
301template <
class F,
int M,
class A,
class B>
304 enum { size = M, mm = 0 };
310template <
class F,
int M,
class A,
class B>
313 enum { size = M, mm = 0 };
319template <
class F,
int M,
class A,
class B,
class C>
322 enum { size = M, mm = 0 };
329template <
class F,
int M,
class A,
class B,
class C>
332 enum { size = M, mm = 0 };
339template <
class F,
int M,
class A,
class B,
class C>
342 enum { size = M, mm = 0 };
349template <
class F,
int M,
class A,
class B,
class C>
352 enum { size = M, mm = 0 };
358template <
class F,
int M,
class A,
class B,
class C>
361 enum { size = M, mm = 0 };
368template <
class F,
int M,
class A,
class B,
class C>
371 enum { size = M, mm = 0 };
377template <
class F,
int M,
class A,
class B,
class C>
380 enum { size = M, mm = 0 };
386template <
class F,
int M,
int N,
class A>
389 enum { size = N, mm = 0 };
396template <
class F,
int M,
int N,
class A,
class B>
399 enum { size = N, mm = 1 };
407template <
class F,
int M,
int N,
class A,
class B>
410 enum { size = N, mm = 0 };
417template <
class F,
int M,
int N,
class A,
class B>
420 enum { size = N, mm = 0 };
427template <
class F,
class... A>
428struct apply<F, scalars_t<A...>, A...> {
429 using type = ret_t<F, A...>;
430 enum { size = 0, mm = 0 };
431 static constexpr type impl(
seq<>, F f, A... a) {
return f(a...); }
436 template <
class A,
class B>
437 constexpr auto operator()(A a, B b)
const ->
438 typename std::remove_reference<
decltype(a < b ? a : b)>::type {
439 return a < b ? a : b;
443 template <
class A,
class B>
444 constexpr auto operator()(A a, B b)
const ->
445 typename std::remove_reference<
decltype(a < b ? b : a)>::type {
446 return a < b ? b : a;
450 template <
class A,
class B,
class C>
451 constexpr auto operator()(A a, B b, C c)
const ->
452 typename std::remove_reference<
decltype(a < b ? b
455 return a < b ? b : a < c ? a : c;
459 template <
class A,
class B,
class C>
460 constexpr auto operator()(A a, B b, C c)
const ->
461 typename std::remove_reference<
decltype(a ? b : c)>::type {
466 template <
class A,
class B,
class C>
467 constexpr auto operator()(A a, B b, C c)
const
468 ->
decltype(a * (1 - c) + b * c) {
469 return a * (1 - c) + b * c;
476 constexpr auto operator()(A a)
const ->
decltype(+a) {
482 constexpr auto operator()(A a)
const ->
decltype(-a) {
488 constexpr auto operator()(A a)
const ->
decltype(!a) {
494 constexpr auto operator()(A a)
const ->
decltype(~(a)) {
499 template <
class A,
class B>
500 constexpr auto operator()(A a, B b)
const ->
decltype(a * b) {
505 template <
class A,
class B>
506 constexpr auto operator()(A a, B b)
const ->
decltype(a / b) {
511 template <
class A,
class B>
512 constexpr auto operator()(A a, B b)
const ->
decltype(a % b) {
517 template <
class A,
class B>
518 constexpr auto operator()(A a, B b)
const ->
decltype(a + b) {
523 template <
class A,
class B>
524 constexpr auto operator()(A a, B b)
const ->
decltype(a - b) {
529 template <
class A,
class B>
530 constexpr auto operator()(A a, B b)
const ->
decltype(a << b) {
535 template <
class A,
class B>
536 constexpr auto operator()(A a, B b)
const ->
decltype(a >> b) {
541 template <
class A,
class B>
542 constexpr auto operator()(A a, B b)
const ->
decltype(a < b) {
547 template <
class A,
class B>
548 constexpr auto operator()(A a, B b)
const ->
decltype(a > b) {
553 template <
class A,
class B>
554 constexpr auto operator()(A a, B b)
const ->
decltype(a <= b) {
559 template <
class A,
class B>
560 constexpr auto operator()(A a, B b)
const ->
decltype(a >= b) {
565 template <
class A,
class B>
566 constexpr auto operator()(A a, B b)
const ->
decltype(a == b) {
571 template <
class A,
class B>
572 constexpr auto operator()(A a, B b)
const ->
decltype(a != b) {
577 template <
class A,
class B>
578 constexpr auto operator()(A a, B b)
const ->
decltype(a & b) {
583 template <
class A,
class B>
584 constexpr auto operator()(A a, B b)
const ->
decltype(a ^ b) {
589 template <
class A,
class B>
590 constexpr auto operator()(A a, B b)
const ->
decltype(a | b) {
595 template <
class A,
class B>
596 constexpr auto operator()(A a, B b)
const ->
decltype(a && b) {
601 template <
class A,
class B>
602 constexpr auto operator()(A a, B b)
const ->
decltype(a || b) {
610 constexpr auto operator()(A a)
const ->
decltype(std::isfinite(a)) {
611 return std::isfinite(a);
616 constexpr auto operator()(A a)
const ->
decltype(std::abs(a)) {
622 constexpr auto operator()(A a)
const ->
decltype(std::floor(a)) {
623 return std::floor(a);
628 constexpr auto operator()(A a)
const ->
decltype(std::ceil(a)) {
634 constexpr auto operator()(A a)
const ->
decltype(std::exp(a)) {
640 constexpr auto operator()(A a)
const ->
decltype(std::log(a)) {
646 constexpr auto operator()(A a)
const ->
decltype(std::log2(a)) {
652 constexpr auto operator()(A a)
const ->
decltype(std::log10(a)) {
653 return std::log10(a);
658 constexpr auto operator()(A a)
const ->
decltype(std::sqrt(a)) {
664 constexpr auto operator()(A a)
const ->
decltype(std::sin(a)) {
670 constexpr auto operator()(A a)
const ->
decltype(std::cos(a)) {
676 constexpr auto operator()(A a)
const ->
decltype(std::tan(a)) {
682 constexpr auto operator()(A a)
const ->
decltype(std::asin(a)) {
688 constexpr auto operator()(A a)
const ->
decltype(std::acos(a)) {
694 constexpr auto operator()(A a)
const ->
decltype(std::atan(a)) {
700 constexpr auto operator()(A a)
const ->
decltype(std::sinh(a)) {
706 constexpr auto operator()(A a)
const ->
decltype(std::cosh(a)) {
712 constexpr auto operator()(A a)
const ->
decltype(std::tanh(a)) {
718 constexpr auto operator()(A a)
const ->
decltype(std::round(a)) {
719 return std::round(a);
723 template <
class A,
class B>
724 constexpr auto operator()(A a, B b)
const ->
decltype(std::fmod(a, b)) {
725 return std::fmod(a, b);
729 template <
class A,
class B>
730 constexpr auto operator()(A a, B b)
const ->
decltype(std::pow(a, b)) {
731 return std::pow(a, b);
735 template <
class A,
class B>
736 constexpr auto operator()(A a, B b)
const ->
decltype(std::atan2(a, b)) {
737 return std::atan2(a, b);
741 template <
class A,
class B>
742 constexpr auto operator()(A a, B b)
const ->
decltype(std::copysign(a, b)) {
743 return std::copysign(a, b);
850 constexpr vec() : x() {}
851 constexpr vec(
const T& x_) : x(x_) {}
855 constexpr explicit vec(
const vec<U, 1>& v) : vec(
static_cast<T
>(v.x)) {}
856 constexpr const T& operator[](
int)
const {
return x; }
857 LINALG_CONSTEXPR14 T& operator[](
int) {
return x; }
859 template <
class U,
class = detail::conv_t<vec, U>>
861 template <
class U,
class = detail::conv_t<U, vec>>
862 constexpr operator U()
const {
869 constexpr vec() : x(), y() {}
870 constexpr vec(
const T& x_,
const T& y_) : x(x_), y(y_) {}
871 constexpr explicit vec(
const T& s) : vec(s, s) {}
872 constexpr explicit vec(
const T* p) : vec(p[0], p[1]) {}
873 template <
class U,
int N>
874 constexpr explicit vec(
const vec<U, N>& v)
875 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y)) {
878 "You must give extra arguments if your input vector is shorter.");
880 constexpr const T& operator[](
int i)
const {
return i == 0 ? x : y; }
881 LINALG_CONSTEXPR14 T& operator[](
int i) {
return i == 0 ? x : y; }
883 template <
class U,
class = detail::conv_t<vec, U>>
885 template <
class U,
class = detail::conv_t<U, vec>>
886 constexpr operator U()
const {
893 constexpr vec() : x(), y(), z() {}
894 constexpr vec(
const T& x_,
const T& y_,
const T& z_) : x(x_), y(y_), z(z_) {}
895 constexpr vec(
const vec<T, 2>& xy,
const T& z_) : vec(xy.x, xy.y, z_) {}
896 constexpr explicit vec(
const T& s) : vec(s, s, s) {}
897 constexpr explicit vec(
const T* p) : vec(p[0], p[1], p[2]) {}
898 template <
class U,
int N>
899 constexpr explicit vec(
const vec<U, N>& v)
900 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y),
static_cast<T
>(v.z)) {
903 "You must give extra arguments if your input vector is shorter.");
905 constexpr const T& operator[](
int i)
const {
906 return i == 0 ? x : i == 1 ? y : z;
908 LINALG_CONSTEXPR14 T& operator[](
int i) {
909 return i == 0 ? x : i == 1 ? y : z;
911 constexpr vec<T, 2> xy()
const {
return vec<T, 2>(x, y); }
912 constexpr vec<T, 2> yz()
const {
return vec<T, 2>(y, z); }
914 template <
class U,
class = detail::conv_t<vec, U>>
916 template <
class U,
class = detail::conv_t<U, vec>>
917 constexpr operator U()
const {
924 constexpr vec() : x(), y(), z(), w() {}
925 constexpr vec(
const T& x_,
const T& y_,
const T& z_,
const T& w_)
926 : x(x_), y(y_), z(z_), w(w_) {}
927 constexpr vec(
const vec<T, 2>& xy,
const T& z_,
const T& w_)
928 : vec(xy.x, xy.y, z_, w_) {}
929 constexpr vec(
const vec<T, 3>& xyz,
const T& w_)
930 : vec(xyz.x, xyz.y, xyz.z, w_) {}
931 constexpr explicit vec(
const T& s) : vec(s, s, s, s) {}
932 constexpr explicit vec(
const T* p) : vec(p[0], p[1], p[2], p[3]) {}
933 template <
class U,
int N>
934 constexpr explicit vec(
const vec<U, N>& v)
935 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y),
static_cast<T
>(v.z),
936 static_cast<T
>(v.w)) {
939 "You must give extra arguments if your input vector is shorter.");
941 constexpr const T& operator[](
int i)
const {
942 return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
944 LINALG_CONSTEXPR14 T& operator[](
int i) {
945 return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
947 constexpr vec<T, 2> xy()
const {
return vec<T, 2>(x, y); }
948 constexpr vec<T, 3> xyz()
const {
return vec<T, 3>(x, y, z); }
950 template <
class U,
class = detail::conv_t<vec, U>>
952 template <
class U,
class = detail::conv_t<U, vec>>
953 constexpr operator U()
const {
1053template <
class T,
int M>
1054struct mat<T, M, 1> {
1057 constexpr mat() : x() {}
1058 constexpr mat(
const V& x_) : x(x_) {}
1059 constexpr explicit mat(
const T& s) : x(s) {}
1060 constexpr explicit mat(
const T* p) : x(p + M * 0) {}
1062 constexpr explicit mat(
const mat<U, M, 1>& m) : mat(V(m.x)) {}
1063 constexpr vec<T, 1> row(
int i)
const {
return {x[i]}; }
1064 constexpr const V& operator[](
int)
const {
return x; }
1065 LINALG_CONSTEXPR14 V& operator[](
int) {
return x; }
1067 template <
class U,
class = detail::conv_t<mat, U>>
1069 template <
class U,
class = detail::conv_t<U, mat>>
1070 constexpr operator U()
const {
1074template <
class T,
int M>
1075struct mat<T, M, 2> {
1078 constexpr mat() : x(), y() {}
1079 constexpr mat(
const V& x_,
const V& y_) : x(x_), y(y_) {}
1080 constexpr explicit mat(
const T& s) : x(s), y(s) {}
1081 constexpr explicit mat(
const T* p) : x(p + M * 0), y(p + M * 1) {}
1082 template <
class U,
int N,
int P>
1083 constexpr explicit mat(
const mat<U, N, P>& m) : mat(V(m.x), V(m.y)) {
1084 static_assert(P >= 2,
"Input matrix dimensions must be at least as big.");
1086 constexpr vec<T, 2> row(
int i)
const {
return {x[i], y[i]}; }
1087 constexpr const V& operator[](
int j)
const {
return j == 0 ? x : y; }
1088 LINALG_CONSTEXPR14 V& operator[](
int j) {
return j == 0 ? x : y; }
1090 template <
class U,
class = detail::conv_t<mat, U>>
1092 template <
class U,
class = detail::conv_t<U, mat>>
1093 constexpr operator U()
const {
1097template <
class T,
int M>
1098struct mat<T, M, 3> {
1101 constexpr mat() : x(), y(), z() {}
1102 constexpr mat(
const V& x_,
const V& y_,
const V& z_) : x(x_), y(y_), z(z_) {}
1103 constexpr mat(
const mat<T, M, 2>& m_,
const V& z_)
1104 : x(m_.x), y(m_.y), z(z_) {}
1105 constexpr explicit mat(
const T& s) : x(s), y(s), z(s) {}
1106 constexpr explicit mat(
const T* p)
1107 : x(p + M * 0), y(p + M * 1), z(p + M * 2) {}
1108 template <
class U,
int N,
int P>
1109 constexpr explicit mat(
const mat<U, N, P>& m) : mat(V(m.x), V(m.y), V(m.z)) {
1110 static_assert(P >= 3,
"Input matrix dimensions must be at least as big.");
1112 constexpr vec<T, 3> row(
int i)
const {
return {x[i], y[i], z[i]}; }
1113 constexpr const V& operator[](
int j)
const {
1114 return j == 0 ? x : j == 1 ? y : z;
1116 LINALG_CONSTEXPR14 V& operator[](
int j) {
1117 return j == 0 ? x : j == 1 ? y : z;
1120 template <
class U,
class = detail::conv_t<mat, U>>
1122 template <
class U,
class = detail::conv_t<U, mat>>
1123 constexpr operator U()
const {
1127template <
class T,
int M>
1128struct mat<T, M, 4> {
1131 constexpr mat() : x(), y(), z(), w() {}
1132 constexpr mat(
const V& x_,
const V& y_,
const V& z_,
const V& w_)
1133 : x(x_), y(y_), z(z_), w(w_) {}
1134 constexpr mat(
const mat<T, M, 3>& m_,
const V& w_)
1135 : x(m_.x), y(m_.y), z(m_.z), w(w_) {}
1136 constexpr explicit mat(
const T& s) : x(s), y(s), z(s), w(s) {}
1137 constexpr explicit mat(
const T* p)
1138 : x(p + M * 0), y(p + M * 1), z(p + M * 2), w(p + M * 3) {}
1139 template <
class U,
int N,
int P>
1140 constexpr explicit mat(
const mat<U, N, P>& m)
1141 : mat(V(m.x), V(m.y), V(m.z), V(m.w)) {
1142 static_assert(P >= 4,
"Input matrix dimensions must be at least as big.");
1145 constexpr vec<T, 4> row(
int i)
const {
return {x[i], y[i], z[i], w[i]}; }
1146 constexpr const V& operator[](
int j)
const {
1147 return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
1149 LINALG_CONSTEXPR14 V& operator[](
int j) {
1150 return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
1153 template <
class U,
class = detail::conv_t<mat, U>>
1155 template <
class U,
class = detail::conv_t<U, mat>>
1156 constexpr operator U()
const {
1169 constexpr explicit identity_t(
int) {}
1178 return {{1, 0}, {0, 1}};
1184 return {{1, 0}, {0, 1}, {0, 0}};
1190 return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
1196 return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, 0}};
1202 return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
1215template <
class F,
class A,
class B>
1216constexpr A fold(F f, A a,
const vec<B, 1>& b) {
1219template <
class F,
class A,
class B>
1220constexpr A fold(F f, A a,
const vec<B, 2>& b) {
1221 return f(f(a, b.x), b.y);
1223template <
class F,
class A,
class B>
1224constexpr A fold(F f, A a,
const vec<B, 3>& b) {
1225 return f(f(f(a, b.x), b.y), b.z);
1227template <
class F,
class A,
class B>
1228constexpr A fold(F f, A a,
const vec<B, 4>& b) {
1229 return f(f(f(f(a, b.x), b.y), b.z), b.w);
1231template <
class F,
class A,
class B,
int M>
1233 return fold(f, a, b.x);
1235template <
class F,
class A,
class B,
int M>
1237 return fold(f, fold(f, a, b.x), b.y);
1239template <
class F,
class A,
class B,
int M>
1241 return fold(f, fold(f, fold(f, a, b.x), b.y), b.z);
1243template <
class F,
class A,
class B,
int M>
1245 return fold(f, fold(f, fold(f, fold(f, a, b.x), b.y), b.z), b.w);
1258template <
class F,
class... A>
1260template <
class F,
class... A>
1261using mm_apply_t =
typename std::enable_if<
detail::apply<F, void, A...>::mm,
1262 apply_t<F, A...>>::type;
1263template <
class F,
class... A>
1264using no_mm_apply_t =
typename std::enable_if<!
detail::apply<F, void, A...>::mm,
1265 apply_t<F, A...>>::type;
1273template <
class F,
class... A>
1274constexpr apply_t<F, A...> apply(F func,
const A&... args) {
1280template <
class A,
class F>
1281constexpr apply_t<F, A> map(
const A& a, F func) {
1282 return apply(func, a);
1286template <
class A,
class B,
class F>
1287constexpr apply_t<F, A, B> zip(
const A& a,
const B& b, F func) {
1288 return apply(func, a, b);
1298template <
class A,
class B>
1303template <
class A,
class B>
1304constexpr auto operator==(
const A& a,
const B& b)
1305 ->
decltype(compare(a, b) == 0) {
1306 return compare(a, b) == 0;
1308template <
class A,
class B>
1309constexpr auto operator!=(
const A& a,
const B& b)
1310 ->
decltype(compare(a, b) != 0) {
1311 return compare(a, b) != 0;
1313template <
class A,
class B>
1314constexpr auto operator<(
const A& a,
const B& b)
1315 ->
decltype(compare(a, b) < 0) {
1316 return compare(a, b) < 0;
1318template <
class A,
class B>
1319constexpr auto operator>(
const A& a,
const B& b)
1320 ->
decltype(compare(a, b) > 0) {
1321 return compare(a, b) > 0;
1323template <
class A,
class B>
1324constexpr auto operator<=(
const A& a,
const B& b)
1325 ->
decltype(compare(a, b) <= 0) {
1326 return compare(a, b) <= 0;
1328template <
class A,
class B>
1329constexpr auto operator>=(
const A& a,
const B& b)
1330 ->
decltype(compare(a, b) >= 0) {
1331 return compare(a, b) >= 0;
1341constexpr bool any(
const A& a) {
1345constexpr bool all(
const A& a) {
1349constexpr scalar_t<A> sum(
const A& a) {
1353constexpr scalar_t<A> product(
const A& a) {
1357constexpr scalar_t<A> minelem(
const A& a) {
1361constexpr scalar_t<A> maxelem(
const A& a) {
1364template <
class T,
int M>
1367 for (
int i = 1; i < M; ++i)
1368 if (a[i] < a[j]) j = i;
1371template <
class T,
int M>
1374 for (
int i = 1; i < M; ++i)
1375 if (a[i] > a[j]) j = i;
1386constexpr apply_t<detail::op_pos, A> operator+(
const A& a) {
1390constexpr apply_t<detail::op_neg, A> operator-(
const A& a) {
1394constexpr apply_t<detail::op_cmp, A> operator~(
const A& a) {
1398constexpr apply_t<detail::op_not, A> operator!(
const A& a) {
1411template <
class A,
class B>
1412constexpr apply_t<detail::op_add, A, B> operator+(
const A& a,
const B& b) {
1415template <
class A,
class B>
1416constexpr apply_t<detail::op_sub, A, B> operator-(
const A& a,
const B& b) {
1419template <
class A,
class B>
1420constexpr apply_t<detail::op_mul, A, B> cmul(
const A& a,
const B& b) {
1423template <
class A,
class B>
1424constexpr apply_t<detail::op_div, A, B> operator/(
const A& a,
const B& b) {
1427template <
class A,
class B>
1428constexpr apply_t<detail::op_mod, A, B> operator%(
const A& a,
const B& b) {
1431template <
class A,
class B>
1432constexpr apply_t<detail::op_un, A, B> operator|(
const A& a,
const B& b) {
1435template <
class A,
class B>
1436constexpr apply_t<detail::op_xor, A, B> operator^(
const A& a,
const B& b) {
1439template <
class A,
class B>
1440constexpr apply_t<detail::op_int, A, B> operator&(
const A& a,
const B& b) {
1443template <
class A,
class B>
1444constexpr apply_t<detail::op_lsh, A, B> operator<<(
const A& a,
const B& b) {
1447template <
class A,
class B>
1448constexpr apply_t<detail::op_rsh, A, B> operator>>(
const A& a,
const B& b) {
1454template <
class A,
class B>
1455constexpr auto operator*(
const A& a,
const B& b) {
1461template <
class A,
class B>
1462constexpr auto operator+=(A& a,
const B& b) ->
decltype(a = a + b) {
1465template <
class A,
class B>
1466constexpr auto operator-=(A& a,
const B& b) ->
decltype(a = a - b) {
1469template <
class A,
class B>
1470constexpr auto operator*=(A& a,
const B& b) ->
decltype(a = a * b) {
1473template <
class A,
class B>
1474constexpr auto operator/=(A& a,
const B& b) ->
decltype(a = a / b) {
1477template <
class A,
class B>
1478constexpr auto operator%=(A& a,
const B& b) ->
decltype(a = a % b) {
1481template <
class A,
class B>
1482constexpr auto operator|=(A& a,
const B& b) ->
decltype(a = a | b) {
1485template <
class A,
class B>
1486constexpr auto operator^=(A& a,
const B& b) ->
decltype(a = a ^ b) {
1489template <
class A,
class B>
1490constexpr auto operator&=(A& a,
const B& b) ->
decltype(a = a & b) {
1493template <
class A,
class B>
1494constexpr auto operator<<=(A& a,
const B& b) ->
decltype(a = a << b) {
1497template <
class A,
class B>
1498constexpr auto operator>>=(A& a,
const B& b) ->
decltype(a = a >> b) {
1512template <
int... I,
class T,
int M>
1520template <
int I0,
int I1,
class T,
int M>
1522 return detail::swizzle(a, detail::make_seq<I0, I1>{});
1528template <
int I0,
int J0,
int I1,
int J1,
class T,
int M,
int N>
1530 return detail::swizzle(a, detail::make_seq<I0, I1>{},
1531 detail::make_seq<J0, J1>{});
1541constexpr apply_t<detail::std_isfinite, A> isfinite(
const A& a) {
1542 return apply(detail::std_isfinite{}, a);
1545constexpr apply_t<detail::std_abs, A> abs(
const A& a) {
1549constexpr apply_t<detail::std_floor, A> floor(
const A& a) {
1553constexpr apply_t<detail::std_ceil, A> ceil(
const A& a) {
1557constexpr apply_t<detail::std_exp, A> exp(
const A& a) {
1561constexpr apply_t<detail::std_log, A> log(
const A& a) {
1565constexpr apply_t<detail::std_log2, A> log2(
const A& a) {
1569constexpr apply_t<detail::std_log10, A> log10(
const A& a) {
1573constexpr apply_t<detail::std_sqrt, A> sqrt(
const A& a) {
1577constexpr apply_t<detail::std_sin, A> sin(
const A& a) {
1581constexpr apply_t<detail::std_cos, A> cos(
const A& a) {
1585constexpr apply_t<detail::std_tan, A> tan(
const A& a) {
1589constexpr apply_t<detail::std_asin, A> asin(
const A& a) {
1593constexpr apply_t<detail::std_acos, A> acos(
const A& a) {
1597constexpr apply_t<detail::std_atan, A> atan(
const A& a) {
1601constexpr apply_t<detail::std_sinh, A> sinh(
const A& a) {
1605constexpr apply_t<detail::std_cosh, A> cosh(
const A& a) {
1609constexpr apply_t<detail::std_tanh, A> tanh(
const A& a) {
1613constexpr apply_t<detail::std_round, A> round(
const A& a) {
1624template <
class A,
class B>
1625constexpr apply_t<detail::std_fmod, A, B> fmod(
const A& a,
const B& b) {
1628template <
class A,
class B>
1629constexpr apply_t<detail::std_pow, A, B> pow(
const A& a,
const B& b) {
1632template <
class A,
class B>
1633constexpr apply_t<detail::std_atan2, A, B> atan2(
const A& a,
const B& b) {
1636template <
class A,
class B>
1637constexpr apply_t<detail::std_copysign, A, B> copysign(
const A& a,
const B& b) {
1648template <
class A,
class B>
1649constexpr apply_t<detail::op_eq, A, B> equal(
const A& a,
const B& b) {
1652template <
class A,
class B>
1653constexpr apply_t<detail::op_ne, A, B> nequal(
const A& a,
const B& b) {
1656template <
class A,
class B>
1657constexpr apply_t<detail::op_lt, A, B> less(
const A& a,
const B& b) {
1660template <
class A,
class B>
1661constexpr apply_t<detail::op_gt, A, B> greater(
const A& a,
const B& b) {
1664template <
class A,
class B>
1665constexpr apply_t<detail::op_le, A, B> lequal(
const A& a,
const B& b) {
1668template <
class A,
class B>
1669constexpr apply_t<detail::op_ge, A, B> gequal(
const A& a,
const B& b) {
1680template <
class A,
class B>
1681constexpr apply_t<detail::min, A, B> min(
const A& a,
const B& b) {
1684template <
class A,
class B>
1685constexpr apply_t<detail::max, A, B> max(
const A& a,
const B& b) {
1691template <
class X,
class L,
class H>
1692constexpr apply_t<detail::clamp, X, L, H>
clamp(
const X& x,
const L& l,
1700template <
class P,
class A,
class B>
1701constexpr apply_t<detail::select, P, A, B>
select(
const P& p,
const A& a,
1709template <
class A,
class B,
class T>
1710constexpr apply_t<detail::lerp, A, B, T>
lerp(
const A& a,
const B& b,
1726 return a.x * b.y - a.y * b.x;
1733 return {-a * b.y, a * b.x};
1740 return {a.y * b, -a.x * b};
1748 return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};
1754template <
class T,
int M>
1761template <
class T,
int M>
1768template <
class T,
int M>
1777template <
class T,
int M>
1786template <
class T,
int M>
1794template <
class T,
int M>
1801template <
class T,
int M>
1804 return d > 1 ? 0 : std::acos(d < -1 ? -1 : d);
1809template <
class T,
int M>
1819 const T s = std::sin(a), c = std::cos(a);
1820 return {v.x * c - v.y * s, v.x * s + v.y * c};
1828 const T s = std::sin(a), c = std::cos(a);
1829 return {v.x, v.y * c - v.z * s, v.y * s + v.z * c};
1837 const T s = std::sin(a), c = std::cos(a);
1838 return {v.x * c + v.z * s, v.y, -v.x * s + v.z * c};
1846 const T s = std::sin(a), c = std::cos(a);
1847 return {v.x * c - v.y * s, v.x * s + v.y * c, v.z};
1852template <
class T,
int M>
1861template <
class T,
int M>
1865 : a * (std::sin(th * (1 - t)) / std::sin(th)) +
1866 b * (std::sin(th * t) / std::sin(th));
1883 return {-q.x, -q.y, -q.z, q.w};
1901 const auto v = q.xyz();
1902 const auto vv =
length(v);
1903 return std::exp(q.w) *
1904 vec<T, 4>{v * (vv > 0 ? std::sin(vv) / vv : 0), std::cos(vv)};
1913 const auto v = q.xyz();
1915 return {v * (vv > 0 ? std::acos(q.w / qq) / vv : 0), std::log(qq)};
1922 const auto v = q.xyz();
1923 const auto vv =
length(v), qq =
length(q), th = std::acos(q.w / qq);
1924 return std::pow(qq, p) *
1925 vec<T, 4>{v * (vv > 0 ? std::sin(p * th) / vv : 0), std::cos(p * th)};
1934 return {a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y,
1935 a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z,
1936 a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x,
1937 a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z};
1942template <
class T,
class... R>
1958 return {q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z,
1959 (q.x * q.y + q.z * q.w) * 2, (q.z * q.x - q.y * q.w) * 2};
1966 return {(q.x * q.y - q.z * q.w) * 2,
1967 q.w * q.w - q.x * q.x + q.y * q.y - q.z * q.z,
1968 (q.y * q.z + q.x * q.w) * 2};
1975 return {(q.z * q.x + q.y * q.w) * 2, (q.y * q.z - q.x * q.w) * 2,
1976 q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z};
1998 return std::atan2(
length(q.xyz()), q.w) * 2;
2014 return nlerp(a,
dot(a, b) < 0 ? -b : b, t);
2021 return slerp(a,
dot(a, b) < 0 ? -b : b, t);
2029 return {axis * std::sin(
angle / 2), std::cos(
angle / 2)};
2050template <
class T,
int M>
2054template <
class T,
int M>
2055constexpr vec<T, M> mul(
const T& b,
const vec<T, M>& a) {
2058template <
class T,
int M,
int N>
2062template <
class T,
int M,
int N>
2066template <
class T,
int M>
2070template <
class T,
int M>
2074template <
class T,
int M>
2076 return a.x * b.x + a.y * b.y;
2078template <
class T,
int M>
2080 return a.x * b.x + a.y * b.y + a.z * b.z;
2082template <
class T,
int M>
2084 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
2086template <
class T,
int M,
int N>
2088 return {mul(a, b.x)};
2090template <
class T,
int M,
int N>
2092 return {mul(a, b.x), mul(a, b.y)};
2094template <
class T,
int M,
int N>
2096 return {mul(a, b.x), mul(a, b.y), mul(a, b.z)};
2098template <
class T,
int M,
int N>
2100 return {mul(a, b.x), mul(a, b.y), mul(a, b.z), mul(a, b.w)};
2102template <
class T,
int M,
int N,
int P>
2105 return mul(mul(a, b), c);
2107template <
class T,
int M,
int N,
int P,
int Q>
2110 return mul(mul(a, b), c);
2112template <
class T,
int M,
int N,
int P,
int Q>
2115 return mul(mul(a, b, c), d);
2117template <
class T,
int M,
int N,
int P,
int Q,
int R>
2120 return mul(mul(a, b, c), d);
2122template <
class T,
int M>
2126template <
class T,
int M>
2128 return {a * b.x, a * b.y};
2130template <
class T,
int M>
2132 return {a * b.x, a * b.y, a * b.z};
2134template <
class T,
int M>
2136 return {a * b.x, a * b.y, a * b.z, a * b.w};
2144 return {a.x.x, a.y.y};
2148 return {a.x.x, a.y.y, a.z.z};
2152 return {a.x.x, a.y.y, a.z.z, a.w.w};
2154template <
class T,
int N>
2156 return sum(diagonal(a));
2158template <
class T,
int M>
2162template <
class T,
int M>
2164 return {m.row(0), m.row(1)};
2166template <
class T,
int M>
2168 return {m.row(0), m.row(1), m.row(2)};
2170template <
class T,
int M>
2172 return {m.row(0), m.row(1), m.row(2), m.row(3)};
2174template <
class T,
int M>
2184 return {{a.y.y, -a.x.y}, {-a.y.x, a.x.x}};
2190template <
class T,
int N>
2192 return transpose(adjugate(a));
2200 return a.x.x * a.y.y - a.x.y * a.y.x;
2204 return a.x.x * (a.y.y * a.z.z - a.z.y * a.y.z) +
2205 a.x.y * (a.y.z * a.z.x - a.z.z * a.y.x) +
2206 a.x.z * (a.y.x * a.z.y - a.z.x * a.y.y);
2210template <
class T,
int N>
2212 return adjugate(a) / determinant(a);
2221template <
class T,
int M>
2225template <
class T,
int M>
2229template <
class T,
int M>
2231 return begin(a) + M;
2233template <
class T,
int M>
2235 return begin(a) + M;
2237template <
class T,
int M,
int N>
2241template <
class T,
int M,
int N>
2245template <
class T,
int M,
int N>
2247 return begin(a) + N;
2249template <
class T,
int M,
int N>
2251 return begin(a) + N;
2271 return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {translation, 1}};
2275 return {{
qxdir(rotation), 0},
2276 {
qydir(rotation), 0},
2277 {
qzdir(rotation), 0},
2282 return {{scaling.x, 0, 0, 0},
2283 {0, scaling.y, 0, 0},
2284 {0, 0, scaling.z, 0},
2293 const vec<T, 3>& view_y_dir, fwd_axis fwd = neg_z);
2295mat<T, 4, 4> frustum_matrix(T x0, T x1, T y0, T y1, T n, T f,
2296 fwd_axis a = neg_z, z_range z = neg_one_to_one);
2298mat<T, 4, 4> perspective_matrix(T fovy, T aspect, T n, T f, fwd_axis a = neg_z,
2299 z_range z = neg_one_to_one) {
2300 T y = n * std::tan(fovy / 2), x = y * aspect;
2301 return frustum_matrix(-x, x, -y, y, n, f, a, z);
2313 vec<T, 1> operator()(
const std::array<T, 1>& a)
const {
return {a[0]}; }
2317 vec<T, 2> operator()(
const std::array<T, 2>& a)
const {
return {a[0], a[1]}; }
2321 vec<T, 3> operator()(
const std::array<T, 3>& a)
const {
2322 return {a[0], a[1], a[2]};
2327 vec<T, 4> operator()(
const std::array<T, 4>& a)
const {
2328 return {a[0], a[1], a[2], a[3]};
2334 std::array<T, 1> operator()(
const vec<T, 1>& a)
const {
return {a[0]}; }
2338 std::array<T, 2> operator()(
const vec<T, 2>& a)
const {
return {a[0], a[1]}; }
2342 std::array<T, 3> operator()(
const vec<T, 3>& a)
const {
2343 return {a[0], a[1], a[2]};
2348 std::array<T, 4> operator()(
const vec<T, 4>& a)
const {
2349 return {a[0], a[1], a[2], a[3]};
2355#ifdef MANIFOLD_DEBUG
2360std::ostream& operator<<(std::ostream& out,
const vec<T, 1>& v) {
2361 return out <<
'{' << v[0] <<
'}';
2364std::ostream& operator<<(std::ostream& out,
const vec<T, 2>& v) {
2365 return out <<
'{' << v[0] <<
',' << v[1] <<
'}';
2368std::ostream& operator<<(std::ostream& out,
const vec<T, 3>& v) {
2369 return out <<
'{' << v[0] <<
',' << v[1] <<
',' << v[2] <<
'}';
2372std::ostream& operator<<(std::ostream& out,
const vec<T, 4>& v) {
2373 return out <<
'{' << v[0] <<
',' << v[1] <<
',' << v[2] <<
',' << v[3] <<
'}';
2376template <
class T,
int M>
2377std::ostream& operator<<(std::ostream& out,
const mat<T, M, 1>& m) {
2378 return out <<
'{' << m[0] <<
'}';
2380template <
class T,
int M>
2381std::ostream& operator<<(std::ostream& out,
const mat<T, M, 2>& m) {
2382 return out <<
'{' << m[0] <<
',' << m[1] <<
'}';
2384template <
class T,
int M>
2385std::ostream& operator<<(std::ostream& out,
const mat<T, M, 3>& m) {
2386 return out <<
'{' << m[0] <<
',' << m[1] <<
',' << m[2] <<
'}';
2388template <
class T,
int M>
2389std::ostream& operator<<(std::ostream& out,
const mat<T, M, 4>& m) {
2390 return out <<
'{' << m[0] <<
',' << m[1] <<
',' << m[2] <<
',' << m[3] <<
'}';
2402struct hash<linalg::vec<T, 1>> {
2409struct hash<linalg::vec<T, 2>> {
2412 return h(v.x) ^ (h(v.y) << 1);
2416struct hash<linalg::vec<T, 3>> {
2419 return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2);
2423struct hash<linalg::vec<T, 4>> {
2426 return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2) ^ (h(v.w) << 3);
2430template <
class T,
int M>
2431struct hash<linalg::mat<T, M, 1>> {
2433 std::hash<linalg::vec<T, M>> h;
2437template <
class T,
int M>
2438struct hash<linalg::mat<T, M, 2>> {
2440 std::hash<linalg::vec<T, M>> h;
2441 return h(v.x) ^ (h(v.y) << M);
2444template <
class T,
int M>
2445struct hash<linalg::mat<T, M, 3>> {
2447 std::hash<linalg::vec<T, M>> h;
2448 return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2));
2451template <
class T,
int M>
2452struct hash<linalg::mat<T, M, 4>> {
2454 std::hash<linalg::vec<T, M>> h;
2455 return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2)) ^ (h(v.w) << (M * 3));
2464 return {{a.y.y * a.z.z - a.z.y * a.y.z, a.z.y * a.x.z - a.x.y * a.z.z,
2465 a.x.y * a.y.z - a.y.y * a.x.z},
2466 {a.y.z * a.z.x - a.z.z * a.y.x, a.z.z * a.x.x - a.x.z * a.z.x,
2467 a.x.z * a.y.x - a.y.z * a.x.x},
2468 {a.y.x * a.z.y - a.z.x * a.y.y, a.z.x * a.x.y - a.x.x * a.z.y,
2469 a.x.x * a.y.y - a.y.x * a.x.y}};
2474 return {{a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
2475 a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
2476 a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w,
2477 a.x.y * a.w.z * a.z.w + a.z.y * a.x.z * a.w.w +
2478 a.w.y * a.z.z * a.x.w - a.w.y * a.x.z * a.z.w -
2479 a.z.y * a.w.z * a.x.w - a.x.y * a.z.z * a.w.w,
2480 a.x.y * a.y.z * a.w.w + a.w.y * a.x.z * a.y.w +
2481 a.y.y * a.w.z * a.x.w - a.x.y * a.w.z * a.y.w -
2482 a.y.y * a.x.z * a.w.w - a.w.y * a.y.z * a.x.w,
2483 a.x.y * a.z.z * a.y.w + a.y.y * a.x.z * a.z.w +
2484 a.z.y * a.y.z * a.x.w - a.x.y * a.y.z * a.z.w -
2485 a.z.y * a.x.z * a.y.w - a.y.y * a.z.z * a.x.w},
2486 {a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
2487 a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
2488 a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x,
2489 a.x.z * a.z.w * a.w.x + a.w.z * a.x.w * a.z.x +
2490 a.z.z * a.w.w * a.x.x - a.x.z * a.w.w * a.z.x -
2491 a.z.z * a.x.w * a.w.x - a.w.z * a.z.w * a.x.x,
2492 a.x.z * a.w.w * a.y.x + a.y.z * a.x.w * a.w.x +
2493 a.w.z * a.y.w * a.x.x - a.x.z * a.y.w * a.w.x -
2494 a.w.z * a.x.w * a.y.x - a.y.z * a.w.w * a.x.x,
2495 a.x.z * a.y.w * a.z.x + a.z.z * a.x.w * a.y.x +
2496 a.y.z * a.z.w * a.x.x - a.x.z * a.z.w * a.y.x -
2497 a.y.z * a.x.w * a.z.x - a.z.z * a.y.w * a.x.x},
2498 {a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
2499 a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
2500 a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y,
2501 a.x.w * a.w.x * a.z.y + a.z.w * a.x.x * a.w.y +
2502 a.w.w * a.z.x * a.x.y - a.x.w * a.z.x * a.w.y -
2503 a.w.w * a.x.x * a.z.y - a.z.w * a.w.x * a.x.y,
2504 a.x.w * a.y.x * a.w.y + a.w.w * a.x.x * a.y.y +
2505 a.y.w * a.w.x * a.x.y - a.x.w * a.w.x * a.y.y -
2506 a.y.w * a.x.x * a.w.y - a.w.w * a.y.x * a.x.y,
2507 a.x.w * a.z.x * a.y.y + a.y.w * a.x.x * a.z.y +
2508 a.z.w * a.y.x * a.x.y - a.x.w * a.y.x * a.z.y -
2509 a.z.w * a.x.x * a.y.y - a.y.w * a.z.x * a.x.y},
2510 {a.y.x * a.w.y * a.z.z + a.z.x * a.y.y * a.w.z +
2511 a.w.x * a.z.y * a.y.z - a.y.x * a.z.y * a.w.z -
2512 a.w.x * a.y.y * a.z.z - a.z.x * a.w.y * a.y.z,
2513 a.x.x * a.z.y * a.w.z + a.w.x * a.x.y * a.z.z +
2514 a.z.x * a.w.y * a.x.z - a.x.x * a.w.y * a.z.z -
2515 a.z.x * a.x.y * a.w.z - a.w.x * a.z.y * a.x.z,
2516 a.x.x * a.w.y * a.y.z + a.y.x * a.x.y * a.w.z +
2517 a.w.x * a.y.y * a.x.z - a.x.x * a.y.y * a.w.z -
2518 a.w.x * a.x.y * a.y.z - a.y.x * a.w.y * a.x.z,
2519 a.x.x * a.y.y * a.z.z + a.z.x * a.x.y * a.y.z +
2520 a.y.x * a.z.y * a.x.z - a.x.x * a.z.y * a.y.z -
2521 a.y.x * a.x.y * a.z.z - a.z.x * a.y.y * a.x.z}};
2525constexpr T linalg::determinant(
const mat<T, 4, 4>& a) {
2526 return a.x.x * (a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
2527 a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
2528 a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w) +
2529 a.x.y * (a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
2530 a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
2531 a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x) +
2532 a.x.z * (a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
2533 a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
2534 a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y) +
2535 a.x.w * (a.y.x * a.w.y * a.z.z + a.z.x * a.y.y * a.w.z +
2536 a.w.x * a.z.y * a.y.z - a.y.x * a.z.y * a.w.z -
2537 a.w.x * a.y.y * a.z.z - a.z.x * a.w.y * a.y.z);
2542 const vec<T, 3>& dest) {
2543 T cosTheta =
dot(orig, dest);
2544 if (cosTheta >= 1 - std::numeric_limits<T>::epsilon()) {
2545 return {0, 0, 0, 1};
2547 if (cosTheta < -1 + std::numeric_limits<T>::epsilon()) {
2548 vec<T, 3> axis =
cross(vec<T, 3>(0, 0, 1), orig);
2549 if (
length2(axis) < std::numeric_limits<T>::epsilon())
2550 axis =
cross(vec<T, 3>(1, 0, 0), orig);
2552 3.14159265358979323846264338327950288);
2554 vec<T, 3> axis =
cross(orig, dest);
2555 T s = std::sqrt((1 + cosTheta) * 2);
2556 return {axis * (1 / s), s * 0.5};
2561 const vec<T, 4> q{m.x.x - m.y.y - m.z.z, m.y.y - m.x.x - m.z.z,
2562 m.z.z - m.x.x - m.y.y, m.x.x + m.y.y + m.z.z},
2563 s[]{{1, m.x.y + m.y.x, m.z.x + m.x.z, m.y.z - m.z.y},
2564 {m.x.y + m.y.x, 1, m.y.z + m.z.y, m.z.x - m.x.z},
2565 {m.x.z + m.z.x, m.y.z + m.z.y, 1, m.x.y - m.y.x},
2566 {m.y.z - m.z.y, m.z.x - m.x.z, m.x.y - m.y.x, 1}};
2567 return copysign(
normalize(sqrt(max(T(0), T(1) + q))), s[argmax(q)]);
2572 const vec<T, 3>& center,
2573 const vec<T, 3>& view_y_dir,
2575 const vec<T, 3> f =
normalize(center - eye), z = a == pos_z ? f : -f,
2577 return inverse(mat<T, 4, 4>{{x, 0}, {y, 0}, {z, 0}, {eye, 1}});
2582 fwd_axis a, z_range z) {
2583 const T s = a == pos_z ? T(1) : T(-1), o = z == neg_one_to_one ? n : 0;
2584 return {{2 * n / (x1 - x0), 0, 0, 0},
2585 {0, 2 * n / (y1 - y0), 0, 0},
2586 {-s * (x0 + x1) / (x1 - x0), -s * (y0 + y1) / (y1 - y0),
2587 s * (f + o) / (f - n), s},
2588 {0, 0, -(n + o) * f / (f - n), 0}};
constexpr mat< T, 3, 3 > qmat(const vec< T, 4 > &q)
Create an equivalent mat3 rotation matrix from the input quaternion.
Definition linalg.h:1982
vec< T, 4 > qslerp(const vec< T, 4 > &a, const vec< T, 4 > &b, T t)
Spherical linear interpolation that takes the shortest path.
Definition linalg.h:2020
T qangle(const vec< T, 4 > &q)
Return the angle in radians of the axis-angle representation of the input normalized quaternion.
Definition linalg.h:1997
constexpr vec< T, 3 > qzdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,0,1})
Definition linalg.h:1974
vec< T, 4 > qnlerp(const vec< T, 4 > &a, const vec< T, 4 > &b, T t)
Linear interpolation that takes the shortest path - this is not geometrically sensible,...
Definition linalg.h:2013
vec< T, 3 > qaxis(const vec< T, 4 > &q)
Return the normalized axis of the axis-angle representation of the input normalized quaternion.
Definition linalg.h:2005
vec< T, 4 > constexpr rotation_quat(const vec< T, 3 > &axis, T angle)
Returns a normalized quaternion representing a rotation by angle in radians about the provided axis.
Definition linalg.h:2028
constexpr vec< T, 3 > qxdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {1,0,0})
Definition linalg.h:1957
constexpr vec< T, 3 > qrot(const vec< T, 4 > &q, const vec< T, 3 > &v)
Rotate a vector by a quaternion.
Definition linalg.h:1989
constexpr vec< T, 3 > qydir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,1,0})
Definition linalg.h:1965
vec< T, 4 > qinv(const vec< T, 4 > &q)
inverse or reciprocal of quaternion q (undefined for zero-length quaternions)
Definition linalg.h:1891
vec< T, 4 > qexp(const vec< T, 4 > &q)
exponential of quaternion q
Definition linalg.h:1900
vec< T, 4 > qpow(const vec< T, 4 > &q, const T &p)
quaternion q raised to the exponent p
Definition linalg.h:1921
vec< T, 4 > qlog(const vec< T, 4 > &q)
logarithm of quaternion q
Definition linalg.h:1912
constexpr vec< T, 4 > qmul(const vec< T, 4 > &a, const vec< T, 4 > &b)
Hamilton product of quaternions a and b
Definition linalg.h:1933
constexpr vec< T, 4 > qconj(const vec< T, 4 > &q)
conjugate of quaternion q
Definition linalg.h:1882
constexpr apply_t< detail::clamp, X, L, H > clamp(const X &x, const L &l, const H &h)
Clamps the components of x between l and h, provided l[i] < h[i].
Definition linalg.h:1692
constexpr apply_t< detail::select, P, A, B > select(const P &p, const A &a, const B &b)
Returns the component from a if the corresponding component of p is true and from b otherwise.
Definition linalg.h:1701
constexpr apply_t< detail::lerp, A, B, T > lerp(const A &a, const B &b, const T &t)
Linear interpolation from a to b as t goes from 0 -> 1. Values beyond [a, b] will result if t is outs...
Definition linalg.h:1710
constexpr vec< T, sizeof...(I)> swizzle(const vec< T, M > &a)
Returns a vector containing the specified ordered indices, e.g. linalg::swizzle<1,...
Definition linalg.h:1513
constexpr mat< T, I1 - I0, J1 - J0 > submat(const mat< T, M, N > &a)
Returns a matrix containing the specified row and column range: linalg::submat<rowStart,...
Definition linalg.h:1529
constexpr vec< T, I1 - I0 > subvec(const vec< T, M > &a)
Returns a vector containing the specified index range, e.g. linalg::subvec<1, 4>(vec4(4,...
Definition linalg.h:1521
vec< T, 3 > roty(T a, const vec< T, 3 > &v)
vector v rotated counter-clockwise by the angle a in radians around the Y axis
Definition linalg.h:1836
vec< T, 2 > rot(T a, const vec< T, 2 > &v)
vector v rotated counter-clockwise by the angle a in radians
Definition linalg.h:1818
constexpr T distance2(const vec< T, M > &a, const vec< T, M > &b)
square of the Euclidean distance between points a and b
Definition linalg.h:1787
vec< T, 3 > rotx(T a, const vec< T, 3 > &v)
vector v rotated counter-clockwise by the angle a in radians around the X axis
Definition linalg.h:1827
constexpr T length2(const vec< T, M > &a)
square of the length or magnitude of vector a
Definition linalg.h:1762
constexpr T dot(const vec< T, M > &a, const vec< T, M > &b)
dot or inner product of vectors a and b
Definition linalg.h:1755
vec< T, M > nlerp(const vec< T, M > &a, const vec< T, M > &b, T t)
shorthand for normalize(lerp(a,b,t))
Definition linalg.h:1853
vec< T, M > normalize(const vec< T, M > &a)
unit length vector in the same direction as a (undefined for zero-length vectors)
Definition linalg.h:1778
vec< T, M > slerp(const vec< T, M > &a, const vec< T, M > &b, T t)
spherical linear interpolation between unit vectors a and b (undefined for non-unit vectors) by param...
Definition linalg.h:1862
T angle(const vec< T, M > &a, const vec< T, M > &b)
Return the angle in radians between two non-unit vectors.
Definition linalg.h:1810
T uangle(const vec< T, M > &a, const vec< T, M > &b)
Return the angle in radians between two unit vectors.
Definition linalg.h:1802
constexpr T cross(const vec< T, 2 > &a, const vec< T, 2 > &b)
shorthand for cross({a.x,a.y,0}, {b.x,b.y,0}).z
Definition linalg.h:1725
vec< T, 3 > rotz(T a, const vec< T, 3 > &v)
vector v rotated counter-clockwise by the angle a in radians around the Z axis
Definition linalg.h:1845
T length(const vec< T, M > &a)
length or magnitude of a vector a
Definition linalg.h:1769
T distance(const vec< T, M > &a, const vec< T, M > &b)
Euclidean distance between points a and b
Definition linalg.h:1795