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
double Scalar
Definition: KmUtils.h:44
GLdouble GLdouble t
Definition: glext.h:3689
GLbyte GLbyte tz
Definition: glext.h:6092
GLsizeiptr size
Definition: glext.h:3923
GLbyte ty
Definition: glext.h:6092
#define MRPT_START
Definition: mrpt_macros.h:425
#define ASSERT_(f)
Definition: mrpt_macros.h:309
#define ASSERTDEB_(f)
Defines an assertion mechanism - only when compiled in debug.
Definition: mrpt_macros.h:355
#define MRPT_END
Definition: mrpt_macros.h:429
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...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.



Page generated by Doxygen 1.9.1 for MRPT 1.9.9 Git: 63ea9d1f1 Thu Nov 23 00:06:53 2017 +0100 at mar 26 may 2026 12:19:29 CEST