42 #define M_PI (3.14159265358979323846) 58 return (a == T(0)) || (a > 0 && a < e) || (a < 0 && a > -e);
72 explicit vec3d() : x(0), y(0), z(0) {}
73 vec3d(T x_, T y_, T z_) : x(x_), y(y_), z(z_) {}
79 vec3d(
const S* s) : x(T(s[0])), y(T(s[1])), z(T(s[2])) {}
116 template <
typename S>
133 template <
typename Scalar>
136 const T i = T(1) / T(s);
143 template <
typename Scalar>
154 return (x == o.
x) && (y == o.
y) && (z == o.
z);
157 template <
typename S>
160 return (x == T(o.
x) && y == T(o.
y) && z == T(o.
z));
165 return !(*
this == o);
168 template <
typename S>
171 return !(*
this == o);
174 template <
typename Scalar>
180 template <
typename Scalar>
186 template <
typename Scalar>
189 return vec3d<T>(p.
x / T(s), p.
y / T(s), p.
z / T(s));
192 friend std::ostream& operator<<(std::ostream& os, const vec3d<T>& p)
194 return (os << p.x <<
" " << p.y <<
" " << p.z);
199 return (is >> p.
x >> p.
y >> p.
z);
226 triangle(
int id0,
int id1,
int id2) : id0(id0), id1(id1), id2(id2) {}
228 : p0(p0_), p1(p1_), p2(p2_), n(n_) {}
230 : p0(p0_), p1(p1_), p2(p2_), id0(id0_), id1(id1_), id2(id2_), n(n_) {}
231 triangle(
const point3d& p0_,
const point3d& p1_,
const point3d& p2_,
const normal3d& n_)
232 : p0(p0_), p1(p1_), p2(p2_), n(n_) {}
235 o << t.
p0 <<
" " << t.
p1 <<
" " << t.
p2;
245 invalid_vector(
const std::string& msg) :
std::logic_error(
"Exception invalid_vector caught: " + msg) {}
272 explicit matrix() : super(), width_(0), height_(0), width(width_), height(height_) {}
274 matrix(
int w,
int h) : super(w * h), width_(w), height_(h), width(width_), height(height_) {}
276 matrix(
int w,
int h,
const T& v) : super(w * h, v), width_(w), height_(h), width(width_), height(height_) {}
286 return super::operator[](r * width_ + c);
288 typename super::const_reference
operator()(
size_t r,
size_t c)
const 290 return super::operator[](r * width_ + c);
293 typename super::reference
at(
const size_t r,
const size_t c)
295 return super::at(r * width_ + c);
297 typename super::const_reference
at(
size_t r,
size_t c)
const 299 return super::at(r * width_ + c);
304 return &(super::operator[](0));
309 return &(super::operator[](0));
314 super::resize(w * h);
321 return super::size();
326 return super::begin();
330 return super::begin();
336 const_iterator
end()
const 346 const_iterator it1(begin()), it2(m.
begin()), it1_end(end());
348 for (; it1 != it1_end; ++it1, ++it2)
349 if (*it1 != *it2)
return false;
356 return !(*
this == m);
365 throw invalid_vector(
"Cannot assign matrices with different sizes.");
371 template <
typename S>
374 for (
size_t i = 0; i < size(); ++i)
375 super::operator[](i) *= T(s);
379 template <
typename S>
382 for (
size_t i = 0; i < size(); ++i)
383 super::operator[](i) /= T(s);
387 friend std::ostream& operator<<(std::ostream& s, const matrix<T>& m)
389 for (
int y = 0; y < m.height_; ++y)
391 for (
int x = 0; x < m.width_; ++x)
393 s << m[y * m.width_ + x] <<
" ";
412 : r00(0), r01(0), r02(0)
413 , r10(0), r11(0), r12(0)
414 , r20(0), r21(0), r22(0)
415 , width(3), height(3)
418 template <
typename S>
420 : r00(v[0]), r01(v[1]), r02(v[2])
421 , r10(v[3]), r11(v[4]), r12(v[5])
422 , r20(v[6]), r21(v[7]), r22(v[8])
423 , width(3), height(3)
451 throw std::logic_error(
"Cannot set column for 3x3 matrix.");
459 if (col == 0)
return r00;
460 if (col == 1)
return r01;
461 if (col == 2)
return r02;
462 else throw std::out_of_range(
"Cannot access element in 3x3 matrix");
464 if (col == 0)
return r10;
465 if (col == 1)
return r11;
466 if (col == 2)
return r12;
467 else throw std::out_of_range(
"Cannot access element in 3x3 matrix");
469 if (col == 0)
return r20;
470 if (col == 1)
return r21;
471 if (col == 2)
return r22;
472 else throw std::out_of_range(
"Cannot access element in 3x3 matrix");
474 throw std::out_of_range(
"Cannot access element in 3x3 matrix");
483 if (col == 0)
return r00;
484 if (col == 1)
return r01;
485 if (col == 2)
return r02;
486 else throw std::out_of_range(
"Cannot access element in 3x3 matrix");
488 if (col == 0)
return r10;
489 if (col == 1)
return r11;
490 if (col == 2)
return r12;
491 else throw std::out_of_range(
"Cannot access element in 3x3 matrix");
493 if (col == 0)
return r20;
494 if (col == 1)
return r21;
495 if (col == 2)
return r22;
496 else throw std::out_of_range(
"Cannot access element in 3x3 matrix");
498 throw std::out_of_range(
"Cannot access element in 3x3 matrix");
502 friend std::ostream& operator<<(std::ostream& s, const matrix3x3<T>& m)
504 s << m.r00 <<
" " << m.r01 <<
" " << m.r02 << std::endl;
505 s << m.r10 <<
" " << m.r11 <<
" " << m.r12 << std::endl;
506 s << m.r20 <<
" " << m.r21 <<
" " << m.r22 << std::endl;
512 template <
typename T>
521 template <
typename T>
547 template <
typename T>
550 if (&r == &m1 || &r == &m2)
throw std::logic_error(
"math3d::mult_matrix() argument alias");
551 return mult_matrix_inplace<T>(m1, m2,
r);
555 template <
typename Rot1,
typename Rot2,
typename Rot3>
558 if ((
char*)&r == (
char*)&m1 || (
char*)&r == (
char*)&m2)
559 throw std::logic_error(
"math3d::mult_matrix() argument alias");
561 if (m1.width != m2.height || r.height != m1.height || r.width != m2.width)
562 throw std::logic_error(
"Incompatible size matrices");
566 for (
int is = 0; is < m1.height; ++is)
568 for (
int jd = 0; jd < m2.width; ++jd)
571 for (
int js = 0; js < m1.width; ++js)
573 sum += m1(is, js) * m2(js, jd);
584 template <
typename T>
591 quaternion(T ww, T ii, T jj, T kk) : w(ww), i(ii), j(jj), k(kk) {}
629 friend std::ostream& operator<<(std::ostream& os, const quaternion<T>& q)
631 return os <<
"[ " << q.w <<
" " << q.i <<
" " << q.j <<
" " << q.k <<
" ]";
637 return (is >> dump >> q.
w >> q.
i >> q.
j >> q.
k >> dump);
641 template <
typename T>
649 template <
typename T>
652 return a.
w * b.
w + a.
i * b.
i + a.
j * b.
j + a.
k * b.
k;
655 template <
typename T>
658 return std::sqrt(
dot(a, a));
661 template <
typename T>
666 result.
w = a.
w * b.
w - a.
i * b.
i - a.
j * b.
j - a.
k * b.
k;
667 result.
i = a.
i * b.
w + a.
w * b.
i - a.
k * b.
j + a.
j * b.
k;
668 result.
j = a.
j * b.
w + a.
k * b.
i + a.
w * b.
j - a.
i * b.
k;
669 result.
k = a.
k * b.
w - a.
j * b.
i + a.
i * b.
j + a.
w * b.
k;
674 template <
typename T>
680 template <
typename T>
688 template <
typename T>
691 T mag = q.
w * q.
w + q.
i * q.
i + q.
j * q.
j + q.
k * q.
k;
694 mag = std::sqrt(mag);
702 template <
typename T>
706 q.
i = q.
j = q.
k = T(0);
713 const T m00 = m(0, 0);
714 const T m11 = m(1, 1);
715 const T m22 = m(2, 2);
716 const T m01 = m(0, 1);
717 const T m02 = m(0, 2);
718 const T m10 = m(1, 0);
719 const T m12 = m(1, 2);
720 const T m20 = m(2, 0);
721 const T m21 = m(2, 1);
722 const T tr = m00 + m11 + m22;
728 T
s = std::sqrt(tr + T(1)) * 2;
730 ret.
i = (m21 - m12) / s;
731 ret.
j = (m02 - m20) / s;
732 ret.
k = (m10 - m01) / s;
734 else if ((m00 > m11) & (m00 > m22))
736 const T
s = std::sqrt(T(1) + m00 - m11 - m22) * 2;
737 ret.
w = (m21 - m12) / s;
739 ret.
j = (m01 + m10) / s;
740 ret.
k = (m02 + m20) / s;
744 const T
s = std::sqrt(T(1) + m11 - m00 - m22) * 2;
745 ret.
w = (m02 - m20) / s;
746 ret.
i = (m01 + m10) / s;
748 ret.
k = (m12 + m21) / s;
752 const T
s = std::sqrt(T(1) + m22 - m00 - m11) * 2;
753 ret.
w = (m10 - m01) / s;
754 ret.
i = (m02 + m20) / s;
755 ret.
j = (m12 + m21) / s;
763 template <
typename T>
767 const T w = q.
w, i = q.
i, j = q.
j, k = q.
k;
769 m(0, 0) = 1 - 2 * j * j - 2 * k * k;
770 m(0, 1) = 2 * i * j - 2 * k * w;
771 m(0, 2) = 2 * i * k + 2 * j * w;
773 m(1, 0) = 2 * i * j + 2 * k * w;
774 m(1, 1) = 1 - 2 * i * i - 2 * k * k;
775 m(1, 2) = 2 * j * k - 2 * i * w;
777 m(2, 0) = 2 * i * k - 2 * j * w;
778 m(2, 1) = 2 * j * k + 2 * i * w;
779 m(2, 2) = 1 - 2 * i * i - 2 * j * j;
784 template <
typename T>
787 r.
w = a.
w * b.
w - (a.
i * b.
i + a.
j * b.
j + a.
k * b.
k);
788 r.
i = a.
w * b.
i + b.
w * a.
i + a.
j * b.
k - a.
k * b.
j;
789 r.
j = a.
w * b.
j + b.
w * a.
j + a.
k * b.
i - a.
i * b.
k;
790 r.
k = a.
w * b.
k + b.
w * a.
k + a.
i * b.
j - a.
j * b.
i;
797 template <
typename T>
801 const int w = m.
width;
805 for (
int row = 0; row < h; ++row)
807 for (
int col = 0; col < w; ++col)
809 m(col, row) = old(row, col);
814 template <
typename T>
826 template <
typename T>
843 template <
typename T>
849 const int w = src.
width;
852 for (
int row = 0; row < h; ++row)
854 for (
int col = 0; col < w; ++col)
856 dest(col, row) = src(row, col);
861 template <
typename T>
875 template <
typename T>
879 throw invalid_vector(
"Cannot set identity on a rectangular matrix.");
885 const int w = m.
width;
888 for (
int k = 0; k < n; ++k)
892 m(k / w, k % w) = val;
900 template <
typename T>
921 template <
typename T>
925 throw std::logic_error(
"Rotation matrix must be 3x3");
927 T oldx = p.
x, oldy = p.
y, oldz = p.
z;
928 p.
x = oldx * rot(0, 0) + oldy * rot(0, 1) + oldz * rot(0, 2);
929 p.
y = oldx * rot(1, 0) + oldy * rot(1, 1) + oldz * rot(1, 2);
930 p.
z = oldx * rot(2, 0) + oldy * rot(2, 1) + oldz * rot(2, 2);
933 template <
typename T>
936 T oldx = p.
x, oldy = p.
y, oldz = p.
z;
937 p.
x = oldx * rot.
r00 + oldy * rot.
r01 + oldz * rot.
r02;
938 p.
y = oldx * rot.
r10 + oldy * rot.
r11 + oldz * rot.
r12;
939 p.
z = oldx * rot.
r20 + oldy * rot.
r21 + oldz * rot.
r22;
942 template <
typename T,
typename S>
946 throw std::logic_error(
"Rotation matrix must be 3x3");
948 T oldx = p.
x, oldy = p.
y, oldz = p.
z;
949 p.
x = T(oldx * rot(0, 0) + oldy * rot(0, 1) + oldz * rot(0, 2));
950 p.
y = T(oldx * rot(1, 0) + oldy * rot(1, 1) + oldz * rot(1, 2));
951 p.
z = T(oldx * rot(2, 0) + oldy * rot(2, 1) + oldz * rot(2, 2));
954 template <
typename T,
typename S>
957 T oldx = p.
x, oldy = p.
y, oldz = p.
z;
958 p.
x = T(oldx * rot.
r00 + oldy * rot.
r01 + oldz * rot.
r02);
959 p.
y = T(oldx * rot.
r10 + oldy * rot.
r11 + oldz * rot.
r12);
960 p.
z = T(oldx * rot.
r20 + oldy * rot.
r21 + oldz * rot.
r22);
963 template <
typename T>
970 template <
typename T>
987 template <
typename T>
996 template <
typename T,
typename RotationType>
1003 template <
typename T>
1011 template <
typename T>
1015 throw std::logic_error(
"Rotation matrix must be 3x3");
1017 return vec3d<T>(p.
x * rot(0, 0) + p.
y * rot(0, 1) + p.
z * rot(0, 2) + t.
x,
1018 p.
x * rot(1, 0) + p.
y * rot(1, 1) + p.
z * rot(1, 2) + t.
y,
1019 p.
x * rot(2, 0) + p.
y * rot(2, 1) + p.
z * rot(2, 2) + t.
z);
1022 template <
typename T>
1028 template <
typename T>
1038 template <
typename R,
typename T>
1053 template <
typename T>
1063 point3d Ti_inv = Ti;
1075 template <
typename T>
1094 template <
typename T>
1102 template <
typename T>
1103 inline double dist(
const T& p1,
const T& p2)
1106 return (sqdist == 0. ? 0. : std::sqrt(sqdist));
1110 template <
typename T>
1116 return ((x * x) + (y * y) + (z * z));
1119 template <
typename T>
1122 return (v1.
x * v2.
x) + (v1.
y * v2.
y) + (v1.
z * v2.
z);
1125 template <
typename T,
typename S>
1128 return (v1.
x * v2.
x) + (v1.
y * v2.
y) + (v1.
z * v2.
z);
1131 template <
typename T>
1134 return (p.
w * q.
w + p.
i * q.
i + p.
j * q.
j + p.
k * q.
k);
1137 template <
typename T>
1143 template <
typename T>
1149 template <
typename T>
1153 (v1.
y * v2.
z) - (v1.
z * v2.
y),
1154 (v1.
z * v2.
x) - (v1.
x * v2.
z),
1155 (v1.
x * v2.
y) - (v1.
y * v2.
x)
1160 template <
typename Iterator>
1161 inline double median(Iterator start, Iterator end)
1163 const typename Iterator::difference_type n = end - start;
1164 if (n <= 0)
return 0.;
1167 return (*(start + (n / 2)) + * (start + (n / 2 - 1))) / 2.;
1169 return *(start + ((n - 1) / 2));
T & operator()(size_t row, size_t col)
vec3d< T > & operator-=(const vec3d< S > &p)
triangle(const point3d &p0_, const point3d &p1_, const point3d &p2_, const normal3d &n_)
const_iterator begin() const
matrix(int w, int h, const T &v)
void rotate_translate(vec3d< T > &v, const RotationType &rot, const point3d &trans)
bool operator==(const vec3d &o) const
void transpose(matrix< T > &m)
void resize(int w, int h)
color_rgb24(uint8_t R, uint8_t G, uint8_t B)
bool operator!=(const vec3d &o) const
oriented_point3d(const point3d &p, const normal3d &nn)
triangle(int id0, int id1, int id2)
quaternion< T > operator~(const quaternion< T > &a)
vec3d< T > operator-(const vec3d< T > &p) const
quaternion(T ww, T ii, T jj, T kk)
friend std::istream & operator>>(std::istream &is, vec3d< T > &p)
std::pair< matrix3x3< double >, point3d > rigid_motion_t
oriented_point3d(const oriented_point3d &p)
matrix & operator=(const matrix< T > &m)
invalid_vector(const std::string &msg)
double median(Iterator start, Iterator end)
matrix3x3< T > identity3x3()
triangle(const oriented_point3d &p0_, const oriented_point3d &p1_, const oriented_point3d &p2_, const normal3d &n_)
static const double rad_on_deg
void to_vector(T *p) const
static const double deg_on_rad
matrix(const matrix< T > &m)
T dot_product(const vec3d< T > &v1, const vec3d< T > &v2)
void set_column(size_t c, const vec3d< T > &v)
void set_identity(quaternion< T > &q)
super::reference operator()(size_t r, size_t c)
vec3d< T > & operator/=(const Scalar &s)
bool operator!=(const vec3d< S > &o) const
friend vec3d< T > operator/(const vec3d< T > &p, const Scalar &s)
double dist(const T &p1, const T &p2)
vec3d< T > operator+(const vec3d< T > &p) const
triangle(const oriented_point3d &p0_, const oriented_point3d &p1_, const oriented_point3d &p2_, const normal3d &n_, int id0_, int id1_, int id2_)
matrix< T > & operator/=(const S &s)
matrix3x3< T > get_transpose(const matrix3x3< T > &m)
friend std::istream & operator>>(std::istream &is, quaternion< T > &q)
T norm(const quaternion< T > &a)
const_iterator end() const
super::const_reference at(size_t r, size_t c) const
void relative_motion(const matrix3x3< T > &Ri, const point3d &Ti, const matrix3x3< T > &Rj, const point3d &Tj, matrix3x3< T > &Rij, point3d &Tij)
super::const_iterator const_iterator
void rotate(vec3d< T > &p, const matrix< T > &rot)
T dot(const quaternion< T > &a, const quaternion< T > &b)
vec3d< T > & operator+=(const vec3d< S > &p)
bool operator==(const matrix< T > &m) const
static quaternion< T > convert(const T *p)
bool almost_zero(T a, double e)
vec3d< T > & operator+=(const vec3d< T > &p)
vec3d< T > get_normalize(const vec3d< T > &p)
quaternion< T > operator*(const quaternion< T > &a, const quaternion< T > &b)
bool operator==(const vec3d< S > &o) const
oriented_point3d(const point3d &p)
quaternion< T > operator+(const quaternion< T > &a, const quaternion< T > &b)
vec3d< T > operator-() const
vec3d< T > & operator*=(const Scalar &s)
static quaternion< T > convert(const vec3d< T > &p)
super::const_reference operator()(size_t r, size_t c) const
vec3d< T > cross_product(const vec3d< T > &v1, const vec3d< T > &v2)
vec3d< T > get_rotate_translate(const vec3d< T > &p, const matrix3x3< T > &rot, const point3d &t)
super::reference at(const size_t r, const size_t c)
double squared_dist(const vec3d< T > &p1, const vec3d< T > &p2)
double magnitude(const T &p)
void normalize(quaternion< T > &q)
void mult_matrix(const matrix3x3< T > &m1, const matrix3x3< T > &m2, matrix3x3< T > &r)
friend vec3d< T > operator*(const vec3d< T > &p, const Scalar &s)
const T & operator()(size_t row, size_t col) const
friend vec3d< T > operator*(const Scalar &s, const vec3d< T > &p)
vec3d< T > get_rotate(const vec3d< T > &v, const quaternion< T > &q)
void mult_matrix_inplace(const matrix3x3< T > &m1, const matrix3x3< T > &m2, matrix3x3< T > &r)
quaternion< T > rot_matrix_to_quaternion(const matrix3x3< T > &m)
vec3d(const vec3d< S > &s)
void conjugate(quaternion< T > &q)
bool operator!=(const matrix< T > &m) const
friend std::ostream & operator<<(std::ostream &o, const triangle &t)
void mult_quaternion(const quaternion< T > &a, const quaternion< T > &b, quaternion< T > &r)
oriented_point3d(double xx, double yy, double zz)
matrix3x3< T > quaternion_to_rot_matrix(const quaternion< T > &q)
vec3d< T > & operator-=(const vec3d< T > &p)
matrix< T > & operator*=(const S &s)