53#if defined(_MSC_VER) && (_MSC_VER <= 1900)
54#define LINALG_CONSTEXPR14
56#define LINALG_CONSTEXPR14 constexpr
62template <
class T,
int M>
67template <
class T,
int M,
int N>
72template <
class T,
class U>
75template <
class T,
class U>
76using conv_t =
typename std::enable_if<!std::is_same<T, U>::value,
78 std::declval<U>()))>::type;
83template <
class T,
int M>
87template <
class T,
int M,
int N>
99constexpr bool operator==(
const ord<T> &o, std::nullptr_t) {
103constexpr bool operator!=(
const ord<T> &o, std::nullptr_t) {
104 return !(o.a == o.b);
107constexpr bool operator<(
const ord<T> &o, std::nullptr_t) {
111constexpr bool operator>(
const ord<T> &o, std::nullptr_t) {
115constexpr bool operator<=(
const ord<T> &o, std::nullptr_t) {
119constexpr bool operator>=(
const ord<T> &o, std::nullptr_t) {
124template <
class A,
class B>
137 return !(a.x == b.x) ?
ord<T>{a.x, b.x} :
ord<T>{a.y, b.y};
144 return !(a.x == b.x) ?
ord<T>{a.x, b.x}
145 : !(a.y == b.y) ?
ord<T>{a.y, b.y}
153 return !(a.x == b.x) ?
ord<T>{a.x, b.x}
154 : !(a.y == b.y) ?
ord<T>{a.y, b.y}
155 : !(a.z == b.z) ?
ord<T>{a.z, b.z}
159template <
class T,
int M>
164 return compare(a.x, b.x);
167template <
class T,
int M>
172 return a.x != b.x ? compare(a.x, b.x) : compare(a.y, b.y);
175template <
class T,
int M>
180 return a.x != b.x ? compare(a.x, b.x)
181 : a.y != b.y ? compare(a.y, b.y)
185template <
class T,
int M>
190 return a.x != b.x ? compare(a.x, b.x)
191 : a.y != b.y ? compare(a.y, b.y)
192 : a.z != b.z ? compare(a.z, b.z)
204 constexpr auto operator()(A &a)
const ->
decltype(a.x) {
211 constexpr auto operator()(A &a)
const ->
decltype(a.y) {
218 constexpr auto operator()(A &a)
const ->
decltype(a.z) {
225 constexpr auto operator()(A &a)
const ->
decltype(a.w) {
233template <
int A,
int N>
255template <
int A,
int B>
257template <
class T,
int M,
int... I>
261template <
class T,
int M,
int N,
int... I,
int... J>
262mat<T,
sizeof...(I),
sizeof...(J)>
constexpr swizzle(
const mat<T, M, N> &m,
263 seq<I...> i, seq<J...> j) {
264 return {swizzle(getter<J>{}(m), i)...};
268template <
class F,
class... T>
269using ret_t =
decltype(std::declval<F>()(std::declval<T>()...));
279template <
class T,
class... U>
280struct scalars<T, U...> : std::conditional<std::is_arithmetic<T>::value,
281 scalars<U...>, empty>::type {};
283using scalars_t =
typename scalars<T...>::type;
287template <
class F,
class Void,
class... T>
289template <
class F,
int M,
class A>
292 enum { size = M, mm = 0 };
298template <
class F,
int M,
class A,
class B>
301 enum { size = M, mm = 0 };
308template <
class F,
int M,
class A,
class B>
311 enum { size = M, mm = 0 };
317template <
class F,
int M,
class A,
class B>
320 enum { size = M, mm = 0 };
326template <
class F,
int M,
class A,
class B,
class C>
329 enum { size = M, mm = 0 };
336template <
class F,
int M,
class A,
class B,
class C>
339 enum { size = M, mm = 0 };
346template <
class F,
int M,
class A,
class B,
class C>
349 enum { size = M, mm = 0 };
356template <
class F,
int M,
class A,
class B,
class C>
359 enum { size = M, mm = 0 };
365template <
class F,
int M,
class A,
class B,
class C>
368 enum { size = M, mm = 0 };
375template <
class F,
int M,
class A,
class B,
class C>
378 enum { size = M, mm = 0 };
384template <
class F,
int M,
class A,
class B,
class C>
387 enum { size = M, mm = 0 };
393template <
class F,
int M,
int N,
class A>
396 enum { size = N, mm = 0 };
403template <
class F,
int M,
int N,
class A,
class B>
406 enum { size = N, mm = 1 };
414template <
class F,
int M,
int N,
class A,
class B>
417 enum { size = N, mm = 0 };
424template <
class F,
int M,
int N,
class A,
class B>
427 enum { size = N, mm = 0 };
434template <
class F,
class... A>
435struct apply<F, scalars_t<A...>, A...> {
436 using type = ret_t<F, A...>;
437 enum { size = 0, mm = 0 };
438 static constexpr type impl(
seq<>, F f, A... a) {
return f(a...); }
443 template <
class A,
class B>
444 constexpr auto operator()(A a, B b)
const ->
445 typename std::remove_reference<
decltype(a < b ? a : b)>::type {
446 return a < b ? a : b;
450 template <
class A,
class B>
451 constexpr auto operator()(A a, B b)
const ->
452 typename std::remove_reference<
decltype(a < b ? b : a)>::type {
453 return a < b ? b : a;
457 template <
class A,
class B,
class C>
458 constexpr auto operator()(A a, B b, C c)
const ->
459 typename std::remove_reference<
decltype(a < b ? b
462 return a < b ? b : a < c ? a : c;
466 template <
class A,
class B,
class C>
467 constexpr auto operator()(A a, B b, C c)
const ->
468 typename std::remove_reference<
decltype(a ? b : c)>::type {
473 template <
class A,
class B,
class C>
474 constexpr auto operator()(A a, B b,
475 C c)
const ->
decltype(a * (1 - c) + b * c) {
476 return a * (1 - c) + b * c;
483 constexpr auto operator()(A a)
const ->
decltype(+a) {
489 constexpr auto operator()(A a)
const ->
decltype(-a) {
495 constexpr auto operator()(A a)
const ->
decltype(!a) {
501 constexpr auto operator()(A a)
const ->
decltype(~(a)) {
506 template <
class A,
class B>
507 constexpr auto operator()(A a, B b)
const ->
decltype(a * b) {
512 template <
class A,
class B>
513 constexpr auto operator()(A a, B b)
const ->
decltype(a / b) {
518 template <
class A,
class B>
519 constexpr auto operator()(A a, B b)
const ->
decltype(a % b) {
524 template <
class A,
class B>
525 constexpr auto operator()(A a, B b)
const ->
decltype(a + b) {
530 template <
class A,
class B>
531 constexpr auto operator()(A a, B b)
const ->
decltype(a - b) {
536 template <
class A,
class B>
537 constexpr auto operator()(A a, B b)
const ->
decltype(a << b) {
542 template <
class A,
class B>
543 constexpr auto operator()(A a, B b)
const ->
decltype(a >> b) {
548 template <
class A,
class B>
549 constexpr auto operator()(A a, B b)
const ->
decltype(a < b) {
554 template <
class A,
class B>
555 constexpr auto operator()(A a, B b)
const ->
decltype(a > b) {
560 template <
class A,
class B>
561 constexpr auto operator()(A a, B b)
const ->
decltype(a <= b) {
566 template <
class A,
class B>
567 constexpr auto operator()(A a, B b)
const ->
decltype(a >= b) {
572 template <
class A,
class B>
573 constexpr auto operator()(A a, B b)
const ->
decltype(a == b) {
578 template <
class A,
class B>
579 constexpr auto operator()(A a, B b)
const ->
decltype(a != b) {
584 template <
class A,
class B>
585 constexpr auto operator()(A a, B b)
const ->
decltype(a & b) {
590 template <
class A,
class B>
591 constexpr auto operator()(A a, B b)
const ->
decltype(a ^ b) {
596 template <
class A,
class B>
597 constexpr auto operator()(A a, B b)
const ->
decltype(a | b) {
602 template <
class A,
class B>
603 constexpr auto operator()(A a, B b)
const ->
decltype(a && b) {
608 template <
class A,
class B>
609 constexpr auto operator()(A a, B b)
const ->
decltype(a || b) {
617 constexpr auto operator()(A a)
const ->
decltype(std::isfinite(a)) {
618 return std::isfinite(a);
623 constexpr auto operator()(A a)
const ->
decltype(std::abs(a)) {
629 constexpr auto operator()(A a)
const ->
decltype(std::floor(a)) {
630 return std::floor(a);
635 constexpr auto operator()(A a)
const ->
decltype(std::ceil(a)) {
641 constexpr auto operator()(A a)
const ->
decltype(std::exp(a)) {
647 constexpr auto operator()(A a)
const ->
decltype(std::log(a)) {
653 constexpr auto operator()(A a)
const ->
decltype(std::log2(a)) {
659 constexpr auto operator()(A a)
const ->
decltype(std::log10(a)) {
660 return std::log10(a);
665 constexpr auto operator()(A a)
const ->
decltype(std::sqrt(a)) {
671 constexpr auto operator()(A a)
const ->
decltype(std::sin(a)) {
677 constexpr auto operator()(A a)
const ->
decltype(std::cos(a)) {
683 constexpr auto operator()(A a)
const ->
decltype(std::tan(a)) {
689 constexpr auto operator()(A a)
const ->
decltype(std::asin(a)) {
695 constexpr auto operator()(A a)
const ->
decltype(std::acos(a)) {
701 constexpr auto operator()(A a)
const ->
decltype(std::atan(a)) {
707 constexpr auto operator()(A a)
const ->
decltype(std::sinh(a)) {
713 constexpr auto operator()(A a)
const ->
decltype(std::cosh(a)) {
719 constexpr auto operator()(A a)
const ->
decltype(std::tanh(a)) {
725 constexpr auto operator()(A a)
const ->
decltype(std::round(a)) {
726 return std::round(a);
730 template <
class A,
class B>
731 constexpr auto operator()(A a, B b)
const ->
decltype(std::fmod(a, b)) {
732 return std::fmod(a, b);
736 template <
class A,
class B>
737 constexpr auto operator()(A a, B b)
const ->
decltype(std::pow(a, b)) {
738 return std::pow(a, b);
742 template <
class A,
class B>
743 constexpr auto operator()(A a, B b)
const ->
decltype(std::atan2(a, b)) {
744 return std::atan2(a, b);
748 template <
class A,
class B>
749 constexpr auto operator()(A a, B b)
const ->
decltype(std::copysign(a, b)) {
750 return std::copysign(a, b);
857 constexpr vec() : x() {}
858 constexpr vec(
const T &x_) : x(x_) {}
862 constexpr explicit vec(
const vec<U, 1> &v) :
vec(
static_cast<T
>(v.x)) {}
863 constexpr const T &operator[](
int i)
const {
return x; }
864 LINALG_CONSTEXPR14 T &operator[](
int i) {
return x; }
866 template <
class U,
class = detail::conv_t<vec, U>>
868 template <
class U,
class = detail::conv_t<U, vec>>
869 constexpr operator U()
const {
876 constexpr vec() : x(), y() {}
877 constexpr vec(
const T &x_,
const T &y_) : x(x_), y(y_) {}
878 constexpr explicit vec(
const T &s) :
vec(s, s) {}
879 constexpr explicit vec(
const T *p) :
vec(p[0], p[1]) {}
880 template <
class U,
int N>
882 :
vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y)) {
885 "You must give extra arguments if your input vector is shorter.");
887 constexpr const T &operator[](
int i)
const {
return i == 0 ? x : y; }
888 LINALG_CONSTEXPR14 T &operator[](
int i) {
return i == 0 ? x : y; }
890 template <
class U,
class = detail::conv_t<vec, U>>
892 template <
class U,
class = detail::conv_t<U, vec>>
893 constexpr operator U()
const {
900 constexpr vec() : x(), y(), z() {}
901 constexpr vec(
const T &x_,
const T &y_,
const T &z_) : x(x_), y(y_), z(z_) {}
902 constexpr vec(
const vec<T, 2> &xy,
const T &z_) :
vec(xy.x, xy.y, z_) {}
903 constexpr explicit vec(
const T &s) :
vec(s, s, s) {}
904 constexpr explicit vec(
const T *p) :
vec(p[0], p[1], p[2]) {}
905 template <
class U,
int N>
907 :
vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y),
static_cast<T
>(v.z)) {
910 "You must give extra arguments if your input vector is shorter.");
912 constexpr const T &operator[](
int i)
const {
913 return i == 0 ? x : i == 1 ? y : z;
915 LINALG_CONSTEXPR14 T &operator[](
int i) {
916 return i == 0 ? x : i == 1 ? y : z;
919 return *
reinterpret_cast<const vec<T, 2> *
>(
this);
923 template <
class U,
class = detail::conv_t<vec, U>>
925 template <
class U,
class = detail::conv_t<U, vec>>
926 constexpr operator U()
const {
933 constexpr vec() : x(), y(), z(), w() {}
934 constexpr vec(
const T &x_,
const T &y_,
const T &z_,
const T &w_)
935 : x(x_), y(y_), z(z_), w(w_) {}
936 constexpr vec(
const vec<T, 2> &xy,
const T &z_,
const T &w_)
937 :
vec(xy.x, xy.y, z_, w_) {}
939 :
vec(xyz.x, xyz.y, xyz.z, w_) {}
940 constexpr explicit vec(
const T &s) :
vec(s, s, s, s) {}
941 constexpr explicit vec(
const T *p) :
vec(p[0], p[1], p[2], p[3]) {}
942 template <
class U,
int N>
944 :
vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y),
static_cast<T
>(v.z),
945 static_cast<T
>(v.w)) {
948 "You must give extra arguments if your input vector is shorter.");
950 constexpr const T &operator[](
int i)
const {
951 return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
953 LINALG_CONSTEXPR14 T &operator[](
int i) {
954 return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
957 return *
reinterpret_cast<const vec<T, 2> *
>(
this);
960 return *
reinterpret_cast<const vec<T, 3> *
>(
this);
965 template <
class U,
class = detail::conv_t<vec, U>>
967 template <
class U,
class = detail::conv_t<U, vec>>
968 constexpr operator U()
const {
1068template <
class T,
int M>
1072 constexpr mat() : x() {}
1073 constexpr mat(
const V &x_) : x(x_) {}
1074 constexpr explicit mat(
const T &s) : x(s) {}
1075 constexpr explicit mat(
const T *p) : x(p + M * 0) {}
1078 constexpr vec<T, 1> row(
int i)
const {
return {x[i]}; }
1079 constexpr const V &operator[](
int j)
const {
return x; }
1080 LINALG_CONSTEXPR14
V &operator[](
int j) {
return x; }
1082 template <
class U,
class = detail::conv_t<mat, U>>
1084 template <
class U,
class = detail::conv_t<U, mat>>
1085 constexpr operator U()
const {
1089template <
class T,
int M>
1093 constexpr mat() : x(), y() {}
1094 constexpr mat(
const V &x_,
const V &y_) : x(x_), y(y_) {}
1095 constexpr explicit mat(
const T &s) : x(s), y(s) {}
1096 constexpr explicit mat(
const T *p) : x(p + M * 0), y(p + M * 1) {}
1097 template <
class U,
int N,
int P>
1099 static_assert(P >= 2,
"Input matrix dimensions must be at least as big.");
1101 constexpr vec<T, 2> row(
int i)
const {
return {x[i], y[i]}; }
1102 constexpr const V &operator[](
int j)
const {
return j == 0 ? x : y; }
1103 LINALG_CONSTEXPR14
V &operator[](
int j) {
return j == 0 ? x : y; }
1105 template <
class U,
class = detail::conv_t<mat, U>>
1107 template <
class U,
class = detail::conv_t<U, mat>>
1108 constexpr operator U()
const {
1112template <
class T,
int M>
1116 constexpr mat() : x(), y(), z() {}
1117 constexpr mat(
const V &x_,
const V &y_,
const V &z_) : x(x_), y(y_), z(z_) {}
1119 : x(m_.x), y(m_.y), z(z_) {}
1120 constexpr explicit mat(
const T &s) : x(s), y(s), z(s) {}
1121 constexpr explicit mat(
const T *p)
1122 : x(p + M * 0), y(p + M * 1), z(p + M * 2) {}
1123 template <
class U,
int N,
int P>
1125 static_assert(P >= 3,
"Input matrix dimensions must be at least as big.");
1127 constexpr vec<T, 3> row(
int i)
const {
return {x[i], y[i], z[i]}; }
1128 constexpr const V &operator[](
int j)
const {
1129 return j == 0 ? x : j == 1 ? y : z;
1131 LINALG_CONSTEXPR14
V &operator[](
int j) {
1132 return j == 0 ? x : j == 1 ? y : z;
1135 template <
class U,
class = detail::conv_t<mat, U>>
1137 template <
class U,
class = detail::conv_t<U, mat>>
1138 constexpr operator U()
const {
1142template <
class T,
int M>
1146 constexpr mat() : x(), y(), z(), w() {}
1147 constexpr mat(
const V &x_,
const V &y_,
const V &z_,
const V &w_)
1148 : x(x_), y(y_), z(z_), w(w_) {}
1150 : x(m_.x), y(m_.y), z(m_.z), w(w_) {}
1151 constexpr explicit mat(
const T &s) : x(s), y(s), z(s), w(s) {}
1152 constexpr explicit mat(
const T *p)
1153 : x(p + M * 0), y(p + M * 1), z(p + M * 2), w(p + M * 3) {}
1154 template <
class U,
int N,
int P>
1156 :
mat(
V(m.x),
V(m.y),
V(m.z),
V(m.w)) {
1157 static_assert(P >= 4,
"Input matrix dimensions must be at least as big.");
1160 constexpr vec<T, 4> row(
int i)
const {
return {x[i], y[i], z[i], w[i]}; }
1161 constexpr const V &operator[](
int j)
const {
1162 return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
1164 LINALG_CONSTEXPR14
V &operator[](
int j) {
1165 return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
1168 template <
class U,
class = detail::conv_t<mat, U>>
1170 template <
class U,
class = detail::conv_t<U, mat>>
1171 constexpr operator U()
const {
1193 return {{1, 0}, {0, 1}};
1199 return {{1, 0}, {0, 1}, {0, 0}};
1205 return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
1211 return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, 0}};
1217 return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
1230template <
class F,
class A,
class B>
1231constexpr A fold(F f, A a,
const vec<B, 1> &b) {
1234template <
class F,
class A,
class B>
1235constexpr A fold(F f, A a,
const vec<B, 2> &b) {
1236 return f(f(a, b.x), b.y);
1238template <
class F,
class A,
class B>
1239constexpr A fold(F f, A a,
const vec<B, 3> &b) {
1240 return f(f(f(a, b.x), b.y), b.z);
1242template <
class F,
class A,
class B>
1243constexpr A fold(F f, A a,
const vec<B, 4> &b) {
1244 return f(f(f(f(a, b.x), b.y), b.z), b.w);
1246template <
class F,
class A,
class B,
int M>
1247constexpr A fold(F f, A a,
const mat<B, M, 1> &b) {
1248 return fold(f, a, b.x);
1250template <
class F,
class A,
class B,
int M>
1251constexpr A fold(F f, A a,
const mat<B, M, 2> &b) {
1252 return fold(f, fold(f, a, b.x), b.y);
1254template <
class F,
class A,
class B,
int M>
1255constexpr A fold(F f, A a,
const mat<B, M, 3> &b) {
1256 return fold(f, fold(f, fold(f, a, b.x), b.y), b.z);
1258template <
class F,
class A,
class B,
int M>
1259constexpr A fold(F f, A a,
const mat<B, M, 4> &b) {
1260 return fold(f, fold(f, fold(f, fold(f, a, b.x), b.y), b.z), b.w);
1273template <
class F,
class... A>
1274using apply_t =
typename detail::apply<F, void, A...>::type;
1275template <
class F,
class... A>
1276using mm_apply_t =
typename std::enable_if<detail::apply<F, void, A...>::mm,
1277 apply_t<F, A...>>::type;
1278template <
class F,
class... A>
1279using no_mm_apply_t =
typename std::enable_if<!detail::apply<F, void, A...>::mm,
1280 apply_t<F, A...>>::type;
1283 typename detail::scalar_type<A>::type;
1288template <
class F,
class... A>
1289constexpr apply_t<F, A...> apply(F func,
const A &...args) {
1290 return detail::apply<F, void, A...>::impl(
1291 detail::make_seq<0, detail::apply<F, void, A...>::size>{}, func, args...);
1295template <
class A,
class F>
1296constexpr apply_t<F, A> map(
const A &a, F func) {
1297 return apply(func, a);
1301template <
class A,
class B,
class F>
1302constexpr apply_t<F, A, B> zip(
const A &a,
const B &b, F func) {
1303 return apply(func, a, b);
1313template <
class A,
class B>
1314constexpr typename detail::any_compare<A, B>::type compare(
const A &a,
1316 return detail::any_compare<A, B>()(a, b);
1318template <
class A,
class B>
1319constexpr auto operator==(
const A &a,
1320 const B &b) ->
decltype(compare(a, b) == 0) {
1321 return compare(a, b) == 0;
1323template <
class A,
class B>
1324constexpr auto operator!=(
const A &a,
1325 const B &b) ->
decltype(compare(a, b) != 0) {
1326 return compare(a, b) != 0;
1328template <
class A,
class B>
1329constexpr auto operator<(
const A &a,
1330 const B &b) ->
decltype(compare(a, b) < 0) {
1331 return compare(a, b) < 0;
1333template <
class A,
class B>
1334constexpr auto operator>(
const A &a,
1335 const B &b) ->
decltype(compare(a, b) > 0) {
1336 return compare(a, b) > 0;
1338template <
class A,
class B>
1339constexpr auto operator<=(
const A &a,
1340 const B &b) ->
decltype(compare(a, b) <= 0) {
1341 return compare(a, b) <= 0;
1343template <
class A,
class B>
1344constexpr auto operator>=(
const A &a,
1345 const B &b) ->
decltype(compare(a, b) >= 0) {
1346 return compare(a, b) >= 0;
1356constexpr bool any(
const A &a) {
1357 return fold(detail::op_or{},
false, a);
1360constexpr bool all(
const A &a) {
1361 return fold(detail::op_and{},
true, a);
1364constexpr scalar_t<A> sum(
const A &a) {
1365 return fold(detail::op_add{}, scalar_t<A>(0), a);
1368constexpr scalar_t<A> product(
const A &a) {
1369 return fold(detail::op_mul{}, scalar_t<A>(1), a);
1372constexpr scalar_t<A> minelem(
const A &a) {
1373 return fold(detail::min{}, a.x, a);
1376constexpr scalar_t<A> maxelem(
const A &a) {
1377 return fold(detail::max{}, a.x, a);
1379template <
class T,
int M>
1380int argmin(
const vec<T, M> &a) {
1382 for (
int i = 1; i < M; ++i)
1383 if (a[i] < a[j]) j = i;
1386template <
class T,
int M>
1387int argmax(
const vec<T, M> &a) {
1389 for (
int i = 1; i < M; ++i)
1390 if (a[i] > a[j]) j = i;
1401constexpr apply_t<detail::op_pos, A> operator+(
const A &a) {
1402 return apply(detail::op_pos{}, a);
1405constexpr apply_t<detail::op_neg, A> operator-(
const A &a) {
1406 return apply(detail::op_neg{}, a);
1409constexpr apply_t<detail::op_cmp, A> operator~(
const A &a) {
1410 return apply(detail::op_cmp{}, a);
1413constexpr apply_t<detail::op_not, A> operator!(
const A &a) {
1414 return apply(detail::op_not{}, a);
1426template <
class A,
class B>
1427constexpr apply_t<detail::op_add, A, B> operator+(
const A &a,
const B &b) {
1428 return apply(detail::op_add{}, a, b);
1430template <
class A,
class B>
1431constexpr apply_t<detail::op_sub, A, B> operator-(
const A &a,
const B &b) {
1432 return apply(detail::op_sub{}, a, b);
1434template <
class A,
class B>
1435constexpr apply_t<detail::op_mul, A, B> cmul(
const A &a,
const B &b) {
1436 return apply(detail::op_mul{}, a, b);
1438template <
class A,
class B>
1439constexpr apply_t<detail::op_div, A, B> operator/(
const A &a,
const B &b) {
1440 return apply(detail::op_div{}, a, b);
1442template <
class A,
class B>
1443constexpr apply_t<detail::op_mod, A, B> operator%(
const A &a,
const B &b) {
1444 return apply(detail::op_mod{}, a, b);
1446template <
class A,
class B>
1447constexpr apply_t<detail::op_un, A, B> operator|(
const A &a,
const B &b) {
1448 return apply(detail::op_un{}, a, b);
1450template <
class A,
class B>
1451constexpr apply_t<detail::op_xor, A, B> operator^(
const A &a,
const B &b) {
1452 return apply(detail::op_xor{}, a, b);
1454template <
class A,
class B>
1455constexpr apply_t<detail::op_int, A, B> operator&(
const A &a,
const B &b) {
1456 return apply(detail::op_int{}, a, b);
1458template <
class A,
class B>
1459constexpr apply_t<detail::op_lsh, A, B> operator<<(
const A &a,
const B &b) {
1460 return apply(detail::op_lsh{}, a, b);
1462template <
class A,
class B>
1463constexpr apply_t<detail::op_rsh, A, B> operator>>(
const A &a,
const B &b) {
1464 return apply(detail::op_rsh{}, a, b);
1469template <
class A,
class B>
1470constexpr auto operator*(
const A &a,
const B &b) {
1476template <
class A,
class B>
1477constexpr auto operator+=(A &a,
const B &b) ->
decltype(a = a + b) {
1480template <
class A,
class B>
1481constexpr auto operator-=(A &a,
const B &b) ->
decltype(a = a - b) {
1484template <
class A,
class B>
1485constexpr auto operator*=(A &a,
const B &b) ->
decltype(a = a * b) {
1488template <
class A,
class B>
1489constexpr auto operator/=(A &a,
const B &b) ->
decltype(a = a / b) {
1492template <
class A,
class B>
1493constexpr auto operator%=(A &a,
const B &b) ->
decltype(a = a % b) {
1496template <
class A,
class B>
1497constexpr auto operator|=(A &a,
const B &b) ->
decltype(a = a | b) {
1500template <
class A,
class B>
1501constexpr auto operator^=(A &a,
const B &b) ->
decltype(a = a ^ b) {
1504template <
class A,
class B>
1505constexpr auto operator&=(A &a,
const B &b) ->
decltype(a = a & b) {
1508template <
class A,
class B>
1509constexpr auto operator<<=(A &a,
const B &b) ->
decltype(a = a << b) {
1512template <
class A,
class B>
1513constexpr auto operator>>=(A &a,
const B &b) ->
decltype(a = a >> b) {
1527template <
int... I,
class T,
int M>
1535template <
int I0,
int I1,
class T,
int M>
1537 return detail::swizzle(a, detail::make_seq<I0, I1>{});
1543template <
int I0,
int J0,
int I1,
int J1,
class T,
int M,
int N>
1545 return detail::swizzle(a, detail::make_seq<I0, I1>{},
1546 detail::make_seq<J0, J1>{});
1556constexpr apply_t<detail::std_isfinite, A> isfinite(
const A &a) {
1557 return apply(detail::std_isfinite{}, a);
1560constexpr apply_t<detail::std_abs, A> abs(
const A &a) {
1561 return apply(detail::std_abs{}, a);
1564constexpr apply_t<detail::std_floor, A> floor(
const A &a) {
1565 return apply(detail::std_floor{}, a);
1568constexpr apply_t<detail::std_ceil, A> ceil(
const A &a) {
1569 return apply(detail::std_ceil{}, a);
1572constexpr apply_t<detail::std_exp, A> exp(
const A &a) {
1573 return apply(detail::std_exp{}, a);
1576constexpr apply_t<detail::std_log, A> log(
const A &a) {
1577 return apply(detail::std_log{}, a);
1580constexpr apply_t<detail::std_log2, A> log2(
const A &a) {
1581 return apply(detail::std_log2{}, a);
1584constexpr apply_t<detail::std_log10, A> log10(
const A &a) {
1585 return apply(detail::std_log10{}, a);
1588constexpr apply_t<detail::std_sqrt, A> sqrt(
const A &a) {
1589 return apply(detail::std_sqrt{}, a);
1592constexpr apply_t<detail::std_sin, A> sin(
const A &a) {
1593 return apply(detail::std_sin{}, a);
1596constexpr apply_t<detail::std_cos, A> cos(
const A &a) {
1597 return apply(detail::std_cos{}, a);
1600constexpr apply_t<detail::std_tan, A> tan(
const A &a) {
1601 return apply(detail::std_tan{}, a);
1604constexpr apply_t<detail::std_asin, A> asin(
const A &a) {
1605 return apply(detail::std_asin{}, a);
1608constexpr apply_t<detail::std_acos, A> acos(
const A &a) {
1609 return apply(detail::std_acos{}, a);
1612constexpr apply_t<detail::std_atan, A> atan(
const A &a) {
1613 return apply(detail::std_atan{}, a);
1616constexpr apply_t<detail::std_sinh, A> sinh(
const A &a) {
1617 return apply(detail::std_sinh{}, a);
1620constexpr apply_t<detail::std_cosh, A> cosh(
const A &a) {
1621 return apply(detail::std_cosh{}, a);
1624constexpr apply_t<detail::std_tanh, A> tanh(
const A &a) {
1625 return apply(detail::std_tanh{}, a);
1628constexpr apply_t<detail::std_round, A> round(
const A &a) {
1629 return apply(detail::std_round{}, a);
1639template <
class A,
class B>
1640constexpr apply_t<detail::std_fmod, A, B> fmod(
const A &a,
const B &b) {
1641 return apply(detail::std_fmod{}, a, b);
1643template <
class A,
class B>
1644constexpr apply_t<detail::std_pow, A, B> pow(
const A &a,
const B &b) {
1645 return apply(detail::std_pow{}, a, b);
1647template <
class A,
class B>
1648constexpr apply_t<detail::std_atan2, A, B> atan2(
const A &a,
const B &b) {
1649 return apply(detail::std_atan2{}, a, b);
1651template <
class A,
class B>
1652constexpr apply_t<detail::std_copysign, A, B> copysign(
const A &a,
const B &b) {
1653 return apply(detail::std_copysign{}, a, b);
1663template <
class A,
class B>
1664constexpr apply_t<detail::op_eq, A, B> equal(
const A &a,
const B &b) {
1665 return apply(detail::op_eq{}, a, b);
1667template <
class A,
class B>
1668constexpr apply_t<detail::op_ne, A, B> nequal(
const A &a,
const B &b) {
1669 return apply(detail::op_ne{}, a, b);
1671template <
class A,
class B>
1672constexpr apply_t<detail::op_lt, A, B> less(
const A &a,
const B &b) {
1673 return apply(detail::op_lt{}, a, b);
1675template <
class A,
class B>
1676constexpr apply_t<detail::op_gt, A, B> greater(
const A &a,
const B &b) {
1677 return apply(detail::op_gt{}, a, b);
1679template <
class A,
class B>
1680constexpr apply_t<detail::op_le, A, B> lequal(
const A &a,
const B &b) {
1681 return apply(detail::op_le{}, a, b);
1683template <
class A,
class B>
1684constexpr apply_t<detail::op_ge, A, B> gequal(
const A &a,
const B &b) {
1685 return apply(detail::op_ge{}, a, b);
1695template <
class A,
class B>
1696constexpr apply_t<detail::min, A, B> min(
const A &a,
const B &b) {
1697 return apply(detail::min{}, a, b);
1699template <
class A,
class B>
1700constexpr apply_t<detail::max, A, B> max(
const A &a,
const B &b) {
1701 return apply(detail::max{}, a, b);
1706template <
class X,
class L,
class H>
1707constexpr apply_t<detail::clamp, X, L, H>
clamp(
const X &x,
const L &l,
1715template <
class P,
class A,
class B>
1716constexpr apply_t<detail::select, P, A, B>
select(
const P &p,
const A &a,
1724template <
class A,
class B,
class T>
1725constexpr apply_t<detail::lerp, A, B, T>
lerp(
const A &a,
const B &b,
1741 return a.x * b.y - a.y * b.x;
1748 return {-a * b.y, a * b.x};
1755 return {a.y * b, -a.x * b};
1763 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};
1769template <
class T,
int M>
1776template <
class T,
int M>
1783template <
class T,
int M>
1792template <
class T,
int M>
1801template <
class T,
int M>
1809template <
class T,
int M>
1816template <
class T,
int M>
1819 return d > 1 ? 0 : std::acos(d < -1 ? -1 : d);
1824template <
class T,
int M>
1834 const T s = std::sin(a), c = std::cos(a);
1835 return {v.x * c - v.y * s, v.x * s + v.y * c};
1843 const T s = std::sin(a), c = std::cos(a);
1844 return {v.x, v.y * c - v.z * s, v.y * s + v.z * c};
1852 const T s = std::sin(a), c = std::cos(a);
1853 return {v.x * c + v.z * s, v.y, -v.x * s + v.z * c};
1861 const T s = std::sin(a), c = std::cos(a);
1862 return {v.x * c - v.y * s, v.x * s + v.y * c, v.z};
1867template <
class T,
int M>
1876template <
class T,
int M>
1880 : a * (std::sin(th * (1 - t)) / std::sin(th)) +
1881 b * (std::sin(th * t) / std::sin(th));
1898 return {-q.x, -q.y, -q.z, q.w};
1916 const auto v = q.xyz();
1917 const auto vv =
length(v);
1918 return std::exp(q.w) *
1919 vec<T, 4>{v * (vv > 0 ? std::sin(vv) / vv : 0), std::cos(vv)};
1928 const auto v = q.xyz();
1930 return {v * (vv > 0 ? std::acos(q.w / qq) / vv : 0), std::log(qq)};
1937 const auto v = q.xyz();
1938 const auto vv =
length(v), qq =
length(q), th = std::acos(q.w / qq);
1939 return std::pow(qq, p) *
1940 vec<T, 4>{v * (vv > 0 ? std::sin(p * th) / vv : 0), std::cos(p * th)};
1949 return {a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y,
1950 a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z,
1951 a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x,
1952 a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z};
1957template <
class T,
class... R>
1973 return {q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z,
1974 (q.x * q.y + q.z * q.w) * 2, (q.z * q.x - q.y * q.w) * 2};
1981 return {(q.x * q.y - q.z * q.w) * 2,
1982 q.w * q.w - q.x * q.x + q.y * q.y - q.z * q.z,
1983 (q.y * q.z + q.x * q.w) * 2};
1990 return {(q.z * q.x + q.y * q.w) * 2, (q.y * q.z - q.x * q.w) * 2,
1991 q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z};
2013 return std::atan2(
length(q.xyz()), q.w) * 2;
2029 return nlerp(a,
dot(a, b) < 0 ? -b : b, t);
2036 return slerp(a,
dot(a, b) < 0 ? -b : b, t);
2044 return {axis * std::sin(
angle / 2), std::cos(
angle / 2)};
2065template <
class T,
int M>
2069template <
class T,
int M>
2070constexpr vec<T, M> mul(
const T &b,
const vec<T, M> &a) {
2073template <
class T,
int M,
int N>
2074constexpr mat<T, M, N> mul(
const mat<T, M, N> &a,
const T &b) {
2077template <
class T,
int M,
int N>
2078constexpr mat<T, M, N> mul(
const T &b,
const mat<T, M, N> &a) {
2081template <
class T,
int M>
2082constexpr vec<T, M> mul(
const vec<T, M> &a,
const vec<T, M> &b) {
2085template <
class T,
int M>
2086constexpr vec<T, M> mul(
const mat<T, M, 1> &a,
const vec<T, 1> &b) {
2089template <
class T,
int M>
2090constexpr vec<T, M> mul(
const mat<T, M, 2> &a,
const vec<T, 2> &b) {
2091 return a.x * b.x + a.y * b.y;
2093template <
class T,
int M>
2094constexpr vec<T, M> mul(
const mat<T, M, 3> &a,
const vec<T, 3> &b) {
2095 return a.x * b.x + a.y * b.y + a.z * b.z;
2097template <
class T,
int M>
2098constexpr vec<T, M> mul(
const mat<T, M, 4> &a,
const vec<T, 4> &b) {
2099 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
2101template <
class T,
int M,
int N>
2102constexpr mat<T, M, 1> mul(
const mat<T, M, N> &a,
const mat<T, N, 1> &b) {
2103 return {mul(a, b.x)};
2105template <
class T,
int M,
int N>
2106constexpr mat<T, M, 2> mul(
const mat<T, M, N> &a,
const mat<T, N, 2> &b) {
2107 return {mul(a, b.x), mul(a, b.y)};
2109template <
class T,
int M,
int N>
2110constexpr mat<T, M, 3> mul(
const mat<T, M, N> &a,
const mat<T, N, 3> &b) {
2111 return {mul(a, b.x), mul(a, b.y), mul(a, b.z)};
2113template <
class T,
int M,
int N>
2114constexpr mat<T, M, 4> mul(
const mat<T, M, N> &a,
const mat<T, N, 4> &b) {
2115 return {mul(a, b.x), mul(a, b.y), mul(a, b.z), mul(a, b.w)};
2117template <
class T,
int M,
int N,
int P>
2118constexpr vec<T, M> mul(
const mat<T, M, N> &a,
const mat<T, N, P> &b,
2119 const vec<T, P> &c) {
2120 return mul(mul(a, b), c);
2122template <
class T,
int M,
int N,
int P,
int Q>
2123constexpr mat<T, M, Q> mul(
const mat<T, M, N> &a,
const mat<T, N, P> &b,
2124 const mat<T, P, Q> &c) {
2125 return mul(mul(a, b), c);
2127template <
class T,
int M,
int N,
int P,
int Q>
2128constexpr vec<T, M> mul(
const mat<T, M, N> &a,
const mat<T, N, P> &b,
2129 const mat<T, P, Q> &c,
const vec<T, Q> &d) {
2130 return mul(mul(a, b, c), d);
2132template <
class T,
int M,
int N,
int P,
int Q,
int R>
2133constexpr mat<T, M, R> mul(
const mat<T, M, N> &a,
const mat<T, N, P> &b,
2134 const mat<T, P, Q> &c,
const mat<T, Q, R> &d) {
2135 return mul(mul(a, b, c), d);
2137template <
class T,
int M>
2138constexpr mat<T, M, 1> outerprod(
const vec<T, M> &a,
const vec<T, 1> &b) {
2141template <
class T,
int M>
2142constexpr mat<T, M, 2> outerprod(
const vec<T, M> &a,
const vec<T, 2> &b) {
2143 return {a * b.x, a * b.y};
2145template <
class T,
int M>
2146constexpr mat<T, M, 3> outerprod(
const vec<T, M> &a,
const vec<T, 3> &b) {
2147 return {a * b.x, a * b.y, a * b.z};
2149template <
class T,
int M>
2150constexpr mat<T, M, 4> outerprod(
const vec<T, M> &a,
const vec<T, 4> &b) {
2151 return {a * b.x, a * b.y, a * b.z, a * b.w};
2154constexpr vec<T, 1> diagonal(
const mat<T, 1, 1> &a) {
2158constexpr vec<T, 2> diagonal(
const mat<T, 2, 2> &a) {
2159 return {a.x.x, a.y.y};
2162constexpr vec<T, 3> diagonal(
const mat<T, 3, 3> &a) {
2163 return {a.x.x, a.y.y, a.z.z};
2166constexpr vec<T, 4> diagonal(
const mat<T, 4, 4> &a) {
2167 return {a.x.x, a.y.y, a.z.z, a.w.w};
2169template <
class T,
int N>
2170constexpr T trace(
const mat<T, N, N> &a) {
2171 return sum(diagonal(a));
2173template <
class T,
int M>
2174constexpr mat<T, M, 1> transpose(
const mat<T, 1, M> &m) {
2177template <
class T,
int M>
2178constexpr mat<T, M, 2> transpose(
const mat<T, 2, M> &m) {
2179 return {m.row(0), m.row(1)};
2181template <
class T,
int M>
2182constexpr mat<T, M, 3> transpose(
const mat<T, 3, M> &m) {
2183 return {m.row(0), m.row(1), m.row(2)};
2185template <
class T,
int M>
2186constexpr mat<T, M, 4> transpose(
const mat<T, 4, M> &m) {
2187 return {m.row(0), m.row(1), m.row(2), m.row(3)};
2189template <
class T,
int M>
2190constexpr mat<T, 1, M> transpose(
const vec<T, M> &m) {
2191 return transpose(mat<T, M, 1>(m));
2194constexpr mat<T, 1, 1> adjugate(
const mat<T, 1, 1> &a) {
2195 return {vec<T, 1>{1}};
2198constexpr mat<T, 2, 2> adjugate(
const mat<T, 2, 2> &a) {
2199 return {{a.y.y, -a.x.y}, {-a.y.x, a.x.x}};
2202constexpr mat<T, 3, 3> adjugate(
const mat<T, 3, 3> &a);
2204constexpr mat<T, 4, 4> adjugate(
const mat<T, 4, 4> &a);
2205template <
class T,
int N>
2206constexpr mat<T, N, N> comatrix(
const mat<T, N, N> &a) {
2207 return transpose(adjugate(a));
2210constexpr T determinant(
const mat<T, 1, 1> &a) {
2214constexpr T determinant(
const mat<T, 2, 2> &a) {
2215 return a.x.x * a.y.y - a.x.y * a.y.x;
2218constexpr T determinant(
const mat<T, 3, 3> &a) {
2219 return a.x.x * (a.y.y * a.z.z - a.z.y * a.y.z) +
2220 a.x.y * (a.y.z * a.z.x - a.z.z * a.y.x) +
2221 a.x.z * (a.y.x * a.z.y - a.z.x * a.y.y);
2224constexpr T determinant(
const mat<T, 4, 4> &a);
2225template <
class T,
int N>
2226constexpr mat<T, N, N> inverse(
const mat<T, N, N> &a) {
2227 return adjugate(a) / determinant(a);
2236template <
class T,
int M>
2237T *begin(vec<T, M> &a) {
2240template <
class T,
int M>
2241const T *begin(
const vec<T, M> &a) {
2244template <
class T,
int M>
2245T *end(vec<T, M> &a) {
2246 return begin(a) + M;
2248template <
class T,
int M>
2249const T *end(
const vec<T, M> &a) {
2250 return begin(a) + M;
2252template <
class T,
int M,
int N>
2253vec<T, M> *begin(mat<T, M, N> &a) {
2256template <
class T,
int M,
int N>
2257const vec<T, M> *begin(
const mat<T, M, N> &a) {
2260template <
class T,
int M,
int N>
2261vec<T, M> *end(mat<T, M, N> &a) {
2262 return begin(a) + N;
2264template <
class T,
int M,
int N>
2265const vec<T, M> *end(
const mat<T, M, N> &a) {
2266 return begin(a) + N;
2285mat<T, 4, 4> translation_matrix(
const vec<T, 3> &translation) {
2286 return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {translation, 1}};
2289mat<T, 4, 4> rotation_matrix(
const vec<T, 4> &rotation) {
2290 return {{
qxdir(rotation), 0},
2291 {
qydir(rotation), 0},
2292 {
qzdir(rotation), 0},
2296mat<T, 4, 4> scaling_matrix(
const vec<T, 3> &scaling) {
2297 return {{scaling.x, 0, 0, 0},
2298 {0, scaling.y, 0, 0},
2299 {0, 0, scaling.z, 0},
2303mat<T, 4, 4> pose_matrix(
const vec<T, 4> &q,
const vec<T, 3> &p) {
2307mat<T, 4, 4> lookat_matrix(
const vec<T, 3> &eye,
const vec<T, 3> ¢er,
2308 const vec<T, 3> &view_y_dir, fwd_axis fwd = neg_z);
2310mat<T, 4, 4> frustum_matrix(T x0, T x1, T y0, T y1, T n, T f,
2311 fwd_axis a = neg_z, z_range z = neg_one_to_one);
2313mat<T, 4, 4> perspective_matrix(T fovy, T aspect, T n, T f, fwd_axis a = neg_z,
2314 z_range z = neg_one_to_one) {
2315 T y = n * std::tan(fovy / 2), x = y * aspect;
2316 return frustum_matrix(-x, x, -y, y, n, f, a, z);
2328 vec<T, 1> operator()(
const std::array<T, 1> &a)
const {
return {a[0]}; }
2332 vec<T, 2> operator()(
const std::array<T, 2> &a)
const {
return {a[0], a[1]}; }
2336 vec<T, 3> operator()(
const std::array<T, 3> &a)
const {
2337 return {a[0], a[1], a[2]};
2342 vec<T, 4> operator()(
const std::array<T, 4> &a)
const {
2343 return {a[0], a[1], a[2], a[3]};
2349 std::array<T, 1> operator()(
const vec<T, 1> &a)
const {
return {a[0]}; }
2353 std::array<T, 2> operator()(
const vec<T, 2> &a)
const {
return {a[0], a[1]}; }
2357 std::array<T, 3> operator()(
const vec<T, 3> &a)
const {
2358 return {a[0], a[1], a[2]};
2363 std::array<T, 4> operator()(
const vec<T, 4> &a)
const {
2364 return {a[0], a[1], a[2], a[3]};
2369#ifdef MANIFOLD_DEBUG
2371std::ostream &operator<<(std::ostream &out,
const vec<T, 1> &v) {
2372 return out <<
'{' << v[0] <<
'}';
2375std::ostream &operator<<(std::ostream &out,
const vec<T, 2> &v) {
2376 return out <<
'{' << v[0] <<
',' << v[1] <<
'}';
2379std::ostream &operator<<(std::ostream &out,
const vec<T, 3> &v) {
2380 return out <<
'{' << v[0] <<
',' << v[1] <<
',' << v[2] <<
'}';
2383std::ostream &operator<<(std::ostream &out,
const vec<T, 4> &v) {
2384 return out <<
'{' << v[0] <<
',' << v[1] <<
',' << v[2] <<
',' << v[3] <<
'}';
2387template <
class T,
int M>
2388std::ostream &operator<<(std::ostream &out,
const mat<T, M, 1> &m) {
2389 return out <<
'{' << m[0] <<
'}';
2391template <
class T,
int M>
2392std::ostream &operator<<(std::ostream &out,
const mat<T, M, 2> &m) {
2393 return out <<
'{' << m[0] <<
',' << m[1] <<
'}';
2395template <
class T,
int M>
2396std::ostream &operator<<(std::ostream &out,
const mat<T, M, 3> &m) {
2397 return out <<
'{' << m[0] <<
',' << m[1] <<
',' << m[2] <<
'}';
2399template <
class T,
int M>
2400std::ostream &operator<<(std::ostream &out,
const mat<T, M, 4> &m) {
2401 return out <<
'{' << m[0] <<
',' << m[1] <<
',' << m[2] <<
',' << m[3] <<
'}';
2413struct hash<linalg::vec<T, 1>> {
2420struct hash<linalg::vec<T, 2>> {
2423 return h(v.x) ^ (h(v.y) << 1);
2427struct hash<linalg::vec<T, 3>> {
2430 return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2);
2434struct hash<linalg::vec<T, 4>> {
2437 return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2) ^ (h(v.w) << 3);
2441template <
class T,
int M>
2442struct hash<linalg::mat<T, M, 1>> {
2444 std::hash<linalg::vec<T, M>> h;
2448template <
class T,
int M>
2449struct hash<linalg::mat<T, M, 2>> {
2451 std::hash<linalg::vec<T, M>> h;
2452 return h(v.x) ^ (h(v.y) << M);
2455template <
class T,
int M>
2456struct hash<linalg::mat<T, M, 3>> {
2458 std::hash<linalg::vec<T, M>> h;
2459 return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2));
2462template <
class T,
int M>
2463struct hash<linalg::mat<T, M, 4>> {
2465 std::hash<linalg::vec<T, M>> h;
2466 return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2)) ^ (h(v.w) << (M * 3));
2475 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,
2476 a.x.y * a.y.z - a.y.y * a.x.z},
2477 {a.y.z * a.z.x - a.z.z * a.y.x, a.z.z * a.x.x - a.x.z * a.z.x,
2478 a.x.z * a.y.x - a.y.z * a.x.x},
2479 {a.y.x * a.z.y - a.z.x * a.y.y, a.z.x * a.x.y - a.x.x * a.z.y,
2480 a.x.x * a.y.y - a.y.x * a.x.y}};
2485 return {{a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
2486 a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
2487 a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w,
2488 a.x.y * a.w.z * a.z.w + a.z.y * a.x.z * a.w.w +
2489 a.w.y * a.z.z * a.x.w - a.w.y * a.x.z * a.z.w -
2490 a.z.y * a.w.z * a.x.w - a.x.y * a.z.z * a.w.w,
2491 a.x.y * a.y.z * a.w.w + a.w.y * a.x.z * a.y.w +
2492 a.y.y * a.w.z * a.x.w - a.x.y * a.w.z * a.y.w -
2493 a.y.y * a.x.z * a.w.w - a.w.y * a.y.z * a.x.w,
2494 a.x.y * a.z.z * a.y.w + a.y.y * a.x.z * a.z.w +
2495 a.z.y * a.y.z * a.x.w - a.x.y * a.y.z * a.z.w -
2496 a.z.y * a.x.z * a.y.w - a.y.y * a.z.z * a.x.w},
2497 {a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
2498 a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
2499 a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x,
2500 a.x.z * a.z.w * a.w.x + a.w.z * a.x.w * a.z.x +
2501 a.z.z * a.w.w * a.x.x - a.x.z * a.w.w * a.z.x -
2502 a.z.z * a.x.w * a.w.x - a.w.z * a.z.w * a.x.x,
2503 a.x.z * a.w.w * a.y.x + a.y.z * a.x.w * a.w.x +
2504 a.w.z * a.y.w * a.x.x - a.x.z * a.y.w * a.w.x -
2505 a.w.z * a.x.w * a.y.x - a.y.z * a.w.w * a.x.x,
2506 a.x.z * a.y.w * a.z.x + a.z.z * a.x.w * a.y.x +
2507 a.y.z * a.z.w * a.x.x - a.x.z * a.z.w * a.y.x -
2508 a.y.z * a.x.w * a.z.x - a.z.z * a.y.w * a.x.x},
2509 {a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
2510 a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
2511 a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y,
2512 a.x.w * a.w.x * a.z.y + a.z.w * a.x.x * a.w.y +
2513 a.w.w * a.z.x * a.x.y - a.x.w * a.z.x * a.w.y -
2514 a.w.w * a.x.x * a.z.y - a.z.w * a.w.x * a.x.y,
2515 a.x.w * a.y.x * a.w.y + a.w.w * a.x.x * a.y.y +
2516 a.y.w * a.w.x * a.x.y - a.x.w * a.w.x * a.y.y -
2517 a.y.w * a.x.x * a.w.y - a.w.w * a.y.x * a.x.y,
2518 a.x.w * a.z.x * a.y.y + a.y.w * a.x.x * a.z.y +
2519 a.z.w * a.y.x * a.x.y - a.x.w * a.y.x * a.z.y -
2520 a.z.w * a.x.x * a.y.y - a.y.w * a.z.x * a.x.y},
2521 {a.y.x * a.w.y * a.z.z + a.z.x * a.y.y * a.w.z +
2522 a.w.x * a.z.y * a.y.z - a.y.x * a.z.y * a.w.z -
2523 a.w.x * a.y.y * a.z.z - a.z.x * a.w.y * a.y.z,
2524 a.x.x * a.z.y * a.w.z + a.w.x * a.x.y * a.z.z +
2525 a.z.x * a.w.y * a.x.z - a.x.x * a.w.y * a.z.z -
2526 a.z.x * a.x.y * a.w.z - a.w.x * a.z.y * a.x.z,
2527 a.x.x * a.w.y * a.y.z + a.y.x * a.x.y * a.w.z +
2528 a.w.x * a.y.y * a.x.z - a.x.x * a.y.y * a.w.z -
2529 a.w.x * a.x.y * a.y.z - a.y.x * a.w.y * a.x.z,
2530 a.x.x * a.y.y * a.z.z + a.z.x * a.x.y * a.y.z +
2531 a.y.x * a.z.y * a.x.z - a.x.x * a.z.y * a.y.z -
2532 a.y.x * a.x.y * a.z.z - a.z.x * a.y.y * a.x.z}};
2536constexpr T linalg::determinant(
const mat<T, 4, 4> &a) {
2537 return a.x.x * (a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
2538 a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
2539 a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w) +
2540 a.x.y * (a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
2541 a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
2542 a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x) +
2543 a.x.z * (a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
2544 a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
2545 a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y) +
2546 a.x.w * (a.y.x * a.w.y * a.z.z + a.z.x * a.y.y * a.w.z +
2547 a.w.x * a.z.y * a.y.z - a.y.x * a.z.y * a.w.z -
2548 a.w.x * a.y.y * a.z.z - a.z.x * a.w.y * a.y.z);
2553 const vec<T, 3> &dest) {
2554 T cosTheta =
dot(orig, dest);
2555 if (cosTheta >= 1 - std::numeric_limits<T>::epsilon()) {
2556 return {0, 0, 0, 1};
2558 if (cosTheta < -1 + std::numeric_limits<T>::epsilon()) {
2559 vec<T, 3> axis =
cross(vec<T, 3>(0, 0, 1), orig);
2560 if (
length2(axis) < std::numeric_limits<T>::epsilon())
2561 axis =
cross(vec<T, 3>(1, 0, 0), orig);
2563 3.14159265358979323846264338327950288);
2565 vec<T, 3> axis =
cross(orig, dest);
2566 T s = std::sqrt((1 + cosTheta) * 2);
2567 return {axis * (1 / s), s * 0.5};
2572 const vec<T, 4> q{m.x.x - m.y.y - m.z.z, m.y.y - m.x.x - m.z.z,
2573 m.z.z - m.x.x - m.y.y, m.x.x + m.y.y + m.z.z},
2574 s[]{{1, m.x.y + m.y.x, m.z.x + m.x.z, m.y.z - m.z.y},
2575 {m.x.y + m.y.x, 1, m.y.z + m.z.y, m.z.x - m.x.z},
2576 {m.x.z + m.z.x, m.y.z + m.z.y, 1, m.x.y - m.y.x},
2577 {m.y.z - m.z.y, m.z.x - m.x.z, m.x.y - m.y.x, 1}};
2578 return copysign(
normalize(sqrt(max(T(0), T(1) + q))), s[argmax(q)]);
2583 const vec<T, 3> ¢er,
2584 const vec<T, 3> &view_y_dir,
2586 const vec<T, 3> f =
normalize(center - eye), z = a == pos_z ? f : -f,
2588 return inverse(mat<T, 4, 4>{{x, 0}, {y, 0}, {z, 0}, {eye, 1}});
2593 fwd_axis a, z_range z) {
2594 const T s = a == pos_z ? T(1) : T(-1), o = z == neg_one_to_one ? n : 0;
2595 return {{2 * n / (x1 - x0), 0, 0, 0},
2596 {0, 2 * n / (y1 - y0), 0, 0},
2597 {-s * (x0 + x1) / (x1 - x0), -s * (y0 + y1) / (y1 - y0),
2598 s * (f + o) / (f - n), s},
2599 {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:1997
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:2035
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:2012
constexpr vec< T, 3 > qzdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,0,1})
Definition linalg.h:1989
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:2028
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:2020
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:2043
constexpr vec< T, 3 > qxdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {1,0,0})
Definition linalg.h:1972
constexpr vec< T, 3 > qrot(const vec< T, 4 > &q, const vec< T, 3 > &v)
Rotate a vector by a quaternion.
Definition linalg.h:2004
constexpr vec< T, 3 > qydir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,1,0})
Definition linalg.h:1980
vec< T, 4 > qinv(const vec< T, 4 > &q)
inverse or reciprocal of quaternion q (undefined for zero-length quaternions)
Definition linalg.h:1906
vec< T, 4 > qexp(const vec< T, 4 > &q)
exponential of quaternion q
Definition linalg.h:1915
vec< T, 4 > qpow(const vec< T, 4 > &q, const T &p)
quaternion q raised to the exponent p
Definition linalg.h:1936
vec< T, 4 > qlog(const vec< T, 4 > &q)
logarithm of quaternion q
Definition linalg.h:1927
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:1948
constexpr vec< T, 4 > qconj(const vec< T, 4 > &q)
conjugate of quaternion q
Definition linalg.h:1897
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:1707
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:1716
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:1725
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:1528
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:1544
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:1536
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:1851
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:1833
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:1802
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:1842
constexpr T length2(const vec< T, M > &a)
square of the length or magnitude of vector a
Definition linalg.h:1777
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:1770
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:1868
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:1793
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:1877
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:1825
T uangle(const vec< T, M > &a, const vec< T, M > &b)
Return the angle in radians between two unit vectors.
Definition linalg.h:1817
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:1740
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:1860
T length(const vec< T, M > &a)
length or magnitude of a vector a
Definition linalg.h:1784
T distance(const vec< T, M > &a, const vec< T, M > &b)
Euclidean distance between points a and b
Definition linalg.h:1810