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::sqrt(a)) {
629 double operator()(
double a)
const {
return manifold::math::sin(a); }
632 double operator()(
double a)
const {
return manifold::math::cos(a); }
635 double operator()(
double a)
const {
return manifold::math::tan(a); }
638 double operator()(
double a)
const {
return manifold::math::asin(a); }
641 double operator()(
double a)
const {
return manifold::math::acos(a); }
644 double operator()(
double a)
const {
return manifold::math::atan(a); }
647 double operator()(
double a,
double b)
const {
648 return manifold::math::atan2(a, b);
652 template <
class A,
class B>
653 constexpr auto operator()(A a, B b)
const ->
decltype(std::copysign(a, b)) {
654 return std::copysign(a, b);
761 constexpr vec() : x() {}
762 constexpr vec(
const T& x_) : x(x_) {}
766 constexpr explicit vec(
const vec<U, 1>& v) : vec(
static_cast<T
>(v.x)) {}
767 constexpr const T& operator[](
int)
const {
return x; }
768 LINALG_CONSTEXPR14 T& operator[](
int) {
return x; }
770 template <
class U,
class = detail::conv_t<vec, U>>
772 template <
class U,
class = detail::conv_t<U, vec>>
773 constexpr operator U()
const {
780 constexpr vec() : x(), y() {}
781 constexpr vec(
const T& x_,
const T& y_) : x(x_), y(y_) {}
782 constexpr explicit vec(
const T& s) : vec(s, s) {}
783 constexpr explicit vec(
const T* p) : vec(p[0], p[1]) {}
784 template <
class U,
int N>
785 constexpr explicit vec(
const vec<U, N>& v)
786 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y)) {
789 "You must give extra arguments if your input vector is shorter.");
791 constexpr const T& operator[](
int i)
const {
return i == 0 ? x : y; }
792 LINALG_CONSTEXPR14 T& operator[](
int i) {
return i == 0 ? x : y; }
794 template <
class U,
class = detail::conv_t<vec, U>>
796 template <
class U,
class = detail::conv_t<U, vec>>
797 constexpr operator U()
const {
804 constexpr vec() : x(), y(), z() {}
805 constexpr vec(
const T& x_,
const T& y_,
const T& z_) : x(x_), y(y_), z(z_) {}
806 constexpr vec(
const vec<T, 2>& xy,
const T& z_) : vec(xy.x, xy.y, z_) {}
807 constexpr explicit vec(
const T& s) : vec(s, s, s) {}
808 constexpr explicit vec(
const T* p) : vec(p[0], p[1], p[2]) {}
809 template <
class U,
int N>
810 constexpr explicit vec(
const vec<U, N>& v)
811 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y),
static_cast<T
>(v.z)) {
814 "You must give extra arguments if your input vector is shorter.");
816 constexpr const T& operator[](
int i)
const {
817 return i == 0 ? x : i == 1 ? y : z;
819 LINALG_CONSTEXPR14 T& operator[](
int i) {
820 return i == 0 ? x : i == 1 ? y : z;
822 constexpr vec<T, 2> xy()
const {
return vec<T, 2>(x, y); }
823 constexpr vec<T, 2> yz()
const {
return vec<T, 2>(y, z); }
825 template <
class U,
class = detail::conv_t<vec, U>>
827 template <
class U,
class = detail::conv_t<U, vec>>
828 constexpr operator U()
const {
835 constexpr vec() : x(), y(), z(), w() {}
836 constexpr vec(
const T& x_,
const T& y_,
const T& z_,
const T& w_)
837 : x(x_), y(y_), z(z_), w(w_) {}
838 constexpr vec(
const vec<T, 2>& xy,
const T& z_,
const T& w_)
839 : vec(xy.x, xy.y, z_, w_) {}
840 constexpr vec(
const vec<T, 3>& xyz,
const T& w_)
841 : vec(xyz.x, xyz.y, xyz.z, w_) {}
842 constexpr explicit vec(
const T& s) : vec(s, s, s, s) {}
843 constexpr explicit vec(
const T* p) : vec(p[0], p[1], p[2], p[3]) {}
844 template <
class U,
int N>
845 constexpr explicit vec(
const vec<U, N>& v)
846 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y),
static_cast<T
>(v.z),
847 static_cast<T
>(v.w)) {
850 "You must give extra arguments if your input vector is shorter.");
852 constexpr const T& operator[](
int i)
const {
853 return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
855 LINALG_CONSTEXPR14 T& operator[](
int i) {
856 return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
858 constexpr vec<T, 2> xy()
const {
return vec<T, 2>(x, y); }
859 constexpr vec<T, 3> xyz()
const {
return vec<T, 3>(x, y, z); }
861 template <
class U,
class = detail::conv_t<vec, U>>
863 template <
class U,
class = detail::conv_t<U, vec>>
864 constexpr operator U()
const {
964template <
class T,
int M>
968 constexpr mat() : x() {}
969 constexpr mat(
const V& x_) : x(x_) {}
970 constexpr explicit mat(
const T& s) : x(s) {}
971 constexpr explicit mat(
const T* p) : x(p + M * 0) {}
973 constexpr explicit mat(
const mat<U, M, 1>& m) : mat(V(m.x)) {}
974 constexpr vec<T, 1> row(
int i)
const {
return {x[i]}; }
975 constexpr const V& operator[](
int)
const {
return x; }
976 LINALG_CONSTEXPR14 V& operator[](
int) {
return x; }
978 template <
class U,
class = detail::conv_t<mat, U>>
980 template <
class U,
class = detail::conv_t<U, mat>>
981 constexpr operator U()
const {
985template <
class T,
int M>
989 constexpr mat() : x(), y() {}
990 constexpr mat(
const V& x_,
const V& y_) : x(x_), y(y_) {}
991 constexpr explicit mat(
const T& s) : x(s), y(s) {}
992 constexpr explicit mat(
const T* p) : x(p + M * 0), y(p + M * 1) {}
993 template <
class U,
int N,
int P>
994 constexpr explicit mat(
const mat<U, N, P>& m) : mat(V(m.x), V(m.y)) {
995 static_assert(P >= 2,
"Input matrix dimensions must be at least as big.");
997 constexpr vec<T, 2> row(
int i)
const {
return {x[i], y[i]}; }
998 constexpr const V& operator[](
int j)
const {
return j == 0 ? x : y; }
999 LINALG_CONSTEXPR14 V& operator[](
int j) {
return j == 0 ? x : y; }
1001 template <
class U,
class = detail::conv_t<mat, U>>
1003 template <
class U,
class = detail::conv_t<U, mat>>
1004 constexpr operator U()
const {
1008template <
class T,
int M>
1009struct mat<T, M, 3> {
1012 constexpr mat() : x(), y(), z() {}
1013 constexpr mat(
const V& x_,
const V& y_,
const V& z_) : x(x_), y(y_), z(z_) {}
1014 constexpr mat(
const mat<T, M, 2>& m_,
const V& z_)
1015 : x(m_.x), y(m_.y), z(z_) {}
1016 constexpr explicit mat(
const T& s) : x(s), y(s), z(s) {}
1017 constexpr explicit mat(
const T* p)
1018 : x(p + M * 0), y(p + M * 1), z(p + M * 2) {}
1019 template <
class U,
int N,
int P>
1020 constexpr explicit mat(
const mat<U, N, P>& m) : mat(V(m.x), V(m.y), V(m.z)) {
1021 static_assert(P >= 3,
"Input matrix dimensions must be at least as big.");
1023 constexpr vec<T, 3> row(
int i)
const {
return {x[i], y[i], z[i]}; }
1024 constexpr const V& operator[](
int j)
const {
1025 return j == 0 ? x : j == 1 ? y : z;
1027 LINALG_CONSTEXPR14 V& operator[](
int j) {
1028 return j == 0 ? x : j == 1 ? y : z;
1031 template <
class U,
class = detail::conv_t<mat, U>>
1033 template <
class U,
class = detail::conv_t<U, mat>>
1034 constexpr operator U()
const {
1038template <
class T,
int M>
1039struct mat<T, M, 4> {
1042 constexpr mat() : x(), y(), z(), w() {}
1043 constexpr mat(
const V& x_,
const V& y_,
const V& z_,
const V& w_)
1044 : x(x_), y(y_), z(z_), w(w_) {}
1045 constexpr mat(
const mat<T, M, 3>& m_,
const V& w_)
1046 : x(m_.x), y(m_.y), z(m_.z), w(w_) {}
1047 constexpr explicit mat(
const T& s) : x(s), y(s), z(s), w(s) {}
1048 constexpr explicit mat(
const T* p)
1049 : x(p + M * 0), y(p + M * 1), z(p + M * 2), w(p + M * 3) {}
1050 template <
class U,
int N,
int P>
1051 constexpr explicit mat(
const mat<U, N, P>& m)
1052 : mat(V(m.x), V(m.y), V(m.z), V(m.w)) {
1053 static_assert(P >= 4,
"Input matrix dimensions must be at least as big.");
1056 constexpr vec<T, 4> row(
int i)
const {
return {x[i], y[i], z[i], w[i]}; }
1057 constexpr const V& operator[](
int j)
const {
1058 return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
1060 LINALG_CONSTEXPR14 V& operator[](
int j) {
1061 return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
1064 template <
class U,
class = detail::conv_t<mat, U>>
1066 template <
class U,
class = detail::conv_t<U, mat>>
1067 constexpr operator U()
const {
1080 constexpr explicit identity_t(
int) {}
1089 return {{1, 0}, {0, 1}};
1095 return {{1, 0}, {0, 1}, {0, 0}};
1101 return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
1107 return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, 0}};
1113 return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
1126template <
class F,
class A,
class B>
1127constexpr A fold(F f, A a,
const vec<B, 1>& b) {
1130template <
class F,
class A,
class B>
1131constexpr A fold(F f, A a,
const vec<B, 2>& b) {
1132 return f(f(a, b.x), b.y);
1134template <
class F,
class A,
class B>
1135constexpr A fold(F f, A a,
const vec<B, 3>& b) {
1136 return f(f(f(a, b.x), b.y), b.z);
1138template <
class F,
class A,
class B>
1139constexpr A fold(F f, A a,
const vec<B, 4>& b) {
1140 return f(f(f(f(a, b.x), b.y), b.z), b.w);
1142template <
class F,
class A,
class B,
int M>
1144 return fold(f, a, b.x);
1146template <
class F,
class A,
class B,
int M>
1148 return fold(f, fold(f, a, b.x), b.y);
1150template <
class F,
class A,
class B,
int M>
1152 return fold(f, fold(f, fold(f, a, b.x), b.y), b.z);
1154template <
class F,
class A,
class B,
int M>
1156 return fold(f, fold(f, fold(f, fold(f, a, b.x), b.y), b.z), b.w);
1169template <
class F,
class... A>
1171template <
class F,
class... A>
1172using mm_apply_t =
typename std::enable_if<
detail::apply<F, void, A...>::mm,
1173 apply_t<F, A...>>::type;
1174template <
class F,
class... A>
1175using no_mm_apply_t =
typename std::enable_if<!
detail::apply<F, void, A...>::mm,
1176 apply_t<F, A...>>::type;
1184template <
class F,
class... A>
1185constexpr apply_t<F, A...> apply(F func,
const A&... args) {
1191template <
class A,
class F>
1192constexpr apply_t<F, A> map(
const A& a, F func) {
1193 return apply(func, a);
1197template <
class A,
class B,
class F>
1198constexpr apply_t<F, A, B> zip(
const A& a,
const B& b, F func) {
1199 return apply(func, a, b);
1209template <
class A,
class B>
1214template <
class A,
class B>
1215constexpr auto operator==(
const A& a,
const B& b)
1216 ->
decltype(compare(a, b) == 0) {
1217 return compare(a, b) == 0;
1219template <
class A,
class B>
1220constexpr auto operator!=(
const A& a,
const B& b)
1221 ->
decltype(compare(a, b) != 0) {
1222 return compare(a, b) != 0;
1224template <
class A,
class B>
1225constexpr auto operator<(
const A& a,
const B& b)
1226 ->
decltype(compare(a, b) < 0) {
1227 return compare(a, b) < 0;
1229template <
class A,
class B>
1230constexpr auto operator>(
const A& a,
const B& b)
1231 ->
decltype(compare(a, b) > 0) {
1232 return compare(a, b) > 0;
1234template <
class A,
class B>
1235constexpr auto operator<=(
const A& a,
const B& b)
1236 ->
decltype(compare(a, b) <= 0) {
1237 return compare(a, b) <= 0;
1239template <
class A,
class B>
1240constexpr auto operator>=(
const A& a,
const B& b)
1241 ->
decltype(compare(a, b) >= 0) {
1242 return compare(a, b) >= 0;
1252constexpr bool any(
const A& a) {
1256constexpr bool all(
const A& a) {
1260constexpr scalar_t<A> sum(
const A& a) {
1264constexpr scalar_t<A> product(
const A& a) {
1268constexpr scalar_t<A> minelem(
const A& a) {
1272constexpr scalar_t<A> maxelem(
const A& a) {
1275template <
class T,
int M>
1278 for (
int i = 1; i < M; ++i)
1279 if (a[i] < a[j]) j = i;
1282template <
class T,
int M>
1285 for (
int i = 1; i < M; ++i)
1286 if (a[i] > a[j]) j = i;
1297constexpr apply_t<detail::op_pos, A> operator+(
const A& a) {
1301constexpr apply_t<detail::op_neg, A> operator-(
const A& a) {
1305constexpr apply_t<detail::op_cmp, A> operator~(
const A& a) {
1309constexpr apply_t<detail::op_not, A> operator!(
const A& a) {
1322template <
class A,
class B>
1323constexpr apply_t<detail::op_add, A, B> operator+(
const A& a,
const B& b) {
1326template <
class A,
class B>
1327constexpr apply_t<detail::op_sub, A, B> operator-(
const A& a,
const B& b) {
1330template <
class A,
class B>
1331constexpr apply_t<detail::op_mul, A, B> cmul(
const A& a,
const B& b) {
1334template <
class A,
class B>
1335constexpr apply_t<detail::op_div, A, B> operator/(
const A& a,
const B& b) {
1338template <
class A,
class B>
1339constexpr apply_t<detail::op_mod, A, B> operator%(
const A& a,
const B& b) {
1342template <
class A,
class B>
1343constexpr apply_t<detail::op_un, A, B> operator|(
const A& a,
const B& b) {
1346template <
class A,
class B>
1347constexpr apply_t<detail::op_xor, A, B> operator^(
const A& a,
const B& b) {
1350template <
class A,
class B>
1351constexpr apply_t<detail::op_int, A, B> operator&(
const A& a,
const B& b) {
1354template <
class A,
class B>
1355constexpr apply_t<detail::op_lsh, A, B> operator<<(
const A& a,
const B& b) {
1358template <
class A,
class B>
1359constexpr apply_t<detail::op_rsh, A, B> operator>>(
const A& a,
const B& b) {
1365template <
class A,
class B>
1366constexpr auto operator*(
const A& a,
const B& b) {
1372template <
class A,
class B>
1373constexpr auto operator+=(A& a,
const B& b) ->
decltype(a = a + b) {
1376template <
class A,
class B>
1377constexpr auto operator-=(A& a,
const B& b) ->
decltype(a = a - b) {
1380template <
class A,
class B>
1381constexpr auto operator*=(A& a,
const B& b) ->
decltype(a = a * b) {
1384template <
class A,
class B>
1385constexpr auto operator/=(A& a,
const B& b) ->
decltype(a = a / b) {
1388template <
class A,
class B>
1389constexpr auto operator%=(A& a,
const B& b) ->
decltype(a = a % b) {
1392template <
class A,
class B>
1393constexpr auto operator|=(A& a,
const B& b) ->
decltype(a = a | b) {
1396template <
class A,
class B>
1397constexpr auto operator^=(A& a,
const B& b) ->
decltype(a = a ^ b) {
1400template <
class A,
class B>
1401constexpr auto operator&=(A& a,
const B& b) ->
decltype(a = a & b) {
1404template <
class A,
class B>
1405constexpr auto operator<<=(A& a,
const B& b) ->
decltype(a = a << b) {
1408template <
class A,
class B>
1409constexpr auto operator>>=(A& a,
const B& b) ->
decltype(a = a >> b) {
1423template <
int... I,
class T,
int M>
1431template <
int I0,
int I1,
class T,
int M>
1433 return detail::swizzle(a, detail::make_seq<I0, I1>{});
1439template <
int I0,
int J0,
int I1,
int J1,
class T,
int M,
int N>
1441 return detail::swizzle(a, detail::make_seq<I0, I1>{},
1442 detail::make_seq<J0, J1>{});
1452constexpr apply_t<detail::std_isfinite, A> isfinite(
const A& a) {
1453 return apply(detail::std_isfinite{}, a);
1456constexpr apply_t<detail::std_abs, A> abs(
const A& a) {
1460constexpr apply_t<detail::std_sqrt, A> sqrt(
const A& a) {
1464constexpr apply_t<detail::std_sin, A> sin(
const A& a) {
1468constexpr apply_t<detail::std_cos, A> cos(
const A& a) {
1472constexpr apply_t<detail::std_tan, A> tan(
const A& a) {
1476constexpr apply_t<detail::std_asin, A> asin(
const A& a) {
1480constexpr apply_t<detail::std_acos, A> acos(
const A& a) {
1484constexpr apply_t<detail::std_atan, A> atan(
const A& a) {
1495template <
class A,
class B>
1496constexpr apply_t<detail::std_atan2, A, B> atan2(
const A& a,
const B& b) {
1499template <
class A,
class B>
1500constexpr apply_t<detail::std_copysign, A, B> copysign(
const A& a,
const B& b) {
1511template <
class A,
class B>
1512constexpr apply_t<detail::op_eq, A, B> equal(
const A& a,
const B& b) {
1515template <
class A,
class B>
1516constexpr apply_t<detail::op_ne, A, B> nequal(
const A& a,
const B& b) {
1519template <
class A,
class B>
1520constexpr apply_t<detail::op_lt, A, B> less(
const A& a,
const B& b) {
1523template <
class A,
class B>
1524constexpr apply_t<detail::op_gt, A, B> greater(
const A& a,
const B& b) {
1527template <
class A,
class B>
1528constexpr apply_t<detail::op_le, A, B> lequal(
const A& a,
const B& b) {
1531template <
class A,
class B>
1532constexpr apply_t<detail::op_ge, A, B> gequal(
const A& a,
const B& b) {
1543template <
class A,
class B>
1544constexpr apply_t<detail::min, A, B> min(
const A& a,
const B& b) {
1547template <
class A,
class B>
1548constexpr apply_t<detail::max, A, B> max(
const A& a,
const B& b) {
1554template <
class X,
class L,
class H>
1555constexpr apply_t<detail::clamp, X, L, H>
clamp(
const X& x,
const L& l,
1563template <
class P,
class A,
class B>
1564constexpr apply_t<detail::select, P, A, B>
select(
const P& p,
const A& a,
1572template <
class A,
class B,
class T>
1573constexpr apply_t<detail::lerp, A, B, T>
lerp(
const A& a,
const B& b,
1589 return a.x * b.y - a.y * b.x;
1596 return {-a * b.y, a * b.x};
1603 return {a.y * b, -a.x * b};
1611 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};
1617template <
class T,
int M>
1624template <
class T,
int M>
1631template <
class T,
int M>
1640template <
class T,
int M>
1649template <
class T,
int M>
1657template <
class T,
int M>
1664template <
class T,
int M>
1667 return d > 1 ? 0 : linalg::acos(d < -1 ? -1 : d);
1672template <
class T,
int M>
1682 const T s = linalg::sin(a), c = linalg::cos(a);
1683 return {v.x * c - v.y * s, v.x * s + v.y * c};
1691 const T s = linalg::sin(a), c = linalg::cos(a);
1692 return {v.x, v.y * c - v.z * s, v.y * s + v.z * c};
1700 const T s = linalg::sin(a), c = linalg::cos(a);
1701 return {v.x * c + v.z * s, v.y, -v.x * s + v.z * c};
1709 const T s = linalg::sin(a), c = linalg::cos(a);
1710 return {v.x * c - v.y * s, v.x * s + v.y * c, v.z};
1715template <
class T,
int M>
1724template <
class T,
int M>
1728 : a * (linalg::sin(th * (1 - t)) / linalg::sin(th)) +
1729 b * (linalg::sin(th * t) / linalg::sin(th));
1746 return {-q.x, -q.y, -q.z, q.w};
1764 const auto v = q.xyz();
1765 const auto vv =
length(v);
1766 return std::exp(q.w) *
1767 vec<T, 4>{v * (vv > 0 ? linalg::sin(vv) / vv : 0), linalg::cos(vv)};
1776 const auto v = q.xyz();
1778 return {v * (vv > 0 ? linalg::acos(q.w / qq) / vv : 0), std::log(qq)};
1785 const auto v = q.xyz();
1786 const auto vv =
length(v), qq =
length(q), th = linalg::acos(q.w / qq);
1787 return std::pow(qq, p) *
1788 vec<T, 4>{v * (vv > 0 ? linalg::sin(p * th) / vv : 0),
1789 linalg::cos(p * th)};
1798 return {a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y,
1799 a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z,
1800 a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x,
1801 a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z};
1806template <
class T,
class... R>
1822 return {q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z,
1823 (q.x * q.y + q.z * q.w) * 2, (q.z * q.x - q.y * q.w) * 2};
1830 return {(q.x * q.y - q.z * q.w) * 2,
1831 q.w * q.w - q.x * q.x + q.y * q.y - q.z * q.z,
1832 (q.y * q.z + q.x * q.w) * 2};
1839 return {(q.z * q.x + q.y * q.w) * 2, (q.y * q.z - q.x * q.w) * 2,
1840 q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z};
1862 return linalg::atan2(
length(q.xyz()), q.w) * 2;
1878 return nlerp(a,
dot(a, b) < 0 ? -b : b, t);
1885 return slerp(a,
dot(a, b) < 0 ? -b : b, t);
1893 return {axis * linalg::sin(
angle / 2), linalg::cos(
angle / 2)};
1914template <
class T,
int M>
1918template <
class T,
int M>
1919constexpr vec<T, M> mul(
const T& b,
const vec<T, M>& a) {
1922template <
class T,
int M,
int N>
1926template <
class T,
int M,
int N>
1930template <
class T,
int M>
1934template <
class T,
int M>
1938template <
class T,
int M>
1940 return a.x * b.x + a.y * b.y;
1942template <
class T,
int M>
1944 return a.x * b.x + a.y * b.y + a.z * b.z;
1946template <
class T,
int M>
1948 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
1950template <
class T,
int M,
int N>
1952 return {mul(a, b.x)};
1954template <
class T,
int M,
int N>
1956 return {mul(a, b.x), mul(a, b.y)};
1958template <
class T,
int M,
int N>
1960 return {mul(a, b.x), mul(a, b.y), mul(a, b.z)};
1962template <
class T,
int M,
int N>
1964 return {mul(a, b.x), mul(a, b.y), mul(a, b.z), mul(a, b.w)};
1966template <
class T,
int M,
int N,
int P>
1969 return mul(mul(a, b), c);
1971template <
class T,
int M,
int N,
int P,
int Q>
1974 return mul(mul(a, b), c);
1976template <
class T,
int M,
int N,
int P,
int Q>
1979 return mul(mul(a, b, c), d);
1981template <
class T,
int M,
int N,
int P,
int Q,
int R>
1984 return mul(mul(a, b, c), d);
1986template <
class T,
int M>
1990template <
class T,
int M>
1992 return {a * b.x, a * b.y};
1994template <
class T,
int M>
1996 return {a * b.x, a * b.y, a * b.z};
1998template <
class T,
int M>
2000 return {a * b.x, a * b.y, a * b.z, a * b.w};
2008 return {a.x.x, a.y.y};
2012 return {a.x.x, a.y.y, a.z.z};
2016 return {a.x.x, a.y.y, a.z.z, a.w.w};
2018template <
class T,
int N>
2020 return sum(diagonal(a));
2022template <
class T,
int M>
2026template <
class T,
int M>
2028 return {m.row(0), m.row(1)};
2030template <
class T,
int M>
2032 return {m.row(0), m.row(1), m.row(2)};
2034template <
class T,
int M>
2036 return {m.row(0), m.row(1), m.row(2), m.row(3)};
2038template <
class T,
int M>
2048 return {{a.y.y, -a.x.y}, {-a.y.x, a.x.x}};
2054template <
class T,
int N>
2056 return transpose(adjugate(a));
2064 return a.x.x * a.y.y - a.x.y * a.y.x;
2068 return a.x.x * (a.y.y * a.z.z - a.z.y * a.y.z) +
2069 a.x.y * (a.y.z * a.z.x - a.z.z * a.y.x) +
2070 a.x.z * (a.y.x * a.z.y - a.z.x * a.y.y);
2074template <
class T,
int N>
2076 return adjugate(a) / determinant(a);
2085template <
class T,
int M>
2089template <
class T,
int M>
2093template <
class T,
int M>
2095 return begin(a) + M;
2097template <
class T,
int M>
2099 return begin(a) + M;
2101template <
class T,
int M,
int N>
2105template <
class T,
int M,
int N>
2109template <
class T,
int M,
int N>
2111 return begin(a) + N;
2113template <
class T,
int M,
int N>
2115 return begin(a) + N;
2135 return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {translation, 1}};
2139 return {{
qxdir(rotation), 0},
2140 {
qydir(rotation), 0},
2141 {
qzdir(rotation), 0},
2146 return {{scaling.x, 0, 0, 0},
2147 {0, scaling.y, 0, 0},
2148 {0, 0, scaling.z, 0},
2157 const vec<T, 3>& view_y_dir, fwd_axis fwd = neg_z);
2159mat<T, 4, 4> frustum_matrix(T x0, T x1, T y0, T y1, T n, T f,
2160 fwd_axis a = neg_z, z_range z = neg_one_to_one);
2162mat<T, 4, 4> perspective_matrix(T fovy, T aspect, T n, T f, fwd_axis a = neg_z,
2163 z_range z = neg_one_to_one) {
2164 T y = n * linalg::tan(fovy / 2), x = y * aspect;
2165 return frustum_matrix(-x, x, -y, y, n, f, a, z);
2177 vec<T, 1> operator()(
const std::array<T, 1>& a)
const {
return {a[0]}; }
2181 vec<T, 2> operator()(
const std::array<T, 2>& a)
const {
return {a[0], a[1]}; }
2185 vec<T, 3> operator()(
const std::array<T, 3>& a)
const {
2186 return {a[0], a[1], a[2]};
2191 vec<T, 4> operator()(
const std::array<T, 4>& a)
const {
2192 return {a[0], a[1], a[2], a[3]};
2198 std::array<T, 1> operator()(
const vec<T, 1>& a)
const {
return {a[0]}; }
2202 std::array<T, 2> operator()(
const vec<T, 2>& a)
const {
return {a[0], a[1]}; }
2206 std::array<T, 3> operator()(
const vec<T, 3>& a)
const {
2207 return {a[0], a[1], a[2]};
2212 std::array<T, 4> operator()(
const vec<T, 4>& a)
const {
2213 return {a[0], a[1], a[2], a[3]};
2219#ifdef MANIFOLD_DEBUG
2224std::ostream& operator<<(std::ostream& out,
const vec<T, 1>& v) {
2225 return out <<
'{' << v[0] <<
'}';
2228std::ostream& operator<<(std::ostream& out,
const vec<T, 2>& v) {
2229 return out <<
'{' << v[0] <<
',' << v[1] <<
'}';
2232std::ostream& operator<<(std::ostream& out,
const vec<T, 3>& v) {
2233 return out <<
'{' << v[0] <<
',' << v[1] <<
',' << v[2] <<
'}';
2236std::ostream& operator<<(std::ostream& out,
const vec<T, 4>& v) {
2237 return out <<
'{' << v[0] <<
',' << v[1] <<
',' << v[2] <<
',' << v[3] <<
'}';
2240template <
class T,
int M>
2241std::ostream& operator<<(std::ostream& out,
const mat<T, M, 1>& m) {
2242 return out <<
'{' << m[0] <<
'}';
2244template <
class T,
int M>
2245std::ostream& operator<<(std::ostream& out,
const mat<T, M, 2>& m) {
2246 return out <<
'{' << m[0] <<
',' << m[1] <<
'}';
2248template <
class T,
int M>
2249std::ostream& operator<<(std::ostream& out,
const mat<T, M, 3>& m) {
2250 return out <<
'{' << m[0] <<
',' << m[1] <<
',' << m[2] <<
'}';
2252template <
class T,
int M>
2253std::ostream& operator<<(std::ostream& out,
const mat<T, M, 4>& m) {
2254 return out <<
'{' << m[0] <<
',' << m[1] <<
',' << m[2] <<
',' << m[3] <<
'}';
2266struct hash<linalg::vec<T, 1>> {
2273struct hash<linalg::vec<T, 2>> {
2276 return h(v.x) ^ (h(v.y) << 1);
2280struct hash<linalg::vec<T, 3>> {
2283 return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2);
2287struct hash<linalg::vec<T, 4>> {
2290 return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2) ^ (h(v.w) << 3);
2294template <
class T,
int M>
2295struct hash<linalg::mat<T, M, 1>> {
2297 std::hash<linalg::vec<T, M>> h;
2301template <
class T,
int M>
2302struct hash<linalg::mat<T, M, 2>> {
2304 std::hash<linalg::vec<T, M>> h;
2305 return h(v.x) ^ (h(v.y) << M);
2308template <
class T,
int M>
2309struct hash<linalg::mat<T, M, 3>> {
2311 std::hash<linalg::vec<T, M>> h;
2312 return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2));
2315template <
class T,
int M>
2316struct hash<linalg::mat<T, M, 4>> {
2318 std::hash<linalg::vec<T, M>> h;
2319 return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2)) ^ (h(v.w) << (M * 3));
2328 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,
2329 a.x.y * a.y.z - a.y.y * a.x.z},
2330 {a.y.z * a.z.x - a.z.z * a.y.x, a.z.z * a.x.x - a.x.z * a.z.x,
2331 a.x.z * a.y.x - a.y.z * a.x.x},
2332 {a.y.x * a.z.y - a.z.x * a.y.y, a.z.x * a.x.y - a.x.x * a.z.y,
2333 a.x.x * a.y.y - a.y.x * a.x.y}};
2338 return {{a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
2339 a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
2340 a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w,
2341 a.x.y * a.w.z * a.z.w + a.z.y * a.x.z * a.w.w +
2342 a.w.y * a.z.z * a.x.w - a.w.y * a.x.z * a.z.w -
2343 a.z.y * a.w.z * a.x.w - a.x.y * a.z.z * a.w.w,
2344 a.x.y * a.y.z * a.w.w + a.w.y * a.x.z * a.y.w +
2345 a.y.y * a.w.z * a.x.w - a.x.y * a.w.z * a.y.w -
2346 a.y.y * a.x.z * a.w.w - a.w.y * a.y.z * a.x.w,
2347 a.x.y * a.z.z * a.y.w + a.y.y * a.x.z * a.z.w +
2348 a.z.y * a.y.z * a.x.w - a.x.y * a.y.z * a.z.w -
2349 a.z.y * a.x.z * a.y.w - a.y.y * a.z.z * a.x.w},
2350 {a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
2351 a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
2352 a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x,
2353 a.x.z * a.z.w * a.w.x + a.w.z * a.x.w * a.z.x +
2354 a.z.z * a.w.w * a.x.x - a.x.z * a.w.w * a.z.x -
2355 a.z.z * a.x.w * a.w.x - a.w.z * a.z.w * a.x.x,
2356 a.x.z * a.w.w * a.y.x + a.y.z * a.x.w * a.w.x +
2357 a.w.z * a.y.w * a.x.x - a.x.z * a.y.w * a.w.x -
2358 a.w.z * a.x.w * a.y.x - a.y.z * a.w.w * a.x.x,
2359 a.x.z * a.y.w * a.z.x + a.z.z * a.x.w * a.y.x +
2360 a.y.z * a.z.w * a.x.x - a.x.z * a.z.w * a.y.x -
2361 a.y.z * a.x.w * a.z.x - a.z.z * a.y.w * a.x.x},
2362 {a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
2363 a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
2364 a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y,
2365 a.x.w * a.w.x * a.z.y + a.z.w * a.x.x * a.w.y +
2366 a.w.w * a.z.x * a.x.y - a.x.w * a.z.x * a.w.y -
2367 a.w.w * a.x.x * a.z.y - a.z.w * a.w.x * a.x.y,
2368 a.x.w * a.y.x * a.w.y + a.w.w * a.x.x * a.y.y +
2369 a.y.w * a.w.x * a.x.y - a.x.w * a.w.x * a.y.y -
2370 a.y.w * a.x.x * a.w.y - a.w.w * a.y.x * a.x.y,
2371 a.x.w * a.z.x * a.y.y + a.y.w * a.x.x * a.z.y +
2372 a.z.w * a.y.x * a.x.y - a.x.w * a.y.x * a.z.y -
2373 a.z.w * a.x.x * a.y.y - a.y.w * a.z.x * a.x.y},
2374 {a.y.x * a.w.y * a.z.z + a.z.x * a.y.y * a.w.z +
2375 a.w.x * a.z.y * a.y.z - a.y.x * a.z.y * a.w.z -
2376 a.w.x * a.y.y * a.z.z - a.z.x * a.w.y * a.y.z,
2377 a.x.x * a.z.y * a.w.z + a.w.x * a.x.y * a.z.z +
2378 a.z.x * a.w.y * a.x.z - a.x.x * a.w.y * a.z.z -
2379 a.z.x * a.x.y * a.w.z - a.w.x * a.z.y * a.x.z,
2380 a.x.x * a.w.y * a.y.z + a.y.x * a.x.y * a.w.z +
2381 a.w.x * a.y.y * a.x.z - a.x.x * a.y.y * a.w.z -
2382 a.w.x * a.x.y * a.y.z - a.y.x * a.w.y * a.x.z,
2383 a.x.x * a.y.y * a.z.z + a.z.x * a.x.y * a.y.z +
2384 a.y.x * a.z.y * a.x.z - a.x.x * a.z.y * a.y.z -
2385 a.y.x * a.x.y * a.z.z - a.z.x * a.y.y * a.x.z}};
2389constexpr T linalg::determinant(
const mat<T, 4, 4>& a) {
2390 return a.x.x * (a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
2391 a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
2392 a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w) +
2393 a.x.y * (a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
2394 a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
2395 a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x) +
2396 a.x.z * (a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
2397 a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
2398 a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y) +
2399 a.x.w * (a.y.x * a.w.y * a.z.z + a.z.x * a.y.y * a.w.z +
2400 a.w.x * a.z.y * a.y.z - a.y.x * a.z.y * a.w.z -
2401 a.w.x * a.y.y * a.z.z - a.z.x * a.w.y * a.y.z);
2406 const vec<T, 3>& dest) {
2407 T cosTheta =
dot(orig, dest);
2408 if (cosTheta >= 1 - std::numeric_limits<T>::epsilon()) {
2409 return {0, 0, 0, 1};
2411 if (cosTheta < -1 + std::numeric_limits<T>::epsilon()) {
2412 vec<T, 3> axis =
cross(vec<T, 3>(0, 0, 1), orig);
2413 if (
length2(axis) < std::numeric_limits<T>::epsilon())
2414 axis =
cross(vec<T, 3>(1, 0, 0), orig);
2416 3.14159265358979323846264338327950288);
2418 vec<T, 3> axis =
cross(orig, dest);
2419 T s = std::sqrt((1 + cosTheta) * 2);
2420 return {axis * (1 / s), s * 0.5};
2425 const vec<T, 4> q{m.x.x - m.y.y - m.z.z, m.y.y - m.x.x - m.z.z,
2426 m.z.z - m.x.x - m.y.y, m.x.x + m.y.y + m.z.z},
2427 s[]{{1, m.x.y + m.y.x, m.z.x + m.x.z, m.y.z - m.z.y},
2428 {m.x.y + m.y.x, 1, m.y.z + m.z.y, m.z.x - m.x.z},
2429 {m.x.z + m.z.x, m.y.z + m.z.y, 1, m.x.y - m.y.x},
2430 {m.y.z - m.z.y, m.z.x - m.x.z, m.x.y - m.y.x, 1}};
2431 return copysign(
normalize(sqrt(max(T(0), T(1) + q))), s[argmax(q)]);
2436 const vec<T, 3>& center,
2437 const vec<T, 3>& view_y_dir,
2439 const vec<T, 3> f =
normalize(center - eye), z = a == pos_z ? f : -f,
2441 return inverse(mat<T, 4, 4>{{x, 0}, {y, 0}, {z, 0}, {eye, 1}});
2446 fwd_axis a, z_range z) {
2447 const T s = a == pos_z ? T(1) : T(-1), o = z == neg_one_to_one ? n : 0;
2448 return {{2 * n / (x1 - x0), 0, 0, 0},
2449 {0, 2 * n / (y1 - y0), 0, 0},
2450 {-s * (x0 + x1) / (x1 - x0), -s * (y0 + y1) / (y1 - y0),
2451 s * (f + o) / (f - n), s},
2452 {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:1846
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:1884
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:1861
constexpr vec< T, 3 > qzdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,0,1})
Definition linalg.h:1838
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:1877
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:1869
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:1892
constexpr vec< T, 3 > qxdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {1,0,0})
Definition linalg.h:1821
constexpr vec< T, 3 > qrot(const vec< T, 4 > &q, const vec< T, 3 > &v)
Rotate a vector by a quaternion.
Definition linalg.h:1853
constexpr vec< T, 3 > qydir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,1,0})
Definition linalg.h:1829
vec< T, 4 > qinv(const vec< T, 4 > &q)
inverse or reciprocal of quaternion q (undefined for zero-length quaternions)
Definition linalg.h:1754
vec< T, 4 > qexp(const vec< T, 4 > &q)
exponential of quaternion q
Definition linalg.h:1763
vec< T, 4 > qpow(const vec< T, 4 > &q, const T &p)
quaternion q raised to the exponent p
Definition linalg.h:1784
vec< T, 4 > qlog(const vec< T, 4 > &q)
logarithm of quaternion q
Definition linalg.h:1775
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:1797
constexpr vec< T, 4 > qconj(const vec< T, 4 > &q)
conjugate of quaternion q
Definition linalg.h:1745
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:1555
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:1564
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:1573
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:1424
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:1440
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:1432
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:1699
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:1681
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:1650
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:1690
constexpr T length2(const vec< T, M > &a)
square of the length or magnitude of vector a
Definition linalg.h:1625
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:1618
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:1716
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:1641
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:1725
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:1673
T uangle(const vec< T, M > &a, const vec< T, M > &b)
Return the angle in radians between two unit vectors.
Definition linalg.h:1665
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:1588
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:1708
T length(const vec< T, M > &a)
length or magnitude of a vector a
Definition linalg.h:1632
T distance(const vec< T, M > &a, const vec< T, M > &b)
Euclidean distance between points a and b
Definition linalg.h:1658