DGtal 2.1.0
Loading...
Searching...
No Matches
testAffineGeometry.cpp File Reference
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include "DGtal/base/Common.h"
#include "DGtal/kernel/SpaceND.h"
#include "DGtal/geometry/tools/AffineGeometry.h"
#include "DGtal/geometry/tools/AffineBasis.h"
#include "DGtalCatch.h"
Include dependency graph for testAffineGeometry.cpp:

Go to the source code of this file.

Functions

std::mt19937 g (rd())
 
std::uniform_real_distribution< double > uniform (-1.0, 1.0)
 
template<typename RealPoint >
void perturbate (RealPoint &x, double perturbation)
 
template<typename RealPoint >
void perturbate (std::vector< RealPoint > &X, double perturbation)
 
template<typename Point >
std::vector< PointmakeRandomVectors (int nb, int amplitude)
 
template<typename Point >
std::vector< PointmakeRandomLatticePointsFromDirVectors (int nb, const vector< Point > &V)
 
template<typename Point >
std::vector< PointmakeRandomRealPointsFromDirVectors (int nb, const vector< Point > &V)
 
 SCENARIO ("AffineGeometry< Point2i > unit tests", "[affine_subset][2i]")
 
 SCENARIO ("AffineGeometry< Point2d > unit tests", "[affine_subset][2d]")
 
 SCENARIO ("AffineGeometry< Point2i > orthogonal tests", "[orthogonal_vector][2i]")
 
 SCENARIO ("AffineGeometry< Point3i > unit tests", "[affine_subset][3i]")
 
 SCENARIO ("AffineGeometry< Point3i > orthogonal tests", "[orthogonal_vector][3i]")
 
 SCENARIO ("AffineGeometry< Point4i > unit tests", "[affine_subset][4i]")
 
 SCENARIO ("AffineGeometry< Point4d > unit tests", "[affine_subset][4d]")
 
 SCENARIO ("AffineGeometry< Point4i > orthogonal tests", "[orthogonal_vector][4i]")
 
 SCENARIO ("AffineGeometry< Z3 > bug", "[affine_geom][3d]")
 
 SCENARIO ("AffineGeometry< Z3 > orthogonality", "[affine_geom][3d]")
 

Variables

std::random_device rd
 

Detailed Description

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Author
Jacques-Olivier Lachaud (jacqu.nosp@m.es-o.nosp@m.livie.nosp@m.r.la.nosp@m.chaud.nosp@m.@uni.nosp@m.v-sav.nosp@m.oie..nosp@m.fr ) Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
Date
2025/08/24

Functions for testing class AffineGeometry.

This file is part of the DGtal library.

Definition in file testAffineGeometry.cpp.

Function Documentation

◆ g()

◆ makeRandomLatticePointsFromDirVectors()

template<typename Point >
std::vector< Point > makeRandomLatticePointsFromDirVectors ( int  nb,
const vector< Point > &  V 
)

Definition at line 79 of file testAffineGeometry.cpp.

80{
81 std::uniform_int_distribution<int> U(-10, 10);
82 vector< Point > P;
83 int n = V[0].size();
84 int m = V.size();
85 Point A;
86 for ( auto i = 0; i < n; i++ )
87 A[ i ] = U( g );
88 P.push_back( A );
89 for ( auto k = 0; k < nb; k++ )
90 {
91 Point B = A;
92 for ( auto i = 0; i < m; i++ )
93 {
94 int l = U( g );
95 B += l * V[ i ];
96 }
97 P.push_back( B );
98 }
99 std::shuffle( P.begin(), P.end(), g );
100 return P;
101}
std::mt19937 g(rd())

References g().

Referenced by SCENARIO(), and SCENARIO().

◆ makeRandomRealPointsFromDirVectors()

template<typename Point >
std::vector< Point > makeRandomRealPointsFromDirVectors ( int  nb,
const vector< Point > &  V 
)

Definition at line 105 of file testAffineGeometry.cpp.

