NDEVR
API Documentation
sim3.h
1#pragma once
2#include "se3_ops.h"
3#include <Eigen/Geometry>
4
5namespace NDEVR
6{
7 using namespace Eigen;
8 typedef Eigen::Matrix <g_type, 7, 1> Vector7d;
9 typedef Eigen::Matrix <g_type, 7, 7> Matrix7d;
10
12 struct Sim3
13 {
14 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
15
16 protected:
18 Vector3<g_type> t;
19 g_type s;
20
21
22 public:
25 {
26 r.setIdentity();
27 t.fill(0.);
28 s = 1.;
29 }
30
35 Sim3(const Quaternion<g_type>& r, const Vector3<g_type>& t, g_type s)
36 : r(r), t(t), s(s)
37 {
38 }
39
44 Sim3(const Matrix3<g_type>& R, const Vector3<g_type>& t, g_type s)
45 : r(Quaternion<g_type>(R)), t(t), s(s)
46 {
47 }
48
52 Sim3(const Vector7d& update, bool fix_scale)
53 {
54
55 Vector3<g_type> omega;
56 for (int i = 0; i < 3; i++)
57 omega[i] = update[i];
58
59 Vector3<g_type> upsilon;
60 for (int i = 0; i < 3; i++)
61 upsilon[i] = update[i + 3];
62
63 g_type sigma = fix_scale ? cast<g_type>(0) : update[6];
64 g_type theta = omega.norm();
65 Matrix3<g_type> Omega = skew(omega);
66 s = std::exp(sigma);
67 Matrix3<g_type> Omega2 = Omega * Omega;
68 Matrix3<g_type> I;
69 I.setIdentity();
70 Matrix3<g_type> R;
71
72 g_type eps = g_type(0.00001);
73 g_type A, B, C;
74 if (fabs(sigma) < eps)
75 {
76 C = 1;
77 if (theta < eps)
78 {
79 A = g_type(1. / 2.);
80 B = g_type(1. / 6.);
81 R = (I + Omega + Omega * Omega);
82 }
83 else
84 {
85 g_type theta2 = theta * theta;
86 A = (1 - cos(theta)) / (theta2);
87 B = (theta - sin(theta)) / (theta2 * theta);
88 R = I + sin(theta) / theta * Omega + (1 - cos(theta)) / (theta * theta) * Omega2;
89 }
90 }
91 else
92 {
93 C = (s - 1) / sigma;
94 if (theta < eps)
95 {
96 g_type sigma2 = sigma * sigma;
97 A = ((sigma - 1) * s + 1) / sigma2;
98 B = ((g_type(0.5) * sigma2 - sigma + 1) * s) / (sigma2 * sigma);
99 R = (I + Omega + Omega2);
100 }
101 else
102 {
103 R = I + sin(theta) / theta * Omega + (1 - cos(theta)) / (theta * theta) * Omega2;
104
105
106
107 g_type a = s * sin(theta);
108 g_type b = s * cos(theta);
109 g_type theta2 = theta * theta;
110 g_type sigma2 = sigma * sigma;
111
112 g_type c = theta2 + sigma2;
113 A = (a * sigma + (1 - b) * theta) / (theta * c);
114 B = (C - ((b - 1) * sigma + a * theta) / (c)) * g_type(1.) / (theta2);
115
116 }
117 }
119
120
121
122 Matrix3<g_type> W = A * Omega + B * Omega2 + C * I;
123 t = W * upsilon;
124 }
125
129 Vector3<g_type> map(const Vector3<g_type>& xyz) const {
130 return s * (r * xyz) + t;
131 }
132
135 Vector7d log() const
136 {
137 Vector7d res;
138 g_type sigma = std::log(s);
139 Vector3<g_type> omega;
140 Vector3<g_type> upsilon;
141
142
143 Matrix3<g_type> R = r.toRotationMatrix();
144 g_type d = g_type(0.5) * (R(0, 0) + R(1, 1) + R(2, 2) - 1);
145
146 Matrix3<g_type> Omega;
147
148 g_type eps = g_type(0.00001);
149 Matrix3<g_type> I = Matrix3<g_type>::Identity();
150
151 g_type A, B, C;
152 if (fabs(sigma) < eps)
153 {
154 C = 1;
155 if (d > 1 - eps)
156 {
157 omega = 0.5 * deltaR(R);
158 Omega = skew(omega);
159 A = g_type(1.0 / 2.0);
160 B = g_type(1.0 / 6.0);
161 }
162 else
163 {
164 g_type theta = acos(d);
165 g_type theta2 = theta * theta;
166 omega = theta / (2 * sqrt(1 - d * d)) * deltaR(R);
167 Omega = skew(omega);
168 A = (1 - cos(theta)) / (theta2);
169 B = (theta - sin(theta)) / (theta2 * theta);
170 }
171 }
172 else
173 {
174 C = (s - 1) / sigma;
175 if (d > 1 - eps)
176 {
177
178 g_type sigma2 = sigma * sigma;
179 omega = 0.5 * deltaR(R);
180 Omega = skew(omega);
181 A = ((sigma - 1) * s + 1) / (sigma2);
182 B = ((g_type(0.5) * sigma2 - sigma + 1) * s) / (sigma2 * sigma);
183 }
184 else
185 {
186 g_type theta = acos(d);
187 omega = theta / (2 * sqrt(1 - d * d)) * deltaR(R);
188 Omega = skew(omega);
189 g_type theta2 = theta * theta;
190 g_type a = s * sin(theta);
191 g_type b = s * cos(theta);
192 g_type c = theta2 + sigma * sigma;
193 A = (a * sigma + (1 - b) * theta) / (theta * c);
194 B = (C - ((b - 1) * sigma + a * theta) / (c)) * g_type(1.) / (theta2);
195 }
196 }
197
198 Matrix3<g_type> W = A * Omega + B * Omega * Omega + C * I;
199
200 upsilon = W.lu().solve(t);
201
202
203 for (int i = 0; i < 3; i++)
204 res[i] = omega[i];
205
206 for (int i = 0; i < 3; i++)
207 res[i + 3] = upsilon[i];
208
209 res[6] = sigma;
210
211 return res;
212
213 }
214
215
218 Sim3 inverse() const
219 {
220 return Sim3(r.conjugate(), r.conjugate() * ((g_type(- 1.) / s) * t), g_type(1.) / s);
221 }
222
223
226 g_type operator[](int i) const
227 {
228 assert(i < 8);
229 if (i < 4) {
230
231 return r.coeffs()[i];
232 }
233 if (i < 7) {
234 return t[i - 4];
235 }
236 return s;
237 }
238
241 g_type& operator[](int i)
242 {
243 assert(i < 8);
244 if (i < 4) {
245
246 return r.coeffs()[i];
247 }
248 if (i < 7)
249 {
250 return t[i - 4];
251 }
252 return s;
253 }
254
257 Sim3 operator *(const Sim3& other) const {
258 Sim3 ret;
259 ret.r = r * other.r;
260 ret.t = s * (r * other.t) + t;
261 ret.s = s * other.s;
262 return ret;
263 }
264
267 Sim3& operator *=(const Sim3& other) {
268 Sim3 ret = (*this) * other;
269 *this = ret;
270 return *this;
271 }
272
274 inline const Vector3<g_type>& translation() const { return t; }
276 inline Vector3<g_type>& translation() { return t; }
278 inline const Quaternion<g_type>& rotation() const { return r; }
280 inline Quaternion<g_type>& rotation() { return r; }
282 inline const g_type& scale() const { return s; }
284 inline g_type& scale() { return s; }
285
286 };
287
288}
https://www.3dgep.com/understanding-quaternions/
The primary namespace for the NDEVR SDK.
Eigen::Matrix< g_type, 7, 1 > Vector7d
7D vector for quaternion + translation representation.
Definition se3quat.h:39
Vector3< g_type > deltaR(const Matrix3< g_type > &R)
Extracts the rotation vector from a rotation matrix using the Rodrigues formula.
Definition se3_ops.hpp:41
Eigen::Matrix< g_type, 7, 7 > Matrix7d
7x7 matrix type for Sim3 operations.
Definition sim3.h:9
Matrix3< g_type > skew(const Vector3< g_type > &v)
Computes the 3x3 skew-symmetric matrix from a 3D vector.
Definition se3_ops.hpp:28
t_type sqrt(const t_type &value)
std::enable_if<!ObjectInfo< t_type >::Float, fltp08 >::type sin(const Angle< t_type > &angle)
Performs optimized sine operation on the given angle using pre-computed lookup table for optimal spee...
std::enable_if<!ObjectInfo< t_type >::Float, fltp08 >::type cos(const Angle< t_type > &angle)
Performs optimized cosine operation on the given angle using pre-computed lookup table for optimal sp...
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
Definition Angle.h:408
Sim3(const Quaternion< g_type > &r, const Vector3< g_type > &t, g_type s)
Constructs from a quaternion, translation, and scale.
Definition sim3.h:35
Sim3 inverse() const
Computes the inverse of this similarity transform.
Definition sim3.h:218
const g_type & scale() const
Returns a const reference to the scale factor.
Definition sim3.h:282
Vector3< g_type > t
Translation component.
Definition sim3.h:18
g_type operator[](int i) const
Const element access: indices 0-3 = quaternion, 4-6 = translation, 7 = scale.
Definition sim3.h:226
g_type & scale()
Returns a mutable reference to the scale factor.
Definition sim3.h:284
Vector3< g_type > map(const Vector3< g_type > &xyz) const
Applies the similarity transform to a 3D point: s * R * xyz + t.
Definition sim3.h:129
Vector7d log() const
Computes the logarithmic map (Sim3 -> 7D tangent vector).
Definition sim3.h:135
Sim3 operator*(const Sim3 &other) const
Composes two Sim3 transforms.
Definition sim3.h:257
g_type & operator[](int i)
Mutable element access: indices 0-3 = quaternion, 4-6 = translation, 7 = scale.
Definition sim3.h:241
Sim3(const Vector7d &update, bool fix_scale)
Constructs from a 7D tangent-space update vector.
Definition sim3.h:52
Quaternion< g_type > r
Rotation component as a unit quaternion.
Definition sim3.h:17
Sim3()
Default constructor.
Definition sim3.h:24
Sim3(const Matrix3< g_type > &R, const Vector3< g_type > &t, g_type s)
Constructs from a rotation matrix, translation, and scale.
Definition sim3.h:44
const Quaternion< g_type > & rotation() const
Returns a const reference to the rotation quaternion.
Definition sim3.h:278
Vector3< g_type > & translation()
Returns a mutable reference to the translation.
Definition sim3.h:276
Quaternion< g_type > & rotation()
Returns a mutable reference to the rotation quaternion.
Definition sim3.h:280
Sim3 & operator*=(const Sim3 &other)
In-place composition with another Sim3 transform.
Definition sim3.h:267
const Vector3< g_type > & translation() const
Returns a const reference to the translation.
Definition sim3.h:274
g_type s
Scale factor.
Definition sim3.h:19