Main MRPT website > C++ reference for MRPT 1.9.9
homog_matrices.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #ifndef MRPT_HOMOG_MATRICES_H
10 #define MRPT_HOMOG_MATRICES_H
11 
12 #include <mrpt/config.h>
14 #include <mrpt/utils/mrpt_macros.h>
15 
16 namespace mrpt
17 {
18 namespace math
19 {
20 /** Efficiently compute the inverse of a 4x4 homogeneous matrix by only
21  * transposing the rotation 3x3 part and solving the translation with dot
22  * products.
23  * This is a generic template which works with:
24  * MATRIXLIKE: CMatrixTemplateNumeric, CMatrixFixedNumeric
25  */
26 template <class MATRIXLIKE1, class MATRIXLIKE2>
27 void homogeneousMatrixInverse(const MATRIXLIKE1& M, MATRIXLIKE2& out_inverse_M)
28 {
30  ASSERT_(M.isSquare() && size(M, 1) == 4);
31 
32  /* Instead of performing a generic 4x4 matrix inversion, we only need to
33  transpose the rotation part, then replace the translation part by
34  three dot products. See, for example:
35  https://graphics.stanford.edu/courses/cs248-98-fall/Final/q4.html
36 
37  [ux vx wx tx] -1 [ux uy uz -dot(u,t)]
38  [uy vy wy ty] [vx vy vz -dot(v,t)]
39  [uz vz wz tz] = [wx wy wz -dot(w,t)]
40  [ 0 0 0 1] [ 0 0 0 1 ]
41  */
42 
43  out_inverse_M.setSize(4, 4);
44 
45  // 3x3 rotation part:
46  out_inverse_M.set_unsafe(0, 0, M.get_unsafe(0, 0));
47  out_inverse_M.set_unsafe(0, 1, M.get_unsafe(1, 0));
48  out_inverse_M.set_unsafe(0, 2, M.get_unsafe(2, 0));
49 
50  out_inverse_M.set_unsafe(1, 0, M.get_unsafe(0, 1));
51  out_inverse_M.set_unsafe(1, 1, M.get_unsafe(1, 1));
52  out_inverse_M.set_unsafe(1, 2, M.get_unsafe(2, 1));
53 
54  out_inverse_M.set_unsafe(2, 0, M.get_unsafe(0, 2));
55  out_inverse_M.set_unsafe(2, 1, M.get_unsafe(1, 2));
56  out_inverse_M.set_unsafe(2, 2, M.get_unsafe(2, 2));
57 
58  const double tx = -M.get_unsafe(0, 3);
59  const double ty = -M.get_unsafe(1, 3);
60  const double tz = -M.get_unsafe(2, 3);
61 
62  const double tx_ = tx * M.get_unsafe(0, 0) + ty * M.get_unsafe(1, 0) +
63  tz * M.get_unsafe(2, 0);
64  const double ty_ = tx * M.get_unsafe(0, 1) + ty * M.get_unsafe(1, 1) +
65  tz * M.get_unsafe(2, 1);
66  const double tz_ = tx * M.get_unsafe(0, 2) + ty * M.get_unsafe(1, 2) +
67  tz * M.get_unsafe(2, 2);
68 
69  out_inverse_M.set_unsafe(0, 3, tx_);
70  out_inverse_M.set_unsafe(1, 3, ty_);
71  out_inverse_M.set_unsafe(2, 3, tz_);
72 
73  out_inverse_M.set_unsafe(3, 0, 0);
74  out_inverse_M.set_unsafe(3, 1, 0);
75  out_inverse_M.set_unsafe(3, 2, 0);
76  out_inverse_M.set_unsafe(3, 3, 1);
77 
78  MRPT_END
79 }
80 //! \overload
81 template <class IN_ROTMATRIX, class IN_XYZ, class OUT_ROTMATRIX, class OUT_XYZ>
83  const IN_ROTMATRIX& in_R, const IN_XYZ& in_xyz, OUT_ROTMATRIX& out_R,
84  OUT_XYZ& out_xyz)
85 {
87  ASSERT_(in_R.isSquare() && size(in_R, 1) == 3 && in_xyz.size() == 3)
88  out_R.setSize(3, 3);
89  out_xyz.resize(3);
90 
91  // translation part:
92  typedef typename IN_ROTMATRIX::Scalar T;
93  const T tx = -in_xyz[0];
94  const T ty = -in_xyz[1];
95  const T tz = -in_xyz[2];
96 
97  out_xyz[0] = tx * in_R.get_unsafe(0, 0) + ty * in_R.get_unsafe(1, 0) +
98  tz * in_R.get_unsafe(2, 0);
99  out_xyz[1] = tx * in_R.get_unsafe(0, 1) + ty * in_R.get_unsafe(1, 1) +
100  tz * in_R.get_unsafe(2, 1);
101  out_xyz[2] = tx * in_R.get_unsafe(0, 2) + ty * in_R.get_unsafe(1, 2) +
102  tz * in_R.get_unsafe(2, 2);
103 
104  // 3x3 rotation part: transpose
105  out_R = in_R.adjoint();
106 
107  MRPT_END
108 }
109 //! \overload
110 template <class MATRIXLIKE>
111 inline void homogeneousMatrixInverse(MATRIXLIKE& M)
112 {
113  ASSERTDEB_(M.isSquare() && size(M, 1) == 4);
114  // translation:
115  const double tx = -M(0, 3);
116  const double ty = -M(1, 3);
117  const double tz = -M(2, 3);
118  M(0, 3) = tx * M(0, 0) + ty * M(1, 0) + tz * M(2, 0);
119  M(1, 3) = tx * M(0, 1) + ty * M(1, 1) + tz * M(2, 1);
120  M(2, 3) = tx * M(0, 2) + ty * M(1, 2) + tz * M(2, 2);
121  // 3x3 rotation part:
122  double t; // avoid std::swap() to avoid <algorithm> only for that.
123  t = M(1, 0);
124  M(1, 0) = M(0, 1);
125  M(0, 1) = t;
126  t = M(2, 0);
127  M(2, 0) = M(0, 2);
128  M(0, 2) = t;
129  t = M(1, 2);
130  M(1, 2) = M(2, 1);
131  M(2, 1) = t;
132 }
133 }
134 }
135 #endif
GLdouble GLdouble t
Definition: glext.h:3689
size_t size(const MATRIXLIKE &m, const int dim)
Definition: bits.h:41
#define MRPT_END
GLbyte ty
Definition: glext.h:6092
#define MRPT_START
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
#define ASSERTDEB_(f)
Defines an assertion mechanism - only when compiled in debug.
void homogeneousMatrixInverse(const MATRIXLIKE1 &M, MATRIXLIKE2 &out_inverse_M)
Efficiently compute the inverse of a 4x4 homogeneous matrix by only transposing the rotation 3x3 part...
#define ASSERT_(f)
GLbyte GLbyte tz
Definition: glext.h:6092
double Scalar
Definition: KmUtils.h:44



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019