106{
107 std::uniform_real_distribution<double> U(-1., 1.);
108 vector< Point > P;
109 int n = V[0].size();
110 int m = V.size();
111 Point A;
112 for ( auto i = 0; i < n; i++ )
113 A[ i ] = U( g );
114 P.push_back( A );
115 for ( auto k = 0; k < nb; k++ )
116 {
117 Point B = A;
118 for ( auto i = 0; i < m; i++ )
119 {
120 double l = 5.* U( g );
121 B += l * V[ i ];
122 }
123 P.push_back( B );
124 }
125 std::shuffle( P.begin(), P.end(), g );
126 return P;
127}

References g().

Referenced by SCENARIO().

◆ makeRandomVectors()

template<typename Point >
std::vector< Point > makeRandomVectors ( int  nb,
int  amplitude 
)

Definition at line 63 of file testAffineGeometry.cpp.

64{
65 std::uniform_int_distribution<int> U(-amplitude, amplitude);
66 std::vector< Point > P;
67 for ( auto n = 0; n < nb; ++n )
68 {
69 Point A;
70 for ( auto i = 0; i < Point::dimension; i++ )
71 A[ i ] = U( g );
72 P.push_back( A );
73 }
74 return P;
75}

References g().

◆ perturbate() [1/2]

template<typename RealPoint >
void perturbate ( RealPoint x,
double  perturbation 
)

Definition at line 50 of file testAffineGeometry.cpp.

51{
52 for ( auto& c : x ) c += uniform( g ) * perturbation;
53}
std::uniform_real_distribution< double > uniform(-1.0, 1.0)

References g(), and uniform().

Referenced by perturbate(), and SCENARIO().

◆ perturbate() [2/2]

template<typename RealPoint >
void perturbate ( std::vector< RealPoint > &  X,
double  perturbation 
)

Definition at line 56 of file testAffineGeometry.cpp.

57{
58 for ( auto& x : X ) perturbate( x, perturbation );
59}
void perturbate(RealPoint &x, double perturbation)

References perturbate().

◆ SCENARIO() [1/10]

SCENARIO ( "AffineGeometry< Point2d > unit tests"  ,
""  [affine_subset][2d] 
)

Definition at line 159 of file testAffineGeometry.cpp.

