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::Affine3f
to_affine
(
const
std::array<double, 16> &m) {
18
Eigen::Matrix4f mat;
19
for
(
int
r = 0; r < 4; ++r)
20
for
(
int
c = 0; c < 4; ++c)
21
mat(r, c) =
static_cast<
float
>
(m[r * 4 + c]);
22
Eigen::Affine3f aff;
23
aff.matrix() = mat;
24
return
aff;
25
}
26
28
inline
std::array<double, 16>
to_array16
(
const
Eigen::Affine3f &aff) {
29
std::array<double, 16> m{};
30
const
Eigen::Matrix4f mat = aff.matrix();
31
for
(
int
r = 0; r < 4; ++r)
32
for
(
int
c = 0; c < 4; ++c)
33
m[r * 4 + c] =
static_cast<
double
>
(mat(r, c));
34
return
m;
35
}
36
43
namespace
se3
{
44
45
using
Vector6d
= Eigen::Matrix<double, 6, 1>;
46
48
inline
Eigen::Matrix3d
hat3
(
const
Eigen::Vector3d &w) {
49
Eigen::Matrix3d s;
50
s << 0.0, -w.z(), w.y(), w.z(), 0.0, -w.x(), -w.y(), w.x(), 0.0;
51
return
s;
52
}
53
55
inline
Eigen::Matrix4d
exp
(
const
Vector6d
&xi) {
56
const
Eigen::Vector3d w = xi.head<3>();
57
const
Eigen::Vector3d v = xi.tail<3>();
58
const
double
theta = w.norm();
59
const
Eigen::Matrix3d W =
hat3
(w);
60
Eigen::Matrix3d R;
61
Eigen::Matrix3d V;
62
if
(theta < 1e-12) {
63
R = Eigen::Matrix3d::Identity() + W;
64
V = Eigen::Matrix3d::Identity() + 0.5 * W;
65
}
else
{
66
const
double
t2 = theta * theta;
67
const
double
s = std::sin(theta);
68
const
double
c = std::cos(theta);
69
R = Eigen::Matrix3d::Identity() + (s / theta) * W +
70
((1.0 - c) / t2) * (W * W);
71
V = Eigen::Matrix3d::Identity() + ((1.0 - c) / t2) * W +
72
((theta - s) / (t2 * theta)) * (W * W);
73
}
74
Eigen::Matrix4d T = Eigen::Matrix4d::Identity();
75
T.block<3, 3>(0, 0) = R;
76
T.block<3, 1>(0, 3) = V * v;
77
return
T;
78
}
79
81
inline
Vector6d
log
(
const
Eigen::Matrix4d &T) {
82
const
Eigen::Matrix3d R = T.block<3, 3>(0, 0);
83
const
Eigen::Vector3d t = T.block<3, 1>(0, 3);
84
const
double
cos_theta = std::clamp((R.trace() - 1.0) * 0.5, -1.0, 1.0);
85
const
double
theta = std::acos(cos_theta);
86
Eigen::Vector3d w;
87
if
(theta < 1e-12) {
88
w = 0.5 * Eigen::Vector3d(R(2, 1) - R(1, 2), R(0, 2) - R(2, 0),
89
R(1, 0) - R(0, 1));
90
}
else
{
91
const
double
s = std::sin(theta);
92
w = (theta / (2.0 * s)) * Eigen::Vector3d(R(2, 1) - R(1, 2),
93
R(0, 2) - R(2, 0),
94
R(1, 0) - R(0, 1));
95
}
96
const
Eigen::Matrix3d W =
hat3
(w);
97
Eigen::Matrix3d Vinv;
98
if
(theta < 1e-12) {
99
Vinv = Eigen::Matrix3d::Identity() - 0.5 * W;
100
}
else
{
101
const
double
a =
102
(1.0 / (theta * theta)) *
103
(1.0 - (theta * std::sin(theta)) / (2.0 * (1.0 - std::cos(theta))));
104
Vinv = Eigen::Matrix3d::Identity() - 0.5 * W + a * (W * W);
105
}
106
Vector6d
xi;
107
xi.head<3>() = w;
108
xi.tail<3>() = Vinv * t;
109
return
xi;
110
}
111
112
}
// namespace se3
113
}
// namespace reusex::geometry
reusex::geometry::se3
Minimal se(3) exp/log used by the joint pose optimizer.
Definition
transform_utils.hpp:43
reusex::geometry::se3::Vector6d
Eigen::Matrix< double, 6, 1 > Vector6d
Definition
transform_utils.hpp:45
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:48
reusex::geometry::se3::exp
Eigen::Matrix4d exp(const Vector6d &xi)
Exponential map se(3) -> SE(3). xi = [omega; v].
Definition
transform_utils.hpp:55
reusex::geometry::se3::log
Vector6d log(const Eigen::Matrix4d &T)
Logarithm map SE(3) -> se(3). Returns xi = [omega; v].
Definition
transform_utils.hpp:81
reusex::geometry
Definition
visual_observer.hpp:33
reusex::geometry::to_array16
std::array< double, 16 > to_array16(const Eigen::Affine3f &aff)
Flatten a 4x4 Eigen affine (float) into a row-major double[16] array.
Definition
transform_utils.hpp:28
reusex::geometry::to_affine
Eigen::Affine3f to_affine(const std::array< double, 16 > &m)
Build a 4x4 Eigen affine (float) from a row-major double[16] array.
Definition
transform_utils.hpp:17
libs
reusex
include
geometry
transform_utils.hpp
Generated by
1.17.0