ReUseX
0.0.5
3D Point Cloud Processing for Building Reuse
Toggle main menu visibility
Loading...
Searching...
No Matches
transform_utils.hpp
Go to the documentation of this file.
1
// SPDX-FileCopyrightText: 2025 Povl Filip Sonne-Frederiksen
2
//
3
// SPDX-License-Identifier: GPL-3.0-or-later
4
5
#pragma once
6
7
#include <Eigen/Core>
8
#include <Eigen/Geometry>
9
10
#include <algorithm>
11
#include <array>
12
#include <cmath>
13
14
namespace
reusex::geometry
{
15
17
inline
Eigen::Affine3d
to_affine
(
const
std::array<double, 16> &m) {
18
Eigen::Matrix4d mat;
19
for
(
int
r = 0; r < 4; ++r)
20
for
(
int
c = 0; c < 4; ++c)
21
mat(r, c) = m[r * 4 + c];
22
Eigen::Affine3d aff;
23
aff.matrix() = mat;
24
return
aff;
25
}
26
28
inline
std::array<double, 16>
to_array16
(
const
Eigen::Affine3d &aff) {
29
std::array<double, 16> m{};
30
const
Eigen::Matrix4d mat = aff.matrix();
31
for
(
int
r = 0; r < 4; ++r)
32
for
(
int
c = 0; c < 4; ++c)
33
m[r * 4 + c] = mat(r, c);
34
return
m;
35
}
36
39
inline
std::array<double, 16>
to_array16
(
const
Eigen::Affine3f &aff) {
40
std::array<double, 16> m{};
41
const
Eigen::Matrix4f mat = aff.matrix();
42
for
(
int
r = 0; r < 4; ++r)
43
for
(
int
c = 0; c < 4; ++c)
44
m[r * 4 + c] =
static_cast<
double
>
(mat(r, c));
45
return
m;
46
}
47
54
namespace
se3
{
55
56
using
Vector6d
= Eigen::Matrix<double, 6, 1>;
57
59
inline
Eigen::Matrix3d
hat3
(
const
Eigen::Vector3d &w) {
60
Eigen::Matrix3d s;
61
s << 0.0, -w.z(), w.y(), w.z(), 0.0, -w.x(), -w.y(), w.x(), 0.0;
62
return
s;
63
}
64
66
inline
Eigen::Matrix4d
exp
(
const
Vector6d
&xi) {
67
const
Eigen::Vector3d w = xi.head<3>();
68
const
Eigen::Vector3d v = xi.tail<3>();
69
const
double
theta = w.norm();
70
const
Eigen::Matrix3d W =
hat3
(w);
71
Eigen::Matrix3d R;
72
Eigen::Matrix3d V;
73
if
(theta < 1e-12) {
74
R = Eigen::Matrix3d::Identity() + W;
75
V = Eigen::Matrix3d::Identity() + 0.5 * W;
76
}
else
{
77
const
double
t2 = theta * theta;
78
const
double
s = std::sin(theta);
79
const
double
c = std::cos(theta);
80
R = Eigen::Matrix3d::Identity() + (s / theta) * W +
81
((1.0 - c) / t2) * (W * W);
82
V = Eigen::Matrix3d::Identity() + ((1.0 - c) / t2) * W +
83
((theta - s) / (t2 * theta)) * (W * W);
84
}
85
Eigen::Matrix4d T = Eigen::Matrix4d::Identity();
86
T.block<3, 3>(0, 0) = R;
87
T.block<3, 1>(0, 3) = V * v;
88
return
T;
89
}
90
92
inline
Vector6d
log
(
const
Eigen::Matrix4d &T) {
93
const
Eigen::Matrix3d R = T.block<3, 3>(0, 0);
94
const
Eigen::Vector3d t = T.block<3, 1>(0, 3);
95
const
double
cos_theta = std::clamp((R.trace() - 1.0) * 0.5, -1.0, 1.0);
96
const
double
theta = std::acos(cos_theta);
97
Eigen::Vector3d w;
98
if
(theta < 1e-12) {
99
w = 0.5 * Eigen::Vector3d(R(2, 1) - R(1, 2), R(0, 2) - R(2, 0),
100
R(1, 0) - R(0, 1));
101
}
else
{
102
const
double
s = std::sin(theta);
103
w = (theta / (2.0 * s)) * Eigen::Vector3d(R(2, 1) - R(1, 2),
104
R(0, 2) - R(2, 0),
105
R(1, 0) - R(0, 1));
106
}
107
const
Eigen::Matrix3d W =
hat3
(w);
108
Eigen::Matrix3d Vinv;
109
if
(theta < 1e-12) {
110
Vinv = Eigen::Matrix3d::Identity() - 0.5 * W;
111
}
else
{
112
const
double
a =
113
(1.0 / (theta * theta)) *
114
(1.0 - (theta * std::sin(theta)) / (2.0 * (1.0 - std::cos(theta))));
115
Vinv = Eigen::Matrix3d::Identity() - 0.5 * W + a * (W * W);
116
}
117
Vector6d
xi;
118
xi.head<3>() = w;
119
xi.tail<3>() = Vinv * t;
120
return
xi;
121
}
122
123
}
// namespace se3
124
}
// namespace reusex::geometry
reusex::geometry::se3
Minimal se(3) exp/log used by the joint pose optimizer.
Definition
transform_utils.hpp:54
reusex::geometry::se3::Vector6d
Eigen::Matrix< double, 6, 1 > Vector6d
Definition
transform_utils.hpp:56
reusex::geometry::se3::hat3
Eigen::Matrix3d hat3(const Eigen::Vector3d &w)
Skew-symmetric matrix [w]_x such that [w]_x v == w x v.
Definition
transform_utils.hpp:59
reusex::geometry::se3::exp
Eigen::Matrix4d exp(const Vector6d &xi)
Exponential map se(3) -> SE(3). xi = [omega; v].
Definition
transform_utils.hpp:66
reusex::geometry::se3::log
Vector6d log(const Eigen::Matrix4d &T)
Logarithm map SE(3) -> se(3). Returns xi = [omega; v].
Definition
transform_utils.hpp:92
reusex::geometry
Definition
visual_observer.hpp:33
reusex::geometry::to_affine
Eigen::Affine3d to_affine(const std::array< double, 16 > &m)
Build a 4x4 Eigen affine (double) from a row-major double[16] array.
Definition
transform_utils.hpp:17
reusex::geometry::to_array16
std::array< double, 16 > to_array16(const Eigen::Affine3d &aff)
Flatten a 4x4 Eigen affine (double) into a row-major double[16] array.
Definition
transform_utils.hpp:28
libs
reusex
include
geometry
transform_utils.hpp
Generated by
1.18.0