Loading [MathJax]/extensions/TeX/AMSsymbols.js
DGtal 2.0.0
testPointVector.cpp
Go to the documentation of this file.
1
16
27
32#include <cstdio>
33#include <cmath>
34#include <iostream>
35#include <fstream>
36#include <vector>
37#include <type_traits>
38#include <functional>
39
40#include "DGtal/base/Common.h"
41#include "DGtal/kernel/PointVector.h"
42
43#include "DGtalCatch.h"
44
45using namespace DGtal;
46using namespace std;
47
48// Compare the value of the two parameters and also their component type.
49#define COMPARE_VALUE_AND_TYPE(expr, check) \
50 REQUIRE( (expr) == (check) ); \
51 REQUIRE( ( std::is_same<decltype(expr)::Component, decltype(check)::Component>::value ) );
52
53TEST_CASE( "2D Point Vector Unit tests" )
54{
55 using Real = double;
56 using Integer = DGtal::int32_t;
57
58 typedef PointVector<2, Integer> Point2D;
59 typedef PointVector<2, Real> RealPoint2D;
62
63 Integer t1[] = {1,2};
64 Integer t2[] = {5,4};
65 Real t3[] = {1.5,2.5};
66 Real t4[] = {5.5,4.5};
67
68 Point2D p1( t1 );
69 Point2D p2( t2 );
70 RealPoint2D p3(t3);
71 RealPoint2D p4(t4);
72
73 Point3D p1_3d( p1[0], p1[1] );
74 Point3D p2_3d( p2[0], p2[1] );
75 RealPoint3D p3_3d( p3[0], p3[1] );
76 RealPoint3D p4_3d( p4[0], p4[1] );
77
78 SECTION("Cross products with integers")
79 {
80 COMPARE_VALUE_AND_TYPE( p1.crossProduct(p2), p1_3d.crossProduct(p2_3d) );
81 COMPARE_VALUE_AND_TYPE( crossProduct(p1, p2), crossProduct(p1_3d, p2_3d) );
82 COMPARE_VALUE_AND_TYPE( p2.crossProduct(p1), p2_3d.crossProduct(p1_3d) );
83 COMPARE_VALUE_AND_TYPE( crossProduct(p2, p1), crossProduct(p2_3d, p1_3d) );
84 }
85
86 SECTION("Cross products with reals")
87 {
88 COMPARE_VALUE_AND_TYPE( p3.crossProduct(p4), p3_3d.crossProduct(p4_3d) );
89 COMPARE_VALUE_AND_TYPE( crossProduct(p3, p4), crossProduct(p3_3d, p4_3d) );
90 COMPARE_VALUE_AND_TYPE( p4.crossProduct(p3), p4_3d.crossProduct(p3_3d) );
91 COMPARE_VALUE_AND_TYPE( crossProduct(p4, p3), crossProduct(p4_3d, p3_3d) );
92 }
93
94 SECTION("Cross products with mixed integers/reals")
95 {
96 COMPARE_VALUE_AND_TYPE( p1.crossProduct(p3), p1_3d.crossProduct(p3_3d) );
97 COMPARE_VALUE_AND_TYPE( crossProduct(p1, p3), crossProduct(p1_3d, p3_3d) );
98 COMPARE_VALUE_AND_TYPE( p3.crossProduct(p1), p3_3d.crossProduct(p1_3d) );
99 COMPARE_VALUE_AND_TYPE( crossProduct(p3, p1), crossProduct(p3_3d, p1_3d) );
100 }
101 SECTION("Access data() of internal container")
102 {
103 const auto d = p1_3d.data();
104 CHECK(d[0] == p1[0]);
105 CHECK(d[1] == p1[1]);
106 }
107}
108
109
110TEST_CASE( "3D Point Vector Unit tests" )
111{
112 using Real = double;
113 using Integer = DGtal::int32_t;
114
117
118 Integer t1[] = {1,2,3};
119 Integer t2[] = {5,4,3};
120 Real t3[] = {1.5,2.5,3.5};
121 Real t4[] = {5.5,4.5,3.5};
122
123 Point p1( t1 );
124 Point p2( t2 );
125 RealPoint p3(t3);
126 RealPoint p4(t4);
127
128 SECTION("Cross products with integers")
129 {
130 COMPARE_VALUE_AND_TYPE( p1.crossProduct(p2), Point(-6, 12, -6) );
131 COMPARE_VALUE_AND_TYPE( crossProduct(p1, p2), Point(-6, 12, -6) );
132 COMPARE_VALUE_AND_TYPE( p2.crossProduct(p1), Point(6, -12, 6) );
133 COMPARE_VALUE_AND_TYPE( crossProduct(p2, p1), Point(6, -12, 6) );
134 }
135
136 SECTION("Cross products with reals")
137 {
138 COMPARE_VALUE_AND_TYPE( p3.crossProduct(p4), RealPoint(-7., 14., -7.) );
139 COMPARE_VALUE_AND_TYPE( crossProduct(p3, p4), RealPoint(-7., 14., -7.) );
140 COMPARE_VALUE_AND_TYPE( p4.crossProduct(p3), RealPoint(7., -14., 7.) );
141 COMPARE_VALUE_AND_TYPE( crossProduct(p4, p3), RealPoint(7., -14., 7.) );
142 }
143
144 SECTION("Cross products with mixed integers/reals")
145 {
146 COMPARE_VALUE_AND_TYPE( p1.crossProduct(p3), RealPoint(-0.5, 1., -0.5) );
147 COMPARE_VALUE_AND_TYPE( crossProduct(p1, p3), RealPoint(-0.5, 1., -0.5) );
148 COMPARE_VALUE_AND_TYPE( p3.crossProduct(p1), RealPoint(0.5, -1., 0.5) );
149 COMPARE_VALUE_AND_TYPE( crossProduct(p3, p1), RealPoint(0.5, -1., 0.5) );
150 }
151}
152
153TEST_CASE( "4D Point Vector Unit tests" )
154{
155 using Real = double;
156 using Integer = DGtal::int32_t;
157
160
161 const Real pi = std::acos(Real(-1));
162
163 Integer t1[] = {1,2,3,4};
164 Integer t2[] = {5,4,3,2};
165 Real t3[] = {1.0,-1.0,2.0,-2.0};
166 Real t4[] = {5.5,-4.5,3.5,2.5};
167
168 Point p1( t1 );
169 Point p1bis( t1 );
170 Point p2( t2 );
171 RealPoint p3(t3);
172 RealPoint p4(t4);
173 RealPoint p1r(p1);
174 RealPoint p2r(p2);
175
176 SECTION("Construction")
177 {
178 REQUIRE( p1 == Point( {1, 2, 3, 4} ) );
179 REQUIRE( p1r == RealPoint( {1., 2., 3., 4.} ) );
180
181 REQUIRE( p1 == Point( p1r ) );
182 REQUIRE( p1 == Point( RealPoint( {0.5, 2.1, 3.1, 3.9} ), DGtal::functors::Round<>() ) );
183 REQUIRE( p1 == Point( Point(0, 0, 1, 3), Point(1, 2, 2, 1), std::plus<Integer>() ) );
184 }
185
186 SECTION("Assignments")
187 {
188 Point dummy1;
189 dummy1 = p1;
190 REQUIRE( p1 == dummy1 );
191
192 Point dummy2(1, 3, 3, 5);
193 dummy2.partialCopy( Point(0, 2, 0, 4), {1, 3} );
194 REQUIRE( p1 == dummy2 );
195
196 Point dummy3(2, 2, 1, 4);
197 dummy3.partialCopyInv( Point(1, 0, 3, 0), {1, 3} );
198 REQUIRE( p1 == dummy3 );
199
200 RealPoint dummy1r;
201 dummy1r = p1;
202 REQUIRE( p1r == dummy1r );
203
204 RealPoint dummy2r(1, 3, 3, 5);
205 dummy2r.partialCopy( Point(0, 2, 0, 4), {1, 3} );
206 REQUIRE( p1r == dummy2r );
207
208 RealPoint dummy3r(2, 2, 1, 4);
209 dummy3r.partialCopyInv( Point(1, 0, 3, 0), {1, 3} );
210 REQUIRE( p1r == dummy3r );
211
212 Point dummy4(1, 3, 3, 5);
213 dummy4.partialCopy( RealPoint(0, 1.5, 0, 4.1), {1, 3}, DGtal::functors::Round<>() );
214 REQUIRE( p1 == dummy4 );
215
216 Point dummy5(2, 2, 1, 4);
217 dummy5.partialCopyInv( RealPoint(1.1, 0, 2.5, 0), {1, 3}, DGtal::functors::Round<>() );
218 REQUIRE( p1 == dummy5 );
219 }
220
221 SECTION("Comparisons")
222 {
223 // Partial equality
224 REQUIRE( p1.partialEqual( RealPoint(0, 2, 0, 4), {1, 3} ) );
225 REQUIRE( ! p1.partialEqual( RealPoint(0, 1, 0, 4), {1, 3} ) );
226 REQUIRE( p1.partialEqualInv( RealPoint(1, 0, 3, 0), {1, 3} ) );
227 REQUIRE( ! p1.partialEqualInv( RealPoint(1, 0, 2, 0), {1, 3} ) );
228
229 // Two equal points of same type
230 REQUIRE( p1 == p1bis );
231 REQUIRE( p1bis == p1 );
232 REQUIRE( ! (p1 != p1bis) );
233 REQUIRE( ! (p1bis != p1) );
234 REQUIRE( p1 <= p1bis );
235 REQUIRE( p1 >= p1bis );
236 REQUIRE( p1bis >= p1 );
237 REQUIRE( p1bis <= p1 );
238 REQUIRE( ! (p1 < p1bis) );
239 REQUIRE( ! (p1 > p1bis) );
240 REQUIRE( ! (p1bis > p1) );
241 REQUIRE( ! (p1bis < p1) );
242
243 // Two equal points of different types
244 REQUIRE( p1 == p1r );
245 REQUIRE( p1r == p1 );
246 REQUIRE( ! (p1 != p1r) );
247 REQUIRE( ! (p1r != p1) );
248 REQUIRE( p1 <= p1r );
249 REQUIRE( p1 >= p1r );
250 REQUIRE( p1r >= p1 );
251 REQUIRE( p1r <= p1 );
252 REQUIRE( ! (p1 < p1r) );
253 REQUIRE( ! (p1 > p1r) );
254 REQUIRE( ! (p1r > p1) );
255 REQUIRE( ! (p1r < p1) );
256
257 // Two ordered points of same type
258 REQUIRE( ! (p1 == p2) );
259 REQUIRE( ! (p2 == p1) );
260 REQUIRE( p1 != p2 );
261 REQUIRE( p2 != p1 );
262 REQUIRE( p1 <= p2 );
263 REQUIRE( ! (p1 >= p2) );
264 REQUIRE( p2 >= p1 );
265 REQUIRE( ! (p2 <= p1) );
266 REQUIRE( p1 < p2 );
267 REQUIRE( ! (p1 > p2) );
268 REQUIRE( p2 > p1 );
269 REQUIRE( ! (p2 < p1) );
270
271 // Two ordered points of different types
272 REQUIRE( ! (p1 == p2r) );
273 REQUIRE( ! (p2r == p1) );
274 REQUIRE( p1 != p2r );
275 REQUIRE( p2r != p1 );
276 REQUIRE( p1 <= p2r );
277 REQUIRE( ! (p1 >= p2r) );
278 REQUIRE( p2r >= p1 );
279 REQUIRE( ! (p2r <= p1) );
280 REQUIRE( p1 < p2r );
281 REQUIRE( ! (p1 > p2r) );
282 REQUIRE( p2r > p1 );
283 REQUIRE( ! (p2r < p1) );
284 }
285
286 SECTION("Min/Max of vector components")
287 {
288 REQUIRE( p3.max() == 2.0 );
289 REQUIRE( p3.min() == -2.0 );
290 REQUIRE( *p3.maxElement() == 2.0 );
291 REQUIRE( *p3.minElement() == -2.0 );
292 }
293
295 aPoint[ 3 ] = 0;
296 aPoint[ 2 ] = 2;
297 aPoint[ 1 ] = -1;
298 aPoint[ 0 ] = 3;
299
300 SECTION("Testing norms")
301 {
302 RealPoint normalized = aPoint.getNormalized();
303 CAPTURE( normalized );
304 REQUIRE( aPoint.norm ( Point::L_1 ) == 6 );
305 REQUIRE( aPoint.norm ( Point::L_infty ) == 3 );
306 REQUIRE( aPoint.squaredNorm() == Approx(aPoint.norm()*aPoint.norm()) );
307 REQUIRE( normalized[0] == Approx( 0.801784) );
308 REQUIRE( normalized[1] == Approx( -0.267261) );
309 REQUIRE( normalized[2] == Approx( 0.534522) );
310 REQUIRE( normalized[3] == Approx( 0.0) );
311 }
312
313 SECTION("PointVector Iterator")
314 {
315 PointVector<25,int> aPoint25;
316 for (unsigned int i=0;i<25;++i)
317 aPoint25[i] = i;
318
319 int sum = 0;
320 for (PointVector<25,int>::ConstIterator it = aPoint25.begin() ; it != aPoint25.end(); ++it)
321 sum += (*it);
322
323 CAPTURE(aPoint25);
324 CAPTURE(sum);
325 REQUIRE( sum == 300 );
326 }
327
328 SECTION("Arithmetical operators with integers")
329 {
330 COMPARE_VALUE_AND_TYPE( p1 + p2, Point(6,6,6,6) );
331 COMPARE_VALUE_AND_TYPE( p1 - p2, Point(-4,-2,0,2) );
332 COMPARE_VALUE_AND_TYPE( p1 * p2, Point(5,8,9,8) );
333 COMPARE_VALUE_AND_TYPE( p2 / p1, Point(5,2,1,0) );
334
335 COMPARE_VALUE_AND_TYPE( p1 + 2, Point(3,4,5,6) );
336 COMPARE_VALUE_AND_TYPE( 2 + p1, Point(3,4,5,6) );
337 COMPARE_VALUE_AND_TYPE( p1 - 2, Point(-1,0,1,2) );
338 COMPARE_VALUE_AND_TYPE( 2 - p1, Point(1,0,-1,-2) );
339 COMPARE_VALUE_AND_TYPE( p1 * 2, Point(2,4,6,8) );
340 COMPARE_VALUE_AND_TYPE( 2 * p1, Point(2,4,6,8) );
341 COMPARE_VALUE_AND_TYPE( p1 / 2, Point(0,1,1,2) );
342 COMPARE_VALUE_AND_TYPE( 2 / p1, Point(2,1,0,0) );
343
344 COMPARE_VALUE_AND_TYPE( -p1, Point(-1,-2,-3,-4) );
345
346 p1 *= 2; COMPARE_VALUE_AND_TYPE( p1, Point(2,4,6,8) );
347 p1 += 2; COMPARE_VALUE_AND_TYPE( p1, Point(4,6,8,10) );
348 p1 -= 2; COMPARE_VALUE_AND_TYPE( p1, Point(2,4,6,8) );
349 p1 /= 2; COMPARE_VALUE_AND_TYPE( p1, Point(1,2,3,4) );
350
351 p1 *= p2; COMPARE_VALUE_AND_TYPE( p1, Point(5,8,9,8) );
352 p1 += p2; COMPARE_VALUE_AND_TYPE( p1, Point(10,12,12,10) );
353 p1 -= p2; COMPARE_VALUE_AND_TYPE( p1, Point(5,8,9,8) );
354 p1 /= p2; COMPARE_VALUE_AND_TYPE( p1, Point(1,2,3,4) );
355 }
356
357 SECTION("Other operators with integers")
358 {
359 COMPARE_VALUE_AND_TYPE( p1.inf(p2), Point(1,2,3,2) );
360 COMPARE_VALUE_AND_TYPE( p1.sup(p2), Point(5,4,3,4) );
361 COMPARE_VALUE_AND_TYPE( inf(p1, p2), Point(1,2,3,2) );
362 COMPARE_VALUE_AND_TYPE( sup(p1, p2), Point(5,4,3,4) );
363
364 REQUIRE( p1.dot(p2) == 30 );
365 REQUIRE( dotProduct(p1, p2) == 30 );
366
367 REQUIRE( p1.cosineSimilarity(p1) == Approx(0.).margin(0.000001));
368 REQUIRE( p1.cosineSimilarity(-p1) == Approx(pi).margin(0.000001));
369 REQUIRE( p1.cosineSimilarity( Point(-2,1,-4,3) ) == Approx(pi/2).margin(0.000001) );
370 REQUIRE( cosineSimilarity(p1, p1) == Approx(0.).margin(0.000001) );
371 REQUIRE( cosineSimilarity(p1, -p1) == Approx(pi).margin(0.000001) );
372 REQUIRE( cosineSimilarity(p1, Point(-2,1,-4,3)) == Approx(pi/2).margin(0.000001) );
373
374 REQUIRE( p1.isLower(p2) == false );
375 REQUIRE( isLower(p1, p2) == false );
376 REQUIRE( p2.isUpper(p1) == false );
377 REQUIRE( isUpper(p2, p1) == false );
378 p1[3] = 2;
379 REQUIRE( p1.isLower(p2) == true );
380 REQUIRE( isLower(p1, p2) == true );
381 REQUIRE( p2.isUpper(p1) == true );
382 REQUIRE( isUpper(p2, p1) == true );
383 }
384
385 SECTION("Arithmetical Operators with reals")
386 {
387 COMPARE_VALUE_AND_TYPE( p3 + p4, RealPoint(6.5,-5.5,5.5,0.5) );
388 COMPARE_VALUE_AND_TYPE( p3 - p4, RealPoint(-4.5,3.5,-1.5,-4.5) );
389 COMPARE_VALUE_AND_TYPE( p3 * p4, RealPoint(5.5,4.5,7.0,-5.0) );
390 COMPARE_VALUE_AND_TYPE( p4 / p3, RealPoint(5.5,4.5,1.75,-1.25) );
391
392 COMPARE_VALUE_AND_TYPE( p3 + 2., RealPoint(3.,1.,4.,0.) );
393 COMPARE_VALUE_AND_TYPE( 2. + p3, RealPoint(3.,1.,4.,0.) );
394 COMPARE_VALUE_AND_TYPE( p3 - 2., RealPoint(-1.,-3.,0.,-4.) );
395 COMPARE_VALUE_AND_TYPE( 2. - p3, RealPoint(1.,3.,0.,4.) );
396 COMPARE_VALUE_AND_TYPE( p3 * 2., RealPoint(2.,-2.,4.,-4.) );
397 COMPARE_VALUE_AND_TYPE( 2. * p3, RealPoint(2.,-2.,4.,-4.) );
398 COMPARE_VALUE_AND_TYPE( p3 / 2., RealPoint(0.5,-0.5,1.,-1.) );
399 COMPARE_VALUE_AND_TYPE( 2. / p3, RealPoint(2.,-2.,1.,-1.) );
400
401 COMPARE_VALUE_AND_TYPE( -p3, RealPoint(-1.,1.,-2.,2.) );
402
403 p3 *= 2.5; COMPARE_VALUE_AND_TYPE( p3, RealPoint(2.5, -2.5, 5., -5.) );
404 p3 += 2.5; COMPARE_VALUE_AND_TYPE( p3, RealPoint(5., 0., 7.5, -2.5) );
405 p3 -= 2.5; COMPARE_VALUE_AND_TYPE( p3, RealPoint(2.5, -2.5, 5., -5.) );
406 p3 /= 2.5; COMPARE_VALUE_AND_TYPE( p3, RealPoint(1., -1., 2., -2.) );
407
408 p3 *= p4; COMPARE_VALUE_AND_TYPE( p3, RealPoint(5.5, 4.5, 7., -5.) );
409 p3 += p4; COMPARE_VALUE_AND_TYPE( p3, RealPoint(11, 0., 10.5, -2.5) );
410 p3 -= p4; COMPARE_VALUE_AND_TYPE( p3, RealPoint(5.5, 4.5, 7., -5.) );
411 p3 /= p4; COMPARE_VALUE_AND_TYPE( p3, RealPoint(1., -1., 2., -2.) );
412 }
413
414 SECTION("Other operators with reals")
415 {
416 COMPARE_VALUE_AND_TYPE( p3.inf(p4), RealPoint(1.,-4.5,2.,-2.) );
417 COMPARE_VALUE_AND_TYPE( p3.sup(p4), RealPoint(5.5,-1.,3.5,2.5) );
418 COMPARE_VALUE_AND_TYPE( inf(p3, p4), RealPoint(1.,-4.5,2.,-2.) );
419 COMPARE_VALUE_AND_TYPE( sup(p3, p4), RealPoint(5.5,-1.,3.5,2.5) );
420
421 REQUIRE( p3.dot(p4) == 12. );
422 REQUIRE( dotProduct(p3, p4) == 12. );
423
424 REQUIRE( p3.cosineSimilarity(p3) == Approx(0.).margin(0.000001) );
425 REQUIRE( p3.cosineSimilarity(-p3) == Approx(pi).margin(0.000001) );
426 REQUIRE( p3.cosineSimilarity( RealPoint(1.0,1.0,2.0,2.0) ) == Approx(pi/2).margin(0.000001) );
427 REQUIRE( cosineSimilarity(p3, p3) == Approx(0.).margin(0.000001) );
428 REQUIRE( cosineSimilarity(p3, -p3) == Approx(pi).margin(0.000001) );
429 REQUIRE( cosineSimilarity(p3, RealPoint(1.0,1.0,2.0,2.0)) == Approx(pi/2).margin(0.000001) );
430
431 REQUIRE( p3.isLower(p4) == false );
432 REQUIRE( isLower(p3, p4) == false );
433 REQUIRE( p4.isUpper(p3) == false );
434 REQUIRE( isUpper(p4, p3) == false );
435 p4[1] = -p4[1];
436 REQUIRE( p3.isLower(p4) == true );
437 REQUIRE( isLower(p3, p4) == true );
438 REQUIRE( p4.isUpper(p3) == true );
439 REQUIRE( isUpper(p4, p3) == true );
440 }
441
442 SECTION("Arithmetical Operators with mixed integers/reals")
443 {
444 COMPARE_VALUE_AND_TYPE( p1 + p4, RealPoint(6.5,-2.5,6.5,6.5) );
445 COMPARE_VALUE_AND_TYPE( p4 + p1, RealPoint(6.5,-2.5,6.5,6.5) );
446 COMPARE_VALUE_AND_TYPE( p1 - p4, RealPoint(-4.5,6.5,-0.5,1.5) );
447 COMPARE_VALUE_AND_TYPE( p4 - p1, RealPoint(4.5,-6.5,0.5,-1.5) );
448 COMPARE_VALUE_AND_TYPE( p1 * p4, RealPoint(5.5,-9.0,10.5,10.0) );
449 COMPARE_VALUE_AND_TYPE( p4 * p1, RealPoint(5.5,-9.0,10.5,10.0) );
450 COMPARE_VALUE_AND_TYPE( p1 / p3, RealPoint(1.,-2.,1.5,-2.0) );
451 COMPARE_VALUE_AND_TYPE( p3 / p1, RealPoint(1.,-0.5,2./3.,-0.5) );
452
453 COMPARE_VALUE_AND_TYPE( p3 + 2, RealPoint(3.,1.,4.,0.) );
454 COMPARE_VALUE_AND_TYPE( 2 + p3, RealPoint(3.,1.,4.,0.) );
455 COMPARE_VALUE_AND_TYPE( p3 - 2, RealPoint(-1.,-3.,0.,-4.) );
456 COMPARE_VALUE_AND_TYPE( 2 - p3, RealPoint(1.,3.,0.,4.) );
457 COMPARE_VALUE_AND_TYPE( p3 * 2, RealPoint(2.,-2.,4.,-4.) );
458 COMPARE_VALUE_AND_TYPE( 2 * p3, RealPoint(2.,-2.,4.,-4.) );
459 COMPARE_VALUE_AND_TYPE( p3 / 2, RealPoint(0.5,-0.5,1.,-1.) );
460 COMPARE_VALUE_AND_TYPE( 2 / p3, RealPoint(2.,-2.,1.,-1.) );
461
462 COMPARE_VALUE_AND_TYPE( p1 + 2.5, RealPoint(3.5,4.5,5.5,6.5) );
463 COMPARE_VALUE_AND_TYPE( 2.5 + p1, RealPoint(3.5,4.5,5.5,6.5) );
464 COMPARE_VALUE_AND_TYPE( p1 - 2.5, RealPoint(-1.5,-0.5,0.5,1.5) );
465 COMPARE_VALUE_AND_TYPE( 2.5 - p1, RealPoint(1.5,0.5,-0.5,-1.5) );
466 COMPARE_VALUE_AND_TYPE( p1 * 2.5, RealPoint(2.5,5.,7.5,10.) );
467 COMPARE_VALUE_AND_TYPE( 2.5 * p1, RealPoint(2.5,5.,7.5,10.) );
468 COMPARE_VALUE_AND_TYPE( p1 / 0.5, RealPoint(2.,4.,6.,8.) );
469 COMPARE_VALUE_AND_TYPE( 2. / p1, RealPoint(2.,1.,2./3.,0.5) );
470
471 p3 *= 2; COMPARE_VALUE_AND_TYPE( p3, RealPoint(2, -2, 4., -4.) );
472 p3 += 2; COMPARE_VALUE_AND_TYPE( p3, RealPoint(4., 0., 6., -2.) );
473 p3 -= 2; COMPARE_VALUE_AND_TYPE( p3, RealPoint(2, -2, 4., -4.) );
474 p3 /= 2; COMPARE_VALUE_AND_TYPE( p3, RealPoint(1., -1., 2., -2.) );
475
476 p3 *= p1; COMPARE_VALUE_AND_TYPE( p3, RealPoint(1., -2., 6., -8.) );
477 p3 += p1; COMPARE_VALUE_AND_TYPE( p3, RealPoint(2., 0., 9., -4.) );
478 p3 -= p1; COMPARE_VALUE_AND_TYPE( p3, RealPoint(1., -2., 6., -8.) );
479 p3 /= p1; COMPARE_VALUE_AND_TYPE( p3, RealPoint(1., -1., 2., -2.) );
480 }
481
482 SECTION("Other operators with mixed integers/reals")
483 {
484 COMPARE_VALUE_AND_TYPE( p1.inf(p3), RealPoint(1.,-1.,2.,-2.) );
485 COMPARE_VALUE_AND_TYPE( p3.inf(p1), RealPoint(1.,-1.,2.,-2.) );
486 COMPARE_VALUE_AND_TYPE( p1.sup(p3), RealPoint(1.,2.,3.,4.) );
487 COMPARE_VALUE_AND_TYPE( p3.sup(p1), RealPoint(1.,2.,3.,4.) );
488 COMPARE_VALUE_AND_TYPE( inf(p1, p3), RealPoint(1.,-1.,2.,-2.) );
489 COMPARE_VALUE_AND_TYPE( inf(p3, p1), RealPoint(1.,-1.,2.,-2.) );
490 COMPARE_VALUE_AND_TYPE( sup(p1, p3), RealPoint(1.,2.,3.,4.) );
491 COMPARE_VALUE_AND_TYPE( sup(p3, p1), RealPoint(1.,2.,3.,4.) );
492
493 REQUIRE( p4.dot(p1) == 17.0 );
494 REQUIRE( dotProduct(p4, p1) == 17.0 );
495 REQUIRE( dotProduct(p1, p4) == 17.0 );
496
497 REQUIRE( p1.cosineSimilarity(RealPoint(p1)) == Approx(0.).margin(0.000001) );
498 REQUIRE( p1.cosineSimilarity(-RealPoint(p1)) == Approx(pi).margin(0.000001) );
499 REQUIRE( p1.cosineSimilarity( RealPoint(-2,1,-4,3) ) == Approx(pi/2).margin(0.000001) );
500 REQUIRE( cosineSimilarity(p1, RealPoint(p1)) == Approx(0.).margin(0.000001) );
501 REQUIRE( cosineSimilarity(p1, -RealPoint(p1)) == Approx(pi).margin(0.000001) );
502 REQUIRE( cosineSimilarity(p1, RealPoint(-2,1,-4,3)) == Approx(pi/2).margin(0.000001) );
503
504 REQUIRE( p3.cosineSimilarity(Point(1,-1,2,-2)) == Approx(0.).margin(0.000001) );
505 REQUIRE( p3.cosineSimilarity(-Point(1,-1,2,-2)) == Approx(pi).margin(0.000001) );
506 REQUIRE( p3.cosineSimilarity( Point(1,1,2,2) ) == Approx(pi/2).margin(0.000001) );
507 REQUIRE( cosineSimilarity(p3, Point(1,-1,2,-2)) == Approx(0.).margin(0.000001) );
508 REQUIRE( cosineSimilarity(p3, -Point(1,-1,2,-2)) == Approx(pi).margin(0.000001) );
509 REQUIRE( cosineSimilarity(p3, Point(1,1,2,2)) == Approx(pi/2).margin(0.000001) );
510
511 REQUIRE( p2.isLower(p4) == false );
512 REQUIRE( isLower(p2, p4) == false );
513 REQUIRE( p4.isUpper(p2) == false );
514 REQUIRE( isUpper(p4, p2) == false );
515 p4[1] = -p4[1];
516 REQUIRE( p2.isLower(p4) == true );
517 REQUIRE( isLower(p2, p4) == true );
518 REQUIRE( p4.isUpper(p2) == true );
519 REQUIRE( isUpper(p4, p2) == true );
520 }
521
522}
523
524
525TEST_CASE("Benchmarking","[.benchmark]")
526{
527 using Integer = DGtal::int32_t;
529 Point p1 = {1,2,3,4};
530 Point p2 = {3,4,5,6};
531
532 using Real = double;
533 typedef PointVector<3, Real> RPoint;
534 RPoint rp1 = {1,2,3,4};
535 RPoint rp2 = {3,4,5,6};
536
537 CHECK(p1.dot(p2) == 26);
538 CHECK(rp1.dot(rp2) == Approx(26));
539
540 BENCHMARK("Dot product int")
541 {
542 return p1.dot(p2);
543 };
544
545 BENCHMARK("Dot product double (with int->double cast)")
546 {
547 return rp1.dot(p2);
548 };
549
550 BENCHMARK("Dot product double")
551 {
552 return rp1.dot(rp2);
553 };
554
555}
556
Aim: Implements basic operations that will be used in Point and Vector classes.
Component max() const
bool isLower(const PointVector< dim, OtherComponent, OtherStorage > &p) const
Return true if this point is below a given point.
auto dot(const PointVector< dim, OtherComponent, OtherStorage > &v) const -> decltype(DGtal::dotProduct(*this, v))
Dot product with a PointVector.
Self & partialCopyInv(const PointVector< dim, OtherComponent, OtherContainer > &pv, const std::vector< Dimension > &dimensions)
Partial copy of a given PointVector.
Iterator maxElement()
auto inf(const PointVector< dim, OtherComponent, OtherStorage > &aPoint) const -> decltype(DGtal::inf(*this, aPoint))
Implements the infimum (or greatest lower bound).
auto sup(const PointVector< dim, OtherComponent, OtherStorage > &aPoint) const -> decltype(DGtal::sup(*this, aPoint))
Implements the supremum (or least upper bound).
auto crossProduct(const PointVector< dim, OtherComponent, OtherStorage > &v) const -> decltype(DGtal::crossProduct(*this, v))
Cross product with a PointVector.
bool isUpper(const PointVector< dim, OtherComponent, OtherStorage > &p) const
Return true if this point is upper a given point.
Component min() const
Container::const_iterator ConstIterator
Constant iterator type.
double cosineSimilarity(const PointVector< dim, OtherComponent, OtherStorage > &v) const
Positive angle between two vectors, deduced from their scalar product.
Iterator minElement()
Self & partialCopy(const PointVector< dim, OtherComponent, OtherContainer > &pv, const std::vector< Dimension > &dimensions)
Partial copy of a given PointVector.
DGtal is the top-level namespace which contains all DGtal functions and types.
std::int32_t int32_t
signed 32-bit integer.
Definition BasicTypes.h:71
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.
DGtal::ArithmeticConversionType< LeftEuclideanRing, RightEuclideanRing > dotProduct(PointVector< ptDim, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< ptDim, RightEuclideanRing, RightContainer > const &rhs)
Dot product between two points/vectors.
bool isUpper(PointVector< ptDim, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< ptDim, RightEuclideanRing, RightContainer > const &rhs)
Return true if the first point is upper the second point.
double cosineSimilarity(PointVector< ptDim, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< ptDim, RightEuclideanRing, RightContainer > const &rhs)
Positive angle between two vectors, deduced from their scalar product.
auto inf(PointVector< ptDim, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< ptDim, RightEuclideanRing, RightContainer > const &rhs) -> decltype(DGtal::constructFromArithmeticConversion(lhs, rhs))
Implements the infimum (or greatest lower bound).
auto sup(PointVector< ptDim, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< ptDim, RightEuclideanRing, RightContainer > const &rhs) -> decltype(DGtal::constructFromArithmeticConversion(lhs, rhs))
Implements the supremum (or least upper bound).
bool isLower(PointVector< ptDim, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< ptDim, RightEuclideanRing, RightContainer > const &rhs)
Return true if the first point is below the second point.
STL namespace.
Z3i::RealPoint RealPoint3D
Functor that rounds to the nearest integer.
BENCHMARK(BM_StringCreation)
MyPointD Point
CAPTURE(thicknessHV)
TEST_CASE("2D Point Vector Unit tests")
#define COMPARE_VALUE_AND_TYPE(expr, check)
const Point aPoint(3, 4)
SECTION("Testing constant forward iterators")
REQUIRE(domain.isInside(aPoint))
PointVector< 3, double > RealPoint