160{
161 typedef SpaceND< 2, int > Space;
162 typedef Space::RealPoint Point;
163 typedef AffineGeometry< Point > Affine;
164 GIVEN( "Given X = { (0,0), (-4,-1), (16,4), (-3,5), (7,3), (5, -2) } of affine dimension 2" ) {
165 std::vector<Point> X
166 = { Point(0,0), Point(-4,-1), Point(16,4), Point(-3,5), Point(7,3), Point(5, -2) };
167 auto I = Affine::affineSubset( X );
168 THEN( "It has an affine basis of 3 points [0,1,3]" ) {
169 CAPTURE( I );
170 REQUIRE( I.size() == 3 );
171 REQUIRE( I[ 2 ] == 3 );
172 }
173 }
174 GIVEN( "Given X = { (0,0), (-4,-1), (-8,-2), (8,2), (16,4), (200,50) } of affine dimension 1" ) {
175 std::vector<Point> X
176 = { Point(0,0), Point(-4,-1), Point(-8,-2), Point(8,2), Point(16,4), Point(200,50) };
177 auto I = Affine::affineSubset( X );
178 THEN( "It has an affine basis of 2 points [0,1]" ) {
179 CAPTURE( I );
180 REQUIRE( I.size() == 2 );
181 }
182 }
183 GIVEN( "Given a perturbated X = { (0,0), (-4,-1), (16,4), (-3,5), (7,3), (5, -2) } of affine dimension 2 by U[-1e-4,1e-4]" ) {
184 std::vector<Point> X
185 = { Point(0,0), Point(-4,-1), Point(16,4), Point(-3,5), Point(7,3), Point(5, -2) };
186 perturbate( X, 1e-4 );
187 auto I = Affine::affineSubset( X, 1e-12 );
188 THEN( "It has an affine basis of 3 points [0,1,x]" ) {
189 CAPTURE( I );
190 REQUIRE( I.size() == 3 );
191 }
192 }
193 GIVEN( "Given a perturbated X = { (0,0), (-4,-1), (-8,-2), (8,2), (16,4), (200,50) } of affine dimension 1 by U[-1e-4,1e-4]" ) {
194 std::vector<Point> X
195 = { Point(0,0), Point(-4,-1), Point(-8,-2), Point(8,2), Point(16,4), Point(200,50) };
196 perturbate( X, 1e-4 );
197 auto I = Affine::affineSubset( X, 1e-12 );
198 THEN( "It has an affine basis of 3 points [0,1,x]" ) {
199 CAPTURE( I );
200 REQUIRE( I.size() == 3 );
201 }
202 }
203 GIVEN( "Given a perturbated X = { (0,0), (-4,-1), (-8,-2), (8,2), (16,4), (200,50) } of affine dimension 1 by U[-1e-11,1e-11]" ) {
204 std::vector<Point> X
205 = { Point(0,0), Point(-4,-1), Point(-8,-2), Point(8,2), Point(16,4), Point(200,50) };
206 perturbate( X, 1e-11 );
207 auto I = Affine::affineSubset( X, 1e-7 );
208 THEN( "It has an affine basis of 2 points [0,1] if tolerance is 1e-7" ) {
209 CAPTURE( X );
210 CAPTURE( I );
211 REQUIRE( I.size() == 2 );
212 }
213 }
214}
Aim: Utility class to determine the affine geometry of an input set of points. It provides exact resu...
MyPointD Point
CAPTURE(thicknessHV)
GIVEN("A cubical complex with random 3-cells")
REQUIRE(domain.isInside(aPoint))

References CAPTURE(), GIVEN(), perturbate(), and REQUIRE().

◆ SCENARIO() [2/10]

SCENARIO ( "AffineGeometry< Point2i > orthogonal tests"  ,
""  [orthogonal_vector][2i] 
)

Definition at line 216 of file testAffineGeometry.cpp.

217{
218 typedef SpaceND< 2, int > Space;
219 typedef Space::Point Point;
220 typedef AffineGeometry< Point > Affine;
221 GIVEN( "Given basis B = { (7,3) } " ) {
222 std::vector<Point> B = { Point(7,3) };
223 Affine::completeBasis( B, true );
224 THEN( "The complete basis has dimension 2" ) {
225 CAPTURE( B );
226 REQUIRE( B.size() == 2 );
227 }
228 THEN( "The last vector is non null and orthogonal to all the others" ) {
229 CAPTURE( B.back() );
230 REQUIRE( B.back().normInfinity() > 0 );
231 REQUIRE( B.back().dot( B[ 0 ] ) == 0 );
232 }
233 }
234}

References CAPTURE(), GIVEN(), and REQUIRE().

◆ SCENARIO() [3/10]

SCENARIO ( "AffineGeometry< Point2i > unit tests"  ,
""  [affine_subset][2i] 
)

Definition at line 133 of file testAffineGeometry.cpp.

134{
135 typedef SpaceND< 2, int > Space;
136 typedef Space::Point Point;
137 typedef AffineGeometry< Point > Affine;
138 GIVEN( "Given X = { (0,0), (-4,-1), (16,4), (-3,5), (7,3), (5, -2) } of affine dimension 2" ) {
139 std::vector<Point> X
140 = { Point(0,0), Point(-4,-1), Point(16,4), Point(-3,5), Point(7,3), Point(5, -2) };
141 auto I = Affine::affineSubset( X );
142 THEN( "It has an affine basis of 3 points" ) {
143 CAPTURE( I );
144 REQUIRE( I.size() == 3 );
145 REQUIRE( I[ 2 ] == 3 );
146 }
147 }
148 GIVEN( "Given X = { (0,0), (-4,-1), (-8,-2), (8,2), (16,4), (200,50) } of affine dimension 1" ) {
149 std::vector<Point> X
150 = { Point(0,0), Point(-4,-1), Point(-8,-2), Point(8,2), Point(16,4), Point(200,50) };
151 auto I = Affine::affineSubset( X );
152 THEN( "It has an affine basis of 2 points" ) {
153 CAPTURE( I );
154 REQUIRE( I.size() == 2 );
155 }
156 }
157}

