farm-ng-core
plane_conv.h
Go to the documentation of this file.
1 // Copyright (c) 2011, Hauke Strasdat
2 // Copyright (c) 2012, Steven Lovegrove
3 // Copyright (c) 2021, farm-ng, inc.
4 //
5 // Use of this source code is governed by an MIT-style
6 // license that can be found in the LICENSE file or at
7 // https://opensource.org/licenses/MIT.
8 
9 /// @file
10 /// Transformations between poses and hyperplanes.
11 
12 #pragma once
13 
14 #include "sophus/common/common.h"
15 #include "sophus/lie/isometry2.h"
16 #include "sophus/lie/isometry3.h"
17 
18 namespace sophus {
19 
20 /// Takes in a rotation ``foo_rotation_plane`` and returns the corresponding
21 /// line normal along the y-axis (in reference frame ``foo``).
22 ///
23 template <class TScalar>
24 auto normalFromRotation2(Rotation2<TScalar> const& foo_rotation_line)
25  -> Eigen::Vector2<TScalar> {
26  return foo_rotation_line.matrix().col(1);
27 }
28 
29 /// Takes in line normal in reference frame foo and constructs a corresponding
30 /// rotation matrix ``foo_rotation_line``.
31 ///
32 /// Precondition: ``normal_in_foo`` must not be close to zero.
33 ///
34 template <class TScalar>
35 auto rotation2FromNormal(Eigen::Vector2<TScalar> normal_in_foo)
38  normal_in_foo.squaredNorm() > kEpsilon<TScalar>,
39  "{}",
40  normal_in_foo.transpose().eval());
41  normal_in_foo.normalize();
43  {normal_in_foo.y(), -normal_in_foo.x()});
44 }
45 
46 /// Takes in a rotation ``foo_rotation_plane`` and returns the corresponding
47 /// plane normal along the z-axis (in reference frame ``foo``).
48 ///
49 template <class TScalar>
50 auto normalFromRotation3(Rotation3<TScalar> const& foo_rotation_plane)
51  -> Eigen::Vector3<TScalar> {
52  return foo_rotation_plane.matrix().col(2);
53 }
54 
55 /// Takes in plane normal in reference frame foo and constructs a corresponding
56 /// rotation matrix ``foo_rotation_plane``.
57 ///
58 /// Note: The ``plane`` frame is defined as such that the normal points along
59 /// the positive z-axis. One can specify hints for the x-axis and y-axis
60 /// of the ``plane`` frame.
61 ///
62 /// Preconditions:
63 /// - ``normal_in_foo``, ``xDirHint_foo``, ``yDirHint_foo`` must not be close to
64 /// zero.
65 /// - ``xDirHint_foo`` and ``yDirHint_foo`` must be approx. perpendicular.
66 ///
67 template <class TScalar>
69  Eigen::Vector3<TScalar> const& normal_in_foo,
70  Eigen::Vector3<TScalar> x_dir_hint_foo =
71  Eigen::Vector3<TScalar>(TScalar(1), TScalar(0), TScalar(0)),
72  Eigen::Vector3<TScalar> y_dir_hint_foo = Eigen::Vector3<TScalar>(
73  TScalar(0), TScalar(1), TScalar(0))) -> Eigen::Matrix3<TScalar> {
75  x_dir_hint_foo.dot(y_dir_hint_foo) < kEpsilon<TScalar>,
76  "xDirHint ({}) and yDirHint ({}) must be perpendicular.",
77  x_dir_hint_foo.transpose(),
78  y_dir_hint_foo.transpose());
79  using std::abs;
80  using std::sqrt;
81  TScalar const x_dir_hint_foo_sqr_length = x_dir_hint_foo.squaredNorm();
82  TScalar const y_dir_hint_foo_sqr_length = y_dir_hint_foo.squaredNorm();
83  TScalar const normal_foo_sqr_length = normal_in_foo.squaredNorm();
85  x_dir_hint_foo_sqr_length > kEpsilon<TScalar>,
86  "{}",
87  x_dir_hint_foo.transpose());
89  y_dir_hint_foo_sqr_length > kEpsilon<TScalar>,
90  "{}",
91  y_dir_hint_foo.transpose());
93  normal_foo_sqr_length > kEpsilon<TScalar>,
94  "{}",
95  normal_in_foo.transpose());
96 
97  Eigen::Matrix3<TScalar> basis_foo;
98  basis_foo.col(2) = normal_in_foo;
99 
100  if (abs(x_dir_hint_foo_sqr_length - TScalar(1)) > kEpsilon<TScalar>) {
101  x_dir_hint_foo.normalize();
102  }
103  if (abs(y_dir_hint_foo_sqr_length - TScalar(1)) > kEpsilon<TScalar>) {
104  y_dir_hint_foo.normalize();
105  }
106  if (abs(normal_foo_sqr_length - TScalar(1)) > kEpsilon<TScalar>) {
107  basis_foo.col(2).normalize();
108  }
109 
110  TScalar abs_x_dot_z = abs(basis_foo.col(2).dot(x_dir_hint_foo));
111  TScalar abs_y_dot_z = abs(basis_foo.col(2).dot(y_dir_hint_foo));
112  if (abs_x_dot_z < abs_y_dot_z) {
113  // basis_foo.z and xDirHint are far from parallel.
114  basis_foo.col(1) = basis_foo.col(2).cross(x_dir_hint_foo).normalized();
115  basis_foo.col(0) = basis_foo.col(1).cross(basis_foo.col(2));
116  } else {
117  // basis_foo.z and yDirHint are far from parallel.
118  basis_foo.col(0) = y_dir_hint_foo.cross(basis_foo.col(2)).normalized();
119  basis_foo.col(1) = basis_foo.col(2).cross(basis_foo.col(0));
120  }
121  TScalar det = basis_foo.determinant();
122  // sanity check
124  det,
125  TScalar(1),
126  kEpsilon<TScalar>,
127  "Determinant of basis is not 1, but {}. Basis is \n{}\n",
128  det,
129  basis_foo);
130  return basis_foo;
131 }
132 
133 /// Takes in plane normal in reference frame foo and constructs a corresponding
134 /// rotation matrix ``foo_rotation_plane``.
135 ///
136 /// See ``rotationFromNormal`` for details.
137 ///
138 template <class TScalar>
139 auto rotation3FromPlane(Eigen::Vector3<TScalar> const& normal_in_foo)
140  -> Rotation3<TScalar> {
142  rotation3FromNormal(normal_in_foo));
143 }
144 
145 /// Returns a line (wrt. to frame ``foo``), given a pose of the ``line`` in
146 /// reference frame ``foo``.
147 ///
148 /// Note: The plane is defined by X-axis of the ``line`` frame.
149 ///
150 template <class TScalar>
151 auto lineFromIsometry(Isometry2<TScalar> const& foo_from_line)
152  -> Eigen::Hyperplane<TScalar, 2> {
153  return Eigen::Hyperplane<TScalar, 2>(
154  normalFromRotation2(foo_from_line.rotation()),
155  foo_from_line.translation());
156 }
157 
158 /// Returns the pose ``T_foo_line``, given a line in reference frame ``foo``.
159 ///
160 /// Note: The line is defined by X-axis of the frame ``line``.
161 ///
162 template <class TScalar>
163 auto isometryFromLine(Eigen::Hyperplane<TScalar, 2> const& line_in_foo)
164  -> Isometry2<TScalar> {
165  TScalar const d = line_in_foo.offset();
166  Eigen::Vector2<TScalar> const n = line_in_foo.normal();
167  Rotation2<TScalar> const foo_rotation_plane = rotation2FromNormal(n);
168  return Isometry2<TScalar>(-d * n, foo_rotation_plane);
169 }
170 
171 /// Returns a plane (wrt. to frame ``foo``), given a pose of the ``plane`` in
172 /// reference frame ``foo``.
173 ///
174 /// Note: The plane is defined by XY-plane of the frame ``plane``.
175 ///
176 template <class TScalar>
177 auto planeFromIsometry(Isometry3<TScalar> const& foo_from_plane)
178  -> Eigen::Hyperplane<TScalar, 3> {
179  return Eigen::Hyperplane<TScalar, 3>(
180  normalFromRotation3(foo_from_plane.so3()), foo_from_plane.translation());
181 }
182 
183 /// Returns the pose ``foo_from_plane``, given a plane in reference frame
184 /// ``foo``.
185 ///
186 /// Note: The plane is defined by XY-plane of the frame ``plane``.
187 ///
188 template <class TScalar>
189 auto isometryFromPlane(Eigen::Hyperplane<TScalar, 3> const& plane_in_foo)
190  -> Isometry3<TScalar> {
191  TScalar const d = plane_in_foo.offset();
192  Eigen::Vector3<TScalar> const n = plane_in_foo.normal();
193  Rotation3<TScalar> const foo_rotation_plane = rotation3FromPlane(n);
194  return Isometry3<TScalar>(-d * n, foo_rotation_plane);
195 }
196 
197 /// Takes in a hyperplane and returns unique representation by ensuring that the
198 /// ``offset`` is not negative.
199 ///
200 template <class TScalar, int kMatrixDim>
201 auto makeHyperplaneUnique(Eigen::Hyperplane<TScalar, kMatrixDim> const& plane)
202  -> Eigen::Hyperplane<TScalar, kMatrixDim> {
203  if (plane.offset() >= 0) {
204  return plane;
205  }
206 
207  return Eigen::Hyperplane<TScalar, kMatrixDim>(
208  -plane.normal(), -plane.offset());
209 }
210 
211 } // namespace sophus
SOPHUS_ASSERT
#define SOPHUS_ASSERT(...)
Definition: common.h:40
sophus::normalFromRotation2
auto normalFromRotation2(Rotation2< TScalar > const &foo_rotation_line) -> Eigen::Vector2< TScalar >
Takes in a rotation foo_rotation_plane and returns the corresponding line normal along the y-axis (in...
Definition: plane_conv.h:24
sophus::Rotation3
Definition: rotation3.h:20
sophus::lineFromIsometry
auto lineFromIsometry(Isometry2< TScalar > const &foo_from_line) -> Eigen::Hyperplane< TScalar, 2 >
Returns a line (wrt. to frame foo), given a pose of the line in reference frame foo.
Definition: plane_conv.h:151
sophus
Image MutImage, owning images types.
Definition: num_diff.h:20
sophus::lie::Group< Rotation2, TScalar, lie::Rotation2Impl >::fromParams
static auto fromParams(Params const &params) -> Derived
Definition: lie_group.h:79
sophus::rotation3FromPlane
auto rotation3FromPlane(Eigen::Vector3< TScalar > const &normal_in_foo) -> Rotation3< TScalar >
Takes in plane normal in reference frame foo and constructs a corresponding rotation matrix foo_rotat...
Definition: plane_conv.h:139
sophus::normalFromRotation3
auto normalFromRotation3(Rotation3< TScalar > const &foo_rotation_plane) -> Eigen::Vector3< TScalar >
Takes in a rotation foo_rotation_plane and returns the corresponding plane normal along the z-axis (i...
Definition: plane_conv.h:50
isometry3.h
sophus::Rotation3::fromRotationMatrix
static auto fromRotationMatrix(Eigen::Matrix3< TScalar > const &mat_r) -> Rotation3
Definition: rotation3.h:65
SOPHUS_ASSERT_NEAR
#define SOPHUS_ASSERT_NEAR(...)
Definition: common.h:47
isometry2.h
sophus::makeHyperplaneUnique
auto makeHyperplaneUnique(Eigen::Hyperplane< TScalar, kMatrixDim > const &plane) -> Eigen::Hyperplane< TScalar, kMatrixDim >
Takes in a hyperplane and returns unique representation by ensuring that the offset is not negative.
Definition: plane_conv.h:201
sophus::Isometry2
Definition: isometry2.h:22
sophus::isometryFromLine
auto isometryFromLine(Eigen::Hyperplane< TScalar, 2 > const &line_in_foo) -> Isometry2< TScalar >
Returns the pose T_foo_line, given a line in reference frame foo.
Definition: plane_conv.h:163
sophus::rotation2FromNormal
auto rotation2FromNormal(Eigen::Vector2< TScalar > normal_in_foo) -> Rotation2< TScalar >
Takes in line normal in reference frame foo and constructs a corresponding rotation matrix foo_rotati...
Definition: plane_conv.h:35
sophus::isometryFromPlane
auto isometryFromPlane(Eigen::Hyperplane< TScalar, 3 > const &plane_in_foo) -> Isometry3< TScalar >
Returns the pose foo_from_plane, given a plane in reference frame foo.
Definition: plane_conv.h:189
common.h
sophus::Rotation2
Definition: rotation2.h:20
sophus::Isometry3
Definition: isometry3.h:22
sophus::rotation3FromNormal
auto rotation3FromNormal(Eigen::Vector3< TScalar > const &normal_in_foo, Eigen::Vector3< TScalar > x_dir_hint_foo=Eigen::Vector3< TScalar >(TScalar(1), TScalar(0), TScalar(0)), Eigen::Vector3< TScalar > y_dir_hint_foo=Eigen::Vector3< TScalar >(TScalar(0), TScalar(1), TScalar(0))) -> Eigen::Matrix3< TScalar >
Takes in plane normal in reference frame foo and constructs a corresponding rotation matrix foo_rotat...
Definition: plane_conv.h:68
sophus::planeFromIsometry
auto planeFromIsometry(Isometry3< TScalar > const &foo_from_plane) -> Eigen::Hyperplane< TScalar, 3 >
Returns a plane (wrt. to frame foo), given a pose of the plane in reference frame foo.
Definition: plane_conv.h:177