TTK
Loading...
Searching...
No Matches
Geometry.cpp
Go to the documentation of this file.
1#include <Geometry.h>
2
3#include <algorithm>
4
5using namespace std;
6using namespace ttk;
7
8static const double PREC_DBL{Geometry::pow(10.0, -DBL_DIG)};
9static const float PREC_FLT{powf(10.0F, -FLT_DIG)};
10static const float PREC_FLT_1{powf(10.0F, -FLT_DIG + 1)};
11
12template <typename T>
13T Geometry::angle(const T *vA0, const T *vA1, const T *vB0, const T *vB1) {
14 return M_PI
15 - acos(dotProduct(vA0, vA1, vB0, vB1)
16 / (magnitude(vA0, vA1) * magnitude(vB0, vB1)));
17}
18
19template <typename T>
21 const T *vA1,
22 const T *vB0,
23 const T *vB1,
24 std::array<T, 3> *coefficients,
25 const T *tolerance) {
26
27 int aNullComponents = 0, bNullComponents = 0;
28 std::array<T, 3> a{}, b{};
29 for(int i = 0; i < 3; i++) {
30 a[i] = vA1[i] - vA0[i];
31 if(fabs(a[i]) < PREC_FLT) {
32 aNullComponents++;
33 }
34 b[i] = vB1[i] - vB0[i];
35 if(fabs(b[i]) < PREC_FLT) {
36 bNullComponents++;
37 }
38 }
39
40 if((aNullComponents == 3) || (bNullComponents == 3)) {
41 return true;
42 }
43
44 // check for axis aligned vectors
45 if((aNullComponents > 1) || (bNullComponents > 1)) {
46 if(aNullComponents == bNullComponents) {
47 // only one non-null component for both vectors
48 return true;
49 }
50 }
51
52 bool useDenominatorA = false;
53 T sumA = 0, sumB = 0;
54 for(int i = 0; i < 3; i++) {
55 sumA += fabs(a[i]);
56 sumB += fabs(b[i]);
57 }
58 if(sumA > sumB) {
59 useDenominatorA = true;
60 }
61
62 std::array<T, 3> k{};
63
64 T maxDenominator = 0;
65 int isNan = -1, maximizer = 0;
66 for(int i = 0; i < 3; i++) {
67 if(useDenominatorA) {
68 if(fabs(a[i]) > PREC_FLT) {
69 k[i] = b[i] / a[i];
70 } else {
71 isNan = i;
72 }
73 } else {
74 if(fabs(b[i]) > PREC_FLT) {
75 k[i] = a[i] / b[i];
76 } else {
77 isNan = i;
78 }
79 }
80
81 if(!i) {
82 maxDenominator = fabs(k[i]);
83 maximizer = i;
84 } else {
85 if(fabs(k[i]) > maxDenominator) {
86 maxDenominator = fabs(k[i]);
87 maximizer = i;
88 }
89 }
90 }
91
92 T colinearityThreshold;
93
94 colinearityThreshold = PREC_FLT;
95 if(tolerance) {
96 colinearityThreshold = *tolerance;
97 }
98
99 if(coefficients) {
100 (*coefficients) = k;
101 }
102
103 if(isNan == -1) {
104
105 if((fabs(1 - fabs(k[(maximizer + 1) % 3] / k[maximizer]))
106 < colinearityThreshold)
107 && (fabs(1 - fabs(k[(maximizer + 2) % 3] / k[maximizer]))
108 < colinearityThreshold)) {
109 return true;
110 }
111 } else {
112 if(fabs(1 - fabs(k[(isNan + 1) % 3] / k[(isNan + 2) % 3]))
113 < colinearityThreshold) {
114 return true;
115 }
116 }
117
118 k[0] = k[1] = k[2] = 0;
119
120 return false;
121}
122
123template <typename T>
125 const T *p1,
126 const T *p,
127 std::array<T, 2> &baryCentrics,
128 const int &dimension) {
129
130 if(dimension > 3) {
131 return -1;
132 }
133
134 int bestI = 0;
135 T maxDenominator = 0;
136
137 for(int i = 0; i < dimension; i++) {
138
139 T denominator = fabs(p0[i] - p1[i]);
140 if(!i) {
141 maxDenominator = denominator;
142 bestI = i;
143 } else {
144 if(denominator > maxDenominator) {
145 maxDenominator = denominator;
146 bestI = i;
147 }
148 }
149 }
150
151 baryCentrics[0] = p0[bestI] - p1[bestI];
152 baryCentrics[0] = (p[bestI] - p1[bestI]) / baryCentrics[0];
153
154 baryCentrics[1] = 1 - baryCentrics[0];
155
156 // check if the point lies in the edge
157 std::array<T, 3> test{};
158 for(int i = 0; i < dimension; i++) {
159 test[i] = baryCentrics[0] * p0[i] + baryCentrics[1] * p1[i];
160 }
161
162 if((!((fabs(test[0] - p[0]) < PREC_FLT_1)
163 && (fabs(test[1] - p[1]) < PREC_FLT_1)))) {
164 for(int i = 0; i < 2; i++) {
165 baryCentrics[i] = -baryCentrics[i];
166 }
167 }
168
169 return 0;
170}
171template <typename T>
173 const T *p1,
174 const T *p2,
175 const T *p,
176 std::array<T, 3> &baryCentrics) {
177
178 // find the pair of coordinates that maximize the sum of the denominators
179 // (more stable computations)
180 int bestI = 0, bestJ = 1;
181 T maxDenominator = 0;
182
183 for(int i = 0; i < 2; i++) {
184 for(int j = i + 1; j < 3; j++) {
185
186 baryCentrics[0]
187 = (p1[j] - p2[j]) * (p0[i] - p2[i]) + (p2[i] - p1[i]) * (p0[j] - p2[j]);
188 baryCentrics[1]
189 = (p1[j] - p2[j]) * (p0[i] - p2[i]) + (p2[i] - p1[i]) * (p0[j] - p2[j]);
190
191 T denominator = fabs(baryCentrics[0]);
192
193 if(fabs(baryCentrics[1]) < denominator) {
194 denominator = fabs(baryCentrics[1]);
195 }
196
197 if((i == 0) && (j == 1)) {
198 maxDenominator = denominator;
199 } else {
200 if(denominator > maxDenominator) {
201 maxDenominator = denominator;
202 bestI = i;
203 bestJ = j;
204 }
205 }
206 }
207 }
208
209 baryCentrics[0] = (p1[bestJ] - p2[bestJ]) * (p0[bestI] - p2[bestI])
210 + (p2[bestI] - p1[bestI]) * (p0[bestJ] - p2[bestJ]);
211 // (y1 - y2)*(x - x2) + (x2 - x1)*(y - y2)
212 baryCentrics[0] = ((p1[bestJ] - p2[bestJ]) * (p[bestI] - p2[bestI])
213 + (p2[bestI] - p1[bestI]) * (p[bestJ] - p2[bestJ]))
214 / baryCentrics[0];
215
216 // (y1 - y2)*(x0 - x2) + (x2 - x1)*(y0 - y2)
217 baryCentrics[1] = (p1[bestJ] - p2[bestJ]) * (p0[bestI] - p2[bestI])
218 + (p2[bestI] - p1[bestI]) * (p0[bestJ] - p2[bestJ]);
219 // (y2 - y0)*(x - x2) + (x0 - x2)*(y - y2)
220 baryCentrics[1] = ((p2[bestJ] - p0[bestJ]) * (p[bestI] - p2[bestI])
221 + (p0[bestI] - p2[bestI]) * (p[bestJ] - p2[bestJ]))
222 / baryCentrics[1];
223
224 baryCentrics[2] = 1 - baryCentrics[0] - baryCentrics[1];
225
226 return 0;
227}
228
229template <typename T>
231 const T &yA,
232 const T &xB,
233 const T &yB,
234 const T &xC,
235 const T &yC,
236 const T &xD,
237 const T &yD,
238 T &x,
239 T &y) {
240
241 T d = (xA - xB) * (yC - yD) - (yA - yB) * (xC - xD);
242
243 if(fabs(d) < PREC_DBL) {
244 return false;
245 }
246
247 x = ((xC - xD) * (xA * yB - yA * xB) - (xA - xB) * (xC * yD - yC * xD)) / d;
248
249 y = ((yC - yD) * (xA * yB - yA * xB) - (yA - yB) * (xC * yD - yC * xD)) / d;
250
251 if((x < std::min(xA, xB) - PREC_FLT) || (x > std::max(xA, xB) + PREC_FLT)) {
252 return false;
253 }
254
255 if((x < std::min(xC, xD) - PREC_FLT) || (x > std::max(xC, xD) + PREC_FLT)) {
256 return false;
257 }
258
259 return true;
260}
261
262template <typename T>
264 const T *p1,
265 const T *p2,
266 T &area) {
267
268 std::array<T, 3> cross{};
269
270 crossProduct(p0, p1, p1, p2, cross);
271
272 area = 0.5 * magnitude(cross.data());
273
274 return 0;
275}
276
277template <typename T>
279 const T s1,
280 const T s2,
281 T &area) {
282
283 double s = (s0 + s1 + s2) / 2.0;
284 area = std::sqrt(s * (s - s0) * (s - s1) * (s - s2));
285
286 return 0;
287}
288
289template <typename T>
291 const T *p1,
292 const T *p2,
293 std::array<T, 3> &angles) {
294
295 angles[0] = angle(p0, p1, p1, p2);
296 angles[1] = angle(p1, p2, p2, p0);
297 angles[2] = angle(p2, p0, p0, p1);
298
299 return 0;
300}
301
302template <typename T>
304 const T s1,
305 const T s2,
306 T &angle) {
307
308 angle = std::acos((s0 * s0 + s1 * s1 - s2 * s2) / (2.0 * s0 * s1));
309
310 return 0;
311}
312
313template <typename T>
314int Geometry::crossProduct(const T *vA0,
315 const T *vA1,
316 const T *vB0,
317 const T *vB1,
318 std::array<T, 3> &crossProduct) {
319
320 std::array<T, 3> a{}, b{};
321
322 for(int i = 0; i < 3; i++) {
323 a[i] = vA1[i] - vA0[i];
324 b[i] = vB1[i] - vB0[i];
325 }
326
327 for(int i = 0; i < 3; i++) {
328 crossProduct[i]
329 = a[(i + 1) % 3] * b[(i + 2) % 3] - a[(i + 2) % 3] * b[(i + 1) % 3];
330 }
331
332 return 0;
333}
334
335template <typename T>
336int Geometry::crossProduct(const T *vA, const T *vB, T *crossProduct) {
337 crossProduct[0] = vA[1] * vB[2] - vA[2] * vB[1];
338 crossProduct[1] = vA[2] * vB[0] - vA[0] * vB[2];
339 crossProduct[2] = vA[0] * vB[1] - vA[1] * vB[0];
340 return 0;
341}
342
343template <typename T>
344T Geometry::distance(const T *p0, const T *p1, const int &dimension) {
345
346 T distance = 0;
347
348 for(int i = 0; i < dimension; i++) {
349 distance += (p0[i] - p1[i]) * (p0[i] - p1[i]);
350 }
351
352 return sqrt(distance);
353}
354
355template <typename T>
356T Geometry::distance(const std::vector<T> &p0, const std::vector<T> &p1) {
357 return distance(p0.data(), p1.data(), p0.size());
358}
359
360template <typename T>
361T Geometry::distanceFlatten(const std::vector<std::vector<T>> &p0,
362 const std::vector<std::vector<T>> &p1) {
363 std::vector<T> p0_flatten, p1_flatten;
364 flattenMultiDimensionalVector(p0, p0_flatten);
365 flattenMultiDimensionalVector(p1, p1_flatten);
366 return distance(p0_flatten, p1_flatten);
367}
368
369template <typename T>
370T Geometry::dotProduct(const T *vA0, const T *vA1, const T *vB0, const T *vB1) {
371
372 T dotProduct = 0;
373 for(int i = 0; i < 3; i++) {
374 dotProduct += (vA1[i] - vA0[i]) * (vB1[i] - vB0[i]);
375 }
376
377 return dotProduct;
378}
379
380template <typename T>
381T Geometry::dotProduct(const T *vA, const T *vB, const int &dimension) {
382 T dotProduct = 0;
383 for(int i = 0; i < dimension; ++i)
384 dotProduct += vA[i] * vB[i];
385 return dotProduct;
386}
387
388template <typename T>
389T Geometry::dotProduct(const std::vector<T> &vA, const std::vector<T> &vB) {
390 return dotProduct(vA.data(), vB.data(), vA.size());
391}
392
393template <typename T>
394T Geometry::dotProductFlatten(const std::vector<std::vector<T>> &vA,
395 const std::vector<std::vector<T>> &vB) {
396 std::vector<T> vA_flatten, vB_flatten;
397 flattenMultiDimensionalVector(vA, vA_flatten);
398 flattenMultiDimensionalVector(vB, vB_flatten);
399 return dotProduct(vA_flatten, vB_flatten);
400}
401
402template <typename T>
404 const T *p1,
405 const T *p2,
406 const T *p) {
407
408 std::array<T, 3> barycentrics{};
409
410 Geometry::computeBarycentricCoordinates(p0, p1, p2, p, barycentrics);
411
412 for(int i = 0; i < static_cast<int>(barycentrics.size()); i++) {
413 if(barycentrics[i] < -PREC_DBL) {
414 return false;
415 }
416 if(barycentrics[i] > 1 + PREC_DBL) {
417 return false;
418 }
419 }
420
421 return true;
422}
423
424template <typename T>
426 const T &x, const T &y, const T &xA, const T &yA, const T &xB, const T &yB) {
427
428 std::array<T, 2> pA{xA, yA}, pB{xB, yB}, p{x, y};
429 return Geometry::isPointOnSegment(p.data(), pA.data(), pB.data(), 2);
430}
431
432template <typename T>
434 const T *pA,
435 const T *pB,
436 const int &dimension) {
437
438 std::array<T, 2> baryCentrics{};
439
440 Geometry::computeBarycentricCoordinates(pA, pB, p, baryCentrics, dimension);
441
442 return (
443 ((baryCentrics[0] > -PREC_DBL) && (baryCentrics[0] < 1 + PREC_DBL))
444 && ((baryCentrics[1] > -PREC_DBL) && (baryCentrics[1] < 1 + PREC_DBL)));
445}
446
447template <typename T>
449 const T *p1,
450 const T *p2,
451 const T *tolerance) {
452
453 bool maxDecision = false;
454 T maxCoefficient = 0;
455 std::array<T, 3> coefficients{};
456
457 bool decision = areVectorsColinear(p0, p1, p1, p2, &coefficients, tolerance);
458 maxDecision = decision;
459 for(int i = 0; i < 3; i++) {
460 if(!i) {
461 maxCoefficient = fabs(coefficients[i]);
462 maxDecision = decision;
463 } else {
464 if(fabs(coefficients[i]) > maxCoefficient) {
465 maxCoefficient = fabs(coefficients[i]);
466 maxDecision = decision;
467 }
468 }
469 }
470
471 decision = areVectorsColinear(p0, p2, p2, p1, &coefficients, tolerance);
472 for(int i = 0; i < 3; i++) {
473 if(fabs(coefficients[i]) > maxCoefficient) {
474 maxCoefficient = fabs(coefficients[i]);
475 maxDecision = decision;
476 }
477 }
478
479 decision = areVectorsColinear(p1, p0, p0, p2, &coefficients, tolerance);
480 for(int i = 0; i < 3; i++) {
481 if(fabs(coefficients[i]) > maxCoefficient) {
482 maxCoefficient = fabs(coefficients[i]);
483 maxDecision = decision;
484 }
485 }
486
487 return maxDecision;
488}
489
490template <typename T>
491T Geometry::magnitude(const T *v, const int &dimension) {
492 return sqrt(dotProduct(v, v, dimension));
493}
494
495template <typename T>
496T Geometry::magnitude(const std::vector<T> &v) {
497 return magnitude(v.data(), v.size());
498}
499
500template <typename T>
501T Geometry::magnitudeFlatten(const std::vector<std::vector<T>> &v) {
502 std::vector<T> v_flatten;
503 flattenMultiDimensionalVector(v, v_flatten);
504 return magnitude(v_flatten);
505}
506
507template <typename T>
508T Geometry::magnitude(const T *o, const T *d) {
509
510 T mag = 0;
511
512 for(int i = 0; i < 3; i++) {
513 mag += (o[i] - d[i]) * (o[i] - d[i]);
514 }
515
516 return sqrt(mag);
517}
518
519template <typename T>
521 const T *b,
522 T *out,
523 const int &dimension) {
524 for(int i = 0; i < dimension; ++i)
525 out[i] = b[i] - a[i];
526 return 0;
527}
528
529template <typename T>
530int Geometry::subtractVectors(const std::vector<T> &a,
531 const std::vector<T> &b,
532 std::vector<T> &out) {
533 out.resize(a.size());
534 return subtractVectors(a.data(), b.data(), out.data(), a.size());
535}
536
537template <typename T>
538int Geometry::addVectors(const T *a, const T *b, T *out, const int &dimension) {
539 for(int i = 0; i < dimension; ++i)
540 out[i] = b[i] + a[i];
541 return 0;
542}
543
544template <typename T>
545int Geometry::addVectors(const std::vector<T> &a,
546 const std::vector<T> &b,
547 std::vector<T> &out) {
548 out.resize(a.size());
549 return addVectors(a.data(), b.data(), out.data(), a.size());
550}
551
552template <typename T>
553int Geometry::multiAddVectors(const std::vector<std::vector<T>> &a,
554 const std::vector<std::vector<T>> &b,
555 std::vector<std::vector<T>> &out) {
556 out.resize(a.size());
557 for(unsigned int i = 0; i < a.size(); ++i)
558 addVectors(a[i], b[i], out[i]);
559 return 0;
560}
561
562template <typename T>
564 const std::vector<std::vector<std::vector<T>>> &a,
565 const std::vector<std::vector<std::vector<T>>> &b,
566 std::vector<std::vector<T>> &out) {
567 std::vector<std::vector<T>> a_flatten, b_flatten;
570 multiAddVectors(a_flatten, b_flatten, out);
571 return 0;
572}
573
574template <typename T>
576 const T factor,
577 T *out,
578 const int &dimension) {
579 for(int i = 0; i < dimension; ++i)
580 out[i] = a[i] * factor;
581 return 0;
582}
583
584template <typename T>
585int Geometry::scaleVector(const std::vector<T> &a,
586 const T factor,
587 std::vector<T> &out) {
588 out.resize(a.size());
589 return scaleVector(a.data(), factor, out.data(), a.size());
590}
591
592template <typename T>
594 const T *b,
595 T *out,
596 const int &dimension) {
597 T dotProdBB = dotProduct(b, b, dimension);
598 T dotProdAB;
599 if(dotProdBB > PREC_DBL) {
600 dotProdAB = dotProduct(a, b, dimension);
601 dotProdAB /= dotProdBB;
602 } else
603 dotProdAB = 0; // Gram-Schmidt convention
604 for(int i = 0; i < dimension; ++i)
605 out[i] = b[i] * dotProdAB;
606 return 0;
607}
608
609template <typename T>
610int Geometry::vectorProjection(const std::vector<T> &a,
611 const std::vector<T> &b,
612 std::vector<T> &out) {
613 out.resize(a.size(), 0.0);
614 return vectorProjection(a.data(), b.data(), out.data(), a.size());
615}
616
617template <typename T>
618void Geometry::addVectorsProjection(const std::vector<T> &a,
619 const std::vector<T> &b,
620 std::vector<T> &a_out,
621 std::vector<T> &b_out) {
622 std::vector<T> sumV;
623 addVectors(a, b, sumV);
624 vectorProjection(a, sumV, a_out);
625 vectorProjection(b, sumV, b_out);
626}
627
628template <typename T>
629void Geometry::gramSchmidt(const std::vector<std::vector<T>> &a,
630 std::vector<std::vector<T>> &out) {
631 out.resize(a.size());
632 out[0] = a[0];
633 for(unsigned int i = 1; i < a.size(); ++i) {
634 std::vector<T> projecSum;
635 vectorProjection(a[i], out[0], projecSum);
636 for(unsigned int j = 1; j < i; ++j) {
637 std::vector<T> projecTemp, projecSumTemp;
638 vectorProjection(a[i], out[j], projecTemp);
639 addVectors(projecSum, projecTemp, projecSumTemp);
640 projecSum = projecSumTemp;
641 }
642 subtractVectors(projecSum, a[i], out[i]);
643 }
644}
645
646template <typename T>
647bool Geometry::isVectorUniform(const std::vector<T> &a) {
648 for(unsigned int i = 0; i < a.size() - 1; ++i)
649 if(not(std::abs(a[i] - a[i + 1]) < PREC_DBL))
650 return false;
651 return true;
652}
653
654template <typename T>
655bool Geometry::isVectorNull(const std::vector<T> &a) {
656 for(unsigned int i = 0; i < a.size(); ++i)
657 if(not(std::abs(a[i]) < PREC_DBL))
658 return false;
659 return true;
660}
661
662template <typename T>
663bool Geometry::isVectorNullFlatten(const std::vector<std::vector<T>> &a) {
664 std::vector<T> a_flatten;
665 flattenMultiDimensionalVector(a, a_flatten);
666 return isVectorNull(a_flatten);
667}
668
669template <typename T>
671 const std::vector<std::vector<T>> &a, std::vector<T> &out) {
672 out.resize(a.size() * a[0].size());
673 for(unsigned int i = 0; i < a.size(); ++i)
674 for(unsigned int j = 0; j < a[0].size(); ++j)
675 out[i * a[0].size() + j] = a[i][j];
676 return 0;
677}
678
679template <typename T>
681 const std::vector<std::vector<std::vector<T>>> &a,
682 std::vector<std::vector<T>> &out) {
683 out.resize(a.size());
684 for(unsigned int i = 0; i < a.size(); ++i)
685 flattenMultiDimensionalVector(a[i], out[i]);
686 return 0;
687}
688
689template <typename T>
691 std::vector<std::vector<T>> &out,
692 const int &no_columns) {
693 if(a.size() % no_columns != 0)
694 return -1;
695 out.resize(a.size() / no_columns);
696 for(unsigned int i = 0; i < out.size(); ++i) {
697 out[i].resize(no_columns);
698 for(unsigned int j = 0; j < out[i].size(); ++j)
699 out[i][j] = a[i * no_columns + j];
700 }
701 return 0;
702}
703
704template <typename T>
705void Geometry::matrixMultiplication(const std::vector<std::vector<T>> &a,
706 const std::vector<std::vector<T>> &b,
707 std::vector<std::vector<T>> &out) {
708 out.resize(a.size(), std::vector<T>(b[0].size(), 0.0));
709 for(unsigned int i = 0; i < out.size(); ++i)
710 for(unsigned int j = 0; j < out[i].size(); ++j)
711 for(unsigned int k = 0; k < a[i].size(); ++k)
712 out[i][j] += a[i][k] * b[k][j];
713}
714
715template <typename T>
716void Geometry::subtractMatrices(const std::vector<std::vector<T>> &a,
717 const std::vector<std::vector<T>> &b,
718 std::vector<std::vector<T>> &out) {
719 out.resize(a.size(), std::vector<T>(a[0].size()));
720 for(unsigned int i = 0; i < out.size(); ++i)
721 for(unsigned int j = 0; j < out[0].size(); ++j)
722 out[i][j] = b[i][j] - a[i][j];
723}
724
725template <typename T>
726void Geometry::addMatrices(const std::vector<std::vector<T>> &a,
727 const std::vector<std::vector<T>> &b,
728 std::vector<std::vector<T>> &out) {
729 out.resize(a.size(), std::vector<T>(a[0].size()));
730 for(unsigned int i = 0; i < a.size(); ++i)
731 for(unsigned int j = 0; j < a[0].size(); ++j)
732 out[i][j] = a[i][j] + b[i][j];
733}
734
735template <typename T>
736void Geometry::scaleMatrix(const std::vector<std::vector<T>> &a,
737 const T factor,
738 std::vector<std::vector<T>> &out) {
739 out.resize(a.size(), std::vector<T>(a[0].size()));
740 for(unsigned int i = 0; i < out.size(); ++i)
741 for(unsigned int j = 0; j < out[i].size(); ++j)
742 out[i][j] = a[i][j] * factor;
743}
744
745template <typename T>
746void Geometry::transposeMatrix(const std::vector<std::vector<T>> &a,
747 std::vector<std::vector<T>> &out) {
748 out.resize(a[0].size(), std::vector<T>(a.size()));
749 for(unsigned int i = 0; i < a.size(); ++i)
750 for(unsigned int j = 0; j < a[0].size(); ++j)
751 out[j][i] = a[i][j];
752}
753
754#define GEOMETRY_SPECIALIZE(TYPE) \
755 template TYPE Geometry::angle<TYPE>( \
756 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
757 template bool Geometry::areVectorsColinear<TYPE>( \
758 TYPE const *, TYPE const *, TYPE const *, TYPE const *, \
759 std::array<TYPE, 3> *, TYPE const *); \
760 template int Geometry::computeBarycentricCoordinates<TYPE>( \
761 TYPE const *, TYPE const *, TYPE const *, std::array<TYPE, 2> &, \
762 int const &); \
763 template int Geometry::computeBarycentricCoordinates<TYPE>( \
764 TYPE const *, TYPE const *, TYPE const *, TYPE const *, \
765 std::array<TYPE, 3> &); \
766 template bool Geometry::computeSegmentIntersection<TYPE>( \
767 TYPE const &, TYPE const &, TYPE const &, TYPE const &, TYPE const &, \
768 TYPE const &, TYPE const &, TYPE const &, TYPE &, TYPE &); \
769 template int Geometry::computeTriangleAngles<TYPE>( \
770 TYPE const *, TYPE const *, TYPE const *, std::array<TYPE, 3> &); \
771 template int Geometry::computeTriangleAngleFromSides<TYPE>( \
772 TYPE const, TYPE const, TYPE const, TYPE &); \
773 template int Geometry::computeTriangleArea<TYPE>( \
774 TYPE const *, TYPE const *, TYPE const *, TYPE &); \
775 template int Geometry::computeTriangleAreaFromSides<TYPE>( \
776 TYPE const, TYPE const, TYPE const, TYPE &); \
777 template int Geometry::crossProduct<TYPE>(TYPE const *, TYPE const *, \
778 TYPE const *, TYPE const *, \
779 std::array<TYPE, 3> &); \
780 template int Geometry::crossProduct<TYPE>( \
781 TYPE const *, TYPE const *, TYPE *); \
782 template TYPE Geometry::distance<TYPE>( \
783 TYPE const *, TYPE const *, int const &); \
784 template TYPE Geometry::distance<TYPE>( \
785 std::vector<TYPE> const &, std::vector<TYPE> const &); \
786 template TYPE Geometry::distanceFlatten<TYPE>( \
787 std::vector<std::vector<TYPE>> const &, \
788 std::vector<std::vector<TYPE>> const &); \
789 template TYPE Geometry::dotProduct<TYPE>( \
790 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
791 template TYPE Geometry::dotProduct<TYPE>( \
792 TYPE const *, TYPE const *, int const &); \
793 template TYPE Geometry::dotProduct<TYPE>( \
794 std::vector<TYPE> const &, std::vector<TYPE> const &); \
795 template TYPE Geometry::dotProductFlatten<TYPE>( \
796 std::vector<std::vector<TYPE>> const &, \
797 std::vector<std::vector<TYPE>> const &); \
798 template bool Geometry::isPointInTriangle<TYPE>( \
799 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
800 template bool Geometry::isPointOnSegment<TYPE>(TYPE const &, TYPE const &, \
801 TYPE const &, TYPE const &, \
802 TYPE const &, TYPE const &); \
803 template bool Geometry::isPointOnSegment<TYPE>( \
804 TYPE const *, TYPE const *, TYPE const *, int const &); \
805 template bool Geometry::isTriangleColinear<TYPE>( \
806 TYPE const *, TYPE const *, TYPE const *, TYPE const *); \
807 template TYPE Geometry::magnitude<TYPE>(TYPE const *, int const &); \
808 template TYPE Geometry::magnitude<TYPE>(std::vector<TYPE> const &); \
809 template TYPE Geometry::magnitudeFlatten<TYPE>( \
810 std::vector<std::vector<TYPE>> const &); \
811 template TYPE Geometry::magnitude<TYPE>(TYPE const *, TYPE const *); \
812 template int Geometry::subtractVectors<TYPE>( \
813 TYPE const *, TYPE const *, TYPE *, int const &); \
814 template int Geometry::subtractVectors<TYPE>(std::vector<TYPE> const &, \
815 std::vector<TYPE> const &, \
816 std::vector<TYPE> &); \
817 template int Geometry::addVectors<TYPE>( \
818 TYPE const *, TYPE const *, TYPE *, int const &); \
819 template int Geometry::addVectors<TYPE>(std::vector<TYPE> const &, \
820 std::vector<TYPE> const &, \
821 std::vector<TYPE> &); \
822 template int Geometry::multiAddVectors<TYPE>( \
823 std::vector<std::vector<TYPE>> const &, \
824 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
825 template int Geometry::multiAddVectorsFlatten<TYPE>( \
826 std::vector<std::vector<std::vector<TYPE>>> const &, \
827 std::vector<std::vector<std::vector<TYPE>>> const &, \
828 std::vector<std::vector<TYPE>> &); \
829 template int Geometry::scaleVector<TYPE>( \
830 TYPE const *, TYPE const, TYPE *, int const &); \
831 template int Geometry::scaleVector<TYPE>( \
832 std::vector<TYPE> const &, TYPE const, std::vector<TYPE> &); \
833 template int Geometry::vectorProjection<TYPE>( \
834 TYPE const *, TYPE const *, TYPE *, int const &); \
835 template int Geometry::vectorProjection<TYPE>(std::vector<TYPE> const &, \
836 std::vector<TYPE> const &, \
837 std::vector<TYPE> &); \
838 template void Geometry::addVectorsProjection<TYPE>( \
839 std::vector<TYPE> const &, std::vector<TYPE> const &, std::vector<TYPE> &, \
840 std::vector<TYPE> &); \
841 template void Geometry::gramSchmidt<TYPE>( \
842 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
843 template bool Geometry::isVectorUniform<TYPE>(std::vector<TYPE> const &); \
844 template bool Geometry::isVectorNull<TYPE>(std::vector<TYPE> const &); \
845 template bool Geometry::isVectorNullFlatten<TYPE>( \
846 std::vector<std::vector<TYPE>> const &); \
847 template int Geometry::flattenMultiDimensionalVector<TYPE>( \
848 std::vector<std::vector<TYPE>> const &, std::vector<TYPE> &); \
849 template int Geometry::multiFlattenMultiDimensionalVector<TYPE>( \
850 std::vector<std::vector<std::vector<TYPE>>> const &, \
851 std::vector<std::vector<TYPE>> &); \
852 template int Geometry::unflattenMultiDimensionalVector<TYPE>( \
853 std::vector<TYPE> const &, std::vector<std::vector<TYPE>> &, int const &); \
854 template void Geometry::matrixMultiplication<TYPE>( \
855 std::vector<std::vector<TYPE>> const &, \
856 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
857 template void Geometry::subtractMatrices<TYPE>( \
858 std::vector<std::vector<TYPE>> const &, \
859 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
860 template void Geometry::addMatrices<TYPE>( \
861 std::vector<std::vector<TYPE>> const &, \
862 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &); \
863 template void Geometry::scaleMatrix<TYPE>( \
864 std::vector<std::vector<TYPE>> const &, TYPE const, \
865 std::vector<std::vector<TYPE>> &); \
866 template void Geometry::transposeMatrix<TYPE>( \
867 std::vector<std::vector<TYPE>> const &, std::vector<std::vector<TYPE>> &);
868
869// explicit specializations for float and double
#define GEOMETRY_SPECIALIZE(TYPE)
Definition: Geometry.cpp:754
#define M_PI
Definition: Os.h:50
int scaleVector(const T *a, const T factor, T *out, const int &dimension=3)
Definition: Geometry.cpp:575
bool areVectorsColinear(const T *vA0, const T *vA1, const T *vB0, const T *vB1, std::array< T, 3 > *coefficients=nullptr, const T *tolerance=NULL)
Definition: Geometry.cpp:20
int computeTriangleArea(const T *p0, const T *p1, const T *p2, T &area)
Definition: Geometry.cpp:263
int addVectors(const T *a, const T *b, T *out, const int &dimension=3)
Definition: Geometry.cpp:538
T dotProductFlatten(const std::vector< std::vector< T > > &vA, const std::vector< std::vector< T > > &vB)
Definition: Geometry.cpp:394
int multiFlattenMultiDimensionalVector(const std::vector< std::vector< std::vector< T > > > &a, std::vector< std::vector< T > > &out)
Definition: Geometry.cpp:680
void subtractMatrices(const std::vector< std::vector< T > > &a, const std::vector< std::vector< T > > &b, std::vector< std::vector< T > > &out)
Definition: Geometry.cpp:716
T dotProduct(const T *vA0, const T *vA1, const T *vB0, const T *vB1)
Definition: Geometry.cpp:370
void matrixMultiplication(const std::vector< std::vector< T > > &a, const std::vector< std::vector< T > > &b, std::vector< std::vector< T > > &out)
Definition: Geometry.cpp:705
bool isVectorNullFlatten(const std::vector< std::vector< T > > &a)
Definition: Geometry.cpp:663
bool isPointOnSegment(const T &x, const T &y, const T &xA, const T &yA, const T &xB, const T &yB)
Definition: Geometry.cpp:425
bool computeSegmentIntersection(const T &xA, const T &yA, const T &xB, const T &yB, const T &xC, const T &yC, const T &xD, const T &yD, T &x, T &y)
Definition: Geometry.cpp:230
int computeBarycentricCoordinates(const T *p0, const T *p1, const T *p, std::array< T, 2 > &baryCentrics, const int &dimension=3)
Definition: Geometry.cpp:124
void addMatrices(const std::vector< std::vector< T > > &a, const std::vector< std::vector< T > > &b, std::vector< std::vector< T > > &out)
Definition: Geometry.cpp:726
void gramSchmidt(const std::vector< std::vector< T > > &a, std::vector< std::vector< T > > &out)
Definition: Geometry.cpp:629
void scaleMatrix(const std::vector< std::vector< T > > &a, const T factor, std::vector< std::vector< T > > &out)
Definition: Geometry.cpp:736
int multiAddVectors(const std::vector< std::vector< T > > &a, const std::vector< std::vector< T > > &b, std::vector< std::vector< T > > &out)
Definition: Geometry.cpp:553
int flattenMultiDimensionalVector(const std::vector< std::vector< T > > &a, std::vector< T > &out)
Definition: Geometry.cpp:670
bool isVectorUniform(const std::vector< T > &a)
Definition: Geometry.cpp:647
int subtractVectors(const T *a, const T *b, T *out, const int &dimension=3)
Definition: Geometry.cpp:520
int computeTriangleAreaFromSides(const T s0, const T s1, const T s2, T &area)
Definition: Geometry.cpp:278
T magnitudeFlatten(const std::vector< std::vector< T > > &v)
Definition: Geometry.cpp:501
bool isVectorNull(const std::vector< T > &a)
Definition: Geometry.cpp:655
T1 pow(const T1 val, const T2 n)
Definition: Geometry.h:411
bool isTriangleColinear(const T *p0, const T *p1, const T *p2, const T *tolerance=nullptr)
Definition: Geometry.cpp:448
T angle(const T *vA0, const T *vA1, const T *vB0, const T *vB1)
Definition: Geometry.cpp:13
void addVectorsProjection(const std::vector< T > &a, const std::vector< T > &b, std::vector< T > &a_out, std::vector< T > &b_out)
Definition: Geometry.cpp:618
int computeTriangleAngles(const T *p0, const T *p1, const T *p2, std::array< T, 3 > &angles)
Definition: Geometry.cpp:290
int computeTriangleAngleFromSides(const T s0, const T s1, const T s2, T &angle)
Definition: Geometry.cpp:303
int vectorProjection(const T *a, const T *b, T *out, const int &dimension=3)
Definition: Geometry.cpp:593
int crossProduct(const T *vA0, const T *vA1, const T *vB0, const T *vB1, std::array< T, 3 > &crossProduct)
Definition: Geometry.cpp:314
void transposeMatrix(const std::vector< std::vector< T > > &a, std::vector< std::vector< T > > &out)
Definition: Geometry.cpp:746
int unflattenMultiDimensionalVector(const std::vector< T > &a, std::vector< std::vector< T > > &out, const int &no_columns=2)
Definition: Geometry.cpp:690
T magnitude(const T *v, const int &dimension=3)
Definition: Geometry.cpp:491
T distance(const T *p0, const T *p1, const int &dimension=3)
Definition: Geometry.cpp:344
T distanceFlatten(const std::vector< std::vector< T > > &p0, const std::vector< std::vector< T > > &p1)
Definition: Geometry.cpp:361
int multiAddVectorsFlatten(const std::vector< std::vector< std::vector< T > > > &a, const std::vector< std::vector< std::vector< T > > > &b, std::vector< std::vector< T > > &out)
Definition: Geometry.cpp:563
bool isPointInTriangle(const T *p0, const T *p1, const T *p2, const T *p)
Definition: Geometry.cpp:403
The Topology ToolKit.