References CAPTURE(), GIVEN(), and REQUIRE().

◆ SCENARIO() [4/10]

SCENARIO ( "AffineGeometry< Point3i > orthogonal tests"  ,
""  [orthogonal_vector][3i] 
)

Definition at line 297 of file testAffineGeometry.cpp.

298{
299 typedef SpaceND< 3, int > Space;
300 typedef Space::Point Point;
301 typedef AffineGeometry< Point > Affine;
302 GIVEN( "Given basis B = { (7,3,1), (2,-5,1) } " ) {
303 std::vector<Point> B = { Point(7,3,1), Point( 2,-5,1) };
304 Point n = B[ 0 ].crossProduct( B[ 1 ] );
305 Affine::completeBasis( B, true );
306 THEN( "The complete basis has dimension 3" ) {
307 CAPTURE( B );
308 REQUIRE( B.size() == 3 );
309 }
310 THEN( "The last vector is non null and orthogonal to all the others" ) {
311 CAPTURE( B.back() );
312 REQUIRE( B.back().normInfinity() > 0 );
313 REQUIRE( B.back().dot( B[ 0 ] ) == 0 );
314 REQUIRE( B.back().dot( B[ 1 ] ) == 0 );
315 }
316 THEN( "The last vector is the cross product of the two others" ) {
317 CAPTURE( B.back() );
318 REQUIRE( B.back() == n );
319 }
320 }
321 GIVEN( "Given basis B = { (7,3,1) } " ) {
322 std::vector<Point> B = { Point(7,3,1) };
323 Affine::completeBasis( B, true );
324 THEN( "The complete basis has dimension 3" ) {
325 CAPTURE( B );
326 REQUIRE( B.size() == 3 );
327 }
328 THEN( "The mid vector is non null and trivial" ) {
329 CAPTURE( B[ 1 ] );
330 REQUIRE( B[ 1 ].norm1() == 1 );
331 }
332 THEN( "The last vector is non null and orthogonal to all the others" ) {
333 CAPTURE( B.back() );
334 REQUIRE( B.back().normInfinity() > 0 );
335 REQUIRE( B.back().dot( B[ 0 ] ) == 0 );
336 REQUIRE( B.back().dot( B[ 1 ] ) == 0 );
337 }
338 THEN( "The last vector is the cross product of the two others" ) {
339 Point n = B[ 0 ].crossProduct( B[ 1 ] );
340 CAPTURE( B.back() );
341 REQUIRE( B.back() == n );
342 }
343 }
344}

References CAPTURE(), GIVEN(), and REQUIRE().

◆ SCENARIO() [5/10]

SCENARIO ( "AffineGeometry< Point3i > unit tests"  ,
""  [affine_subset][3i] 
)

Definition at line 240 of file testAffineGeometry.cpp.

