51#if defined(_MSC_VER) && (_MSC_VER <= 1900)
52#define LINALG_CONSTEXPR14
54#define LINALG_CONSTEXPR14 constexpr
60template <
class T,
int M>
65template <
class T,
int M,
int N>
70template <
class T,
class U>
73template <
class T,
class U>
74using conv_t =
typename std::enable_if<!std::is_same<T, U>::value,
76 std::declval<U>()))>::type;
81template <
class T,
int M>
85template <
class T,
int M,
int N>
97constexpr bool operator==(
const ord<T> &o, std::nullptr_t) {
101constexpr bool operator!=(
const ord<T> &o, std::nullptr_t) {
102 return !(o.a == o.b);
105constexpr bool operator<(
const ord<T> &o, std::nullptr_t) {
109constexpr bool operator>(
const ord<T> &o, std::nullptr_t) {
113constexpr bool operator<=(
const ord<T> &o, std::nullptr_t) {
117constexpr bool operator>=(
const ord<T> &o, std::nullptr_t) {
122template <
class A,
class B>
135 return !(a.x == b.x) ?
ord<T>{a.x, b.x} :
ord<T>{a.y, b.y};
142 return !(a.x == b.x) ?
ord<T>{a.x, b.x}
143 : !(a.y == b.y) ?
ord<T>{a.y, b.y}
151 return !(a.x == b.x) ?
ord<T>{a.x, b.x}
152 : !(a.y == b.y) ?
ord<T>{a.y, b.y}
153 : !(a.z == b.z) ?
ord<T>{a.z, b.z}
157template <
class T,
int M>
162 return compare(a.x, b.x);
165template <
class T,
int M>
170 return a.x != b.x ? compare(a.x, b.x) : compare(a.y, b.y);
173template <
class T,
int M>
178 return a.x != b.x ? compare(a.x, b.x)
179 : a.y != b.y ? compare(a.y, b.y)
183template <
class T,
int M>
188 return a.x != b.x ? compare(a.x, b.x)
189 : a.y != b.y ? compare(a.y, b.y)
190 : a.z != b.z ? compare(a.z, b.z)
202 constexpr auto operator()(A &a)
const ->
decltype(a.x) {
209 constexpr auto operator()(A &a)
const ->
decltype(a.y) {
216 constexpr auto operator()(A &a)
const ->
decltype(a.z) {
223 constexpr auto operator()(A &a)
const ->
decltype(a.w) {
231template <
int A,
int N>
253template <
int A,
int B>
255template <
class T,
int M,
int... I>
259template <
class T,
int M,
int N,
int... I,
int... J>
260mat<T,
sizeof...(I),
sizeof...(J)>
constexpr swizzle(
const mat<T, M, N> &m,
266template <
class F,
class... T>
267using ret_t =
decltype(std::declval<F>()(std::declval<T>()...));
277template <
class T,
class... U>
278struct scalars<T, U...> : std::conditional<std::is_arithmetic<T>::value,
279 scalars<U...>, empty>::type {};
281using scalars_t =
typename scalars<T...>::type;
285template <
class F,
class Void,
class... T>
287template <
class F,
int M,
class A>
290 enum { size = M, mm = 0 };
296template <
class F,
int M,
class A,
class B>
299 enum { size = M, mm = 0 };
306template <
class F,
int M,
class A,
class B>
309 enum { size = M, mm = 0 };
315template <
class F,
int M,
class A,
class B>
318 enum { size = M, mm = 0 };
324template <
class F,
int M,
class A,
class B,
class C>
327 enum { size = M, mm = 0 };
334template <
class F,
int M,
class A,
class B,
class C>
337 enum { size = M, mm = 0 };
344template <
class F,
int M,
class A,
class B,
class C>
347 enum { size = M, mm = 0 };
354template <
class F,
int M,
class A,
class B,
class C>
357 enum { size = M, mm = 0 };
363template <
class F,
int M,
class A,
class B,
class C>
366 enum { size = M, mm = 0 };
373template <
class F,
int M,
class A,
class B,
class C>
376 enum { size = M, mm = 0 };
382template <
class F,
int M,
class A,
class B,
class C>
385 enum { size = M, mm = 0 };
391template <
class F,
int M,
int N,
class A>
394 enum { size = N, mm = 0 };
401template <
class F,
int M,
int N,
class A,
class B>
404 enum { size = N, mm = 1 };
412template <
class F,
int M,
int N,
class A,
class B>
415 enum { size = N, mm = 0 };
422template <
class F,
int M,
int N,
class A,
class B>
425 enum { size = N, mm = 0 };
432template <
class F,
class... A>
433struct apply<F, scalars_t<A...>, A...> {
434 using type = ret_t<F, A...>;
435 enum { size = 0, mm = 0 };
436 static constexpr type impl(
seq<>, F f, A... a) {
return f(a...); }
441 template <
class A,
class B>
442 constexpr auto operator()(A a, B b)
const ->
443 typename std::remove_reference<
decltype(a < b ? a : b)>::type {
444 return a < b ? a : b;
448 template <
class A,
class B>
449 constexpr auto operator()(A a, B b)
const ->
450 typename std::remove_reference<
decltype(a < b ? b : a)>::type {
451 return a < b ? b : a;
455 template <
class A,
class B,
class C>
456 constexpr auto operator()(A a, B b, C c)
const ->
457 typename std::remove_reference<
decltype(a < b ? b
460 return a < b ? b : a < c ? a : c;
464 template <
class A,
class B,
class C>
465 constexpr auto operator()(A a, B b, C c)
const ->
466 typename std::remove_reference<
decltype(a ? b : c)>::type {
471 template <
class A,
class B,
class C>
472 constexpr auto operator()(A a, B b,
473 C c)
const ->
decltype(a * (1 - c) + b * c) {
474 return a * (1 - c) + b * c;
481 constexpr auto operator()(A a)
const ->
decltype(+a) {
487 constexpr auto operator()(A a)
const ->
decltype(-a) {
493 constexpr auto operator()(A a)
const ->
decltype(!a) {
499 constexpr auto operator()(A a)
const ->
decltype(~(a)) {
504 template <
class A,
class B>
505 constexpr auto operator()(A a, B b)
const ->
decltype(a * b) {
510 template <
class A,
class B>
511 constexpr auto operator()(A a, B b)
const ->
decltype(a / b) {
516 template <
class A,
class B>
517 constexpr auto operator()(A a, B b)
const ->
decltype(a % b) {
522 template <
class A,
class B>
523 constexpr auto operator()(A a, B b)
const ->
decltype(a + b) {
528 template <
class A,
class B>
529 constexpr auto operator()(A a, B b)
const ->
decltype(a - b) {
534 template <
class A,
class B>
535 constexpr auto operator()(A a, B b)
const ->
decltype(a << b) {
540 template <
class A,
class B>
541 constexpr auto operator()(A a, B b)
const ->
decltype(a >> b) {
546 template <
class A,
class B>
547 constexpr auto operator()(A a, B b)
const ->
decltype(a < b) {
552 template <
class A,
class B>
553 constexpr auto operator()(A a, B b)
const ->
decltype(a > b) {
558 template <
class A,
class B>
559 constexpr auto operator()(A a, B b)
const ->
decltype(a <= b) {
564 template <
class A,
class B>
565 constexpr auto operator()(A a, B b)
const ->
decltype(a >= b) {
570 template <
class A,
class B>
571 constexpr auto operator()(A a, B b)
const ->
decltype(a == b) {
576 template <
class A,
class B>
577 constexpr auto operator()(A a, B b)
const ->
decltype(a != b) {
582 template <
class A,
class B>
583 constexpr auto operator()(A a, B b)
const ->
decltype(a & b) {
588 template <
class A,
class B>
589 constexpr auto operator()(A a, B b)
const ->
decltype(a ^ b) {
594 template <
class A,
class B>
595 constexpr auto operator()(A a, B b)
const ->
decltype(a | b) {
600 template <
class A,
class B>
601 constexpr auto operator()(A a, B b)
const ->
decltype(a && b) {
606 template <
class A,
class B>
607 constexpr auto operator()(A a, B b)
const ->
decltype(a || b) {
615 constexpr auto operator()(A a)
const ->
decltype(std::isfinite(a)) {
616 return std::isfinite(a);
621 constexpr auto operator()(A a)
const ->
decltype(std::abs(a)) {
627 constexpr auto operator()(A a)
const ->
decltype(std::floor(a)) {
628 return std::floor(a);
633 constexpr auto operator()(A a)
const ->
decltype(std::ceil(a)) {
639 constexpr auto operator()(A a)
const ->
decltype(std::exp(a)) {
645 constexpr auto operator()(A a)
const ->
decltype(std::log(a)) {
651 constexpr auto operator()(A a)
const ->
decltype(std::log2(a)) {
657 constexpr auto operator()(A a)
const ->
decltype(std::log10(a)) {
658 return std::log10(a);
663 constexpr auto operator()(A a)
const ->
decltype(std::sqrt(a)) {
669 constexpr auto operator()(A a)
const ->
decltype(std::sin(a)) {
675 constexpr auto operator()(A a)
const ->
decltype(std::cos(a)) {
681 constexpr auto operator()(A a)
const ->
decltype(std::tan(a)) {
687 constexpr auto operator()(A a)
const ->
decltype(std::asin(a)) {
693 constexpr auto operator()(A a)
const ->
decltype(std::acos(a)) {
699 constexpr auto operator()(A a)
const ->
decltype(std::atan(a)) {
705 constexpr auto operator()(A a)
const ->
decltype(std::sinh(a)) {
711 constexpr auto operator()(A a)
const ->
decltype(std::cosh(a)) {
717 constexpr auto operator()(A a)
const ->
decltype(std::tanh(a)) {
723 constexpr auto operator()(A a)
const ->
decltype(std::round(a)) {
724 return std::round(a);
728 template <
class A,
class B>
729 constexpr auto operator()(A a, B b)
const ->
decltype(std::fmod(a, b)) {
730 return std::fmod(a, b);
734 template <
class A,
class B>
735 constexpr auto operator()(A a, B b)
const ->
decltype(std::pow(a, b)) {
736 return std::pow(a, b);
740 template <
class A,
class B>
741 constexpr auto operator()(A a, B b)
const ->
decltype(std::atan2(a, b)) {
742 return std::atan2(a, b);
746 template <
class A,
class B>
747 constexpr auto operator()(A a, B b)
const ->
decltype(std::copysign(a, b)) {
748 return std::copysign(a, b);
855 constexpr vec() : x() {}
856 constexpr vec(
const T &x_) : x(x_) {}
860 constexpr explicit vec(
const vec<U, 1> &v) : vec(
static_cast<T
>(v.x)) {}
861 constexpr const T &operator[](
int)
const {
return x; }
862 LINALG_CONSTEXPR14 T &operator[](
int) {
return x; }
864 template <
class U,
class = detail::conv_t<vec, U>>
866 template <
class U,
class = detail::conv_t<U, vec>>
867 constexpr operator U()
const {
874 constexpr vec() : x(), y() {}
875 constexpr vec(
const T &x_,
const T &y_) : x(x_), y(y_) {}
876 constexpr explicit vec(
const T &s) : vec(s, s) {}
877 constexpr explicit vec(
const T *p) : vec(p[0], p[1]) {}
878 template <
class U,
int N>
879 constexpr explicit vec(
const vec<U, N> &v)
880 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y)) {
883 "You must give extra arguments if your input vector is shorter.");
885 constexpr const T &operator[](
int i)
const {
return i == 0 ? x : y; }
886 LINALG_CONSTEXPR14 T &operator[](
int i) {
return i == 0 ? x : y; }
888 template <
class U,
class = detail::conv_t<vec, U>>
890 template <
class U,
class = detail::conv_t<U, vec>>
891 constexpr operator U()
const {
898 constexpr vec() : x(), y(), z() {}
899 constexpr vec(
const T &x_,
const T &y_,
const T &z_) : x(x_), y(y_), z(z_) {}
900 constexpr vec(
const vec<T, 2> &xy,
const T &z_) : vec(xy.x, xy.y, z_) {}
901 constexpr explicit vec(
const T &s) : vec(s, s, s) {}
902 constexpr explicit vec(
const T *p) : vec(p[0], p[1], p[2]) {}
903 template <
class U,
int N>
904 constexpr explicit vec(
const vec<U, N> &v)
905 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y),
static_cast<T
>(v.z)) {
908 "You must give extra arguments if your input vector is shorter.");
910 constexpr const T &operator[](
int i)
const {
911 return i == 0 ? x : i == 1 ? y : z;
913 LINALG_CONSTEXPR14 T &operator[](
int i) {
914 return i == 0 ? x : i == 1 ? y : z;
916 constexpr const vec<T, 2> &xy()
const {
917 return *
reinterpret_cast<const vec<T, 2> *
>(
this);
919 vec<T, 2> &xy() {
return *
reinterpret_cast<vec<T, 2> *
>(
this); }
921 template <
class U,
class = detail::conv_t<vec, U>>
923 template <
class U,
class = detail::conv_t<U, vec>>
924 constexpr operator U()
const {
931 constexpr vec() : x(), y(), z(), w() {}
932 constexpr vec(
const T &x_,
const T &y_,
const T &z_,
const T &w_)
933 : x(x_), y(y_), z(z_), w(w_) {}
934 constexpr vec(
const vec<T, 2> &xy,
const T &z_,
const T &w_)
935 : vec(xy.x, xy.y, z_, w_) {}
936 constexpr vec(
const vec<T, 3> &xyz,
const T &w_)
937 : vec(xyz.x, xyz.y, xyz.z, w_) {}
938 constexpr explicit vec(
const T &s) : vec(s, s, s, s) {}
939 constexpr explicit vec(
const T *p) : vec(p[0], p[1], p[2], p[3]) {}
940 template <
class U,
int N>
941 constexpr explicit vec(
const vec<U, N> &v)
942 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y),
static_cast<T
>(v.z),
943 static_cast<T
>(v.w)) {
946 "You must give extra arguments if your input vector is shorter.");
948 constexpr const T &operator[](
int i)
const {
949 return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
951 LINALG_CONSTEXPR14 T &operator[](
int i) {
952 return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
954 constexpr const vec<T, 2> &xy()
const {
955 return *
reinterpret_cast<const vec<T, 2> *
>(
this);
957 constexpr const vec<T, 3> &xyz()
const {
958 return *
reinterpret_cast<const vec<T, 3> *
>(
this);
960 vec<T, 2> &xy() {
return *
reinterpret_cast<vec<T, 2> *
>(
this); }
961 vec<T, 3> &xyz() {
return *
reinterpret_cast<vec<T, 3> *
>(
this); }
963 template <
class U,
class = detail::conv_t<vec, U>>
965 template <
class U,
class = detail::conv_t<U, vec>>
966 constexpr operator U()
const {
1066template <
class T,
int M>
1067struct mat<T, M, 1> {
1070 constexpr mat() : x() {}
1071 constexpr mat(
const V &x_) : x(x_) {}
1072 constexpr explicit mat(
const T &s) : x(s) {}
1073 constexpr explicit mat(
const T *p) : x(p + M * 0) {}
1075 constexpr explicit mat(
const mat<U, M, 1> &m) : mat(V(m.x)) {}
1076 constexpr vec<T, 1> row(
int i)
const {
return {x[i]}; }
1077 constexpr const V &operator[](
int)
const {
return x; }
1078 LINALG_CONSTEXPR14 V &operator[](
int) {
return x; }
1080 template <
class U,
class = detail::conv_t<mat, U>>
1082 template <
class U,
class = detail::conv_t<U, mat>>
1083 constexpr operator U()
const {
1087template <
class T,
int M>
1088struct mat<T, M, 2> {
1091 constexpr mat() : x(), y() {}
1092 constexpr mat(
const V &x_,
const V &y_) : x(x_), y(y_) {}
1093 constexpr explicit mat(
const T &s) : x(s), y(s) {}
1094 constexpr explicit mat(
const T *p) : x(p + M * 0), y(p + M * 1) {}
1095 template <
class U,
int N,
int P>
1096 constexpr explicit mat(
const mat<U, N, P> &m) : mat(V(m.x), V(m.y)) {
1097 static_assert(P >= 2,
"Input matrix dimensions must be at least as big.");
1099 constexpr vec<T, 2> row(
int i)
const {
return {x[i], y[i]}; }
1100 constexpr const V &operator[](
int j)
const {
return j == 0 ? x : y; }
1101 LINALG_CONSTEXPR14 V &operator[](
int j) {
return j == 0 ? x : y; }
1103 template <
class U,
class = detail::conv_t<mat, U>>
1105 template <
class U,
class = detail::conv_t<U, mat>>
1106 constexpr operator U()
const {
1110template <
class T,
int M>
1111struct mat<T, M, 3> {
1114 constexpr mat() : x(), y(), z() {}
1115 constexpr mat(
const V &x_,
const V &y_,
const V &z_) : x(x_), y(y_), z(z_) {}
1116 constexpr mat(
const mat<T, M, 2> &m_,
const V &z_)
1117 : x(m_.x), y(m_.y), z(z_) {}
1118 constexpr explicit mat(
const T &s) : x(s), y(s), z(s) {}
1119 constexpr explicit mat(
const T *p)
1120 : x(p + M * 0), y(p + M * 1), z(p + M * 2) {}
1121 template <
class U,
int N,
int P>
1122 constexpr explicit mat(
const mat<U, N, P> &m) : mat(V(m.x), V(m.y), V(m.z)) {
1123 static_assert(P >= 3,
"Input matrix dimensions must be at least as big.");
1125 constexpr vec<T, 3> row(
int i)
const {
return {x[i], y[i], z[i]}; }
1126 constexpr const V &operator[](
int j)
const {
1127 return j == 0 ? x : j == 1 ? y : z;
1129 LINALG_CONSTEXPR14 V &operator[](
int j) {
1130 return j == 0 ? x : j == 1 ? y : z;
1133 template <
class U,
class = detail::conv_t<mat, U>>
1135 template <
class U,
class = detail::conv_t<U, mat>>
1136 constexpr operator U()
const {
1140template <
class T,
int M>
1141struct mat<T, M, 4> {
1144 constexpr mat() : x(), y(), z(), w() {}
1145 constexpr mat(
const V &x_,
const V &y_,
const V &z_,
const V &w_)
1146 : x(x_), y(y_), z(z_), w(w_) {}
1147 constexpr mat(
const mat<T, M, 3> &m_,
const V &w_)
1148 : x(m_.x), y(m_.y), z(m_.z), w(w_) {}
1149 constexpr explicit mat(
const T &s) : x(s), y(s), z(s), w(s) {}
1150 constexpr explicit mat(
const T *p)
1151 : x(p + M * 0), y(p + M * 1), z(p + M * 2), w(p + M * 3) {}
1152 template <
class U,
int N,
int P>
1153 constexpr explicit mat(
const mat<U, N, P> &m)
1154 : mat(V(m.x), V(m.y), V(m.z), V(m.w)) {
1155 static_assert(P >= 4,
"Input matrix dimensions must be at least as big.");
1158 constexpr vec<T, 4> row(
int i)
const {
return {x[i], y[i], z[i], w[i]}; }
1159 constexpr const V &operator[](
int j)
const {
1160 return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
1162 LINALG_CONSTEXPR14 V &operator[](
int j) {
1163 return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
1166 template <
class U,
class = detail::conv_t<mat, U>>
1168 template <
class U,
class = detail::conv_t<U, mat>>
1169 constexpr operator U()
const {
1182 constexpr explicit identity_t(
int) {}
1191 return {{1, 0}, {0, 1}};
1197 return {{1, 0}, {0, 1}, {0, 0}};
1203 return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
1209 return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, 0}};
1215 return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
1228template <
class F,
class A,
class B>
1229constexpr A fold(F f, A a,
const vec<B, 1> &b) {
1232template <
class F,
class A,
class B>
1233constexpr A fold(F f, A a,
const vec<B, 2> &b) {
1234 return f(f(a, b.x), b.y);
1236template <
class F,
class A,
class B>
1237constexpr A fold(F f, A a,
const vec<B, 3> &b) {
1238 return f(f(f(a, b.x), b.y), b.z);
1240template <
class F,
class A,
class B>
1241constexpr A fold(F f, A a,
const vec<B, 4> &b) {
1242 return f(f(f(f(a, b.x), b.y), b.z), b.w);
1244template <
class F,
class A,
class B,
int M>
1246 return fold(f, a, b.x);
1248template <
class F,
class A,
class B,
int M>
1250 return fold(f, fold(f, a, b.x), b.y);
1252template <
class F,
class A,
class B,
int M>
1254 return fold(f, fold(f, fold(f, a, b.x), b.y), b.z);
1256template <
class F,
class A,
class B,
int M>
1258 return fold(f, fold(f, fold(f, fold(f, a, b.x), b.y), b.z), b.w);
1271template <
class F,
class... A>
1273template <
class F,
class... A>
1274using mm_apply_t =
typename std::enable_if<
detail::apply<F, void, A...>::mm,
1275 apply_t<F, A...>>::type;
1276template <
class F,
class... A>
1277using no_mm_apply_t =
typename std::enable_if<!
detail::apply<F, void, A...>::mm,
1278 apply_t<F, A...>>::type;
1286template <
class F,
class... A>
1287constexpr apply_t<F, A...> apply(F func,
const A &...args) {
1293template <
class A,
class F>
1294constexpr apply_t<F, A> map(
const A &a, F func) {
1295 return apply(func, a);
1299template <
class A,
class B,
class F>
1300constexpr apply_t<F, A, B> zip(
const A &a,
const B &b, F func) {
1301 return apply(func, a, b);
1311template <
class A,
class B>
1316template <
class A,
class B>
1317constexpr auto operator==(
const A &a,
1318 const B &b) ->
decltype(compare(a, b) == 0) {
1319 return compare(a, b) == 0;
1321template <
class A,
class B>
1322constexpr auto operator!=(
const A &a,
1323 const B &b) ->
decltype(compare(a, b) != 0) {
1324 return compare(a, b) != 0;
1326template <
class A,
class B>
1327constexpr auto operator<(
const A &a,
1328 const B &b) ->
decltype(compare(a, b) < 0) {
1329 return compare(a, b) < 0;
1331template <
class A,
class B>
1332constexpr auto operator>(
const A &a,
1333 const B &b) ->
decltype(compare(a, b) > 0) {
1334 return compare(a, b) > 0;
1336template <
class A,
class B>
1337constexpr auto operator<=(
const A &a,
1338 const B &b) ->
decltype(compare(a, b) <= 0) {
1339 return compare(a, b) <= 0;
1341template <
class A,
class B>
1342constexpr auto operator>=(
const A &a,
1343 const B &b) ->
decltype(compare(a, b) >= 0) {
1344 return compare(a, b) >= 0;
1354constexpr bool any(
const A &a) {
1358constexpr bool all(
const A &a) {
1362constexpr scalar_t<A> sum(
const A &a) {
1366constexpr scalar_t<A> product(
const A &a) {
1370constexpr scalar_t<A> minelem(
const A &a) {
1374constexpr scalar_t<A> maxelem(
const A &a) {
1377template <
class T,
int M>
1380 for (
int i = 1; i < M; ++i)
1381 if (a[i] < a[j]) j = i;
1384template <
class T,
int M>
1387 for (
int i = 1; i < M; ++i)
1388 if (a[i] > a[j]) j = i;
1399constexpr apply_t<detail::op_pos, A> operator+(
const A &a) {
1403constexpr apply_t<detail::op_neg, A> operator-(
const A &a) {
1407constexpr apply_t<detail::op_cmp, A> operator~(
const A &a) {
1411constexpr apply_t<detail::op_not, A> operator!(
const A &a) {
1424template <
class A,
class B>
1425constexpr apply_t<detail::op_add, A, B> operator+(
const A &a,
const B &b) {
1428template <
class A,
class B>
1429constexpr apply_t<detail::op_sub, A, B> operator-(
const A &a,
const B &b) {
1432template <
class A,
class B>
1433constexpr apply_t<detail::op_mul, A, B> cmul(
const A &a,
const B &b) {
1436template <
class A,
class B>
1437constexpr apply_t<detail::op_div, A, B> operator/(
const A &a,
const B &b) {
1440template <
class A,
class B>
1441constexpr apply_t<detail::op_mod, A, B> operator%(
const A &a,
const B &b) {
1444template <
class A,
class B>
1445constexpr apply_t<detail::op_un, A, B> operator|(
const A &a,
const B &b) {
1448template <
class A,
class B>
1449constexpr apply_t<detail::op_xor, A, B> operator^(
const A &a,
const B &b) {
1452template <
class A,
class B>
1453constexpr apply_t<detail::op_int, A, B> operator&(
const A &a,
const B &b) {
1456template <
class A,
class B>
1457constexpr apply_t<detail::op_lsh, A, B> operator<<(
const A &a,
const B &b) {
1460template <
class A,
class B>
1461constexpr apply_t<detail::op_rsh, A, B> operator>>(
const A &a,
const B &b) {
1467template <
class A,
class B>
1468constexpr auto operator*(
const A &a,
const B &b) {
1474template <
class A,
class B>
1475constexpr auto operator+=(A &a,
const B &b) ->
decltype(a = a + b) {
1478template <
class A,
class B>
1479constexpr auto operator-=(A &a,
const B &b) ->
decltype(a = a - b) {
1482template <
class A,
class B>
1483constexpr auto operator*=(A &a,
const B &b) ->
decltype(a = a * b) {
1486template <
class A,
class B>
1487constexpr auto operator/=(A &a,
const B &b) ->
decltype(a = a / b) {
1490template <
class A,
class B>
1491constexpr auto operator%=(A &a,
const B &b) ->
decltype(a = a % b) {
1494template <
class A,
class B>
1495constexpr auto operator|=(A &a,
const B &b) ->
decltype(a = a | b) {
1498template <
class A,
class B>
1499constexpr auto operator^=(A &a,
const B &b) ->
decltype(a = a ^ b) {
1502template <
class A,
class B>
1503constexpr auto operator&=(A &a,
const B &b) ->
decltype(a = a & b) {
1506template <
class A,
class B>
1507constexpr auto operator<<=(A &a,
const B &b) ->
decltype(a = a << b) {
1510template <
class A,
class B>
1511constexpr auto operator>>=(A &a,
const B &b) ->
decltype(a = a >> b) {
1525template <
int... I,
class T,
int M>
1533template <
int I0,
int I1,
class T,
int M>
1535 return detail::swizzle(a, detail::make_seq<I0, I1>{});
1541template <
int I0,
int J0,
int I1,
int J1,
class T,
int M,
int N>
1543 return detail::swizzle(a, detail::make_seq<I0, I1>{},
1544 detail::make_seq<J0, J1>{});
1554constexpr apply_t<detail::std_isfinite, A> isfinite(
const A &a) {
1555 return apply(detail::std_isfinite{}, a);
1558constexpr apply_t<detail::std_abs, A> abs(
const A &a) {
1562constexpr apply_t<detail::std_floor, A> floor(
const A &a) {
1566constexpr apply_t<detail::std_ceil, A> ceil(
const A &a) {
1570constexpr apply_t<detail::std_exp, A> exp(
const A &a) {
1574constexpr apply_t<detail::std_log, A> log(
const A &a) {
1578constexpr apply_t<detail::std_log2, A> log2(
const A &a) {
1582constexpr apply_t<detail::std_log10, A> log10(
const A &a) {
1586constexpr apply_t<detail::std_sqrt, A> sqrt(
const A &a) {
1590constexpr apply_t<detail::std_sin, A> sin(
const A &a) {
1594constexpr apply_t<detail::std_cos, A> cos(
const A &a) {
1598constexpr apply_t<detail::std_tan, A> tan(
const A &a) {
1602constexpr apply_t<detail::std_asin, A> asin(
const A &a) {
1606constexpr apply_t<detail::std_acos, A> acos(
const A &a) {
1610constexpr apply_t<detail::std_atan, A> atan(
const A &a) {
1614constexpr apply_t<detail::std_sinh, A> sinh(
const A &a) {
1618constexpr apply_t<detail::std_cosh, A> cosh(
const A &a) {
1622constexpr apply_t<detail::std_tanh, A> tanh(
const A &a) {
1626constexpr apply_t<detail::std_round, A> round(
const A &a) {
1637template <
class A,
class B>
1638constexpr apply_t<detail::std_fmod, A, B> fmod(
const A &a,
const B &b) {
1641template <
class A,
class B>
1642constexpr apply_t<detail::std_pow, A, B> pow(
const A &a,
const B &b) {
1645template <
class A,
class B>
1646constexpr apply_t<detail::std_atan2, A, B> atan2(
const A &a,
const B &b) {
1649template <
class A,
class B>
1650constexpr apply_t<detail::std_copysign, A, B> copysign(
const A &a,
const B &b) {
1661template <
class A,
class B>
1662constexpr apply_t<detail::op_eq, A, B> equal(
const A &a,
const B &b) {
1665template <
class A,
class B>
1666constexpr apply_t<detail::op_ne, A, B> nequal(
const A &a,
const B &b) {
1669template <
class A,
class B>
1670constexpr apply_t<detail::op_lt, A, B> less(
const A &a,
const B &b) {
1673template <
class A,
class B>
1674constexpr apply_t<detail::op_gt, A, B> greater(
const A &a,
const B &b) {
1677template <
class A,
class B>
1678constexpr apply_t<detail::op_le, A, B> lequal(
const A &a,
const B &b) {
1681template <
class A,
class B>
1682constexpr apply_t<detail::op_ge, A, B> gequal(
const A &a,
const B &b) {
1693template <
class A,
class B>
1694constexpr apply_t<detail::min, A, B> min(
const A &a,
const B &b) {
1697template <
class A,
class B>
1698constexpr apply_t<detail::max, A, B> max(
const A &a,
const B &b) {
1704template <
class X,
class L,
class H>
1705constexpr apply_t<detail::clamp, X, L, H>
clamp(
const X &x,
const L &l,
1713template <
class P,
class A,
class B>
1714constexpr apply_t<detail::select, P, A, B>
select(
const P &p,
const A &a,
1722template <
class A,
class B,
class T>
1723constexpr apply_t<detail::lerp, A, B, T>
lerp(
const A &a,
const B &b,
1739 return a.x * b.y - a.y * b.x;
1746 return {-a * b.y, a * b.x};
1753 return {a.y * b, -a.x * b};
1761 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};
1767template <
class T,
int M>
1774template <
class T,
int M>
1781template <
class T,
int M>
1790template <
class T,
int M>
1799template <
class T,
int M>
1807template <
class T,
int M>
1814template <
class T,
int M>
1817 return d > 1 ? 0 : std::acos(d < -1 ? -1 : d);
1822template <
class T,
int M>
1832 const T s = std::sin(a), c = std::cos(a);
1833 return {v.x * c - v.y * s, v.x * s + v.y * c};
1841 const T s = std::sin(a), c = std::cos(a);
1842 return {v.x, v.y * c - v.z * s, v.y * s + v.z * c};
1850 const T s = std::sin(a), c = std::cos(a);
1851 return {v.x * c + v.z * s, v.y, -v.x * s + v.z * c};
1859 const T s = std::sin(a), c = std::cos(a);
1860 return {v.x * c - v.y * s, v.x * s + v.y * c, v.z};
1865template <
class T,
int M>
1874template <
class T,
int M>
1878 : a * (std::sin(th * (1 - t)) / std::sin(th)) +
1879 b * (std::sin(th * t) / std::sin(th));
1896 return {-q.x, -q.y, -q.z, q.w};
1914 const auto v = q.xyz();
1915 const auto vv =
length(v);
1916 return std::exp(q.w) *
1917 vec<T, 4>{v * (vv > 0 ? std::sin(vv) / vv : 0), std::cos(vv)};
1926 const auto v = q.xyz();
1928 return {v * (vv > 0 ? std::acos(q.w / qq) / vv : 0), std::log(qq)};
1935 const auto v = q.xyz();
1936 const auto vv =
length(v), qq =
length(q), th = std::acos(q.w / qq);
1937 return std::pow(qq, p) *
1938 vec<T, 4>{v * (vv > 0 ? std::sin(p * th) / vv : 0), std::cos(p * th)};
1947 return {a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y,
1948 a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z,
1949 a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x,
1950 a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z};
1955template <
class T,
class... R>
1971 return {q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z,
1972 (q.x * q.y + q.z * q.w) * 2, (q.z * q.x - q.y * q.w) * 2};
1979 return {(q.x * q.y - q.z * q.w) * 2,
1980 q.w * q.w - q.x * q.x + q.y * q.y - q.z * q.z,
1981 (q.y * q.z + q.x * q.w) * 2};
1988 return {(q.z * q.x + q.y * q.w) * 2, (q.y * q.z - q.x * q.w) * 2,
1989 q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z};
2011 return std::atan2(
length(q.xyz()), q.w) * 2;
2027 return nlerp(a,
dot(a, b) < 0 ? -b : b, t);
2034 return slerp(a,
dot(a, b) < 0 ? -b : b, t);
2042 return {axis * std::sin(
angle / 2), std::cos(
angle / 2)};
2063template <
class T,
int M>
2067template <
class T,
int M>
2068constexpr vec<T, M> mul(
const T &b,
const vec<T, M> &a) {
2071template <
class T,
int M,
int N>
2075template <
class T,
int M,
int N>
2079template <
class T,
int M>
2083template <
class T,
int M>
2087template <
class T,
int M>
2089 return a.x * b.x + a.y * b.y;
2091template <
class T,
int M>
2093 return a.x * b.x + a.y * b.y + a.z * b.z;
2095template <
class T,
int M>
2097 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
2099template <
class T,
int M,
int N>
2101 return {mul(a, b.x)};
2103template <
class T,
int M,
int N>
2105 return {mul(a, b.x), mul(a, b.y)};
2107template <
class T,
int M,
int N>
2109 return {mul(a, b.x), mul(a, b.y), mul(a, b.z)};
2111template <
class T,
int M,
int N>
2113 return {mul(a, b.x), mul(a, b.y), mul(a, b.z), mul(a, b.w)};
2115template <
class T,
int M,
int N,
int P>
2118 return mul(mul(a, b), c);
2120template <
class T,
int M,
int N,
int P,
int Q>
2123 return mul(mul(a, b), c);
2125template <
class T,
int M,
int N,
int P,
int Q>
2128 return mul(mul(a, b, c), d);
2130template <
class T,
int M,
int N,
int P,
int Q,
int R>
2133 return mul(mul(a, b, c), d);
2135template <
class T,
int M>
2139template <
class T,
int M>
2141 return {a * b.x, a * b.y};
2143template <
class T,
int M>
2145 return {a * b.x, a * b.y, a * b.z};
2147template <
class T,
int M>
2149 return {a * b.x, a * b.y, a * b.z, a * b.w};
2157 return {a.x.x, a.y.y};
2161 return {a.x.x, a.y.y, a.z.z};
2165 return {a.x.x, a.y.y, a.z.z, a.w.w};
2167template <
class T,
int N>
2169 return sum(diagonal(a));
2171template <
class T,
int M>
2175template <
class T,
int M>
2177 return {m.row(0), m.row(1)};
2179template <
class T,
int M>
2181 return {m.row(0), m.row(1), m.row(2)};
2183template <
class T,
int M>
2185 return {m.row(0), m.row(1), m.row(2), m.row(3)};
2187template <
class T,
int M>
2197 return {{a.y.y, -a.x.y}, {-a.y.x, a.x.x}};
2203template <
class T,
int N>
2205 return transpose(adjugate(a));
2213 return a.x.x * a.y.y - a.x.y * a.y.x;
2217 return a.x.x * (a.y.y * a.z.z - a.z.y * a.y.z) +
2218 a.x.y * (a.y.z * a.z.x - a.z.z * a.y.x) +
2219 a.x.z * (a.y.x * a.z.y - a.z.x * a.y.y);
2223template <
class T,
int N>
2225 return adjugate(a) / determinant(a);
2234template <
class T,
int M>
2238template <
class T,
int M>
2242template <
class T,
int M>
2244 return begin(a) + M;
2246template <
class T,
int M>
2248 return begin(a) + M;
2250template <
class T,
int M,
int N>
2254template <
class T,
int M,
int N>
2258template <
class T,
int M,
int N>
2260 return begin(a) + N;
2262template <
class T,
int M,
int N>
2264 return begin(a) + N;
2284 return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {translation, 1}};
2288 return {{
qxdir(rotation), 0},
2289 {
qydir(rotation), 0},
2290 {
qzdir(rotation), 0},
2295 return {{scaling.x, 0, 0, 0},
2296 {0, scaling.y, 0, 0},
2297 {0, 0, scaling.z, 0},
2306 const vec<T, 3> &view_y_dir, fwd_axis fwd = neg_z);
2308mat<T, 4, 4> frustum_matrix(T x0, T x1, T y0, T y1, T n, T f,
2309 fwd_axis a = neg_z, z_range z = neg_one_to_one);
2311mat<T, 4, 4> perspective_matrix(T fovy, T aspect, T n, T f, fwd_axis a = neg_z,
2312 z_range z = neg_one_to_one) {
2313 T y = n * std::tan(fovy / 2), x = y * aspect;
2314 return frustum_matrix(-x, x, -y, y, n, f, a, z);
2326 vec<T, 1> operator()(
const std::array<T, 1> &a)
const {
return {a[0]}; }
2330 vec<T, 2> operator()(
const std::array<T, 2> &a)
const {
return {a[0], a[1]}; }
2334 vec<T, 3> operator()(
const std::array<T, 3> &a)
const {
2335 return {a[0], a[1], a[2]};
2340 vec<T, 4> operator()(
const std::array<T, 4> &a)
const {
2341 return {a[0], a[1], a[2], a[3]};
2347 std::array<T, 1> operator()(
const vec<T, 1> &a)
const {
return {a[0]}; }
2351 std::array<T, 2> operator()(
const vec<T, 2> &a)
const {
return {a[0], a[1]}; }
2355 std::array<T, 3> operator()(
const vec<T, 3> &a)
const {
2356 return {a[0], a[1], a[2]};
2361 std::array<T, 4> operator()(
const vec<T, 4> &a)
const {
2362 return {a[0], a[1], a[2], a[3]};
2367#ifdef MANIFOLD_DEBUG
2369std::ostream &operator<<(std::ostream &out,
const vec<T, 1> &v) {
2370 return out <<
'{' << v[0] <<
'}';
2373std::ostream &operator<<(std::ostream &out,
const vec<T, 2> &v) {
2374 return out <<
'{' << v[0] <<
',' << v[1] <<
'}';
2377std::ostream &operator<<(std::ostream &out,
const vec<T, 3> &v) {
2378 return out <<
'{' << v[0] <<
',' << v[1] <<
',' << v[2] <<
'}';
2381std::ostream &operator<<(std::ostream &out,
const vec<T, 4> &v) {
2382 return out <<
'{' << v[0] <<
',' << v[1] <<
',' << v[2] <<
',' << v[3] <<
'}';
2385template <
class T,
int M>
2386std::ostream &operator<<(std::ostream &out,
const mat<T, M, 1> &m) {
2387 return out <<
'{' << m[0] <<
'}';
2389template <
class T,
int M>
2390std::ostream &operator<<(std::ostream &out,
const mat<T, M, 2> &m) {
2391 return out <<
'{' << m[0] <<
',' << m[1] <<
'}';
2393template <
class T,
int M>
2394std::ostream &operator<<(std::ostream &out,
const mat<T, M, 3> &m) {
2395 return out <<
'{' << m[0] <<
',' << m[1] <<
',' << m[2] <<
'}';
2397template <
class T,
int M>
2398std::ostream &operator<<(std::ostream &out,
const mat<T, M, 4> &m) {
2399 return out <<
'{' << m[0] <<
',' << m[1] <<
',' << m[2] <<
',' << m[3] <<
'}';
2411struct hash<linalg::vec<T, 1>> {
2418struct hash<linalg::vec<T, 2>> {
2421 return h(v.x) ^ (h(v.y) << 1);
2425struct hash<linalg::vec<T, 3>> {
2428 return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2);
2432struct hash<linalg::vec<T, 4>> {
2435 return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2) ^ (h(v.w) << 3);
2439template <
class T,
int M>
2440struct hash<linalg::mat<T, M, 1>> {
2442 std::hash<linalg::vec<T, M>> h;
2446template <
class T,
int M>
2447struct hash<linalg::mat<T, M, 2>> {
2449 std::hash<linalg::vec<T, M>> h;
2450 return h(v.x) ^ (h(v.y) << M);
2453template <
class T,
int M>
2454struct hash<linalg::mat<T, M, 3>> {
2456 std::hash<linalg::vec<T, M>> h;
2457 return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2));
2460template <
class T,
int M>
2461struct hash<linalg::mat<T, M, 4>> {
2463 std::hash<linalg::vec<T, M>> h;
2464 return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2)) ^ (h(v.w) << (M * 3));
2473 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,
2474 a.x.y * a.y.z - a.y.y * a.x.z},
2475 {a.y.z * a.z.x - a.z.z * a.y.x, a.z.z * a.x.x - a.x.z * a.z.x,
2476 a.x.z * a.y.x - a.y.z * a.x.x},
2477 {a.y.x * a.z.y - a.z.x * a.y.y, a.z.x * a.x.y - a.x.x * a.z.y,
2478 a.x.x * a.y.y - a.y.x * a.x.y}};
2483 return {{a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
2484 a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
2485 a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w,
2486 a.x.y * a.w.z * a.z.w + a.z.y * a.x.z * a.w.w +
2487 a.w.y * a.z.z * a.x.w - a.w.y * a.x.z * a.z.w -
2488 a.z.y * a.w.z * a.x.w - a.x.y * a.z.z * a.w.w,
2489 a.x.y * a.y.z * a.w.w + a.w.y * a.x.z * a.y.w +
2490 a.y.y * a.w.z * a.x.w - a.x.y * a.w.z * a.y.w -
2491 a.y.y * a.x.z * a.w.w - a.w.y * a.y.z * a.x.w,
2492 a.x.y * a.z.z * a.y.w + a.y.y * a.x.z * a.z.w +
2493 a.z.y * a.y.z * a.x.w - a.x.y * a.y.z * a.z.w -
2494 a.z.y * a.x.z * a.y.w - a.y.y * a.z.z * a.x.w},
2495 {a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
2496 a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
2497 a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x,
2498 a.x.z * a.z.w * a.w.x + a.w.z * a.x.w * a.z.x +
2499 a.z.z * a.w.w * a.x.x - a.x.z * a.w.w * a.z.x -
2500 a.z.z * a.x.w * a.w.x - a.w.z * a.z.w * a.x.x,
2501 a.x.z * a.w.w * a.y.x + a.y.z * a.x.w * a.w.x +
2502 a.w.z * a.y.w * a.x.x - a.x.z * a.y.w * a.w.x -
2503 a.w.z * a.x.w * a.y.x - a.y.z * a.w.w * a.x.x,
2504 a.x.z * a.y.w * a.z.x + a.z.z * a.x.w * a.y.x +
2505 a.y.z * a.z.w * a.x.x - a.x.z * a.z.w * a.y.x -
2506 a.y.z * a.x.w * a.z.x - a.z.z * a.y.w * a.x.x},
2507 {a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
2508 a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
2509 a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y,
2510 a.x.w * a.w.x * a.z.y + a.z.w * a.x.x * a.w.y +
2511 a.w.w * a.z.x * a.x.y - a.x.w * a.z.x * a.w.y -
2512 a.w.w * a.x.x * a.z.y - a.z.w * a.w.x * a.x.y,
2513 a.x.w * a.y.x * a.w.y + a.w.w * a.x.x * a.y.y +
2514 a.y.w * a.w.x * a.x.y - a.x.w * a.w.x * a.y.y -
2515 a.y.w * a.x.x * a.w.y - a.w.w * a.y.x * a.x.y,
2516 a.x.w * a.z.x * a.y.y + a.y.w * a.x.x * a.z.y +
2517 a.z.w * a.y.x * a.x.y - a.x.w * a.y.x * a.z.y -
2518 a.z.w * a.x.x * a.y.y - a.y.w * a.z.x * a.x.y},
2519 {a.y.x * a.w.y * a.z.z + a.z.x * a.y.y * a.w.z +
2520 a.w.x * a.z.y * a.y.z - a.y.x * a.z.y * a.w.z -
2521 a.w.x * a.y.y * a.z.z - a.z.x * a.w.y * a.y.z,
2522 a.x.x * a.z.y * a.w.z + a.w.x * a.x.y * a.z.z +
2523 a.z.x * a.w.y * a.x.z - a.x.x * a.w.y * a.z.z -
2524 a.z.x * a.x.y * a.w.z - a.w.x * a.z.y * a.x.z,
2525 a.x.x * a.w.y * a.y.z + a.y.x * a.x.y * a.w.z +
2526 a.w.x * a.y.y * a.x.z - a.x.x * a.y.y * a.w.z -
2527 a.w.x * a.x.y * a.y.z - a.y.x * a.w.y * a.x.z,
2528 a.x.x * a.y.y * a.z.z + a.z.x * a.x.y * a.y.z +
2529 a.y.x * a.z.y * a.x.z - a.x.x * a.z.y * a.y.z -
2530 a.y.x * a.x.y * a.z.z - a.z.x * a.y.y * a.x.z}};
2534constexpr T linalg::determinant(
const mat<T, 4, 4> &a) {
2535 return a.x.x * (a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
2536 a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
2537 a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w) +
2538 a.x.y * (a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
2539 a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
2540 a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x) +
2541 a.x.z * (a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
2542 a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
2543 a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y) +
2544 a.x.w * (a.y.x * a.w.y * a.z.z + a.z.x * a.y.y * a.w.z +
2545 a.w.x * a.z.y * a.y.z - a.y.x * a.z.y * a.w.z -
2546 a.w.x * a.y.y * a.z.z - a.z.x * a.w.y * a.y.z);
2551 const vec<T, 3> &dest) {
2552 T cosTheta =
dot(orig, dest);
2553 if (cosTheta >= 1 - std::numeric_limits<T>::epsilon()) {
2554 return {0, 0, 0, 1};
2556 if (cosTheta < -1 + std::numeric_limits<T>::epsilon()) {
2557 vec<T, 3> axis =
cross(vec<T, 3>(0, 0, 1), orig);
2558 if (
length2(axis) < std::numeric_limits<T>::epsilon())
2559 axis =
cross(vec<T, 3>(1, 0, 0), orig);
2561 3.14159265358979323846264338327950288);
2563 vec<T, 3> axis =
cross(orig, dest);
2564 T s = std::sqrt((1 + cosTheta) * 2);
2565 return {axis * (1 / s), s * 0.5};
2570 const vec<T, 4> q{m.x.x - m.y.y - m.z.z, m.y.y - m.x.x - m.z.z,
2571 m.z.z - m.x.x - m.y.y, m.x.x + m.y.y + m.z.z},
2572 s[]{{1, m.x.y + m.y.x, m.z.x + m.x.z, m.y.z - m.z.y},
2573 {m.x.y + m.y.x, 1, m.y.z + m.z.y, m.z.x - m.x.z},
2574 {m.x.z + m.z.x, m.y.z + m.z.y, 1, m.x.y - m.y.x},
2575 {m.y.z - m.z.y, m.z.x - m.x.z, m.x.y - m.y.x, 1}};
2576 return copysign(
normalize(sqrt(max(T(0), T(1) + q))), s[argmax(q)]);
2581 const vec<T, 3> ¢er,
2582 const vec<T, 3> &view_y_dir,
2584 const vec<T, 3> f =
normalize(center - eye), z = a == pos_z ? f : -f,
2586 return inverse(mat<T, 4, 4>{{x, 0}, {y, 0}, {z, 0}, {eye, 1}});
2591 fwd_axis a, z_range z) {
2592 const T s = a == pos_z ? T(1) : T(-1), o = z == neg_one_to_one ? n : 0;
2593 return {{2 * n / (x1 - x0), 0, 0, 0},
2594 {0, 2 * n / (y1 - y0), 0, 0},
2595 {-s * (x0 + x1) / (x1 - x0), -s * (y0 + y1) / (y1 - y0),
2596 s * (f + o) / (f - n), s},
2597 {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:1995
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:2033
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:2010
constexpr vec< T, 3 > qzdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,0,1})
Definition linalg.h:1987
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:2026
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:2018
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:2041
constexpr vec< T, 3 > qxdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {1,0,0})
Definition linalg.h:1970
constexpr vec< T, 3 > qrot(const vec< T, 4 > &q, const vec< T, 3 > &v)
Rotate a vector by a quaternion.
Definition linalg.h:2002
constexpr vec< T, 3 > qydir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,1,0})
Definition linalg.h:1978
vec< T, 4 > qinv(const vec< T, 4 > &q)
inverse or reciprocal of quaternion q (undefined for zero-length quaternions)
Definition linalg.h:1904
vec< T, 4 > qexp(const vec< T, 4 > &q)
exponential of quaternion q
Definition linalg.h:1913
vec< T, 4 > qpow(const vec< T, 4 > &q, const T &p)
quaternion q raised to the exponent p
Definition linalg.h:1934
vec< T, 4 > qlog(const vec< T, 4 > &q)
logarithm of quaternion q
Definition linalg.h:1925
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:1946
constexpr vec< T, 4 > qconj(const vec< T, 4 > &q)
conjugate of quaternion q
Definition linalg.h:1895
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:1705
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:1714
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:1723
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:1526
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:1542
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:1534
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:1849
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:1831
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:1800
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:1840
constexpr T length2(const vec< T, M > &a)
square of the length or magnitude of vector a
Definition linalg.h:1775
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:1768
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:1866
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:1791
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:1875
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:1823
T uangle(const vec< T, M > &a, const vec< T, M > &b)
Return the angle in radians between two unit vectors.
Definition linalg.h:1815
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:1738
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:1858
T length(const vec< T, M > &a)
length or magnitude of a vector a
Definition linalg.h:1782
T distance(const vec< T, M > &a, const vec< T, M > &b)
Euclidean distance between points a and b
Definition linalg.h:1808