Eigen  5.0.1
 
Loading...
Searching...
No Matches
Hyperplane.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6//
7// This Source Code Form is subject to the terms of the Mozilla
8// Public License v. 2.0. If a copy of the MPL was not distributed
9// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10// SPDX-License-Identifier: MPL-2.0
11
12#ifndef EIGEN_HYPERPLANE_H
13#define EIGEN_HYPERPLANE_H
14
15// IWYU pragma: private
16#include "./InternalHeaderCheck.h"
17
18namespace Eigen {
19
37template <typename Scalar_, int AmbientDim_, int Options_>
39 public:
40 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar_,
41 AmbientDim_ == Dynamic ? Dynamic : AmbientDim_ + 1)
42 enum { AmbientDimAtCompileTime = AmbientDim_, Options = Options_ };
43 using Scalar = Scalar_;
44 using RealScalar = typename NumTraits<Scalar>::Real;
45 using Index = Eigen::Index;
47 using Coefficients =
48 Matrix<Scalar, Index(AmbientDimAtCompileTime) == Dynamic ? Dynamic : Index(AmbientDimAtCompileTime) + 1, 1,
49 Options>;
51 using ConstNormalReturnType = const Block<const Coefficients, AmbientDimAtCompileTime, 1>;
52
54 EIGEN_DEVICE_FUNC inline Hyperplane() {}
55
56 template <int OtherOptions>
58 : m_coeffs(other.coeffs()) {}
59
62 EIGEN_DEVICE_FUNC inline explicit Hyperplane(Index _dim) : m_coeffs(_dim + 1) {}
63
67 EIGEN_DEVICE_FUNC inline Hyperplane(const VectorType& n, const VectorType& e) : m_coeffs(n.size() + 1) {
68 normal() = n;
69 offset() = -n.dot(e);
70 }
71
76 EIGEN_DEVICE_FUNC inline Hyperplane(const VectorType& n, const Scalar& d) : m_coeffs(n.size() + 1) {
77 normal() = n;
78 offset() = d;
79 }
80
84 EIGEN_DEVICE_FUNC static inline Hyperplane Through(const VectorType& p0, const VectorType& p1) {
85 Hyperplane result(p0.size());
86 result.normal() = (p1 - p0).unitOrthogonal();
87 result.offset() = -p0.dot(result.normal());
88 return result;
89 }
90
94 EIGEN_DEVICE_FUNC static inline Hyperplane Through(const VectorType& p0, const VectorType& p1, const VectorType& p2) {
95 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 3)
96 Hyperplane result(p0.size());
97 VectorType v0(p2 - p0), v1(p1 - p0);
98 result.normal() = v0.cross(v1);
99 RealScalar norm = result.normal().norm();
100 if (norm <= v0.norm() * v1.norm() * NumTraits<RealScalar>::epsilon()) {
102 m << v0.transpose(), v1.transpose();
104 result.normal() = svd.matrixV().col(2);
105 } else
106 result.normal() /= norm;
107 result.offset() = -p0.dot(result.normal());
108 return result;
109 }
110
115 // FIXME: for consistency, consider implementing as a static Through function.
116 EIGEN_DEVICE_FUNC explicit Hyperplane(const ParametrizedLine<Scalar, AmbientDimAtCompileTime>& parametrized) {
117 normal() = parametrized.direction().unitOrthogonal();
118 offset() = -parametrized.origin().dot(normal());
119 }
120
122 EIGEN_DEVICE_FUNC inline Index dim() const {
123 return AmbientDimAtCompileTime == Dynamic ? m_coeffs.size() - 1 : Index(AmbientDimAtCompileTime);
124 }
125
127 EIGEN_DEVICE_FUNC void normalize(void) { m_coeffs /= normal().norm(); }
128
132 EIGEN_DEVICE_FUNC inline Scalar signedDistance(const VectorType& p) const { return normal().dot(p) + offset(); }
133
137 EIGEN_DEVICE_FUNC inline Scalar absDistance(const VectorType& p) const { return numext::abs(signedDistance(p)); }
138
141 EIGEN_DEVICE_FUNC inline VectorType projection(const VectorType& p) const { return p - signedDistance(p) * normal(); }
142
146 EIGEN_DEVICE_FUNC inline ConstNormalReturnType normal() const {
147 return ConstNormalReturnType(m_coeffs, 0, 0, dim(), 1);
148 }
149
153 EIGEN_DEVICE_FUNC inline NormalReturnType normal() { return NormalReturnType(m_coeffs, 0, 0, dim(), 1); }
154
158 EIGEN_DEVICE_FUNC inline const Scalar& offset() const { return m_coeffs.coeff(dim()); }
159
162 EIGEN_DEVICE_FUNC inline Scalar& offset() { return m_coeffs(dim()); }
163
167 EIGEN_DEVICE_FUNC inline const Coefficients& coeffs() const { return m_coeffs; }
168
172 EIGEN_DEVICE_FUNC inline Coefficients& coeffs() { return m_coeffs; }
173
180 EIGEN_DEVICE_FUNC VectorType intersection(const Hyperplane& other) const {
181 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2)
182 Scalar det = coeffs().coeff(0) * other.coeffs().coeff(1) - coeffs().coeff(1) * other.coeffs().coeff(0);
183 // since the line equations ax+by=c are normalized with a^2+b^2=1, the following tests
184 // whether the two lines are approximately parallel.
185 if (internal::isMuchSmallerThan(det, Scalar(1))) { // special case where the two lines are approximately parallel.
186 // Pick any point on the first line.
187 if (numext::abs(coeffs().coeff(1)) > numext::abs(coeffs().coeff(0)))
188 return VectorType(coeffs().coeff(1), -coeffs().coeff(2) / coeffs().coeff(1) - coeffs().coeff(0));
189 else
190 return VectorType(-coeffs().coeff(2) / coeffs().coeff(0) - coeffs().coeff(1), coeffs().coeff(0));
191 } else { // general case
192 Scalar invdet = Scalar(1) / det;
193 return VectorType(
194 invdet * (coeffs().coeff(1) * other.coeffs().coeff(2) - other.coeffs().coeff(1) * coeffs().coeff(2)),
195 invdet * (other.coeffs().coeff(0) * coeffs().coeff(2) - coeffs().coeff(0) * other.coeffs().coeff(2)));
196 }
197 }
198
205 template <typename XprType>
206 EIGEN_DEVICE_FUNC inline Hyperplane& transform(const MatrixBase<XprType>& mat, TransformTraits traits = Affine) {
207 if (traits == Affine) {
208 normal() = mat.inverse().transpose() * normal();
209 m_coeffs /= normal().norm();
210 } else if (traits == Isometry)
211 normal() = mat * normal();
212 else {
213 eigen_assert(0 && "invalid traits value in Hyperplane::transform()");
214 }
215 return *this;
216 }
217
225 template <int TrOptions>
227 TransformTraits traits = Affine) {
228 transform(t.linear(), traits);
229 offset() -= normal().dot(t.translation());
230 return *this;
231 }
232
238 template <typename NewScalarType>
239 EIGEN_DEVICE_FUNC inline
240 typename internal::cast_return_type<Hyperplane,
242 cast() const {
243 return
244 typename internal::cast_return_type<Hyperplane,
246 }
247
249 template <typename OtherScalarType, int OtherOptions>
250 EIGEN_DEVICE_FUNC inline explicit Hyperplane(
252 m_coeffs = other.coeffs().template cast<Scalar>();
253 }
254
263 template <int OtherOptions>
264 EIGEN_DEVICE_FUNC bool isApprox(
266 const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const {
267 return m_coeffs.isApprox(other.m_coeffs, prec);
268 }
269
292 template <int OtherOptions>
293 EIGEN_DEVICE_FUNC bool isCoincident(
295 const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const {
296 const RealScalar this_norm = normal().norm();
297 const RealScalar other_norm = other.normal().norm();
298 eigen_assert(this_norm > RealScalar(0) && other_norm > RealScalar(0));
299 // Normalizing accounts for |gamma|; what is left of it is a unit-modulus factor, and the
300 // normals themselves determine it, since the inner product of two coincident unit normals is
301 // exactly that factor. Orthogonal normals leave it undetermined, but no factor makes those
302 // agree either, so the choice made for them does not matter.
303 const Scalar inner = normal().dot(other.normal());
304 const RealScalar inner_norm = numext::abs(inner);
305 const Scalar phase = inner_norm > RealScalar(0) ? inner / Scalar(inner_norm) : Scalar(1);
306 if (!((other.normal() / Scalar(other_norm) - phase * (normal() / Scalar(this_norm))).norm() <= prec)) return false;
307 return internal::isApprox(other.offset() / Scalar(other_norm), numext::conj(phase) * (offset() / Scalar(this_norm)),
308 prec);
309 }
310
311 protected:
312 Coefficients m_coeffs;
313};
314
315} // end namespace Eigen
316
317#endif // EIGEN_HYPERPLANE_H
Expression of a fixed-size or dynamic-size block.
Definition Block.h:111
A hyperplane.
Definition Hyperplane.h:38
static Hyperplane Through(const VectorType &p0, const VectorType &p1)
Definition Hyperplane.h:84
Hyperplane & transform(const MatrixBase< XprType > &mat, TransformTraits traits=Affine)
Definition Hyperplane.h:206
VectorType intersection(const Hyperplane &other) const
Definition Hyperplane.h:180
ConstNormalReturnType normal() const
Definition Hyperplane.h:146
Scalar signedDistance(const VectorType &p) const
Definition Hyperplane.h:132
Hyperplane(const VectorType &n, const VectorType &e)
Definition Hyperplane.h:67
NormalReturnType normal()
Definition Hyperplane.h:153
Eigen::Index Index
Definition Hyperplane.h:45
Hyperplane()
Definition Hyperplane.h:54
const Coefficients & coeffs() const
Definition Hyperplane.h:167
Coefficients & coeffs()
Definition Hyperplane.h:172
internal::cast_return_type< Hyperplane, Hyperplane< NewScalarType, AmbientDimAtCompileTime, Options > >::type cast() const
Definition Hyperplane.h:242
Index dim() const
Definition Hyperplane.h:122
Scalar absDistance(const VectorType &p) const
Definition Hyperplane.h:137
static Hyperplane Through(const VectorType &p0, const VectorType &p1, const VectorType &p2)
Definition Hyperplane.h:94
const Scalar & offset() const
Definition Hyperplane.h:158
Hyperplane(const VectorType &n, const Scalar &d)
Definition Hyperplane.h:76
bool isApprox(const Hyperplane< Scalar, AmbientDimAtCompileTime, OtherOptions > &other, const typename NumTraits< Scalar >::Real &prec=NumTraits< Scalar >::dummy_precision()) const
Definition Hyperplane.h:264
Hyperplane(const Hyperplane< OtherScalarType, AmbientDimAtCompileTime, OtherOptions > &other)
Definition Hyperplane.h:250
bool isCoincident(const Hyperplane< Scalar, AmbientDimAtCompileTime, OtherOptions > &other, const typename NumTraits< Scalar >::Real &prec=NumTraits< Scalar >::dummy_precision()) const
Definition Hyperplane.h:293
void normalize(void)
Definition Hyperplane.h:127
Scalar & offset()
Definition Hyperplane.h:162
Hyperplane(Index _dim)
Definition Hyperplane.h:62
Hyperplane(const ParametrizedLine< Scalar, AmbientDimAtCompileTime > &parametrized)
Definition Hyperplane.h:116
VectorType projection(const VectorType &p) const
Definition Hyperplane.h:141
Hyperplane & transform(const Transform< Scalar, AmbientDimAtCompileTime, Affine, TrOptions > &t, TransformTraits traits=Affine)
Definition Hyperplane.h:226
Two-sided Jacobi SVD decomposition of a rectangular matrix.
Definition JacobiSVD.h:613
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:53
Inverse< Derived > inverse() const
Definition InverseImpl.h:280
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:188
A parametrized line.
Definition ParametrizedLine.h:36
constexpr const Scalar & coeff(Index rowId, Index colId) const
Definition PlainObjectBase.h:187
const MatrixVType & matrixV() const
Definition SVDBase.h:192
Represents an homogeneous transformation in a N dimensional space.
Definition Transform.h:222
ConstLinearPart linear() const
Definition Transform.h:415
ConstTranslationPart translation() const
Definition Transform.h:425
TransformTraits
Definition Constants.h:470
@ ComputeFullV
Definition Constants.h:398
@ Affine
Definition Constants.h:475
@ Isometry
Definition Constants.h:472