241{
242 typedef SpaceND< 3, int > Space;
243 typedef Space::Point Point;
244 typedef AffineGeometry< Point > Affine;
245 GIVEN( "Given X = { (1, 0, 0), (2, 1, 0), (3, 1, 1), (3, 2, 0), (5, 2, 2), (4, 2, 1)} of affine dimension 2" ) {
246 std::vector<Point> X
247 = { Point{1, 0, 0}, Point{2, 1, 0}, Point{3, 1, 1}, Point{3, 2, 0}, Point{5, 2, 2}, Point{4, 2, 1} };
248
249 auto I = Affine::affineSubset( X );
250 THEN( "It has an affine basis of 3 points" ) {
251 CAPTURE( I );
252 REQUIRE( I.size() == 3 );
253 REQUIRE( I[ 2 ] == 2 );
254 }
255 }
256 GIVEN( "Given X = { (1, 0, 0), (2, 1, 0), (3, 1, 1), (3, 2, 0), (5, 2, 2), (4, 2, 1), (7, 3, 2)} of affine dimension 3" ) {
257 std::vector<Point> X
258 = { Point{1, 0, 0}, Point{2, 1, 0}, Point{3, 1, 1}, Point{3, 2, 0}, Point{5, 2, 2}, Point{4, 2, 1}, Point{7, 3, 2} };
259
260 auto I = Affine::affineSubset( X );
261 THEN( "It has an affine basis of 4 points" ) {
262 CAPTURE( I );
263 REQUIRE( I.size() == 4 );
264 REQUIRE( I[ 2 ] == 2 );
265 REQUIRE( I[ 3 ] == 6 );
266 }
267 }
268 GIVEN( "Given X a set of randomly generated points by adding linear combinations of 1 lattice vectors" ) {
269 std::vector< Point > V = { Point{ 3, 1, 0 } };
271 auto I = Affine::affineSubset( X );
272 THEN( "It has an affine basis of 2 points" ) {
273 CAPTURE( I );
274 REQUIRE( I.size() == 2 );
275 }
276 }
277 GIVEN( "Given X a set of randomly generated points by adding linear combinations of 2 lattice vectors" ) {
278 std::vector< Point > V = { Point{ 3, 1, 0 }, Point{ -2, -1, 2 } };
280 auto I = Affine::affineSubset( X );
281 THEN( "It has an affine basis of 3 points" ) {
282 CAPTURE( I );
283 REQUIRE( I.size() == 3 );
284 }
285 }
286 GIVEN( "Given X a set of randomly generated points by adding linear combinations of 3 lattice vectors" ) {
287 std::vector< Point > V = { Point{ 3, 1, 0 }, Point{ -2, -1, 2 }, Point{ -1, 4, 3 } };
289 auto I = Affine::affineSubset( X );
290 THEN( "It has an affine basis of 4 points" ) {
291 CAPTURE( I );
292 REQUIRE( I.size() == 4 );
293 }
294 }
295}
std::vector< Point > makeRandomLatticePointsFromDirVectors(int nb, const vector< Point > &V)

References CAPTURE(), GIVEN(), makeRandomLatticePointsFromDirVectors(), and REQUIRE().

◆ SCENARIO() [6/10]

SCENARIO ( "AffineGeometry< Point4d > unit tests"  ,
""  [affine_subset][4d] 
)

Definition at line 417 of file testAffineGeometry.cpp.

