48#if defined(_MSC_VER) && (_MSC_VER <= 1900)
49#define LINALG_CONSTEXPR14
51#define LINALG_CONSTEXPR14 constexpr
57template <
class T,
int M>
62template <
class T,
int M,
int N>
67template <
class T,
class U>
70template <
class T,
class U>
71using conv_t =
typename std::enable_if<!std::is_same<T, U>::value,
73 std::declval<U>()))>::type;
78template <
class T,
int M>
82template <
class T,
int M,
int N>
94constexpr bool operator==(
const ord<T>& o, std::nullptr_t) {
98constexpr bool operator!=(
const ord<T>& o, std::nullptr_t) {
102constexpr bool operator<(
const ord<T>& o, std::nullptr_t) {
106constexpr bool operator>(
const ord<T>& o, std::nullptr_t) {
110constexpr bool operator<=(
const ord<T>& o, std::nullptr_t) {
114constexpr bool operator>=(
const ord<T>& o, std::nullptr_t) {
119template <
class A,
class B>
132 return !(a.x == b.x) ?
ord<T>{a.x, b.x} :
ord<T>{a.y, b.y};
139 return !(a.x == b.x) ?
ord<T>{a.x, b.x}
140 : !(a.y == b.y) ?
ord<T>{a.y, b.y}
148 return !(a.x == b.x) ?
ord<T>{a.x, b.x}
149 : !(a.y == b.y) ?
ord<T>{a.y, b.y}
150 : !(a.z == b.z) ?
ord<T>{a.z, b.z}
154template <
class T,
int M>
159 return compare(a.x, b.x);
162template <
class T,
int M>
167 return a.x != b.x ? compare(a.x, b.x) : compare(a.y, b.y);
170template <
class T,
int M>
175 return a.x != b.x ? compare(a.x, b.x)
176 : a.y != b.y ? compare(a.y, b.y)
180template <
class T,
int M>
185 return a.x != b.x ? compare(a.x, b.x)
186 : a.y != b.y ? compare(a.y, b.y)
187 : a.z != b.z ? compare(a.z, b.z)
199 constexpr auto operator()(A& a)
const ->
decltype(a.x) {
206 constexpr auto operator()(A& a)
const ->
decltype(a.y) {
213 constexpr auto operator()(A& a)
const ->
decltype(a.z) {
220 constexpr auto operator()(A& a)
const ->
decltype(a.w) {
228template <
int A,
int N>
250template <
int A,
int B>
252template <
class T,
int M,
int... I>
256template <
class T,
int M,
int N,
int... I,
int... J>
257mat<T,
sizeof...(I),
sizeof...(J)>
constexpr swizzle(
const mat<T, M, N>& m,
263template <
class F,
class... T>
264using ret_t =
decltype(std::declval<F>()(std::declval<T>()...));
274template <
class T,
class... U>
275struct scalars<T, U...> : std::conditional<std::is_arithmetic<T>::value,
276 scalars<U...>, empty>::type {};
278using scalars_t =
typename scalars<T...>::type;
282template <
class F,
class Void,
class... T>
284template <
class F,
int M,
class A>
287 enum { size = M, mm = 0 };
293template <
class F,
int M,
class A,
class B>
296 enum { size = M, mm = 0 };
303template <
class F,
int M,
class A,
class B>
306 enum { size = M, mm = 0 };
312template <
class F,
int M,
class A,
class B>
315 enum { size = M, mm = 0 };
321template <
class F,
int M,
class A,
class B,
class C>
324 enum { size = M, mm = 0 };
331template <
class F,
int M,
class A,
class B,
class C>
334 enum { size = M, mm = 0 };
341template <
class F,
int M,
class A,
class B,
class C>
344 enum { size = M, mm = 0 };
351template <
class F,
int M,
class A,
class B,
class C>
354 enum { size = M, mm = 0 };
360template <
class F,
int M,
class A,
class B,
class C>
363 enum { size = M, mm = 0 };
370template <
class F,
int M,
class A,
class B,
class C>
373 enum { size = M, mm = 0 };
379template <
class F,
int M,
class A,
class B,
class C>
382 enum { size = M, mm = 0 };
388template <
class F,
int M,
int N,
class A>
391 enum { size = N, mm = 0 };
398template <
class F,
int M,
int N,
class A,
class B>
401 enum { size = N, mm = 1 };
409template <
class F,
int M,
int N,
class A,
class B>
412 enum { size = N, mm = 0 };
419template <
class F,
int M,
int N,
class A,
class B>
422 enum { size = N, mm = 0 };
429template <
class F,
class... A>
430struct apply<F, scalars_t<A...>, A...> {
431 using type = ret_t<F, A...>;
432 enum { size = 0, mm = 0 };
433 static constexpr type impl(
seq<>, F f, A... a) {
return f(a...); }
438 template <
class A,
class B>
439 constexpr auto operator()(A a, B b)
const ->
440 typename std::remove_reference<
decltype(a < b ? a : b)>::type {
441 return a < b ? a : b;
445 template <
class A,
class B>
446 constexpr auto operator()(A a, B b)
const ->
447 typename std::remove_reference<
decltype(a < b ? b : a)>::type {
448 return a < b ? b : a;
452 template <
class A,
class B,
class C>
453 constexpr auto operator()(A a, B b, C c)
const ->
454 typename std::remove_reference<
decltype(a < b ? b
457 return a < b ? b : a < c ? a : c;
461 template <
class A,
class B,
class C>
462 constexpr auto operator()(A a, B b, C c)
const ->
463 typename std::remove_reference<
decltype(a ? b : c)>::type {
468 template <
class A,
class B,
class C>
469 constexpr auto operator()(A a, B b, C c)
const
470 ->
decltype(a * (1 - c) + b * c) {
471 return a * (1 - c) + b * c;
478 constexpr auto operator()(A a)
const ->
decltype(+a) {
484 constexpr auto operator()(A a)
const ->
decltype(-a) {
490 constexpr auto operator()(A a)
const ->
decltype(!a) {
496 constexpr auto operator()(A a)
const ->
decltype(~(a)) {
501 template <
class A,
class B>
502 constexpr auto operator()(A a, B b)
const ->
decltype(a * b) {
507 template <
class A,
class B>
508 constexpr auto operator()(A a, B b)
const ->
decltype(a / b) {
513 template <
class A,
class B>
514 constexpr auto operator()(A a, B b)
const ->
decltype(a % b) {
519 template <
class A,
class B>
520 constexpr auto operator()(A a, B b)
const ->
decltype(a + b) {
525 template <
class A,
class B>
526 constexpr auto operator()(A a, B b)
const ->
decltype(a - b) {
531 template <
class A,
class B>
532 constexpr auto operator()(A a, B b)
const ->
decltype(a << b) {
537 template <
class A,
class B>
538 constexpr auto operator()(A a, B b)
const ->
decltype(a >> b) {
543 template <
class A,
class B>
544 constexpr auto operator()(A a, B b)
const ->
decltype(a < b) {
549 template <
class A,
class B>
550 constexpr auto operator()(A a, B b)
const ->
decltype(a > b) {
555 template <
class A,
class B>
556 constexpr auto operator()(A a, B b)
const ->
decltype(a <= b) {
561 template <
class A,
class B>
562 constexpr auto operator()(A a, B b)
const ->
decltype(a >= b) {
567 template <
class A,
class B>
568 constexpr auto operator()(A a, B b)
const ->
decltype(a == b) {
573 template <
class A,
class B>
574 constexpr auto operator()(A a, B b)
const ->
decltype(a != b) {
579 template <
class A,
class B>
580 constexpr auto operator()(A a, B b)
const ->
decltype(a & b) {
585 template <
class A,
class B>
586 constexpr auto operator()(A a, B b)
const ->
decltype(a ^ b) {
591 template <
class A,
class B>
592 constexpr auto operator()(A a, B b)
const ->
decltype(a | b) {
597 template <
class A,
class B>
598 constexpr auto operator()(A a, B b)
const ->
decltype(a && b) {
603 template <
class A,
class B>
604 constexpr auto operator()(A a, B b)
const ->
decltype(a || b) {
612 constexpr auto operator()(A a)
const ->
decltype(std::isfinite(a)) {
613 return std::isfinite(a);
618 constexpr auto operator()(A a)
const ->
decltype(std::abs(a)) {
624 constexpr auto operator()(A a)
const ->
decltype(std::floor(a)) {
625 return std::floor(a);
630 constexpr auto operator()(A a)
const ->
decltype(std::ceil(a)) {
636 constexpr auto operator()(A a)
const ->
decltype(std::exp(a)) {
642 constexpr auto operator()(A a)
const ->
decltype(std::log(a)) {
648 constexpr auto operator()(A a)
const ->
decltype(std::log2(a)) {
654 constexpr auto operator()(A a)
const ->
decltype(std::log10(a)) {
655 return std::log10(a);
660 constexpr auto operator()(A a)
const ->
decltype(std::sqrt(a)) {
665 double operator()(
double a)
const {
return manifold::math::sin(a); }
668 double operator()(
double a)
const {
return manifold::math::cos(a); }
671 double operator()(
double a)
const {
return manifold::math::tan(a); }
674 double operator()(
double a)
const {
return manifold::math::asin(a); }
677 double operator()(
double a)
const {
return manifold::math::acos(a); }
680 double operator()(
double a)
const {
return manifold::math::atan(a); }
684 constexpr auto operator()(A a)
const ->
decltype(std::sinh(a)) {
690 constexpr auto operator()(A a)
const ->
decltype(std::cosh(a)) {
696 constexpr auto operator()(A a)
const ->
decltype(std::tanh(a)) {
702 constexpr auto operator()(A a)
const ->
decltype(std::round(a)) {
703 return std::round(a);
707 template <
class A,
class B>
708 constexpr auto operator()(A a, B b)
const ->
decltype(std::fmod(a, b)) {
709 return std::fmod(a, b);
713 template <
class A,
class B>
714 constexpr auto operator()(A a, B b)
const ->
decltype(std::pow(a, b)) {
715 return std::pow(a, b);
719 double operator()(
double a,
double b)
const {
720 return manifold::math::atan2(a, b);
724 template <
class A,
class B>
725 constexpr auto operator()(A a, B b)
const ->
decltype(std::copysign(a, b)) {
726 return std::copysign(a, b);
833 constexpr vec() : x() {}
834 constexpr vec(
const T& x_) : x(x_) {}
838 constexpr explicit vec(
const vec<U, 1>& v) : vec(
static_cast<T
>(v.x)) {}
839 constexpr const T& operator[](
int)
const {
return x; }
840 LINALG_CONSTEXPR14 T& operator[](
int) {
return x; }
842 template <
class U,
class = detail::conv_t<vec, U>>
844 template <
class U,
class = detail::conv_t<U, vec>>
845 constexpr operator U()
const {
852 constexpr vec() : x(), y() {}
853 constexpr vec(
const T& x_,
const T& y_) : x(x_), y(y_) {}
854 constexpr explicit vec(
const T& s) : vec(s, s) {}
855 constexpr explicit vec(
const T* p) : vec(p[0], p[1]) {}
856 template <
class U,
int N>
857 constexpr explicit vec(
const vec<U, N>& v)
858 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y)) {
861 "You must give extra arguments if your input vector is shorter.");
863 constexpr const T& operator[](
int i)
const {
return i == 0 ? x : y; }
864 LINALG_CONSTEXPR14 T& operator[](
int i) {
return i == 0 ? x : y; }
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(), z() {}
877 constexpr vec(
const T& x_,
const T& y_,
const T& z_) : x(x_), y(y_), z(z_) {}
878 constexpr vec(
const vec<T, 2>& xy,
const T& z_) : vec(xy.x, xy.y, z_) {}
879 constexpr explicit vec(
const T& s) : vec(s, s, s) {}
880 constexpr explicit vec(
const T* p) : vec(p[0], p[1], p[2]) {}
881 template <
class U,
int N>
882 constexpr explicit vec(
const vec<U, N>& v)
883 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y),
static_cast<T
>(v.z)) {
886 "You must give extra arguments if your input vector is shorter.");
888 constexpr const T& operator[](
int i)
const {
889 return i == 0 ? x : i == 1 ? y : z;
891 LINALG_CONSTEXPR14 T& operator[](
int i) {
892 return i == 0 ? x : i == 1 ? y : z;
894 constexpr vec<T, 2> xy()
const {
return vec<T, 2>(x, y); }
895 constexpr vec<T, 2> yz()
const {
return vec<T, 2>(y, z); }
897 template <
class U,
class = detail::conv_t<vec, U>>
899 template <
class U,
class = detail::conv_t<U, vec>>
900 constexpr operator U()
const {
907 constexpr vec() : x(), y(), z(), w() {}
908 constexpr vec(
const T& x_,
const T& y_,
const T& z_,
const T& w_)
909 : x(x_), y(y_), z(z_), w(w_) {}
910 constexpr vec(
const vec<T, 2>& xy,
const T& z_,
const T& w_)
911 : vec(xy.x, xy.y, z_, w_) {}
912 constexpr vec(
const vec<T, 3>& xyz,
const T& w_)
913 : vec(xyz.x, xyz.y, xyz.z, w_) {}
914 constexpr explicit vec(
const T& s) : vec(s, s, s, s) {}
915 constexpr explicit vec(
const T* p) : vec(p[0], p[1], p[2], p[3]) {}
916 template <
class U,
int N>
917 constexpr explicit vec(
const vec<U, N>& v)
918 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y),
static_cast<T
>(v.z),
919 static_cast<T
>(v.w)) {
922 "You must give extra arguments if your input vector is shorter.");
924 constexpr const T& operator[](
int i)
const {
925 return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
927 LINALG_CONSTEXPR14 T& operator[](
int i) {
928 return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
930 constexpr vec<T, 2> xy()
const {
return vec<T, 2>(x, y); }
931 constexpr vec<T, 3> xyz()
const {
return vec<T, 3>(x, y, z); }
933 template <
class U,
class = detail::conv_t<vec, U>>
935 template <
class U,
class = detail::conv_t<U, vec>>
936 constexpr operator U()
const {
1036template <
class T,
int M>
1037struct mat<T, M, 1> {
1040 constexpr mat() : x() {}
1041 constexpr mat(
const V& x_) : x(x_) {}
1042 constexpr explicit mat(
const T& s) : x(s) {}
1043 constexpr explicit mat(
const T* p) : x(p + M * 0) {}
1045 constexpr explicit mat(
const mat<U, M, 1>& m) : mat(V(m.x)) {}
1046 constexpr vec<T, 1> row(
int i)
const {
return {x[i]}; }
1047 constexpr const V& operator[](
int)
const {
return x; }
1048 LINALG_CONSTEXPR14 V& operator[](
int) {
return x; }
1050 template <
class U,
class = detail::conv_t<mat, U>>
1052 template <
class U,
class = detail::conv_t<U, mat>>
1053 constexpr operator U()
const {
1057template <
class T,
int M>
1058struct mat<T, M, 2> {
1061 constexpr mat() : x(), y() {}
1062 constexpr mat(
const V& x_,
const V& y_) : x(x_), y(y_) {}
1063 constexpr explicit mat(
const T& s) : x(s), y(s) {}
1064 constexpr explicit mat(
const T* p) : x(p + M * 0), y(p + M * 1) {}
1065 template <
class U,
int N,
int P>
1066 constexpr explicit mat(
const mat<U, N, P>& m) : mat(V(m.x), V(m.y)) {
1067 static_assert(P >= 2,
"Input matrix dimensions must be at least as big.");
1069 constexpr vec<T, 2> row(
int i)
const {
return {x[i], y[i]}; }
1070 constexpr const V& operator[](
int j)
const {
return j == 0 ? x : y; }
1071 LINALG_CONSTEXPR14 V& operator[](
int j) {
return j == 0 ? x : y; }
1073 template <
class U,
class = detail::conv_t<mat, U>>
1075 template <
class U,
class = detail::conv_t<U, mat>>
1076 constexpr operator U()
const {
1080template <
class T,
int M>
1081struct mat<T, M, 3> {
1084 constexpr mat() : x(), y(), z() {}
1085 constexpr mat(
const V& x_,
const V& y_,
const V& z_) : x(x_), y(y_), z(z_) {}
1086 constexpr mat(
const mat<T, M, 2>& m_,
const V& z_)
1087 : x(m_.x), y(m_.y), z(z_) {}
1088 constexpr explicit mat(
const T& s) : x(s), y(s), z(s) {}
1089 constexpr explicit mat(
const T* p)
1090 : x(p + M * 0), y(p + M * 1), z(p + M * 2) {}
1091 template <
class U,
int N,
int P>
1092 constexpr explicit mat(
const mat<U, N, P>& m) : mat(V(m.x), V(m.y), V(m.z)) {
1093 static_assert(P >= 3,
"Input matrix dimensions must be at least as big.");
1095 constexpr vec<T, 3> row(
int i)
const {
return {x[i], y[i], z[i]}; }
1096 constexpr const V& operator[](
int j)
const {
1097 return j == 0 ? x : j == 1 ? y : z;
1099 LINALG_CONSTEXPR14 V& operator[](
int j) {
1100 return j == 0 ? x : j == 1 ? y : z;
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, 4> {
1114 constexpr mat() : x(), y(), z(), w() {}
1115 constexpr mat(
const V& x_,
const V& y_,
const V& z_,
const V& w_)
1116 : x(x_), y(y_), z(z_), w(w_) {}
1117 constexpr mat(
const mat<T, M, 3>& m_,
const V& w_)
1118 : x(m_.x), y(m_.y), z(m_.z), w(w_) {}
1119 constexpr explicit mat(
const T& s) : x(s), y(s), z(s), w(s) {}
1120 constexpr explicit mat(
const T* p)
1121 : x(p + M * 0), y(p + M * 1), z(p + M * 2), w(p + M * 3) {}
1122 template <
class U,
int N,
int P>
1123 constexpr explicit mat(
const mat<U, N, P>& m)
1124 : mat(V(m.x), V(m.y), V(m.z), V(m.w)) {
1125 static_assert(P >= 4,
"Input matrix dimensions must be at least as big.");
1128 constexpr vec<T, 4> row(
int i)
const {
return {x[i], y[i], z[i], w[i]}; }
1129 constexpr const V& operator[](
int j)
const {
1130 return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
1132 LINALG_CONSTEXPR14 V& operator[](
int j) {
1133 return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
1136 template <
class U,
class = detail::conv_t<mat, U>>
1138 template <
class U,
class = detail::conv_t<U, mat>>
1139 constexpr operator U()
const {
1152 constexpr explicit identity_t(
int) {}
1161 return {{1, 0}, {0, 1}};
1167 return {{1, 0}, {0, 1}, {0, 0}};
1173 return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
1179 return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, 0}};
1185 return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
1198template <
class F,
class A,
class B>
1199constexpr A fold(F f, A a,
const vec<B, 1>& b) {
1202template <
class F,
class A,
class B>
1203constexpr A fold(F f, A a,
const vec<B, 2>& b) {
1204 return f(f(a, b.x), b.y);
1206template <
class F,
class A,
class B>
1207constexpr A fold(F f, A a,
const vec<B, 3>& b) {
1208 return f(f(f(a, b.x), b.y), b.z);
1210template <
class F,
class A,
class B>
1211constexpr A fold(F f, A a,
const vec<B, 4>& b) {
1212 return f(f(f(f(a, b.x), b.y), b.z), b.w);
1214template <
class F,
class A,
class B,
int M>
1216 return fold(f, a, b.x);
1218template <
class F,
class A,
class B,
int M>
1220 return fold(f, fold(f, a, b.x), b.y);
1222template <
class F,
class A,
class B,
int M>
1224 return fold(f, fold(f, fold(f, a, b.x), b.y), b.z);
1226template <
class F,
class A,
class B,
int M>
1228 return fold(f, fold(f, fold(f, fold(f, a, b.x), b.y), b.z), b.w);
1241template <
class F,
class... A>
1243template <
class F,
class... A>
1244using mm_apply_t =
typename std::enable_if<
detail::apply<F, void, A...>::mm,
1245 apply_t<F, A...>>::type;
1246template <
class F,
class... A>
1247using no_mm_apply_t =
typename std::enable_if<!
detail::apply<F, void, A...>::mm,
1248 apply_t<F, A...>>::type;
1256template <
class F,
class... A>
1257constexpr apply_t<F, A...> apply(F func,
const A&... args) {
1263template <
class A,
class F>
1264constexpr apply_t<F, A> map(
const A& a, F func) {
1265 return apply(func, a);
1269template <
class A,
class B,
class F>
1270constexpr apply_t<F, A, B> zip(
const A& a,
const B& b, F func) {
1271 return apply(func, a, b);
1281template <
class A,
class B>
1286template <
class A,
class B>
1287constexpr auto operator==(
const A& a,
const B& b)
1288 ->
decltype(compare(a, b) == 0) {
1289 return compare(a, b) == 0;
1291template <
class A,
class B>
1292constexpr auto operator!=(
const A& a,
const B& b)
1293 ->
decltype(compare(a, b) != 0) {
1294 return compare(a, b) != 0;
1296template <
class A,
class B>
1297constexpr auto operator<(
const A& a,
const B& b)
1298 ->
decltype(compare(a, b) < 0) {
1299 return compare(a, b) < 0;
1301template <
class A,
class B>
1302constexpr auto operator>(
const A& a,
const B& b)
1303 ->
decltype(compare(a, b) > 0) {
1304 return compare(a, b) > 0;
1306template <
class A,
class B>
1307constexpr auto operator<=(
const A& a,
const B& b)
1308 ->
decltype(compare(a, b) <= 0) {
1309 return compare(a, b) <= 0;
1311template <
class A,
class B>
1312constexpr auto operator>=(
const A& a,
const B& b)
1313 ->
decltype(compare(a, b) >= 0) {
1314 return compare(a, b) >= 0;
1324constexpr bool any(
const A& a) {
1328constexpr bool all(
const A& a) {
1332constexpr scalar_t<A> sum(
const A& a) {
1336constexpr scalar_t<A> product(
const A& a) {
1340constexpr scalar_t<A> minelem(
const A& a) {
1344constexpr scalar_t<A> maxelem(
const A& a) {
1347template <
class T,
int M>
1350 for (
int i = 1; i < M; ++i)
1351 if (a[i] < a[j]) j = i;
1354template <
class T,
int M>
1357 for (
int i = 1; i < M; ++i)
1358 if (a[i] > a[j]) j = i;
1369constexpr apply_t<detail::op_pos, A> operator+(
const A& a) {
1373constexpr apply_t<detail::op_neg, A> operator-(
const A& a) {
1377constexpr apply_t<detail::op_cmp, A> operator~(
const A& a) {
1381constexpr apply_t<detail::op_not, A> operator!(
const A& a) {
1394template <
class A,
class B>
1395constexpr apply_t<detail::op_add, A, B> operator+(
const A& a,
const B& b) {
1398template <
class A,
class B>
1399constexpr apply_t<detail::op_sub, A, B> operator-(
const A& a,
const B& b) {
1402template <
class A,
class B>
1403constexpr apply_t<detail::op_mul, A, B> cmul(
const A& a,
const B& b) {
1406template <
class A,
class B>
1407constexpr apply_t<detail::op_div, A, B> operator/(
const A& a,
const B& b) {
1410template <
class A,
class B>
1411constexpr apply_t<detail::op_mod, A, B> operator%(
const A& a,
const B& b) {
1414template <
class A,
class B>
1415constexpr apply_t<detail::op_un, A, B> operator|(
const A& a,
const B& b) {
1418template <
class A,
class B>
1419constexpr apply_t<detail::op_xor, A, B> operator^(
const A& a,
const B& b) {
1422template <
class A,
class B>
1423constexpr apply_t<detail::op_int, A, B> operator&(
const A& a,
const B& b) {
1426template <
class A,
class B>
1427constexpr apply_t<detail::op_lsh, A, B> operator<<(
const A& a,
const B& b) {
1430template <
class A,
class B>
1431constexpr apply_t<detail::op_rsh, A, B> operator>>(
const A& a,
const B& b) {
1437template <
class A,
class B>
1438constexpr auto operator*(
const A& a,
const B& b) {
1444template <
class A,
class B>
1445constexpr auto operator+=(A& a,
const B& b) ->
decltype(a = a + b) {
1448template <
class A,
class B>
1449constexpr auto operator-=(A& a,
const B& b) ->
decltype(a = a - b) {
1452template <
class A,
class B>
1453constexpr auto operator*=(A& a,
const B& b) ->
decltype(a = a * b) {
1456template <
class A,
class B>
1457constexpr auto operator/=(A& a,
const B& b) ->
decltype(a = a / b) {
1460template <
class A,
class B>
1461constexpr auto operator%=(A& a,
const B& b) ->
decltype(a = a % b) {
1464template <
class A,
class B>
1465constexpr auto operator|=(A& a,
const B& b) ->
decltype(a = a | b) {
1468template <
class A,
class B>
1469constexpr auto operator^=(A& a,
const B& b) ->
decltype(a = a ^ b) {
1472template <
class A,
class B>
1473constexpr auto operator&=(A& a,
const B& b) ->
decltype(a = a & 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) {
1495template <
int... I,
class T,
int M>
1503template <
int I0,
int I1,
class T,
int M>
1505 return detail::swizzle(a, detail::make_seq<I0, I1>{});
1511template <
int I0,
int J0,
int I1,
int J1,
class T,
int M,
int N>
1513 return detail::swizzle(a, detail::make_seq<I0, I1>{},
1514 detail::make_seq<J0, J1>{});
1524constexpr apply_t<detail::std_isfinite, A> isfinite(
const A& a) {
1525 return apply(detail::std_isfinite{}, a);
1528constexpr apply_t<detail::std_abs, A> abs(
const A& a) {
1532constexpr apply_t<detail::std_floor, A> floor(
const A& a) {
1536constexpr apply_t<detail::std_ceil, A> ceil(
const A& a) {
1540constexpr apply_t<detail::std_exp, A> exp(
const A& a) {
1544constexpr apply_t<detail::std_log, A> log(
const A& a) {
1548constexpr apply_t<detail::std_log2, A> log2(
const A& a) {
1552constexpr apply_t<detail::std_log10, A> log10(
const A& a) {
1556constexpr apply_t<detail::std_sqrt, A> sqrt(
const A& a) {
1560constexpr apply_t<detail::std_sin, A> sin(
const A& a) {
1564constexpr apply_t<detail::std_cos, A> cos(
const A& a) {
1568constexpr apply_t<detail::std_tan, A> tan(
const A& a) {
1572constexpr apply_t<detail::std_asin, A> asin(
const A& a) {
1576constexpr apply_t<detail::std_acos, A> acos(
const A& a) {
1580constexpr apply_t<detail::std_atan, A> atan(
const A& a) {
1584constexpr apply_t<detail::std_sinh, A> sinh(
const A& a) {
1588constexpr apply_t<detail::std_cosh, A> cosh(
const A& a) {
1592constexpr apply_t<detail::std_tanh, A> tanh(
const A& a) {
1596constexpr apply_t<detail::std_round, A> round(
const A& a) {
1607template <
class A,
class B>
1608constexpr apply_t<detail::std_fmod, A, B> fmod(
const A& a,
const B& b) {
1611template <
class A,
class B>
1612constexpr apply_t<detail::std_pow, A, B> pow(
const A& a,
const B& b) {
1615template <
class A,
class B>
1616constexpr apply_t<detail::std_atan2, A, B> atan2(
const A& a,
const B& b) {
1619template <
class A,
class B>
1620constexpr apply_t<detail::std_copysign, A, B> copysign(
const A& a,
const B& b) {
1631template <
class A,
class B>
1632constexpr apply_t<detail::op_eq, A, B> equal(
const A& a,
const B& b) {
1635template <
class A,
class B>
1636constexpr apply_t<detail::op_ne, A, B> nequal(
const A& a,
const B& b) {
1639template <
class A,
class B>
1640constexpr apply_t<detail::op_lt, A, B> less(
const A& a,
const B& b) {
1643template <
class A,
class B>
1644constexpr apply_t<detail::op_gt, A, B> greater(
const A& a,
const B& b) {
1647template <
class A,
class B>
1648constexpr apply_t<detail::op_le, A, B> lequal(
const A& a,
const B& b) {
1651template <
class A,
class B>
1652constexpr apply_t<detail::op_ge, A, B> gequal(
const A& a,
const B& b) {
1663template <
class A,
class B>
1664constexpr apply_t<detail::min, A, B> min(
const A& a,
const B& b) {
1667template <
class A,
class B>
1668constexpr apply_t<detail::max, A, B> max(
const A& a,
const B& b) {
1674template <
class X,
class L,
class H>
1675constexpr apply_t<detail::clamp, X, L, H>
clamp(
const X& x,
const L& l,
1683template <
class P,
class A,
class B>
1684constexpr apply_t<detail::select, P, A, B>
select(
const P& p,
const A& a,
1692template <
class A,
class B,
class T>
1693constexpr apply_t<detail::lerp, A, B, T>
lerp(
const A& a,
const B& b,
1709 return a.x * b.y - a.y * b.x;
1716 return {-a * b.y, a * b.x};
1723 return {a.y * b, -a.x * b};
1731 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};
1737template <
class T,
int M>
1744template <
class T,
int M>
1751template <
class T,
int M>
1760template <
class T,
int M>
1769template <
class T,
int M>
1777template <
class T,
int M>
1784template <
class T,
int M>
1787 return d > 1 ? 0 : linalg::acos(d < -1 ? -1 : d);
1792template <
class T,
int M>
1802 const T s = linalg::sin(a), c = linalg::cos(a);
1803 return {v.x * c - v.y * s, v.x * s + v.y * c};
1811 const T s = linalg::sin(a), c = linalg::cos(a);
1812 return {v.x, v.y * c - v.z * s, v.y * s + v.z * c};
1820 const T s = linalg::sin(a), c = linalg::cos(a);
1821 return {v.x * c + v.z * s, v.y, -v.x * s + v.z * c};
1829 const T s = linalg::sin(a), c = linalg::cos(a);
1830 return {v.x * c - v.y * s, v.x * s + v.y * c, v.z};
1835template <
class T,
int M>
1844template <
class T,
int M>
1848 : a * (linalg::sin(th * (1 - t)) / linalg::sin(th)) +
1849 b * (linalg::sin(th * t) / linalg::sin(th));
1866 return {-q.x, -q.y, -q.z, q.w};
1884 const auto v = q.xyz();
1885 const auto vv =
length(v);
1886 return std::exp(q.w) *
1887 vec<T, 4>{v * (vv > 0 ? linalg::sin(vv) / vv : 0), linalg::cos(vv)};
1896 const auto v = q.xyz();
1898 return {v * (vv > 0 ? linalg::acos(q.w / qq) / vv : 0), std::log(qq)};
1905 const auto v = q.xyz();
1906 const auto vv =
length(v), qq =
length(q), th = linalg::acos(q.w / qq);
1907 return std::pow(qq, p) *
1908 vec<T, 4>{v * (vv > 0 ? linalg::sin(p * th) / vv : 0),
1909 linalg::cos(p * th)};
1918 return {a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y,
1919 a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z,
1920 a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x,
1921 a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z};
1926template <
class T,
class... R>
1942 return {q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z,
1943 (q.x * q.y + q.z * q.w) * 2, (q.z * q.x - q.y * q.w) * 2};
1950 return {(q.x * q.y - q.z * q.w) * 2,
1951 q.w * q.w - q.x * q.x + q.y * q.y - q.z * q.z,
1952 (q.y * q.z + q.x * q.w) * 2};
1959 return {(q.z * q.x + q.y * q.w) * 2, (q.y * q.z - q.x * q.w) * 2,
1960 q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z};
1982 return linalg::atan2(
length(q.xyz()), q.w) * 2;
1998 return nlerp(a,
dot(a, b) < 0 ? -b : b, t);
2005 return slerp(a,
dot(a, b) < 0 ? -b : b, t);
2013 return {axis * linalg::sin(
angle / 2), linalg::cos(
angle / 2)};
2034template <
class T,
int M>
2038template <
class T,
int M>
2039constexpr vec<T, M> mul(
const T& b,
const vec<T, M>& a) {
2042template <
class T,
int M,
int N>
2046template <
class T,
int M,
int N>
2050template <
class T,
int M>
2054template <
class T,
int M>
2058template <
class T,
int M>
2060 return a.x * b.x + a.y * b.y;
2062template <
class T,
int M>
2064 return a.x * b.x + a.y * b.y + a.z * b.z;
2066template <
class T,
int M>
2068 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
2070template <
class T,
int M,
int N>
2072 return {mul(a, b.x)};
2074template <
class T,
int M,
int N>
2076 return {mul(a, b.x), mul(a, b.y)};
2078template <
class T,
int M,
int N>
2080 return {mul(a, b.x), mul(a, b.y), mul(a, b.z)};
2082template <
class T,
int M,
int N>
2084 return {mul(a, b.x), mul(a, b.y), mul(a, b.z), mul(a, b.w)};
2086template <
class T,
int M,
int N,
int P>
2089 return mul(mul(a, b), c);
2091template <
class T,
int M,
int N,
int P,
int Q>
2094 return mul(mul(a, b), c);
2096template <
class T,
int M,
int N,
int P,
int Q>
2099 return mul(mul(a, b, c), d);
2101template <
class T,
int M,
int N,
int P,
int Q,
int R>
2104 return mul(mul(a, b, c), d);
2106template <
class T,
int M>
2110template <
class T,
int M>
2112 return {a * b.x, a * b.y};
2114template <
class T,
int M>
2116 return {a * b.x, a * b.y, a * b.z};
2118template <
class T,
int M>
2120 return {a * b.x, a * b.y, a * b.z, a * b.w};
2128 return {a.x.x, a.y.y};
2132 return {a.x.x, a.y.y, a.z.z};
2136 return {a.x.x, a.y.y, a.z.z, a.w.w};
2138template <
class T,
int N>
2140 return sum(diagonal(a));
2142template <
class T,
int M>
2146template <
class T,
int M>
2148 return {m.row(0), m.row(1)};
2150template <
class T,
int M>
2152 return {m.row(0), m.row(1), m.row(2)};
2154template <
class T,
int M>
2156 return {m.row(0), m.row(1), m.row(2), m.row(3)};
2158template <
class T,
int M>
2168 return {{a.y.y, -a.x.y}, {-a.y.x, a.x.x}};
2174template <
class T,
int N>
2176 return transpose(adjugate(a));
2184 return a.x.x * a.y.y - a.x.y * a.y.x;
2188 return a.x.x * (a.y.y * a.z.z - a.z.y * a.y.z) +
2189 a.x.y * (a.y.z * a.z.x - a.z.z * a.y.x) +
2190 a.x.z * (a.y.x * a.z.y - a.z.x * a.y.y);
2194template <
class T,
int N>
2196 return adjugate(a) / determinant(a);
2205template <
class T,
int M>
2209template <
class T,
int M>
2213template <
class T,
int M>
2215 return begin(a) + M;
2217template <
class T,
int M>
2219 return begin(a) + M;
2221template <
class T,
int M,
int N>
2225template <
class T,
int M,
int N>
2229template <
class T,
int M,
int N>
2231 return begin(a) + N;
2233template <
class T,
int M,
int N>
2235 return begin(a) + N;
2255 return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {translation, 1}};
2259 return {{
qxdir(rotation), 0},
2260 {
qydir(rotation), 0},
2261 {
qzdir(rotation), 0},
2266 return {{scaling.x, 0, 0, 0},
2267 {0, scaling.y, 0, 0},
2268 {0, 0, scaling.z, 0},
2277 const vec<T, 3>& view_y_dir, fwd_axis fwd = neg_z);
2279mat<T, 4, 4> frustum_matrix(T x0, T x1, T y0, T y1, T n, T f,
2280 fwd_axis a = neg_z, z_range z = neg_one_to_one);
2282mat<T, 4, 4> perspective_matrix(T fovy, T aspect, T n, T f, fwd_axis a = neg_z,
2283 z_range z = neg_one_to_one) {
2284 T y = n * linalg::tan(fovy / 2), x = y * aspect;
2285 return frustum_matrix(-x, x, -y, y, n, f, a, z);
2297 vec<T, 1> operator()(
const std::array<T, 1>& a)
const {
return {a[0]}; }
2301 vec<T, 2> operator()(
const std::array<T, 2>& a)
const {
return {a[0], a[1]}; }
2305 vec<T, 3> operator()(
const std::array<T, 3>& a)
const {
2306 return {a[0], a[1], a[2]};
2311 vec<T, 4> operator()(
const std::array<T, 4>& a)
const {
2312 return {a[0], a[1], a[2], a[3]};
2318 std::array<T, 1> operator()(
const vec<T, 1>& a)
const {
return {a[0]}; }
2322 std::array<T, 2> operator()(
const vec<T, 2>& a)
const {
return {a[0], a[1]}; }
2326 std::array<T, 3> operator()(
const vec<T, 3>& a)
const {
2327 return {a[0], a[1], a[2]};
2332 std::array<T, 4> operator()(
const vec<T, 4>& a)
const {
2333 return {a[0], a[1], a[2], a[3]};
2339#ifdef MANIFOLD_DEBUG
2344std::ostream& operator<<(std::ostream& out,
const vec<T, 1>& v) {
2345 return out <<
'{' << v[0] <<
'}';
2348std::ostream& operator<<(std::ostream& out,
const vec<T, 2>& v) {
2349 return out <<
'{' << v[0] <<
',' << v[1] <<
'}';
2352std::ostream& operator<<(std::ostream& out,
const vec<T, 3>& v) {
2353 return out <<
'{' << v[0] <<
',' << v[1] <<
',' << v[2] <<
'}';
2356std::ostream& operator<<(std::ostream& out,
const vec<T, 4>& v) {
2357 return out <<
'{' << v[0] <<
',' << v[1] <<
',' << v[2] <<
',' << v[3] <<
'}';
2360template <
class T,
int M>
2361std::ostream& operator<<(std::ostream& out,
const mat<T, M, 1>& m) {
2362 return out <<
'{' << m[0] <<
'}';
2364template <
class T,
int M>
2365std::ostream& operator<<(std::ostream& out,
const mat<T, M, 2>& m) {
2366 return out <<
'{' << m[0] <<
',' << m[1] <<
'}';
2368template <
class T,
int M>
2369std::ostream& operator<<(std::ostream& out,
const mat<T, M, 3>& m) {
2370 return out <<
'{' << m[0] <<
',' << m[1] <<
',' << m[2] <<
'}';
2372template <
class T,
int M>
2373std::ostream& operator<<(std::ostream& out,
const mat<T, M, 4>& m) {
2374 return out <<
'{' << m[0] <<
',' << m[1] <<
',' << m[2] <<
',' << m[3] <<
'}';
2386struct hash<linalg::vec<T, 1>> {
2393struct hash<linalg::vec<T, 2>> {
2396 return h(v.x) ^ (h(v.y) << 1);
2400struct hash<linalg::vec<T, 3>> {
2403 return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2);
2407struct hash<linalg::vec<T, 4>> {
2410 return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2) ^ (h(v.w) << 3);
2414template <
class T,
int M>
2415struct hash<linalg::mat<T, M, 1>> {
2417 std::hash<linalg::vec<T, M>> h;
2421template <
class T,
int M>
2422struct hash<linalg::mat<T, M, 2>> {
2424 std::hash<linalg::vec<T, M>> h;
2425 return h(v.x) ^ (h(v.y) << M);
2428template <
class T,
int M>
2429struct hash<linalg::mat<T, M, 3>> {
2431 std::hash<linalg::vec<T, M>> h;
2432 return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2));
2435template <
class T,
int M>
2436struct hash<linalg::mat<T, M, 4>> {
2438 std::hash<linalg::vec<T, M>> h;
2439 return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2)) ^ (h(v.w) << (M * 3));
2448 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,
2449 a.x.y * a.y.z - a.y.y * a.x.z},
2450 {a.y.z * a.z.x - a.z.z * a.y.x, a.z.z * a.x.x - a.x.z * a.z.x,
2451 a.x.z * a.y.x - a.y.z * a.x.x},
2452 {a.y.x * a.z.y - a.z.x * a.y.y, a.z.x * a.x.y - a.x.x * a.z.y,
2453 a.x.x * a.y.y - a.y.x * a.x.y}};
2458 return {{a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
2459 a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
2460 a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w,
2461 a.x.y * a.w.z * a.z.w + a.z.y * a.x.z * a.w.w +
2462 a.w.y * a.z.z * a.x.w - a.w.y * a.x.z * a.z.w -
2463 a.z.y * a.w.z * a.x.w - a.x.y * a.z.z * a.w.w,
2464 a.x.y * a.y.z * a.w.w + a.w.y * a.x.z * a.y.w +
2465 a.y.y * a.w.z * a.x.w - a.x.y * a.w.z * a.y.w -
2466 a.y.y * a.x.z * a.w.w - a.w.y * a.y.z * a.x.w,
2467 a.x.y * a.z.z * a.y.w + a.y.y * a.x.z * a.z.w +
2468 a.z.y * a.y.z * a.x.w - a.x.y * a.y.z * a.z.w -
2469 a.z.y * a.x.z * a.y.w - a.y.y * a.z.z * a.x.w},
2470 {a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
2471 a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
2472 a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x,
2473 a.x.z * a.z.w * a.w.x + a.w.z * a.x.w * a.z.x +
2474 a.z.z * a.w.w * a.x.x - a.x.z * a.w.w * a.z.x -
2475 a.z.z * a.x.w * a.w.x - a.w.z * a.z.w * a.x.x,
2476 a.x.z * a.w.w * a.y.x + a.y.z * a.x.w * a.w.x +
2477 a.w.z * a.y.w * a.x.x - a.x.z * a.y.w * a.w.x -
2478 a.w.z * a.x.w * a.y.x - a.y.z * a.w.w * a.x.x,
2479 a.x.z * a.y.w * a.z.x + a.z.z * a.x.w * a.y.x +
2480 a.y.z * a.z.w * a.x.x - a.x.z * a.z.w * a.y.x -
2481 a.y.z * a.x.w * a.z.x - a.z.z * a.y.w * a.x.x},
2482 {a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
2483 a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
2484 a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y,
2485 a.x.w * a.w.x * a.z.y + a.z.w * a.x.x * a.w.y +
2486 a.w.w * a.z.x * a.x.y - a.x.w * a.z.x * a.w.y -
2487 a.w.w * a.x.x * a.z.y - a.z.w * a.w.x * a.x.y,
2488 a.x.w * a.y.x * a.w.y + a.w.w * a.x.x * a.y.y +
2489 a.y.w * a.w.x * a.x.y - a.x.w * a.w.x * a.y.y -
2490 a.y.w * a.x.x * a.w.y - a.w.w * a.y.x * a.x.y,
2491 a.x.w * a.z.x * a.y.y + a.y.w * a.x.x * a.z.y +
2492 a.z.w * a.y.x * a.x.y - a.x.w * a.y.x * a.z.y -
2493 a.z.w * a.x.x * a.y.y - a.y.w * a.z.x * a.x.y},
2494 {a.y.x * a.w.y * a.z.z + a.z.x * a.y.y * a.w.z +
2495 a.w.x * a.z.y * a.y.z - a.y.x * a.z.y * a.w.z -
2496 a.w.x * a.y.y * a.z.z - a.z.x * a.w.y * a.y.z,
2497 a.x.x * a.z.y * a.w.z + a.w.x * a.x.y * a.z.z +
2498 a.z.x * a.w.y * a.x.z - a.x.x * a.w.y * a.z.z -
2499 a.z.x * a.x.y * a.w.z - a.w.x * a.z.y * a.x.z,
2500 a.x.x * a.w.y * a.y.z + a.y.x * a.x.y * a.w.z +
2501 a.w.x * a.y.y * a.x.z - a.x.x * a.y.y * a.w.z -
2502 a.w.x * a.x.y * a.y.z - a.y.x * a.w.y * a.x.z,
2503 a.x.x * a.y.y * a.z.z + a.z.x * a.x.y * a.y.z +
2504 a.y.x * a.z.y * a.x.z - a.x.x * a.z.y * a.y.z -
2505 a.y.x * a.x.y * a.z.z - a.z.x * a.y.y * a.x.z}};
2509constexpr T linalg::determinant(
const mat<T, 4, 4>& a) {
2510 return a.x.x * (a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
2511 a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
2512 a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w) +
2513 a.x.y * (a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
2514 a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
2515 a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x) +
2516 a.x.z * (a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
2517 a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
2518 a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y) +
2519 a.x.w * (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);
2526 const vec<T, 3>& dest) {
2527 T cosTheta =
dot(orig, dest);
2528 if (cosTheta >= 1 - std::numeric_limits<T>::epsilon()) {
2529 return {0, 0, 0, 1};
2531 if (cosTheta < -1 + std::numeric_limits<T>::epsilon()) {
2532 vec<T, 3> axis =
cross(vec<T, 3>(0, 0, 1), orig);
2533 if (
length2(axis) < std::numeric_limits<T>::epsilon())
2534 axis =
cross(vec<T, 3>(1, 0, 0), orig);
2536 3.14159265358979323846264338327950288);
2538 vec<T, 3> axis =
cross(orig, dest);
2539 T s = std::sqrt((1 + cosTheta) * 2);
2540 return {axis * (1 / s), s * 0.5};
2545 const vec<T, 4> q{m.x.x - m.y.y - m.z.z, m.y.y - m.x.x - m.z.z,
2546 m.z.z - m.x.x - m.y.y, m.x.x + m.y.y + m.z.z},
2547 s[]{{1, m.x.y + m.y.x, m.z.x + m.x.z, m.y.z - m.z.y},
2548 {m.x.y + m.y.x, 1, m.y.z + m.z.y, m.z.x - m.x.z},
2549 {m.x.z + m.z.x, m.y.z + m.z.y, 1, m.x.y - m.y.x},
2550 {m.y.z - m.z.y, m.z.x - m.x.z, m.x.y - m.y.x, 1}};
2551 return copysign(
normalize(sqrt(max(T(0), T(1) + q))), s[argmax(q)]);
2556 const vec<T, 3>& center,
2557 const vec<T, 3>& view_y_dir,
2559 const vec<T, 3> f =
normalize(center - eye), z = a == pos_z ? f : -f,
2561 return inverse(mat<T, 4, 4>{{x, 0}, {y, 0}, {z, 0}, {eye, 1}});
2566 fwd_axis a, z_range z) {
2567 const T s = a == pos_z ? T(1) : T(-1), o = z == neg_one_to_one ? n : 0;
2568 return {{2 * n / (x1 - x0), 0, 0, 0},
2569 {0, 2 * n / (y1 - y0), 0, 0},
2570 {-s * (x0 + x1) / (x1 - x0), -s * (y0 + y1) / (y1 - y0),
2571 s * (f + o) / (f - n), s},
2572 {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:1966
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:2004
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:1981
constexpr vec< T, 3 > qzdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,0,1})
Definition linalg.h:1958
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:1997
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:1989
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:2012
constexpr vec< T, 3 > qxdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {1,0,0})
Definition linalg.h:1941
constexpr vec< T, 3 > qrot(const vec< T, 4 > &q, const vec< T, 3 > &v)
Rotate a vector by a quaternion.
Definition linalg.h:1973
constexpr vec< T, 3 > qydir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,1,0})
Definition linalg.h:1949
vec< T, 4 > qinv(const vec< T, 4 > &q)
inverse or reciprocal of quaternion q (undefined for zero-length quaternions)
Definition linalg.h:1874
vec< T, 4 > qexp(const vec< T, 4 > &q)
exponential of quaternion q
Definition linalg.h:1883
vec< T, 4 > qpow(const vec< T, 4 > &q, const T &p)
quaternion q raised to the exponent p
Definition linalg.h:1904
vec< T, 4 > qlog(const vec< T, 4 > &q)
logarithm of quaternion q
Definition linalg.h:1895
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:1917
constexpr vec< T, 4 > qconj(const vec< T, 4 > &q)
conjugate of quaternion q
Definition linalg.h:1865
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:1675
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:1684
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:1693
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:1496
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:1512
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:1504
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:1819
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:1801
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:1770
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:1810
constexpr T length2(const vec< T, M > &a)
square of the length or magnitude of vector a
Definition linalg.h:1745
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:1738
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:1836
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:1761
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:1845
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:1793
T uangle(const vec< T, M > &a, const vec< T, M > &b)
Return the angle in radians between two unit vectors.
Definition linalg.h:1785
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:1708
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:1828
T length(const vec< T, M > &a)
length or magnitude of a vector a
Definition linalg.h:1752
T distance(const vec< T, M > &a, const vec< T, M > &b)
Euclidean distance between points a and b
Definition linalg.h:1778