DGtal 2.1.0
Loading...
Searching...
No Matches
testAffineGeometry.cpp
Go to the documentation of this file.
1
31#include <iostream>
32#include <vector>
33#include <algorithm>
34#include <random>
35#include "DGtal/base/Common.h"
36#include "DGtal/kernel/SpaceND.h"
37#include "DGtal/geometry/tools/AffineGeometry.h"
38#include "DGtal/geometry/tools/AffineBasis.h"
39#include "DGtalCatch.h"
41
42using namespace std;
43using namespace DGtal;
44
45std::random_device rd;
46std::mt19937 g(rd());
47std::uniform_real_distribution<double> uniform(-1.0, 1.0);
48
49template <typename RealPoint>
50void perturbate( RealPoint& x, double perturbation )
51{
52 for ( auto& c : x ) c += uniform( g ) * perturbation;
53}
54
55template <typename RealPoint>
56void perturbate( std::vector< RealPoint >& X, double perturbation )
57{
58 for ( auto& x : X ) perturbate( x, perturbation );
59}
60
61template < typename Point >
62std::vector< Point >
63makeRandomVectors( int nb, int amplitude )
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}
76
77template < typename Point >
78std::vector< Point >
79makeRandomLatticePointsFromDirVectors( int nb, const vector< Point>& V )
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}
102
103template < typename Point >
104std::vector< Point >
105makeRandomRealPointsFromDirVectors( int nb, const vector< Point>& V )
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}
128
130// Functions for testing class AffineGeometry in 2D.
132
133SCENARIO( "AffineGeometry< Point2i > unit tests", "[affine_subset][2i]" )
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}
158
159SCENARIO( "AffineGeometry< Point2d > unit tests", "[affine_subset][2d]" )
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}
215
216SCENARIO( "AffineGeometry< Point2i > orthogonal tests", "[orthogonal_vector][2i]" )
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}
235
237// Functions for testing class AffineGeometry in 3D.
239
240SCENARIO( "AffineGeometry< Point3i > unit tests", "[affine_subset][3i]" )
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}
296
297SCENARIO( "AffineGeometry< Point3i > orthogonal tests", "[orthogonal_vector][3i]" )
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}
345
347// Functions for testing class AffineGeometry in 4D.
349
350SCENARIO( "AffineGeometry< Point4i > unit tests", "[affine_subset][4i]" )
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}
416
417SCENARIO( "AffineGeometry< Point4d > unit tests", "[affine_subset][4d]" )
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}
484
485SCENARIO( "AffineGeometry< Point4i > orthogonal tests", "[orthogonal_vector][4i]" )
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}
525
526
527SCENARIO( "AffineGeometry< Z3 > bug", "[affine_geom][3d]" )
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}
550
551SCENARIO( "AffineGeometry< Z3 > orthogonality", "[affine_geom][3d]" )
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}
582
void getAffineBasis(TInputPoint &o, std::vector< TPoint > &basis, const std::vector< TInputPoint > &X, const double tolerance=1e-12)
static void getOrthogonalVector(TPoint &w, const std::vector< TInputPoint > &X, const TIndexRange &I, const double tolerance=1e-12)
static TPoint computeOrthogonalVectorToBasis(const std::vector< TPoint > &basis)
std::vector< std::size_t > computeAffineSubset(const std::vector< TPoint > &X, const double tolerance=1e-12)
TPoint computeSimplifiedVector(const TPoint &v)
DGtal is the top-level namespace which contains all DGtal functions and types.
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.
STL namespace.
Aim: Utility class to determine the affine geometry of an input set of points. It provides exact resu...
std::mt19937 g(rd())
void perturbate(RealPoint &x, double perturbation)
std::random_device rd
std::vector< Point > makeRandomLatticePointsFromDirVectors(int nb, const vector< Point > &V)
std::vector< Point > makeRandomRealPointsFromDirVectors(int nb, const vector< Point > &V)
std::vector< Point > makeRandomVectors(int nb, int amplitude)
std::uniform_real_distribution< double > uniform(-1.0, 1.0)
MyPointD Point
CAPTURE(thicknessHV)
GIVEN("A cubical complex with random 3-cells")
REQUIRE(domain.isInside(aPoint))
SCENARIO("UnorderedSetByBlock< PointVector< 2, int > unit tests with 32 bits blocks", "[unorderedsetbyblock][2d]")