418{
419 // NB: 1e-10 in tolerance is ok for these examples.
420 // max norm of rejected vectors are 2e-12.
421 typedef SpaceND< 4, int > Space;
422 typedef Space::RealPoint Point;
423 GIVEN( "Given X a set of randomly generated points by adding linear combinations of 1 lattice vectors" ) {
424 std::vector< Point > V = { Point{ 3, 1, 0, 2 } };
425 auto X = makeRandomRealPointsFromDirVectors( 20, V );
426 auto I = functions::computeAffineSubset( X, 1e-10 );
427 Point o;
428 std::vector< Point > B;
429 functions::getAffineBasis( o, B, X, 1e-10 );
430 THEN( "It has an affine subset of 2 points" ) {
431 CAPTURE( I );
432 REQUIRE( I.size() == 2 );
433 }
434 THEN( "It has an affine basis of 1 vector" ) {
435 REQUIRE( B.size() == 1 );
436 }
437 }
438 GIVEN( "Given X a set of randomly generated points by adding linear combinations of 2 lattice vectors" ) {
439 std::vector< Point > V = { Point{ 3, 1, 0, 2 }, Point{ -2, -1, 2, 7 } };
440 auto X = makeRandomRealPointsFromDirVectors( 20, V );
441 auto I = functions::computeAffineSubset( X, 1e-10 );
442 Point o;
443 std::vector< Point > B;
444 functions::getAffineBasis( o, B, X, 1e-10 );
445 THEN( "It has an affine subset of 3 points" ) {
446 CAPTURE( I );
447 REQUIRE( I.size() == 3 );
448 }
449 THEN( "It has an affine basis of 2 vectors" ) {
450 REQUIRE( B.size() == 2 );
451 }
452 }
453 GIVEN( "Given X a set of randomly generated points by adding linear combinations of 3 lattice vectors" ) {
454 std::vector< Point > V = { Point{ 3, 1, 0, 2 }, Point{ -2, -1, 2, 7 }, Point{ -1, 4, 3, -1 } };
455 auto X = makeRandomRealPointsFromDirVectors( 20, V );
456 auto I = functions::computeAffineSubset( X, 1e-10 );
457 Point o;
458 std::vector< Point > B;
459 functions::getAffineBasis( o, B, X, 1e-10 );
460 THEN( "It has an affine subset of 4 points" ) {
461 CAPTURE( I );
462 REQUIRE( I.size() == 4 );
463 }
464 THEN( "It has an affine basis of 3 vectors" ) {
465 REQUIRE( B.size() == 3 );
466 }
467 }
468 GIVEN( "Given X a set of randomly generated points by adding linear combinations of 4 lattice vectors" ) {
469 std::vector< Point > V = { Point{ 3, 1, 0, 2 }, Point{ -2, -1, 2, 7 }, Point{ -1, 4, 3, -1 }, Point{ 2, 1, -3, -4 } };
470 auto X = makeRandomRealPointsFromDirVectors( 20, V );
471 auto I = functions::computeAffineSubset( X, 1e-10 );
472 Point o;
473 std::vector< Point > B;
474 functions::getAffineBasis( o, B, X, 1e-10 );
475 THEN( "It has an affine subset of 5 points" ) {
476 CAPTURE( I );
477 REQUIRE( I.size() == 5 );
478 }
479 THEN( "It has an affine basis of 4 vectors" ) {
480 REQUIRE( B.size() == 4 );
481 }
482 }
483}
void getAffineBasis(TInputPoint &o, std::vector< TPoint > &basis, const std::vector< TInputPoint > &X, const double tolerance=1e-12)
std::vector< std::size_t > computeAffineSubset(const std::vector< TPoint > &X, const double tolerance=1e-12)
std::vector< Point > makeRandomRealPointsFromDirVectors(int nb, const vector< Point > &V)

References CAPTURE(), DGtal::functions::computeAffineSubset(), DGtal::functions::getAffineBasis(), GIVEN(), makeRandomRealPointsFromDirVectors(), and REQUIRE().

◆ SCENARIO() [7/10]

SCENARIO ( "AffineGeometry< Point4i > orthogonal tests"  ,
""  [orthogonal_vector][4i] 
)

Definition at line 485 of file testAffineGeometry.cpp.

