XRPrimer (C++ API)  0.6.0
math_util.h
Go to the documentation of this file.
1 #pragma once
2 #include <Eigen/Core>
3 #include <cfloat>
4 #include <cmath>
5 #include <fstream>
6 #include <type_traits>
7 
8 namespace MathUtil {
9 typedef Eigen::Matrix<unsigned char, Eigen::Dynamic, Eigen::Dynamic> MatrixXb;
10 typedef Eigen::Matrix<unsigned char, 3, 3> Matrix3b;
11 typedef Eigen::Matrix<unsigned char, 3, Eigen::Dynamic> Matrix3Xb;
12 typedef Eigen::Matrix<unsigned char, 4, Eigen::Dynamic> Matrix4Xb;
13 typedef Eigen::Matrix<unsigned char, 2, 1> Vector2b;
14 typedef Eigen::Matrix<unsigned char, 3, 1> Vector3b;
15 typedef Eigen::Matrix<unsigned char, 4, 1> Vector4b;
16 typedef Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic> MatrixXu;
17 typedef Eigen::Matrix<unsigned int, 3, 3> Matrix3u;
18 typedef Eigen::Matrix<unsigned int, 3, Eigen::Dynamic> Matrix3Xu;
19 typedef Eigen::Matrix<unsigned int, 4, Eigen::Dynamic> Matrix4Xu;
20 typedef Eigen::Matrix<unsigned int, 2, 1> Vector2u;
21 typedef Eigen::Matrix<unsigned int, 3, 1> Vector3u;
22 typedef Eigen::Matrix<unsigned int, 4, 1> Vector4u;
23 typedef Eigen::Matrix<float, 6, 1> Vector6f;
24 typedef Eigen::Matrix<float, 3, 4> Matrix34f;
25 typedef Eigen::Matrix<float, 3, 2> Matrix32f;
26 typedef Eigen::Matrix<double, 6, 1> Vector6d;
27 typedef Eigen::Matrix<double, 3, 4> Matrix34d;
28 typedef Eigen::Matrix<double, 3, 2> Matrix32d;
29 
30 // basic
31 template <typename T> inline bool Equal(const T &a, const T &b) {
32  if (std::is_same<float, std::decay<T>>::value)
33  return (a - b <= FLT_EPSILON && a - b >= -FLT_EPSILON);
34  else if (std::is_same<double, std::decay<T>>::value)
35  return (a - b <= DBL_EPSILON && a - b >= -DBL_EPSILON);
36  else
37  return a == b;
38 }
39 
40 template <typename T> inline bool EqualZero(const T &a) { return Equal(a, 0); }
41 
42 template <typename T>
43 inline bool Approx(const T &a, const T &b, const T &rate = 10) {
45  return (a - b <= rate * FLT_EPSILON && a - b >= -rate * FLT_EPSILON);
47  return (a - b <= rate * DBL_EPSILON && a - b >= -rate * DBL_EPSILON);
48  else
49  return a == b;
50 }
51 
52 template <typename T> inline bool ApproxZero(const T &a, const T &rate = 10) {
53  return Approx(a, T(0), rate);
54 }
55 
56 // Linear Algebra
57 template <typename T>
58 inline Eigen::Matrix<T, 3, 3> Skew(const Eigen::Matrix<T, 3, 1> &vec) {
59  Eigen::Matrix<T, 3, 3> skew;
60  skew << 0, -vec.z(), vec.y(), vec.z(), 0, -vec.x(), -vec.y(), vec.x(), 0;
61  return skew;
62 }
63 
64 template <typename T>
65 inline Eigen::Matrix<T, 3, 3> Rodrigues(const Eigen::Matrix<T, 3, 1> &vec) {
66  const T theta = vec.norm();
67  const Eigen::Matrix<T, 3, 3> I = Eigen::Matrix<T, 3, 3>::Identity();
68 
69  if (ApproxZero(theta))
70  return I;
71  else {
72  const T c = std::cos(theta);
73  const T s = std::sin(theta);
74  const T itheta = 1 / theta;
75  const Eigen::Matrix<T, 3, 1> r = vec / theta;
76  return c * I + (1 - c) * r * r.transpose() + s * Skew(r);
77  }
78 }
79 
80 template <typename T>
81 inline Eigen::Matrix<T, 3, 9>
82 RodriguesJacobi(const Eigen::Matrix<T, 3, 1> &vec) {
83  const T theta = vec.norm();
84  Eigen::Matrix<T, 3, 9> dSkew;
85  dSkew.setZero();
86  dSkew(0, 5) = dSkew(1, 6) = dSkew(2, 1) = -1;
87  dSkew(0, 7) = dSkew(1, 2) = dSkew(2, 3) = 1;
88  if (ApproxZero(theta)) {
89  return -dSkew;
90  } else {
91  const T c = std::cos(theta);
92  const T s = std::sin(theta);
93  const T c1 = 1 - c;
94  const T itheta = 1 / theta;
95  const Eigen::Matrix<T, 3, 1> r = vec / theta;
96  const Eigen::Matrix<T, 3, 3> rrt = r * r.transpose();
97  const Eigen::Matrix<T, 3, 3> skew = Skew(r);
98  const Eigen::Matrix<T, 3, 3> I = Eigen::Matrix3f::Identity();
99  Eigen::Matrix<T, 3, 9> drrt;
100  drrt << r.x() + r.x(), r.y(), r.z(), r.y(), 0, 0, r.z(), 0, 0, 0, r.x(),
101  0, r.x(), r.y() + r.y(), r.z(), 0, r.z(), 0, 0, 0, r.x(), 0, 0,
102  r.y(), r.x(), r.y(), r.z() + r.z();
103  Eigen::Matrix<T, 3, 9> jaocbi;
104  Eigen::Matrix<T, 5, 1> a;
105  for (int i = 0; i < 3; i++) {
106  a << -s * r[i], (s - 2 * c1 * itheta) * r[i], c1 * itheta,
107  (c - s * itheta) * r[i], s * itheta;
108  for (int j = 0; j < 3; j++)
109  for (int k = 0; k < 3; k++)
110  jaocbi(i, k + k + k + j) =
111  (a[0] * I(j, k) + a[1] * rrt(j, k) +
112  a[2] * drrt(i, j + j + j + k) + a[3] * skew(j, k) +
113  a[4] * dSkew(i, j + j + j + k));
114  }
115  return jaocbi;
116  }
117 }
118 
119 // robust function
120 template <typename T> inline T Welsch(const T &c, const T &_x) {
121  const T x = _x / c;
122  return 1 - exp(-x * x / 2);
123 }
124 
125 // 3D measure
126 template <typename T>
127 inline T Point2LineDist(const Eigen::Matrix<T, 3, 1> &pA,
128  const Eigen::Matrix<T, 3, 1> &pB,
129  const Eigen::Matrix<T, 3, 1> &ray) {
130  return ((pA - pB).cross(ray)).norm();
131 }
132 
133 template <typename T>
134 inline T Line2LineDist(const Eigen::Matrix<T, 3, 1> &pA,
135  const Eigen::Matrix<T, 3, 1> &rayA,
136  const Eigen::Matrix<T, 3, 1> &pB,
137  const Eigen::Matrix<T, 3, 1> &rayB) {
138  if (Approx<T>(rayA.dot(rayB), 1))
139  return Point2LineDist(pA, pB, rayA);
140  else
141  return std::abs((pA - pB).dot((rayA.cross(rayB)).normalized()));
142 }
143 
144 // others
145 inline int LayGrid(const int &x, const int &dim) { return (x + dim - 1) / dim; }
146 } // namespace MathUtil
Eigen::Matrix< unsigned char, 4, 1 > Vector4b
Definition: math_util.h:15
bool Approx(const T &a, const T &b, const T &rate=10)
Definition: math_util.h:43
bool ApproxZero(const T &a, const T &rate=10)
Definition: math_util.h:52
Eigen::Matrix< unsigned char, Eigen::Dynamic, Eigen::Dynamic > MatrixXb
Definition: math_util.h:9
GeneratorWrapper< T > value(T &&value)
Definition: catch.hpp:4001
Eigen::Matrix< unsigned char, 3, 3 > Matrix3b
Definition: math_util.h:10
Eigen::Matrix< unsigned char, 2, 1 > Vector2b
Definition: math_util.h:13
T Point2LineDist(const Eigen::Matrix< T, 3, 1 > &pA, const Eigen::Matrix< T, 3, 1 > &pB, const Eigen::Matrix< T, 3, 1 > &ray)
Definition: math_util.h:127
T Welsch(const T &c, const T &_x)
Definition: math_util.h:120
Eigen::Matrix< float, 6, 1 > Vector6f
Definition: math_util.h:23
Eigen::Matrix< float, 3, 2 > Matrix32f
Definition: math_util.h:25
Eigen::Matrix< double, 3, 4 > Matrix34d
Definition: math_util.h:27
Eigen::Matrix< float, 3, 4 > Matrix34f
Definition: math_util.h:24
Eigen::Matrix< unsigned int, 2, 1 > Vector2u
Definition: math_util.h:20
Eigen::Matrix< double, 6, 1 > Vector6d
Definition: math_util.h:26
Eigen::Matrix< T, 3, 3 > Skew(const Eigen::Matrix< T, 3, 1 > &vec)
Definition: math_util.h:58
Eigen::Matrix< T, 3, 9 > RodriguesJacobi(const Eigen::Matrix< T, 3, 1 > &vec)
Definition: math_util.h:82
Eigen::Matrix< unsigned char, 4, Eigen::Dynamic > Matrix4Xb
Definition: math_util.h:12
T Line2LineDist(const Eigen::Matrix< T, 3, 1 > &pA, const Eigen::Matrix< T, 3, 1 > &rayA, const Eigen::Matrix< T, 3, 1 > &pB, const Eigen::Matrix< T, 3, 1 > &rayB)
Definition: math_util.h:134
Eigen::Matrix< unsigned int, 3, 3 > Matrix3u
Definition: math_util.h:17
Eigen::Matrix< T, 3, 3 > Rodrigues(const Eigen::Matrix< T, 3, 1 > &vec)
Definition: math_util.h:65
Eigen::Matrix< unsigned int, 3, 1 > Vector3u
Definition: math_util.h:21
bool Equal(const T &a, const T &b)
Definition: math_util.h:31
Eigen::Matrix< unsigned char, 3, Eigen::Dynamic > Matrix3Xb
Definition: math_util.h:11
Eigen::Matrix< double, 3, 2 > Matrix32d
Definition: math_util.h:28
Eigen::Matrix< unsigned int, 3, Eigen::Dynamic > Matrix3Xu
Definition: math_util.h:18
int LayGrid(const int &x, const int &dim)
Definition: math_util.h:145
Eigen::Matrix< unsigned int, 4, 1 > Vector4u
Definition: math_util.h:22
Eigen::Matrix< unsigned int, 4, Eigen::Dynamic > Matrix4Xu
Definition: math_util.h:19
Eigen::Matrix< unsigned int, Eigen::Dynamic, Eigen::Dynamic > MatrixXu
Definition: math_util.h:16
bool EqualZero(const T &a)
Definition: math_util.h:40
Eigen::Matrix< unsigned char, 3, 1 > Vector3b
Definition: math_util.h:14
Definition: math_util.h:8