TTK
Loading...
Searching...
No Matches
Geometry.h
Go to the documentation of this file.
1
7
8#pragma once
9
10#include <Debug.h>
11#include <VisitedMask.h>
12#include <array>
13#include <cmath>
14#include <stack>
15
16namespace ttk {
17
18 namespace Geometry {
19
25 template <typename T>
26 T angle(const T *vA0, const T *vA1, const T *vB0, const T *vB1);
27
28 template <typename T>
29 T angle2D(const T *vA0, const T *vA1, const T *vB0, const T *vB1);
30
31 // Computes the BAC angle, in the interval [0, 2pi]
32 template <typename T>
33 inline double angle2DUndirected(const T *vA, const T *vB, const T *vC) {
34 double angle = angle2D<T>(vA, vB, vA, vC);
35 if(angle < 0) {
36 angle += 2 * M_PI;
37 }
38 return angle;
39 }
40
51 template <typename T>
52 bool areVectorsColinear(const T *vA0,
53 const T *vA1,
54 const T *vB0,
55 const T *vB1,
56 std::array<T, 3> *coefficients = nullptr,
57 const T *tolerance = NULL);
58 template <typename T>
59 bool isTriangleColinear2D(const T *pptA,
60 const T *pptB,
61 const T *pptC,
62 const T tolerance);
63
74 template <typename T>
75 int computeBarycentricCoordinates(const T *p0,
76 const T *p1,
77 const T *p,
78 std::array<T, 2> &baryCentrics,
79 const int &dimension = 3);
80
90 template <typename T>
91 int computeBarycentricCoordinates(const T *p0,
92 const T *p1,
93 const T *p2,
94 const T *p,
95 std::array<T, 3> &baryCentrics);
96
109 template <typename T>
110 bool computeSegmentIntersection(const T &xA,
111 const T &yA,
112 const T &xB,
113 const T &yB,
114 const T &xC,
115 const T &yC,
116 const T &xD,
117 const T &yD,
118 T &x,
119 T &y);
120
126 template <typename T>
127 int computeTriangleAngles(const T *p0,
128 const T *p1,
129 const T *p2,
130 std::array<T, 3> &angles);
131
132 // Get the angle opposite to edge s2 using cosine law
138 template <typename T>
139 int computeTriangleAngleFromSides(const T s0,
140 const T s1,
141 const T s2,
142 T &angle);
143
150 template <typename T>
151 int computeTriangleArea(const T *p0, const T *p1, const T *p2, T &area);
152
159 template <typename T>
160 int
161 computeTriangleAreaFromSides(const T s0, const T s1, const T s2, T &area);
162
170 template <typename T>
171 int crossProduct(const T *vA0,
172 const T *vA1,
173 const T *vB0,
174 const T *vB1,
175 std::array<T, 3> &crossProduct);
176
182 template <typename T>
183 int crossProduct(const T *vA, const T *vB, T *crossProduct);
184
190 template <typename T>
191 T distance(const T *p0, const T *p1, const int &dimension = 3);
192
196 template <typename T>
197 T distance(const std::vector<T> &p0, const std::vector<T> &p1);
198
199 template <typename T>
200 inline T distance2D(const T *p0, const T *p1) {
201 T distance = 0;
202 T di0 = (p0[0] - p1[0]);
203 T di1 = (p0[1] - p1[1]);
204 if(std::is_same<T, float>::value) { // TODO constexpr when c++17
205 distance = fmaf(di0, di0, distance);
206 distance = fmaf(di1, di1, distance);
207 } else {
208 distance = fma(di0, di0, distance);
209 distance = fma(di1, di1, distance);
210 }
211
212 return sqrt(distance);
213 }
214
219 template <typename T>
220 T distanceFlatten(const std::vector<std::vector<T>> &p0,
221 const std::vector<std::vector<T>> &p1);
222
227 template <typename T>
228 T distanceFlatten(const std::vector<std::vector<T>> &p0,
229 const std::vector<std::vector<T>> &p1);
230
237 template <typename T>
238 T dotProduct(const T *vA0, const T *vA1, const T *vB0, const T *vB1);
239
246 template <typename T>
247 T dotProduct(const T *vA, const T *vB, const int &dimension = 3);
248
253 template <typename T>
254 T dotProduct(const std::vector<T> &vA, const std::vector<T> &vB);
255
260 template <typename T>
261 T dotProductFlatten(const std::vector<std::vector<T>> &vA,
262 const std::vector<std::vector<T>> &vB);
263
272 template <typename T, typename Container, size_t dim>
273 int getBoundingBox(const Container &points,
274 std::array<std::pair<T, T>, dim> &bBox) {
275 if(points.empty()) {
276 return -1;
277 }
278
279 for(size_t i = 0; i < points.size(); i++) {
280
281 if(i == 0) {
282 for(size_t j = 0; j < dim; j++) {
283 bBox[j].first = points[i][j];
284 bBox[j].second = points[i][j];
285 }
286 } else {
287 for(size_t j = 0; j < dim; j++) {
288 if(points[i][j] < bBox[j].first) {
289 bBox[j].first = points[i][j];
290 }
291 if(points[i][j] > bBox[j].second) {
292 bBox[j].second = points[i][j];
293 }
294 }
295 }
296 }
297
298 return 0;
299 }
300
307 template <typename T>
308 bool isPointInTriangle(const T *p0, const T *p1, const T *p2, const T *p);
309
319 template <typename T>
320 bool isPointOnSegment(const T &x,
321 const T &y,
322 const T &xA,
323 const T &yA,
324 const T &xB,
325 const T &yB);
326
335 template <typename T>
336 bool isPointOnSegment(const T *p,
337 const T *pA,
338 const T *pB,
339 const int &dimension = 3);
340
347 template <typename T>
348 bool isTriangleColinear(const T *p0,
349 const T *p1,
350 const T *p2,
351 const T *tolerance = nullptr);
352
358 template <typename T>
359 T magnitude(const T *v, const int &dimension = 3);
360
364 template <typename T>
365 T magnitude(const std::vector<T> &v);
366
371 template <typename T>
372 T magnitudeFlatten(const std::vector<std::vector<T>> &v);
373
377 template <typename T>
378 T magnitude(const T *o, const T *d);
379
382 template <typename T>
383 inline T powInt(const T val, const int n) {
384 if(n < 0) {
385 return 1.0 / powInt(val, -n);
386 } else if(n == 0) {
387 return 1;
388 } else if(n == 1) {
389 return val;
390 } else if(n == 2) {
391 return val * val;
392 } else if(n == 3) {
393 return val * val * val;
394 } else {
395 T ret = val;
396 for(int i = 0; i < n - 1; ++i) {
397 ret *= val;
398 }
399 return ret;
400 }
401 }
402
404 template <typename T = double>
405 inline T powIntTen(const int n) {
406 return powInt(static_cast<T>(10), n);
407 }
408
430#define TTK_POW_LAMBDA(CALLEXPR, TYPE, EXPN, ...) \
431 { \
432 const auto one = [](const TYPE ttkNotUsed(a)) { return TYPE{1}; }; \
433 const auto id = [](const TYPE a) { return a; }; \
434 const auto square = [](const TYPE a) { return a * a; }; \
435 const auto cube = [](const TYPE a) { return a * a * a; }; \
436 const auto powInt \
437 = [EXPN](const TYPE a) { return Geometry::powInt(a, EXPN); }; \
438 \
439 if(EXPN == 0) { \
440 CALLEXPR(__VA_ARGS__, one); \
441 } else if(EXPN == 1) { \
442 CALLEXPR(__VA_ARGS__, id); \
443 } else if(EXPN == 2) { \
444 CALLEXPR(__VA_ARGS__, square); \
445 } else if(EXPN == 3) { \
446 CALLEXPR(__VA_ARGS__, cube); \
447 } else { \
448 CALLEXPR(__VA_ARGS__, powInt); \
449 } \
450 }
451
455 template <typename T1, typename T2>
456 inline T1 pow(const T1 val, const T2 n) {
457 static_assert(
458 std::is_arithmetic<T1>::value && std::is_arithmetic<T2>::value,
459 "pow can only be applied on arithmetic values");
460
461 if(std::is_integral<T2>::value) {
462 return powInt(val, n);
463 } else if(std::is_floating_point<T2>::value) {
464 return std::pow(val, n);
465 }
466 // this return statement should be unreachable thanks to the
467 // static_assert
468 return T1{};
469 }
470
480 template <typename T>
481 void
482 projectOnTrianglePlane(const T *p, const T *a, const T *normTri, T *out);
483
493 template <typename T>
494 void projectOnEdge(const T *p, const T *a, const T *b, T *out);
495
505 template <typename T>
506 void computeTriangleNormal(const T *a, const T *b, const T *c, T *out);
507
516 template <typename T, typename triangulationType>
518 std::vector<T> &dists,
519 const triangulationType &triangulation) {
520 for(SimplexId i = 0; i < triangulation.getNumberOfVertices(); ++i) {
521 std::array<T, 3> pv{};
522 triangulation.getVertexPoint(i, pv[0], pv[1], pv[2]);
523 dists[i] = distance(pa, pv.data());
524 }
525 return std::min_element(dists.begin(), dists.end()) - dists.begin();
526 }
527
535 template <typename T>
536 int
537 subtractVectors(const T *a, const T *b, T *out, const int &dimension = 3);
538
544 template <typename T>
545 int subtractVectors(const std::vector<T> &a,
546 const std::vector<T> &b,
547 std::vector<T> &out);
548
556 template <typename T>
557 int addVectors(const T *a, const T *b, T *out, const int &dimension = 3);
558
564 template <typename T>
565 int addVectors(const std::vector<T> &a,
566 const std::vector<T> &b,
567 std::vector<T> &out);
568
573 template <typename T>
574 int multiAddVectors(const std::vector<std::vector<T>> &a,
575 const std::vector<std::vector<T>> &b,
576 std::vector<std::vector<T>> &out);
577
583 template <typename T>
584 int
585 multiAddVectorsFlatten(const std::vector<std::vector<std::vector<T>>> &a,
586 const std::vector<std::vector<std::vector<T>>> &b,
587 std::vector<std::vector<T>> &out);
588
596 template <typename T>
597 int
598 scaleVector(const T *a, const T factor, T *out, const int &dimension = 3);
599
605 template <typename T>
606 int
607 scaleVector(const std::vector<T> &a, const T factor, std::vector<T> &out);
608
616 template <typename T>
617 int vectorProjection(const T *a,
618 const T *b,
619 T *out,
620 const int &dimension = 3);
621
627 template <typename T>
628 int vectorProjection(const std::vector<T> &a,
629 const std::vector<T> &b,
630 std::vector<T> &out);
631
637 template <typename T>
638 void addVectorsProjection(const std::vector<T> &a,
639 const std::vector<T> &b,
640 std::vector<T> &a_out,
641 std::vector<T> &b_out);
642
648 template <typename T>
649 void gramSchmidt(const std::vector<std::vector<T>> &a,
650 std::vector<std::vector<T>> &out);
651
655 template <typename T>
656 bool isVectorUniform(const std::vector<T> &a);
657
661 template <typename T>
662 bool isVectorNull(const std::vector<T> &a);
663
668 template <typename T>
669 bool isVectorNullFlatten(const std::vector<std::vector<T>> &a);
670
676 template <typename T>
677 int flattenMultiDimensionalVector(const std::vector<std::vector<T>> &a,
678 std::vector<T> &out);
679
684 template <typename T>
686 const std::vector<std::vector<std::vector<T>>> &a,
687 std::vector<std::vector<T>> &out);
688
696 template <typename T>
697 int unflattenMultiDimensionalVector(const std::vector<T> &a,
698 std::vector<std::vector<T>> &out,
699 const int &no_columns = 2);
700
705 template <typename T>
706 void matrixMultiplication(const std::vector<std::vector<T>> &a,
707 const std::vector<std::vector<T>> &b,
708 std::vector<std::vector<T>> &out);
709
715 template <typename T>
716 void subtractMatrices(const std::vector<std::vector<T>> &a,
717 const std::vector<std::vector<T>> &b,
718 std::vector<std::vector<T>> &out);
719
724 template <typename T>
725 void addMatrices(const std::vector<std::vector<T>> &a,
726 const std::vector<std::vector<T>> &b,
727 std::vector<std::vector<T>> &out);
728
733 template <typename T>
734 void scaleMatrix(const std::vector<std::vector<T>> &a,
735 const T factor,
736 std::vector<std::vector<T>> &out);
737
741 template <typename T>
742 void transposeMatrix(const std::vector<std::vector<T>> &a,
743 std::vector<std::vector<T>> &out);
744
752 template <typename triangulationType>
753 std::array<float, 3>
755 const triangulationType &triangulation) {
756
757 std::array<float, 3> res{};
758
759 // store for each triangle in a's star a's two direct neighbors
760 std::vector<std::array<SimplexId, 2>> edges{};
761
762 const auto nStar{triangulation.getVertexStarNumber(a)};
763
764 if(triangulation.getCellVertexNumber(0) == 3) {
765 // triangle mesh
766 for(SimplexId i = 0; i < nStar; ++i) {
767 SimplexId c{};
768 triangulation.getVertexStar(a, i, c);
769 SimplexId v0{}, v1{};
770 triangulation.getCellVertex(c, 0, v0);
771 if(v0 == a) {
772 triangulation.getCellVertex(c, 1, v0);
773 } else {
774 triangulation.getCellVertex(c, 1, v1);
775 if(v1 == a) {
776 triangulation.getCellVertex(c, 2, v1);
777 }
778 }
779 edges.emplace_back(std::array<SimplexId, 2>{v0, v1});
780 }
781 } else if(triangulation.getCellVertexNumber(0) == 4) {
782 // quad mesh
783 for(SimplexId i = 0; i < nStar; ++i) {
784 SimplexId c{};
785 triangulation.getVertexStar(a, i, c);
786 std::array<SimplexId, 4> q{};
787 triangulation.getCellVertex(c, 0, q[0]);
788 triangulation.getCellVertex(c, 1, q[1]);
789 triangulation.getCellVertex(c, 2, q[2]);
790 triangulation.getCellVertex(c, 3, q[3]);
791 if(q[0] == a) {
792 edges.emplace_back(std::array<SimplexId, 2>{
793 static_cast<SimplexId>(q[3]),
794 static_cast<SimplexId>(q[1]),
795 });
796 } else if(q[1] == a) {
797 edges.emplace_back(std::array<SimplexId, 2>{
798 static_cast<SimplexId>(q[0]),
799 static_cast<SimplexId>(q[2]),
800 });
801 } else if(q[2] == a) {
802 edges.emplace_back(std::array<SimplexId, 2>{
803 static_cast<SimplexId>(q[1]),
804 static_cast<SimplexId>(q[3]),
805 });
806 } else if(q[3] == a) {
807 edges.emplace_back(std::array<SimplexId, 2>{
808 static_cast<SimplexId>(q[2]),
809 static_cast<SimplexId>(q[0]),
810 });
811 }
812 }
813 }
814
815 // current vertex 3d coordinates
816 std::array<float, 3> pa{};
817 triangulation.getVertexPoint(a, pa[0], pa[1], pa[2]);
818
819 // triangle normals around current surface vertex
820 std::vector<std::array<float, 3>> normals{};
821 normals.reserve(nStar);
822
823 for(auto &e : edges) {
824 std::array<float, 3> pb{}, pc{};
825 triangulation.getVertexPoint(e[0], pb[0], pb[1], pb[2]);
826 triangulation.getVertexPoint(e[1], pc[0], pc[1], pc[2]);
827
828 std::array<float, 3> normal{};
829 computeTriangleNormal(pa.data(), pb.data(), pc.data(), normal.data());
830 // ensure normal not null
831 if(normal[0] != -1.0F && normal[1] != -1.0F && normal[2] != -1.0F) {
832 // unitary normal vector
833 normals.emplace_back(normal);
834 }
835 }
836
837 if(!normals.empty()) {
838
839 // ensure normals have same direction
840 for(size_t i = 1; i < normals.size(); ++i) {
841 const auto dotProd = dotProduct(normals[0].data(), normals[i].data());
842 if(dotProd < 0.0F) {
843 scaleVector(normals[i].data(), -1.0F, normals[i].data());
844 }
845 }
846
847 // compute mean of normals
848 for(unsigned int i = 0; i < normals.size(); ++i)
849 addVectors(res.data(), normals[i].data(), res.data());
850 scaleVector(res.data(), static_cast<float>(normals.size()), res.data());
851
852 } else {
853
854 // set error value directly in output variable...
855 res[0] = NAN;
856 }
857
858 return res;
859 }
860
876
882 size_t id;
884 std::array<float, 3> &pt;
887 };
888
889 template <typename triangulationType0, typename triangulationType1>
892 VisitedMask &trianglesTested,
893 std::vector<float> &dists,
894 std::stack<SimplexId> &trianglesToTest,
895 const bool reverseProjection,
896 const triangulationType0 &triangulationToSmooth,
897 const triangulationType1 &triangulation) {
898
899 ProjectionResult res{pi.pt, pi.nearestVertex, 0, false, false};
900
901 std::array<float, 3> surfaceNormal{};
902 if(reverseProjection) {
903 surfaceNormal
904 = computeSurfaceNormalAtPoint(pi.id, triangulationToSmooth);
905 res.reverseProjection = !std::isnan(surfaceNormal[0]);
906 }
907
908 // clean trianglesToTest
909 while(!trianglesToTest.empty()) {
910 trianglesToTest.pop();
911 }
912
913 // init pipeline by checking in the first triangle around selected vertex
914 if(triangulation.getVertexTriangleNumber(res.nearestVertex) > 0) {
915 SimplexId next{};
916 triangulation.getVertexTriangle(res.nearestVertex, 0, next);
917 trianglesToTest.push(next);
918 }
919
920 while(!trianglesToTest.empty()) {
921
922 const auto curr = trianglesToTest.top();
923 trianglesToTest.pop();
924
925 // skip if already tested
926 if(trianglesTested.isVisited_[curr]) {
927 continue;
928 }
929
930 // get triangle vertices
931 std::array<SimplexId, 3> tverts{};
932 triangulation.getTriangleVertex(curr, 0, tverts[0]);
933 triangulation.getTriangleVertex(curr, 1, tverts[1]);
934 triangulation.getTriangleVertex(curr, 2, tverts[2]);
935
936 // get coordinates of triangle vertices (lets name is MNO)
937 std::array<std::array<float, 3>, 3>
938 mno{}; // [0] is M, [1] is N and [2] is O
939 triangulation.getVertexPoint(
940 tverts[0], mno[0][0], mno[0][1], mno[0][2]);
941 triangulation.getVertexPoint(
942 tverts[1], mno[1][0], mno[1][1], mno[1][2]);
943 triangulation.getVertexPoint(
944 tverts[2], mno[2][0], mno[2][1], mno[2][2]);
945
946 std::array<float, 3> normTri{};
948 mno[0].data(), mno[1].data(), mno[2].data(), normTri.data());
949
950 static const float PREC_FLT{powf(10, -FLT_DIG)};
951
952 if(res.reverseProjection) {
953
954 const auto denom = dotProduct(surfaceNormal.data(), normTri.data());
955
956 // check if triangle plane is parallel to surface to project normal
957 if(std::abs(denom) < PREC_FLT) {
958 // fill pipeline with neighboring triangles
959 for(auto &vert : tverts) {
960 auto ntr = triangulation.getVertexTriangleNumber(vert);
961 for(SimplexId j = 0; j < ntr; ++j) {
962 SimplexId tid;
963 triangulation.getVertexTriangle(vert, j, tid);
964 if(tid != curr) {
965 trianglesToTest.push(tid);
966 }
967 }
968 }
969 continue;
970 }
971
972 // compute intersection between _surface to project normal at
973 // current vertex line_ and _reference surface triangle plane_
974 std::array<float, 3> tmp{};
975 subtractVectors(pi.pt.data(), mno[0].data(), tmp.data());
976 auto alpha = dotProduct(tmp.data(), normTri.data()) / denom;
977 std::array<float, 3> surfaceNormalScaled{};
978 scaleVector(surfaceNormal.data(), alpha, surfaceNormalScaled.data());
979 addVectors(pi.pt.data(), surfaceNormalScaled.data(), res.pt.data());
980
981 } else {
983 pi.pt.data(), mno[0].data(), normTri.data(), res.pt.data());
984 }
985
986 // compute barycentric coords of projection
987 std::array<float, 3> baryCoords{};
988 computeBarycentricCoordinates(mno[0].data(), mno[1].data(),
989 mno[2].data(), res.pt.data(), baryCoords);
990
991 // check if projection in triangle
992 bool inTriangle = true;
993
994 for(auto &coord : baryCoords) {
995 if(coord < -PREC_FLT) {
996 inTriangle = false;
997 }
998 if(coord > 1 + PREC_FLT) {
999 inTriangle = false;
1000 }
1001 }
1002
1003 // mark triangle as tested
1004 trianglesTested.insert(curr);
1005 res.trianglesChecked++;
1006
1007 if(inTriangle) {
1008 res.projSuccess = true;
1009 // should we check if we have the nearest triangle?
1010 break;
1011 }
1012
1013 // extrema values in baryCoords
1014 const auto extrema
1015 = std::minmax_element(baryCoords.begin(), baryCoords.end());
1016
1017 // find the nearest triangle vertices local ids (with the
1018 // highest/positive values in baryCoords) from proj
1019 std::array<SimplexId, 2> vid{
1020 static_cast<SimplexId>(extrema.second - baryCoords.begin()), 0};
1021 for(size_t j = 0; j < baryCoords.size(); j++) {
1022 if(j != static_cast<size_t>(extrema.first - baryCoords.begin())
1023 && j != static_cast<size_t>(extrema.second - baryCoords.begin())) {
1024 vid[1] = j;
1025 break;
1026 }
1027 }
1028
1029 // store vertex with highest barycentric coordinate
1030 res.nearestVertex = tverts[vid[0]];
1031 const auto secondNearVert{tverts[vid[1]]};
1032
1033 // get the triangle edge with the two vertices
1034 SimplexId edge{};
1035 const auto nEdges{triangulation.getVertexEdgeNumber(res.nearestVertex)};
1036 for(SimplexId i = 0; i < nEdges; ++i) {
1037 triangulation.getVertexEdge(res.nearestVertex, i, edge);
1038 SimplexId v{};
1039 triangulation.getEdgeVertex(edge, 0, v);
1040 if(v == res.nearestVertex) {
1041 triangulation.getEdgeVertex(edge, 1, v);
1042 }
1043 if(v == secondNearVert) {
1044 break;
1045 }
1046 }
1047
1048 // next triangle to visit
1049 SimplexId next{};
1050 const auto nTri{triangulation.getEdgeTriangleNumber(edge)};
1051 for(SimplexId i = 0; i < nTri; ++i) {
1052 triangulation.getEdgeTriangle(edge, i, next);
1053 if(next != curr) {
1054 break;
1055 }
1056 }
1057
1058 const auto nVisited{trianglesTested.visitedIds_.size()};
1059 if(nVisited > 1 && next == trianglesTested.visitedIds_[nVisited - 2]) {
1060 // the relaxed point is probably over the edge separating the
1061 // current and the last visited triangles
1062 projectOnEdge(pi.pt.data(), mno[vid[0]].data(), mno[vid[1]].data(),
1063 res.pt.data());
1064 // check that projected point is indeed on segment
1065 res.projSuccess = isPointOnSegment(
1066 res.pt.data(), mno[vid[0]].data(), mno[vid[1]].data());
1067 if(!res.projSuccess) {
1068 // if not, replace with nearest triangle vertex
1069 triangulation.getVertexPoint(
1070 tverts[vid[0]], res.pt[0], res.pt[1], res.pt[2]);
1071 res.projSuccess = true;
1072 }
1073 break;
1074 }
1075
1076 if(!trianglesTested.isVisited_[next]) {
1077 trianglesToTest.push(next);
1078 }
1079 }
1080
1081 const size_t maxTrChecked = 100;
1082
1083 if(res.projSuccess && res.trianglesChecked > maxTrChecked) {
1084 res.projSuccess = false;
1085 }
1086
1087 std::array<float, 3> nearestCoords{};
1088 triangulation.getVertexPoint(
1089 pi.nearestVertex, nearestCoords[0], nearestCoords[1], nearestCoords[2]);
1090 if(Geometry::distance(res.pt.data(), pi.pt.data())
1091 > 5.0 * Geometry::distance(res.pt.data(), nearestCoords.data())) {
1092 res.projSuccess = false;
1093 if(triangulationToSmooth.getDimensionality() == 2
1094 && !reverseProjection) {
1095 // clean trianglesTested
1096 for(const auto t : trianglesTested.visitedIds_) {
1097 trianglesTested.isVisited_[t] = false;
1098 }
1099 trianglesTested.visitedIds_.clear();
1100 return findProjection(pi, trianglesTested, dists, trianglesToTest,
1101 true, triangulationToSmooth, triangulation);
1102 }
1103 }
1104
1105 if(!res.projSuccess) {
1106 // replace proj by the nearest vertex?
1107 res.nearestVertex = Geometry::getNearestSurfaceVertex(
1108 pi.pt.data(), dists, triangulation);
1109 triangulation.getVertexPoint(
1110 res.nearestVertex, res.pt[0], res.pt[1], res.pt[2]);
1111 }
1112
1113 return res;
1114 }
1115
1116 } // namespace Geometry
1117} // namespace ttk
#define M_PI
Definition Os.h:50
int scaleVector(const T *a, const T factor, T *out, const int &dimension=3)
Definition Geometry.cpp:647
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:27
int computeTriangleArea(const T *p0, const T *p1, const T *p2, T &area)
Definition Geometry.cpp:281
double angle2DUndirected(const T *vA, const T *vB, const T *vC)
Definition Geometry.h:33
int addVectors(const T *a, const T *b, T *out, const int &dimension=3)
Definition Geometry.cpp:610
void projectOnEdge(const T *p, const T *a, const T *b, T *out)
Compute euclidean projection on a 3D segment.
Definition Geometry.cpp:550
T dotProductFlatten(const std::vector< std::vector< T > > &vA, const std::vector< std::vector< T > > &vB)
Definition Geometry.cpp:412
int multiFlattenMultiDimensionalVector(const std::vector< std::vector< std::vector< T > > > &a, std::vector< std::vector< T > > &out)
Definition Geometry.cpp:752
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:788
bool isTriangleColinear2D(const T *pptA, const T *pptB, const T *pptC, const T tolerance)
Definition Geometry.cpp:130
T dotProduct(const T *vA0, const T *vA1, const T *vB0, const T *vB1)
Definition Geometry.cpp:388
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:777
bool isVectorNullFlatten(const std::vector< std::vector< T > > &a)
Definition Geometry.cpp:735
bool isPointOnSegment(const T &x, const T &y, const T &xA, const T &yA, const T &xB, const T &yB)
Definition Geometry.cpp:443
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:248
int computeBarycentricCoordinates(const T *p0, const T *p1, const T *p, std::array< T, 2 > &baryCentrics, const int &dimension=3)
Definition Geometry.cpp:142
void projectOnTrianglePlane(const T *p, const T *a, const T *normTri, T *out)
Compute euclidean projection in a triangle plane.
Definition Geometry.cpp:538
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:798
void gramSchmidt(const std::vector< std::vector< T > > &a, std::vector< std::vector< T > > &out)
Definition Geometry.cpp:701
void scaleMatrix(const std::vector< std::vector< T > > &a, const T factor, std::vector< std::vector< T > > &out)
Definition Geometry.cpp:808
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:625
SimplexId getNearestSurfaceVertex(const T *pa, std::vector< T > &dists, const triangulationType &triangulation)
Find nearest vertex on the surface.
Definition Geometry.h:517
int flattenMultiDimensionalVector(const std::vector< std::vector< T > > &a, std::vector< T > &out)
Definition Geometry.cpp:742
bool isVectorUniform(const std::vector< T > &a)
Definition Geometry.cpp:719
int subtractVectors(const T *a, const T *b, T *out, const int &dimension=3)
Definition Geometry.cpp:592
int computeTriangleAreaFromSides(const T s0, const T s1, const T s2, T &area)
Definition Geometry.cpp:296
T magnitudeFlatten(const std::vector< std::vector< T > > &v)
Definition Geometry.cpp:519
bool isVectorNull(const std::vector< T > &a)
Definition Geometry.cpp:727
void computeTriangleNormal(const T *a, const T *b, const T *c, T *out)
Compute normal vector to triangle.
Definition Geometry.cpp:564
T1 pow(const T1 val, const T2 n)
Definition Geometry.h:456
T distance2D(const T *p0, const T *p1)
Definition Geometry.h:200
bool isTriangleColinear(const T *p0, const T *p1, const T *p2, const T *tolerance=nullptr)
Definition Geometry.cpp:466
int getBoundingBox(const Container &points, std::array< std::pair< T, T >, dim > &bBox)
Definition Geometry.h:273
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:690
T powIntTen(const int n)
Compute the nth power of ten.
Definition Geometry.h:405
T powInt(const T val, const int n)
Definition Geometry.h:383
int computeTriangleAngles(const T *p0, const T *p1, const T *p2, std::array< T, 3 > &angles)
Definition Geometry.cpp:308
int computeTriangleAngleFromSides(const T s0, const T s1, const T s2, T &angle)
Definition Geometry.cpp:321
int vectorProjection(const T *a, const T *b, T *out, const int &dimension=3)
Definition Geometry.cpp:665
int crossProduct(const T *vA0, const T *vA1, const T *vB0, const T *vB1, std::array< T, 3 > &crossProduct)
Definition Geometry.cpp:332
void transposeMatrix(const std::vector< std::vector< T > > &a, std::vector< std::vector< T > > &out)
Definition Geometry.cpp:818
std::array< float, 3 > computeSurfaceNormalAtPoint(const SimplexId a, const triangulationType &triangulation)
Compute (mean) surface normal at given surface vertex.
Definition Geometry.h:754
int unflattenMultiDimensionalVector(const std::vector< T > &a, std::vector< std::vector< T > > &out, const int &no_columns=2)
Definition Geometry.cpp:762
T magnitude(const T *v, const int &dimension=3)
Definition Geometry.cpp:509
T distance(const T *p0, const T *p1, const int &dimension=3)
Definition Geometry.cpp:362
T angle2D(const T *vA0, const T *vA1, const T *vB0, const T *vB1)
Definition Geometry.cpp:20
ProjectionResult findProjection(const ProjectionInput &pi, VisitedMask &trianglesTested, std::vector< float > &dists, std::stack< SimplexId > &trianglesToTest, const bool reverseProjection, const triangulationType0 &triangulationToSmooth, const triangulationType1 &triangulation)
Definition Geometry.h:891
T distanceFlatten(const std::vector< std::vector< T > > &p0, const std::vector< std::vector< T > > &p1)
Definition Geometry.cpp:379
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:635
bool isPointInTriangle(const T *p0, const T *p1, const T *p2, const T *p)
Definition Geometry.cpp:421
The Topology ToolKit.
int SimplexId
Identifier type for simplices of any dimension.
Definition DataTypes.h:22
Stores the findProjection() input.
Definition Geometry.h:880
std::array< float, 3 > & pt
Definition Geometry.h:884
Stores the findProjection() result.
Definition Geometry.h:864
std::array< float, 3 > pt
Definition Geometry.h:866
Auto-cleaning re-usable graph propagations data structure.
Definition VisitedMask.h:27
std::vector< bool > & isVisited_
Definition VisitedMask.h:28
void insert(const SimplexId id)
Definition VisitedMask.h:45
std::vector< SimplexId > & visitedIds_
Definition VisitedMask.h:29