486{
487 typedef SpaceND< 4, int > Space;
488 typedef Space::Point Point;
489 typedef AffineGeometry< Point > Affine;
490 GIVEN( "Given basis B = { (7,3,1,0), (2,-5,1,2), (-1,2,2,-3) } " ) {
491 std::vector<Point> B = { Point(7,3,1,0), Point(2,-5,1,2), Point(-1,2,2,-3) };
492 Affine::completeBasis( B, true );
493 THEN( "The complete basis has dimension 4" ) {
494 CAPTURE( B );
495 REQUIRE( B.size() == 4 );
496 }
497 THEN( "The last vector is non null and orthogonal to all the others" ) {
498 CAPTURE( B.back() );
499 REQUIRE( B.back().normInfinity() > 0 );
500 REQUIRE( B.back().dot( B[ 0 ] ) == 0 );
501 REQUIRE( B.back().dot( B[ 1 ] ) == 0 );
502 REQUIRE( B.back().dot( B[ 2 ] ) == 0 );
503 }
504 }
505 GIVEN( "Given basis B = { (7,3,1,0), (2,-5,1,2) } " ) {
506 std::vector<Point> B = { Point(7,3,1,0), Point(2,-5,1,2) };
507 Affine::completeBasis( B, true );
508 THEN( "The complete basis has dimension 4" ) {
509 CAPTURE( B );
510 REQUIRE( B.size() == 4 );
511 }
512 THEN( "The third vector is non null and trivial" ) {
513 CAPTURE( B[ 2 ] );
514 REQUIRE( B[ 2 ].norm1() == 1 );
515 }
516 THEN( "The last vector is non null and orthogonal to all the others" ) {
517 CAPTURE( B.back() );
518 REQUIRE( B.back().normInfinity() > 0 );
519 REQUIRE( B.back().dot( B[ 0 ] ) == 0 );
520 REQUIRE( B.back().dot( B[ 1 ] ) == 0 );
521 REQUIRE( B.back().dot( B[ 2 ] ) == 0 );
522 }
523 }
524}

References CAPTURE(), GIVEN(), and REQUIRE().

◆ SCENARIO() [8/10]

SCENARIO ( "AffineGeometry< Point4i > unit tests"  ,
""  [affine_subset][4i] 
)

Definition at line 350 of file testAffineGeometry.cpp.

351{
352 typedef SpaceND< 4, int > Space;
353 typedef Space::Point Point;
354 GIVEN( "Given X a set of randomly generated points by adding linear combinations of 1 lattice vectors" ) {
355 std::vector< Point > V = { Point{ 3, 1, 0, 2 } };
357 auto I = functions::computeAffineSubset( X );
358 Point o;
359 std::vector< Point > B;
361 THEN( "It has an affine basis of 2 points" ) {
362 CAPTURE( I );
363 REQUIRE( I.size() == 2 );
364 }
365 THEN( "It has an affine basis of 1 vector" ) {
366 REQUIRE( B.size() == 1 );
367 }
368
369 }
370 GIVEN( "Given X a set of randomly generated points by adding linear combinations of 2 lattice vectors" ) {
371 std::vector< Point > V = { Point{ 3, 1, 0, 2 }, Point{ -2, -1, 2, 7 } };
373 auto I = functions::computeAffineSubset( X );
374 Point o;
375 std::vector< Point > B;
377 THEN( "It has an affine basis of 3 points" ) {
378 CAPTURE( I );
379 REQUIRE( I.size() == 3 );
380 }
381 THEN( "It has an affine basis of 2 vectors" ) {
382 REQUIRE( B.size() == 2 );
383 }
384 }
385 GIVEN( "Given X a set of randomly generated points by adding linear combinations of 3 lattice vectors" ) {
386 std::vector< Point > V = { Point{ 3, 1, 0, 2 }, Point{ -2, -1, 2, 7 }, Point{ -1, 4, 3, -1 } };
388 auto I = functions::computeAffineSubset( X );
389 Point o;
390 std::vector< Point > B;
392 THEN( "It has an affine basis of 4 points" ) {
393 CAPTURE( I );
394 REQUIRE( I.size() == 4 );
395 }
396 THEN( "It has an affine basis of 3 vectors" ) {
397 REQUIRE( B.size() == 3 );
398 }
399 }
400 GIVEN( "Given X a set of randomly generated points by adding linear combinations of 4 lattice vectors" ) {
401 std::vector< Point > V = { Point{ 3, 1, 0, 2 }, Point{ -2, -1, 2, 7 }, Point{ -1, 4, 3, -1 }, Point{ 2, 1, -3, -4 } };
403 auto I = functions::computeAffineSubset( X );
404 Point o;
405 std::vector< Point > B;
406 functions::getAffineBasis( o, B, X, 1e-10 );
407 THEN( "It has an affine basis of 5 points" ) {
408 CAPTURE( I );
409 REQUIRE( I.size() == 5 );
410 }
411 THEN( "It has an affine basis of 4 vectors" ) {
412 REQUIRE( B.size() == 4 );
413 }
414 }
415}

