1*bf2c3715SXin Li // This file is part of Eigen, a lightweight C++ template library
2*bf2c3715SXin Li // for linear algebra.
3*bf2c3715SXin Li //
4*bf2c3715SXin Li // Copyright (C) 2008 Gael Guennebaud <[email protected]>
5*bf2c3715SXin Li // Copyright (C) 2008 Benoit Jacob <[email protected]>
6*bf2c3715SXin Li //
7*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla
8*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed
9*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10*bf2c3715SXin Li
11*bf2c3715SXin Li #include "main.h"
12*bf2c3715SXin Li #include <Eigen/Geometry>
13*bf2c3715SXin Li #include <Eigen/LU>
14*bf2c3715SXin Li #include <Eigen/QR>
15*bf2c3715SXin Li
parametrizedline(const LineType & _line)16*bf2c3715SXin Li template<typename LineType> void parametrizedline(const LineType& _line)
17*bf2c3715SXin Li {
18*bf2c3715SXin Li /* this test covers the following files:
19*bf2c3715SXin Li ParametrizedLine.h
20*bf2c3715SXin Li */
21*bf2c3715SXin Li using std::abs;
22*bf2c3715SXin Li const Index dim = _line.dim();
23*bf2c3715SXin Li typedef typename LineType::Scalar Scalar;
24*bf2c3715SXin Li typedef typename NumTraits<Scalar>::Real RealScalar;
25*bf2c3715SXin Li typedef Matrix<Scalar, LineType::AmbientDimAtCompileTime, 1> VectorType;
26*bf2c3715SXin Li typedef Hyperplane<Scalar,LineType::AmbientDimAtCompileTime> HyperplaneType;
27*bf2c3715SXin Li typedef Matrix<Scalar, HyperplaneType::AmbientDimAtCompileTime,
28*bf2c3715SXin Li HyperplaneType::AmbientDimAtCompileTime> MatrixType;
29*bf2c3715SXin Li
30*bf2c3715SXin Li VectorType p0 = VectorType::Random(dim);
31*bf2c3715SXin Li VectorType p1 = VectorType::Random(dim);
32*bf2c3715SXin Li
33*bf2c3715SXin Li VectorType d0 = VectorType::Random(dim).normalized();
34*bf2c3715SXin Li
35*bf2c3715SXin Li LineType l0(p0, d0);
36*bf2c3715SXin Li
37*bf2c3715SXin Li Scalar s0 = internal::random<Scalar>();
38*bf2c3715SXin Li Scalar s1 = abs(internal::random<Scalar>());
39*bf2c3715SXin Li
40*bf2c3715SXin Li VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(p0), RealScalar(1) );
41*bf2c3715SXin Li VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(p0+s0*d0), RealScalar(1) );
42*bf2c3715SXin Li VERIFY_IS_APPROX( (l0.projection(p1)-p1).norm(), l0.distance(p1) );
43*bf2c3715SXin Li VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(l0.projection(p1)), RealScalar(1) );
44*bf2c3715SXin Li VERIFY_IS_APPROX( Scalar(l0.distance((p0+s0*d0) + d0.unitOrthogonal() * s1)), s1 );
45*bf2c3715SXin Li
46*bf2c3715SXin Li // casting
47*bf2c3715SXin Li const int Dim = LineType::AmbientDimAtCompileTime;
48*bf2c3715SXin Li typedef typename GetDifferentType<Scalar>::type OtherScalar;
49*bf2c3715SXin Li ParametrizedLine<OtherScalar,Dim> hp1f = l0.template cast<OtherScalar>();
50*bf2c3715SXin Li VERIFY_IS_APPROX(hp1f.template cast<Scalar>(),l0);
51*bf2c3715SXin Li ParametrizedLine<Scalar,Dim> hp1d = l0.template cast<Scalar>();
52*bf2c3715SXin Li VERIFY_IS_APPROX(hp1d.template cast<Scalar>(),l0);
53*bf2c3715SXin Li
54*bf2c3715SXin Li // intersections
55*bf2c3715SXin Li VectorType p2 = VectorType::Random(dim);
56*bf2c3715SXin Li VectorType n2 = VectorType::Random(dim).normalized();
57*bf2c3715SXin Li HyperplaneType hp(p2,n2);
58*bf2c3715SXin Li Scalar t = l0.intersectionParameter(hp);
59*bf2c3715SXin Li VectorType pi = l0.pointAt(t);
60*bf2c3715SXin Li VERIFY_IS_MUCH_SMALLER_THAN(hp.signedDistance(pi), RealScalar(1));
61*bf2c3715SXin Li VERIFY_IS_MUCH_SMALLER_THAN(l0.distance(pi), RealScalar(1));
62*bf2c3715SXin Li VERIFY_IS_APPROX(l0.intersectionPoint(hp), pi);
63*bf2c3715SXin Li
64*bf2c3715SXin Li // transform
65*bf2c3715SXin Li if (!NumTraits<Scalar>::IsComplex)
66*bf2c3715SXin Li {
67*bf2c3715SXin Li MatrixType rot = MatrixType::Random(dim,dim).householderQr().householderQ();
68*bf2c3715SXin Li DiagonalMatrix<Scalar,LineType::AmbientDimAtCompileTime> scaling(VectorType::Random());
69*bf2c3715SXin Li Translation<Scalar,LineType::AmbientDimAtCompileTime> translation(VectorType::Random());
70*bf2c3715SXin Li
71*bf2c3715SXin Li while(scaling.diagonal().cwiseAbs().minCoeff()<RealScalar(1e-4)) scaling.diagonal() = VectorType::Random();
72*bf2c3715SXin Li
73*bf2c3715SXin Li LineType l1 = l0;
74*bf2c3715SXin Li VectorType p3 = l0.pointAt(Scalar(1));
75*bf2c3715SXin Li VERIFY_IS_MUCH_SMALLER_THAN( l1.transform(rot).distance(rot * p3), Scalar(1) );
76*bf2c3715SXin Li l1 = l0;
77*bf2c3715SXin Li VERIFY_IS_MUCH_SMALLER_THAN( l1.transform(rot,Isometry).distance(rot * p3), Scalar(1) );
78*bf2c3715SXin Li l1 = l0;
79*bf2c3715SXin Li VERIFY_IS_MUCH_SMALLER_THAN( l1.transform(rot*scaling).distance((rot*scaling) * p3), Scalar(1) );
80*bf2c3715SXin Li l1 = l0;
81*bf2c3715SXin Li VERIFY_IS_MUCH_SMALLER_THAN( l1.transform(rot*scaling*translation)
82*bf2c3715SXin Li .distance((rot*scaling*translation) * p3), Scalar(1) );
83*bf2c3715SXin Li l1 = l0;
84*bf2c3715SXin Li VERIFY_IS_MUCH_SMALLER_THAN( l1.transform(rot*translation,Isometry)
85*bf2c3715SXin Li .distance((rot*translation) * p3), Scalar(1) );
86*bf2c3715SXin Li }
87*bf2c3715SXin Li
88*bf2c3715SXin Li }
89*bf2c3715SXin Li
parametrizedline_alignment()90*bf2c3715SXin Li template<typename Scalar> void parametrizedline_alignment()
91*bf2c3715SXin Li {
92*bf2c3715SXin Li typedef ParametrizedLine<Scalar,4,AutoAlign> Line4a;
93*bf2c3715SXin Li typedef ParametrizedLine<Scalar,4,DontAlign> Line4u;
94*bf2c3715SXin Li
95*bf2c3715SXin Li EIGEN_ALIGN_MAX Scalar array1[16];
96*bf2c3715SXin Li EIGEN_ALIGN_MAX Scalar array2[16];
97*bf2c3715SXin Li EIGEN_ALIGN_MAX Scalar array3[16+1];
98*bf2c3715SXin Li Scalar* array3u = array3+1;
99*bf2c3715SXin Li
100*bf2c3715SXin Li Line4a *p1 = ::new(reinterpret_cast<void*>(array1)) Line4a;
101*bf2c3715SXin Li Line4u *p2 = ::new(reinterpret_cast<void*>(array2)) Line4u;
102*bf2c3715SXin Li Line4u *p3 = ::new(reinterpret_cast<void*>(array3u)) Line4u;
103*bf2c3715SXin Li
104*bf2c3715SXin Li p1->origin().setRandom();
105*bf2c3715SXin Li p1->direction().setRandom();
106*bf2c3715SXin Li *p2 = *p1;
107*bf2c3715SXin Li *p3 = *p1;
108*bf2c3715SXin Li
109*bf2c3715SXin Li VERIFY_IS_APPROX(p1->origin(), p2->origin());
110*bf2c3715SXin Li VERIFY_IS_APPROX(p1->origin(), p3->origin());
111*bf2c3715SXin Li VERIFY_IS_APPROX(p1->direction(), p2->direction());
112*bf2c3715SXin Li VERIFY_IS_APPROX(p1->direction(), p3->direction());
113*bf2c3715SXin Li }
114*bf2c3715SXin Li
EIGEN_DECLARE_TEST(geo_parametrizedline)115*bf2c3715SXin Li EIGEN_DECLARE_TEST(geo_parametrizedline)
116*bf2c3715SXin Li {
117*bf2c3715SXin Li for(int i = 0; i < g_repeat; i++) {
118*bf2c3715SXin Li CALL_SUBTEST_1( parametrizedline(ParametrizedLine<float,2>()) );
119*bf2c3715SXin Li CALL_SUBTEST_2( parametrizedline(ParametrizedLine<float,3>()) );
120*bf2c3715SXin Li CALL_SUBTEST_2( parametrizedline_alignment<float>() );
121*bf2c3715SXin Li CALL_SUBTEST_3( parametrizedline(ParametrizedLine<double,4>()) );
122*bf2c3715SXin Li CALL_SUBTEST_3( parametrizedline_alignment<double>() );
123*bf2c3715SXin Li CALL_SUBTEST_4( parametrizedline(ParametrizedLine<std::complex<double>,5>()) );
124*bf2c3715SXin Li }
125*bf2c3715SXin Li }
126