Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef EIGEN_HYPERPLANE_H
00027 #define EIGEN_HYPERPLANE_H
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 template <typename _Scalar, int _AmbientDim>
00047 class Hyperplane
00048 {
00049 public:
00050 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim==Dynamic ? Dynamic : _AmbientDim+1)
00051 enum { AmbientDimAtCompileTime = _AmbientDim };
00052 typedef _Scalar Scalar;
00053 typedef typename NumTraits<Scalar>::Real RealScalar;
00054 typedef DenseIndex Index;
00055 typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
00056 typedef Matrix<Scalar,Index(AmbientDimAtCompileTime)==Dynamic
00057 ? Dynamic
00058 : Index(AmbientDimAtCompileTime)+1,1> Coefficients;
00059 typedef Block<Coefficients,AmbientDimAtCompileTime,1> NormalReturnType;
00060 typedef const Block<const Coefficients,AmbientDimAtCompileTime,1> ConstNormalReturnType;
00061
00062
00063 inline explicit Hyperplane() {}
00064
00065
00066
00067 inline explicit Hyperplane(Index _dim) : m_coeffs(_dim+1) {}
00068
00069
00070
00071
00072 inline Hyperplane(const VectorType& n, const VectorType& e)
00073 : m_coeffs(n.size()+1)
00074 {
00075 normal() = n;
00076 offset() = -n.dot(e);
00077 }
00078
00079
00080
00081
00082
00083 inline Hyperplane(const VectorType& n, Scalar d)
00084 : m_coeffs(n.size()+1)
00085 {
00086 normal() = n;
00087 offset() = d;
00088 }
00089
00090
00091
00092
00093 static inline Hyperplane Through(const VectorType& p0, const VectorType& p1)
00094 {
00095 Hyperplane result(p0.size());
00096 result.normal() = (p1 - p0).unitOrthogonal();
00097 result.offset() = -p0.dot(result.normal());
00098 return result;
00099 }
00100
00101
00102
00103
00104 static inline Hyperplane Through(const VectorType& p0, const VectorType& p1, const VectorType& p2)
00105 {
00106 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 3)
00107 Hyperplane result(p0.size());
00108 result.normal() = (p2 - p0).cross(p1 - p0).normalized();
00109 result.offset() = -p0.dot(result.normal());
00110 return result;
00111 }
00112
00113
00114
00115
00116
00117
00118 explicit Hyperplane(const ParametrizedLine<Scalar, AmbientDimAtCompileTime>& parametrized)
00119 {
00120 normal() = parametrized.direction().unitOrthogonal();
00121 offset() = -parametrized.origin().dot(normal());
00122 }
00123
00124 ~Hyperplane() {}
00125
00126
00127 inline Index dim() const { return AmbientDimAtCompileTime==Dynamic ? m_coeffs.size()-1 : Index(AmbientDimAtCompileTime); }
00128
00129
00130 void normalize(void)
00131 {
00132 m_coeffs /= normal().norm();
00133 }
00134
00135
00136
00137
00138 inline Scalar signedDistance(const VectorType& p) const { return normal().dot(p) + offset(); }
00139
00140
00141
00142
00143 inline Scalar absDistance(const VectorType& p) const { return internal::abs(signedDistance(p)); }
00144
00145
00146
00147 inline VectorType projection(const VectorType& p) const { return p - signedDistance(p) * normal(); }
00148
00149
00150
00151
00152 inline ConstNormalReturnType normal() const { return ConstNormalReturnType(m_coeffs,0,0,dim(),1); }
00153
00154
00155
00156
00157 inline NormalReturnType normal() { return NormalReturnType(m_coeffs,0,0,dim(),1); }
00158
00159
00160
00161
00162 inline const Scalar& offset() const { return m_coeffs.coeff(dim()); }
00163
00164
00165
00166 inline Scalar& offset() { return m_coeffs(dim()); }
00167
00168
00169
00170
00171 inline const Coefficients& coeffs() const { return m_coeffs; }
00172
00173
00174
00175
00176 inline Coefficients& coeffs() { return m_coeffs; }
00177
00178
00179
00180
00181
00182
00183
00184 VectorType intersection(const Hyperplane& other)
00185 {
00186 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2)
00187 Scalar det = coeffs().coeff(0) * other.coeffs().coeff(1) - coeffs().coeff(1) * other.coeffs().coeff(0);
00188
00189
00190 if(internal::isMuchSmallerThan(det, Scalar(1)))
00191 {
00192 if(internal::abs(coeffs().coeff(1))>internal::abs(coeffs().coeff(0)))
00193 return VectorType(coeffs().coeff(1), -coeffs().coeff(2)/coeffs().coeff(1)-coeffs().coeff(0));
00194 else
00195 return VectorType(-coeffs().coeff(2)/coeffs().coeff(0)-coeffs().coeff(1), coeffs().coeff(0));
00196 }
00197 else
00198 {
00199 Scalar invdet = Scalar(1) / det;
00200 return VectorType(invdet*(coeffs().coeff(1)*other.coeffs().coeff(2)-other.coeffs().coeff(1)*coeffs().coeff(2)),
00201 invdet*(other.coeffs().coeff(0)*coeffs().coeff(2)-coeffs().coeff(0)*other.coeffs().coeff(2)));
00202 }
00203 }
00204
00205
00206
00207
00208
00209
00210
00211 template<typename XprType>
00212 inline Hyperplane& transform(const MatrixBase<XprType>& mat, TransformTraits traits = Affine)
00213 {
00214 if (traits==Affine)
00215 normal() = mat.inverse().transpose() * normal();
00216 else if (traits==Isometry)
00217 normal() = mat * normal();
00218 else
00219 {
00220 eigen_assert("invalid traits value in Hyperplane::transform()");
00221 }
00222 return *this;
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232 inline Hyperplane& transform(const Transform<Scalar,AmbientDimAtCompileTime,Affine>& t,
00233 TransformTraits traits = Affine)
00234 {
00235 transform(t.linear(), traits);
00236 offset() -= normal().dot(t.translation());
00237 return *this;
00238 }
00239
00240
00241
00242
00243
00244
00245 template<typename NewScalarType>
00246 inline typename internal::cast_return_type<Hyperplane,
00247 Hyperplane<NewScalarType,AmbientDimAtCompileTime> >::type cast() const
00248 {
00249 return typename internal::cast_return_type<Hyperplane,
00250 Hyperplane<NewScalarType,AmbientDimAtCompileTime> >::type(*this);
00251 }
00252
00253
00254 template<typename OtherScalarType>
00255 inline explicit Hyperplane(const Hyperplane<OtherScalarType,AmbientDimAtCompileTime>& other)
00256 { m_coeffs = other.coeffs().template cast<Scalar>(); }
00257
00258
00259
00260
00261
00262 bool isApprox(const Hyperplane& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
00263 { return m_coeffs.isApprox(other.m_coeffs, prec); }
00264
00265 protected:
00266
00267 Coefficients m_coeffs;
00268 };
00269
00270 #endif // EIGEN_HYPERPLANE_H