References CAPTURE(), DGtal::functions::computeAffineSubset(), DGtal::functions::getAffineBasis(), GIVEN(), makeRandomLatticePointsFromDirVectors(), and REQUIRE().

◆ SCENARIO() [9/10]

SCENARIO ( "AffineGeometry< Z3 > bug"  ,
""  [affine_geom][3d] 
)

Definition at line 527 of file testAffineGeometry.cpp.

528{
529 typedef SpaceND<3,int> Space;
530 typedef Space::Point Point;
531 std::vector< Point > X = { {-46, 38, -43}, {27, -89, 20}, {53, 26, -57} };
532 Point o;
533 std::vector< Point > B;
535 auto C = ( X[1]-X[0] ).crossProduct( X[2]-X[0] );
537 WHEN( "Computing orthogonal vector" ) {
539 THEN( "It is non null" ) {
540 CAPTURE( N );
541 REQUIRE( N != Point::zero );
542 }
543 THEN( "It corresponds to the reduced cross product" ) {
544 CAPTURE( C );
545 CAPTURE( sC );
546 REQUIRE( N == sC );
547 }
548 }
549}
static TPoint computeOrthogonalVectorToBasis(const std::vector< TPoint > &basis)
TPoint computeSimplifiedVector(const TPoint &v)
auto crossProduct(PointVector< 3, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< 3, RightEuclideanRing, RightContainer > const &rhs) -> decltype(DGtal::constructFromArithmeticConversion(lhs, rhs))
Cross product of two 3D Points/Vectors.

References CAPTURE(), DGtal::functions::computeOrthogonalVectorToBasis(), DGtal::functions::computeSimplifiedVector(), DGtal::crossProduct(), DGtal::functions::getAffineBasis(), and REQUIRE().

◆ SCENARIO() [10/10]

SCENARIO ( "AffineGeometry< Z3 > orthogonality"  ,
""  [affine_geom][3d] 
)

Definition at line 551 of file testAffineGeometry.cpp.

552{
554 typedef Space::Point Point;
555
556 WHEN( "Computing orthogonal vector to multiple random points" ) {
557 std::vector< Point > X = makeRandomVectors<Point>( 100, 50 );
558 std::size_t nb = 300;
559 std::size_t nb_equal = 0;
560 std::size_t nb_C_zero = 0;
561 std::size_t nb_N_zero = 0;
562 for ( auto i = 0; i < nb; i++ )
563 {
564 std::vector< Point > Y = { X[ rand() % 100 ], X[ rand() % 100 ], X[ rand() % 100 ] };
565 auto C = ( Y[1]-Y[0] ).crossProduct( Y[2]-Y[0] );
567 Point N;
569 nb_equal += (sC == N) ? 1 : 0;
570 if ( sC != N )
571 std::cout << "Y = " << Y[0] << " " << Y[1] << " " << Y[ 2 ]
572 << " sC = " << sC << " N = " << N << "\n";
573 nb_C_zero += ( C == Point::zero ) ? 1 : 0;
574 nb_N_zero += ( N == Point::zero ) ? 1 : 0;
575 }
576 THEN( "They corresponds to the reduced cross product" ) {
577 REQUIRE( nb_equal == nb );
578 REQUIRE( nb_C_zero == nb_N_zero );
579 }
580 }
581}
static void getOrthogonalVector(TPoint &w, const std::vector< TInputPoint > &X, const TIndexRange &I, const double tolerance=1e-12)

References DGtal::functions::computeSimplifiedVector(), DGtal::crossProduct(), DGtal::functions::getOrthogonalVector(), and REQUIRE().

◆ uniform()

std::uniform_real_distribution< double > uniform ( -1.  0,
1.  0 
)

Referenced by perturbate().

Variable Documentation

◆ rd

std::random_device rd

Definition at line 45 of file testAffineGeometry.cpp.