17 # include <vcl_msvc_warnings.h> 22 static const double vgl_nan = std::sqrt(-1.0);
23 static const double sqrteps = std::sqrt(std::numeric_limits<double>::epsilon());
24 static const double pi = 3.14159265358979323846;
34 auto *a = reinterpret_cast<double *>(&plane);
36 a[0] = p2.
y()*p3.
z() - p2.
z()*p3.
y()
37 + p3.
y()*p1.
z() - p3.
z()*p1.
y()
38 + p1.
y()*p2.
z() - p1.
z()*p2.
y();
40 a[1] = p2.
z()*p3.
x() - p2.
x()*p3.
z()
41 + p3.
z()*p1.
x() - p3.
x()*p1.
z()
42 + p1.
z()*p2.
x() - p1.
x()*p2.
z();
44 a[2] = p2.
x()*p3.
y() - p2.
y()*p3.
x()
45 + p3.
x()*p1.
y() - p3.
y()*p1.
x()
46 + p1.
x()*p2.
y() - p1.
y()*p2.
x();
48 a[3] = p1.
x()*(p2.
z()*p3.
y() - p2.
y()*p3.
z())
49 + p2.
x()*(p3.
z()*p1.
y() - p3.
y()*p1.
z())
50 + p3.
x()*(p1.
z()*p2.
y() - p1.
y()*p2.
z());
66 std::vector<std::pair<unsigned,unsigned> > coinc_edges;
71 std::pair<unsigned,unsigned> e[3] = { std::make_pair(0,1),
73 std::make_pair(2,0) };
76 for (
unsigned j = 0; j < 3; ++j)
78 for (
unsigned i = 0; i < 3; ++i)
82 double e1_len =
length(a[e[j].first] - a[e[j].second]);
83 double b1_dist =
length(a[e[j].first] - b[e[i].first]) +
84 length(a[e[j].second] - b[e[i].first]);
85 double b2_dist =
length(a[e[j].first] - b[e[i].second]) +
86 length(a[e[j].second] - b[e[i].second]);
88 double e2_len =
length(b[e[i].first] - b[e[i].second]);
89 double a1_dist =
length(b[e[i].first] - a[e[j].first]) +
90 length(b[e[i].second] - a[e[j].first]);
91 double a2_dist =
length(b[e[i].first] - a[e[j].second]) +
92 length(b[e[i].second] - a[e[j].second]);
94 if ((std::fabs(e1_len - b1_dist) < sqrteps &&
95 std::fabs(e1_len - b2_dist) < sqrteps) ||
96 (std::fabs(e2_len - a1_dist) < sqrteps &&
97 std::fabs(e2_len - a2_dist) < sqrteps))
99 coinc_edges.emplace_back(j,i);
119 double coplanar_tolerance)
125 if (p1==p2&&p2==p3&&p1==p3)
138 create_plane_and_ignore_degenerate(p1, p2, p3);
148 norm.
set(std::fabs(norm.
x()),std::fabs(norm.
y()),std::fabs(norm.
z()));
152 if (norm.
y()>=norm.
x() && norm.
y()>=norm.
z())
156 else if (norm.
x()>=norm.
y() && norm.
x()>=norm.
z())
161 double point[3] = {i_pnt.
x(), i_pnt.
y(), i_pnt.
z()};
162 double vert0[3] = {p1.
x(), p1.
y(), p1.
z()};
163 double vert1[3] = {p2.
x(), p2.
y(), p2.
z()};
164 double vert2[3] = {p3.
x(), p3.
y(), p3.
z()};
170 double u0 = (std::fabs(point[i1]) < sqrteps ? 0 : point[i1]) - (std::fabs(vert0[i1]) < sqrteps ? 0 : vert0[i1]);
171 double v0 = (std::fabs(point[i2]) < sqrteps ? 0 : point[i2]) - (std::fabs(vert0[i2]) < sqrteps ? 0 : vert0[i2]);
173 double u1 = (std::fabs(vert1[i1]) < sqrteps ? 0 : vert1[i1]) - (std::fabs(vert0[i1]) < sqrteps ? 0 : vert0[i1]);
174 double u2 = (std::fabs(vert2[i1]) < sqrteps ? 0 : vert2[i1]) - (std::fabs(vert0[i1]) < sqrteps ? 0 : vert0[i1]);
175 double v1 = (std::fabs(vert1[i2]) < sqrteps ? 0 : vert1[i2]) - (std::fabs(vert0[i2]) < sqrteps ? 0 : vert0[i2]);
176 double v2 = (std::fabs(vert2[i2]) < sqrteps ? 0 : vert2[i2]) - (std::fabs(vert0[i2]) < sqrteps ? 0 : vert0[i2]);
182 if (beta < -sqrteps/*0*/ || beta > 1+sqrteps)
184 alpha = (v0 - beta * v2) / v1;
188 beta = (v0 * u1 - u0 * v1) / (v2 * u1 - u2 * v1);
189 if (beta < -sqrteps/*0*/ || beta > 1+sqrteps)
191 alpha = (u0 - beta * u2) / u1;
194 return alpha >= -sqrteps
195 && alpha + beta <= 1.0+sqrteps;
228 double test_val = std::fabs(int_ang-(2*pi));
230 return test_val < sqrteps;
253 if (std::abs(d_dot) < std::sqrt(
254 std::numeric_limits<double>::epsilon()) *
255 std::max(1.0e-100, std::max(std::sqrt(A.x()*A.x()+A.y()*A.y()+A.z()*A.z()),
256 std::sqrt(D.
x()*D.
x()+D.
y()*D.
y()+D.
z()*D.
z()) ) ) )
261 if (d_dot * e_dot >= 0)
278 bool ignore_coplanar)
284 if (line_p1 == line_p2)
294 if (p1==p2&&p2==p3&&p1==p3)
300 if ( !ignore_coplanar && (
359 i_pnt.
set(vgl_nan, vgl_nan, vgl_nan);
366 if (same_side(p1, p2, p3, line_p1, line_p2) ==
Skew)
376 #define UINT_MAX 0xffffffffU 380 static const unsigned calc_edge_index_lookup[8] = {
UINT_MAX, 0, 2, 0,
UINT_MAX, 1, 2, 1};
384 inline unsigned calc_edge_index(
unsigned v,
unsigned w)
386 unsigned lookup =
v*3u + w;
388 unsigned edge = calc_edge_index_lookup[lookup];
412 unsigned &i_line_point1_edge,
413 unsigned &i_line_point2_edge
422 if (a_p1 == a_p2 && a_p2==a_p3)
426 i_line_point1_edge = i_line_point2_edge = 0;
427 i_line.
set(a_p1,a_p1);
435 unsigned tmp_iline_edges[2];
436 unsigned n_tmp_iline_edges = 0;
439 i_line.
set(i_pnt,i_pnt);
442 i_line_point1_edge = i_line_point2_edge = 0;
445 tmp_iline_edges[0] = 0;
446 n_tmp_iline_edges = 1;
450 i_line.
set(i_pnt,i_pnt);
453 i_line_point1_edge = i_line_point2_edge = 1;
456 tmp_iline_edges[n_tmp_iline_edges] = 1;
461 i_line.
set(i_pnt,i_pnt);
464 i_line_point1_edge = i_line_point2_edge = 2;
467 if (n_tmp_iline_edges >= 2)
469 i_line_point1_edge = i_line_point2_edge = 0;
472 tmp_iline_edges[n_tmp_iline_edges] = 2;
475 if (!n_tmp_iline_edges)
return None;
476 if (n_tmp_iline_edges == 1)
478 i_line_point1_edge = i_line_point2_edge = tmp_iline_edges[0];
482 i_line_point1_edge = tmp_iline_edges[0];
483 i_line_point2_edge = tmp_iline_edges[1];
488 if (b_p1 == b_p2 && b_p2==b_p3 && b_p1 == b_p3)
492 i_line_point1_edge = i_line_point2_edge = 3;
493 i_line.
set(b_p1,b_p1);
501 unsigned tmp_iline_edges[2];
502 unsigned n_tmp_iline_edges = 0;
505 i_line.
set(i_pnt,i_pnt);
508 i_line_point1_edge = i_line_point2_edge = 3;
511 tmp_iline_edges[0] = 3;
512 n_tmp_iline_edges = 1;
516 i_line.
set(i_pnt,i_pnt);
519 i_line_point1_edge = i_line_point2_edge = 4;
522 tmp_iline_edges[n_tmp_iline_edges] = 4;
527 i_line.
set(i_pnt,i_pnt);
530 i_line_point1_edge = i_line_point2_edge = 5;
533 if (n_tmp_iline_edges >= 2)
535 i_line_point1_edge = i_line_point2_edge = 3;
538 tmp_iline_edges[n_tmp_iline_edges] = 5;
541 if (!n_tmp_iline_edges)
return None;
542 if (n_tmp_iline_edges == 1)
544 i_line_point1_edge = i_line_point2_edge = tmp_iline_edges[0];
548 i_line_point1_edge = tmp_iline_edges[0];
549 i_line_point2_edge = tmp_iline_edges[1];
559 double d_b[3], d_a[3];
560 double d_b1d_b2, d_b1d_b3, d_a1d_a2, d_a1d_a3;
566 double TRI_TRI_EPS = 1000000*std::numeric_limits<double>::epsilon();
576 a_d = -( a_norm.
x()*a_p1.x() + a_norm.
y()*a_p1.y() +a_norm.
z()*a_p1.z() );
580 d_b[0] = ( a_norm.
x()*b_p1.
x() + a_norm.
y()*b_p1.
y() + a_norm.
z()*b_p1.
z() ) + a_d;
581 d_b[1] = ( a_norm.
x()*b_p2.
x() + a_norm.
y()*b_p2.
y() + a_norm.
z()*b_p2.
z() ) + a_d;
582 d_b[2] = ( a_norm.
x()*b_p3.
x() + a_norm.
y()*b_p3.
y() + a_norm.
z()*b_p3.
z() ) + a_d;
584 d_b[0] = (a_plane.nx()*b_p1.
x() + a_plane.ny()*b_p1.
y() + a_plane.nz()*b_p1.
z() ) + a_plane.d();
585 d_b[1] = (a_plane.nx()*b_p2.
x() + a_plane.ny()*b_p2.
y() + a_plane.nz()*b_p2.
z() ) + a_plane.d();
586 d_b[2] = (a_plane.nx()*b_p3.
x() + a_plane.ny()*b_p3.
y() + a_plane.nz()*b_p3.
z() ) + a_plane.d();
590 if (std::fabs(d_b[0]) < TRI_TRI_EPS) d_b[0] = 0.0;
591 if (std::fabs(d_b[1]) < TRI_TRI_EPS) d_b[1] = 0.0;
592 if (std::fabs(d_b[2]) < TRI_TRI_EPS) d_b[2] = 0.0;
594 d_b1d_b2 = d_b[0]*d_b[1];
595 d_b1d_b3 = d_b[0]*d_b[2];
598 if (d_b1d_b2 > 0 && d_b1d_b3 > 0)
608 b_d = -( b_norm.
x()*b_p1.x() + b_norm.
y()*b_p1.y() + b_norm.
z()*b_p1.z() );
612 d_a[0] = ( b_norm.
x()*a_p1.x() + b_norm.
y()*a_p1.y() + b_norm.
z()*a_p1.z() ) + b_d;
613 d_a[1] = ( b_norm.
x()*a_p2.
x() + b_norm.
y()*a_p2.
y() + b_norm.
z()*a_p2.
z() ) + b_d;
614 d_a[2] = ( b_norm.
x()*a_p3.
x() + b_norm.
y()*a_p3.
y() + b_norm.
z()*a_p3.
z() ) + b_d;
616 d_a[0] = (b_plane.nx()*a_p1.x() + b_plane.ny()*a_p1.y() + b_plane.nz()*a_p1.z() ) + b_plane.d();
617 d_a[1] = (b_plane.nx()*a_p2.
x() + b_plane.ny()*a_p2.
y() + b_plane.nz()*a_p2.
z() ) + b_plane.d();
618 d_a[2] = (b_plane.nx()*a_p3.
x() + b_plane.ny()*a_p3.
y() + b_plane.nz()*a_p3.
z() ) + b_plane.d();
622 if (std::fabs(d_a[0]) < TRI_TRI_EPS) d_a[0] = 0.0;
623 if (std::fabs(d_a[1]) < TRI_TRI_EPS) d_a[1] = 0.0;
624 if (std::fabs(d_a[2]) < TRI_TRI_EPS) d_a[2] = 0.0;
626 d_a1d_a2 = d_a[0]*d_a[1];
627 d_a1d_a3 = d_a[0]*d_a[2];
630 if (d_a1d_a2 > 0 && d_a1d_a3 > 0)
646 int_line.
set(std::fabs(int_line.
x()),std::fabs(int_line.
y()),std::fabs(int_line.
z()));
648 if (int_line.
y()>=int_line.
x() && int_line.
y()>=int_line.
z())
658 else if (int_line.
x()>=int_line.
y() && int_line.
x()>=int_line.
z())
678 int a_ival[3] = {0,1,2};
688 else if (d_a1d_a3 > 0)
694 else if (d_a[1]*d_a[2] > 0 || d_a[0] != 0)
700 else if (d_a[1] != 0)
706 else if (d_a[2] != 0)
718 int b_ival[3] = {0,1,2};
728 else if (d_b1d_b3 > 0)
734 else if (d_b[1]*d_b[2] > 0 || d_b[0] != 0)
740 else if (d_b[1] != 0)
746 else if (d_b[2] != 0)
770 if ( isect1 || isect2 || isect3 )
775 i_line_point1 = i_pnt1;
776 i_line_point1_edge = i_line_point2_edge = 0;
782 i_line_point1 = i_pnt2;
783 i_line_point1_edge = i_line_point2_edge = 1;
787 i_line_point1 = i_pnt3;
788 i_line_point1_edge = i_line_point2_edge = 2;
792 if (isect1 && isect2)
793 i_line_point2 = i_pnt2;
794 else if ((isect1 || isect2) && isect3)
795 i_line_point2 = i_pnt3;
799 i_line_point2 = i_pnt1;
803 i_line_point2 = i_pnt2;
805 i_line_point2 = i_pnt3;
808 i_line.
set( i_line_point1, i_line_point2);
815 i_line_point1_edge = i_line_point2_edge = 0;
816 i_line.
set(a_p1, a_p3);
822 i_line_point1_edge = i_line_point2_edge = 3;
823 i_line.
set(b_p1, b_p3);
833 double tmp = d_a[a_ival[0]]/(d_a[a_ival[0]]-d_a[a_ival[1]]);
834 isect_a[0] = p_a[a_ival[0]] + (p_a[a_ival[1]] - p_a[a_ival[0]])*tmp;
838 i_pnts[0] = a_vs[a_ival[0]] + diff ;
840 tmp = d_a[a_ival[0]]/(d_a[a_ival[0]]-d_a[a_ival[2]]);
841 isect_a[1] = p_a[a_ival[0]] + (p_a[a_ival[2]] - p_a[a_ival[0]])*tmp;
842 diff = a_vs[a_ival[2]] - a_vs[a_ival[0]];
844 i_pnts[1] = a_vs[a_ival[0]] + diff;
848 tmp = d_b[b_ival[0]]/(d_b[b_ival[0]] - d_b[b_ival[1]]);
849 isect_b[0] = p_b[b_ival[0]] + (p_b[b_ival[1]] - p_b[b_ival[0]])*tmp;
851 diff = b_vs[b_ival[1]] - b_vs[b_ival[0]];
853 i_pnts[2] = b_vs[b_ival[0]] + diff;
855 tmp = d_b[b_ival[0]]/(d_b[b_ival[0]]-d_b[b_ival[2]]);
856 isect_b[1] = p_b[b_ival[0]] + (p_b[b_ival[2]] - p_b[b_ival[0]])*tmp;
857 diff = b_vs[b_ival[2]] - b_vs[b_ival[0]];
859 i_pnts[3] = b_vs[b_ival[0]] + diff;
861 unsigned smallest1 = 0;
862 if (isect_a[0] > isect_a[1])
864 std::swap(isect_a[0], isect_a[1]);
867 unsigned smallest2 = 0;
868 if (isect_b[0] > isect_b[1])
870 std::swap(isect_b[0], isect_b[1]);
874 if (isect_a[1] < isect_b[0] || isect_b[1] < isect_a[0])
879 unsigned i_pt1,i_pt2;
881 if (isect_b[0]<isect_a[0])
886 i_line_point1_edge = calc_edge_index(a_ival[0], a_ival[1]);
891 i_line_point1_edge = calc_edge_index(a_ival[0], a_ival[2]);
894 if (isect_b[1]<isect_a[1])
899 i_line_point2_edge = calc_edge_index(b_ival[0], b_ival[2]) + 3;
904 i_line_point2_edge = calc_edge_index(b_ival[0], b_ival[1]) + 3;
912 i_line_point2_edge = calc_edge_index(a_ival[0], a_ival[2]);
917 i_line_point2_edge = calc_edge_index(a_ival[0], a_ival[1]);
926 i_line_point1_edge = calc_edge_index(b_ival[0], b_ival[1]) + 3;
931 i_line_point1_edge = calc_edge_index(b_ival[0], b_ival[2]) + 3;
934 if (isect_b[1]>isect_a[1])
939 i_line_point2_edge = calc_edge_index(a_ival[0], a_ival[2]);
944 i_line_point2_edge = calc_edge_index(a_ival[0], a_ival[1]);
952 i_line_point2_edge = calc_edge_index(b_ival[0], b_ival[2]) + 3;
957 i_line_point2_edge = calc_edge_index(b_ival[0], b_ival[1]) + 3;
962 i_line.
set(i_pnts[i_pt1],i_pnts[i_pt2]);
980 unsigned iline_p1, iline_p2;
984 i_line, iline_p1, iline_p2);
1006 if (a_p1 == a_p2 && a_p2==a_p3 && a_p1 == a_p3)
1024 if (b_p1 == b_p2 && b_p2==b_p3 && b_p1 == b_p3)
1048 double d_b1, d_b2, d_b3, d_a1, d_a2, d_a3;
1049 double isect1[2], isect2[2];
1050 double d_b1d_b2, d_b1d_b3, d_a1d_a2, d_a1d_a3;
1052 double p_a1, p_a2, p_a3;
1053 double p_b1, p_b2, p_b3;
1056 double a=0.0, b=0.0, c=0.0, x0=0.0, x1=0.0;
1057 double d=0.0, e=0.0, f=0.0, y0=0.0, y1=0.0;
1058 double xx, yy, xxyy, tmp;
1059 double TRI_TRI_EPS = 100000*std::numeric_limits<double>::epsilon();
1065 edge1 = a_p2 - a_p1;
1066 edge2 = a_p3 - a_p1;
1070 a_d = -( a_norm.
x()*a_p1.x() + a_norm.
y()*a_p1.y() +a_norm.
z()*a_p1.z() );
1074 d_b1 = ( a_norm.
x()*b_p1.
x() + a_norm.
y()*b_p1.
y() + a_norm.
z()*b_p1.
z() ) + a_d;
1075 d_b2 = ( a_norm.
x()*b_p2.
x() + a_norm.
y()*b_p2.
y() + a_norm.
z()*b_p2.
z() ) + a_d;
1076 d_b3 = ( a_norm.
x()*b_p3.
x() + a_norm.
y()*b_p3.
y() + a_norm.
z()*b_p3.
z() ) + a_d;
1078 d_b1 = (a_plane.nx()*b_p1.
x() + a_plane.ny()*b_p1.
y() + a_plane.nz()*b_p1.
z() ) + a_plane.d();
1079 d_b2 = (a_plane.nx()*b_p2.
x() + a_plane.ny()*b_p2.
y() + a_plane.nz()*b_p2.
z() ) + a_plane.d();
1080 d_b3 = (a_plane.nx()*b_p3.
x() + a_plane.ny()*b_p3.
y() + a_plane.nz()*b_p3.
z() ) + a_plane.d();
1084 if (std::fabs(d_b1) < TRI_TRI_EPS) d_b1 = 0.0;
1085 if (std::fabs(d_b2) < TRI_TRI_EPS) d_b2 = 0.0;
1086 if (std::fabs(d_b3) < TRI_TRI_EPS) d_b3 = 0.0;
1088 d_b1d_b2 = d_b1*d_b2;
1089 d_b1d_b3 = d_b1*d_b3;
1092 if (d_b1d_b2 > 0 && d_b1d_b3 > 0)
1098 edge1 = b_p2 - b_p1;
1099 edge2 = b_p3 - b_p1;
1103 b_d = -( b_norm.
x()*b_p1.x() + b_norm.
y()*b_p1.y() + b_norm.
z()*b_p1.z() );
1107 d_a1 = ( b_norm.
x()*a_p1.x() + b_norm.
y()*a_p1.y() + b_norm.
z()*a_p1.z() ) + b_d;
1108 d_a2 = ( b_norm.
x()*a_p2.
x() + b_norm.
y()*a_p2.
y() + b_norm.
z()*a_p2.
z() ) + b_d;
1109 d_a3 = ( b_norm.
x()*a_p3.
x() + b_norm.
y()*a_p3.
y() + b_norm.
z()*a_p3.
z() ) + b_d;
1111 d_a1 = (b_plane.nx()*a_p1.x() + b_plane.ny()*a_p1.y() + b_plane.nz()*a_p1.z() ) + b_plane.d();
1112 d_a2 = (b_plane.nx()*a_p2.
x() + b_plane.ny()*a_p2.
y() + b_plane.nz()*a_p2.
z() ) + b_plane.d();
1113 d_a3 = (b_plane.nx()*a_p3.
x() + b_plane.ny()*a_p3.
y() + b_plane.nz()*a_p3.
z() ) + b_plane.d();
1117 if (std::fabs(d_a1) < TRI_TRI_EPS) d_a1 = 0.0;
1118 if (std::fabs(d_a2) < TRI_TRI_EPS) d_a2 = 0.0;
1119 if (std::fabs(d_a3) < TRI_TRI_EPS) d_a3 = 0.0;
1121 d_a1d_a2 = d_a1*d_a2;
1122 d_a1d_a3 = d_a1*d_a3;
1125 if (d_a1d_a2 > 0 && d_a1d_a3 > 0)
1141 int_line.
set(std::fabs(int_line.
x()),std::fabs(int_line.
y()),std::fabs(int_line.
z()));
1143 if (int_line.
y()>=int_line.
x() && int_line.
y()>=int_line.
z())
1153 else if (int_line.
x()>=int_line.
y() && int_line.
x()>=int_line.
z())
1177 b = (p_a1-p_a3)*d_a3;
1178 c = (p_a2-p_a3)*d_a3;
1183 else if (d_a1d_a3 > 0)
1186 b = (p_a1-p_a2)*d_a2;
1187 c = (p_a3-p_a2)*d_a2;
1192 else if (d_a2*d_a3 > 0 || d_a1 != 0)
1195 b = (p_a2-p_a1)*d_a1;
1196 c = (p_a3-p_a1)*d_a1;
1204 b = (p_a1-p_a2)*d_a2;
1205 c = (p_a3-p_a2)*d_a2;
1213 b = (p_a1-p_a3)*d_a3;
1214 c = (p_a2-p_a3)*d_a3;
1231 e = (p_b1-p_b3)*d_b3;
1232 f = (p_b2-p_b3)*d_b3;
1237 else if (d_b1d_b3 > 0)
1246 else if (d_b2*d_b3 > 0 || d_b1 != 0)
1249 e = (p_b2-p_b1)*d_b1;
1250 f = (p_b3-p_b1)*d_b1;
1258 e = (p_b1-p_b2)*d_b2;
1259 f = (p_b3-p_b2)*d_b2;
1267 e = (p_b1-p_b3)*d_b3;
1268 f = (p_b2-p_b3)*d_b3;
1308 isect1[0] = tmp+b*x1*yy;
1309 isect1[1] = tmp+c*x0*yy;
1312 isect2[0] = tmp+e*xx*y1;
1313 isect2[1] = tmp+f*xx*y0;
1315 if (isect1[0] > isect1[1])
1318 isect1[0] = isect1[1];
1322 if (isect2[0] > isect2[1])
1325 isect2[0] = isect2[1];
1329 if (isect1[1] < isect2[0] || isect2[1] < isect1[0])
1353 double p1_d = i_plane.
nx()*p1.
x() + i_plane.
ny()*p1.
y() + i_plane.
nz()*p1.
z() + i_plane.
d();
1354 double p2_d = i_plane.
nx()*p2.
x() + i_plane.
ny()*p2.
y() + i_plane.
nz()*p2.
z() + i_plane.
d();
1355 double p3_d = i_plane.
nx()*p3.
x() + i_plane.
ny()*p3.
y() + i_plane.
nz()*p3.
z() + i_plane.
d();
1358 if (std::fabs(p1_d) < sqrteps) p1_d = 0.0;
1359 if (std::fabs(p2_d) < sqrteps) p2_d = 0.0;
1360 if (std::fabs(p3_d) < sqrteps) p3_d = 0.0;
1364 if (p1_d*p2_d > 0 && p1_d*p3_d > 0)
1369 else if (p1_d == 0 && p2_d == 0 && p3_d == 0)
1372 i_line.
set(i_pnt1,i_pnt1);
1375 else if (p1_d*p2_d > 0)
1381 i_line.
set(i_pnt1,i_pnt2);
1383 else if (p1_d*p3_d > 0)
1389 i_line.
set(i_pnt1,i_pnt2);
1391 else if (p2_d*p3_d > 0)
1397 i_line.
set(i_pnt1,i_pnt2);
1399 else if (p1_d == 0 && p2_d == 0)
1403 else if (p1_d == 0 && p3_d == 0)
1407 else if (p3_d == 0 && p2_d == 0)
1415 i_line.
set(p1,i_pnt2);
1421 i_line.
set(p2,i_pnt2);
1427 i_line.
set(p3,i_pnt2);
1445 if (p2 == p3)
return p3;
1469 double cp1x, cp1y, cp1z;
1472 p1.
x(), p1.
y(), p1.
z(),
1473 p2.
x(), p2.
y(), p2.
z(),
1474 q.
x(), q.
y(), q.
z());
1479 double cp2x, cp2y, cp2z;
1482 p2.
x(), p2.
y(), p2.
z(),
1483 p3.
x(), p3.
y(), p3.
z(),
1484 q.
x(), q.
y(), q.
z());
1489 double cp3x, cp3y, cp3z;
1492 p1.
x(), p1.
y(), p1.
z(),
1493 p3.
x(), p3.
y(), p3.
z(),
1494 q.
x(), q.
y(), q.
z());
1499 if (d1<=d2 && d1<=d3)
1501 else if (d2<=d1 && d2<=d3)
1533 return coplanar(a_p1,b_p1,b_p2,b_p3)
1546 edge_vector0 = p0 - p1;
1548 edge_vector1 = p0 - p2;
1554 area = area_vector.
length();
double vgl_triangle_3d_area(const vgl_point_3d< double > &p0, const vgl_point_3d< double > &p1, const vgl_point_3d< double > &p2)
Compute the area of a triangle.
Set of intersection functions.
v normalized(v const &a)
Return a normalised version of a.
T dot_product(v const &a, v const &b)
dot product or inner product of two vectors.
vgl_point_3d< Type > point1() const
void set(vgl_point_3d< Type > const &p1, vgl_point_3d< Type > const &p2)
Assignment.
void set(vgl_point_3d< Type > const &p1, vgl_point_3d< Type > const &p2)
assignment.
double vgl_triangle_3d_aspect_ratio(const vgl_point_3d< double > &p0, const vgl_point_3d< double > &p1, const vgl_point_3d< double > &p2)
Compute the aspect ration of a triangle.
std::vector< std::pair< unsigned, unsigned > > vgl_triangle_3d_coincident_edges(const vgl_point_3d< double > &a_p1, const vgl_point_3d< double > &a_p2, const vgl_point_3d< double > &a_p3, const vgl_point_3d< double > &b_p1, const vgl_point_3d< double > &b_p2, const vgl_point_3d< double > &b_p3)
Check for coincident edges of triangles a and b.
double vgl_triangle_3d_distance(const vgl_point_3d< double > &q, const vgl_point_3d< double > &p1, const vgl_point_3d< double > &p2, const vgl_point_3d< double > &p3)
Compute the distance to the closest point on a triangle from a reference point.
bool vgl_triangle_3d_test_inside(const vgl_point_3d< double > &i_pnt, const vgl_point_3d< double > &p1, const vgl_point_3d< double > &p2, const vgl_point_3d< double > &p3, double coplanar_tolerance)
Check if the given point is inside the triangle.
vgl_point_3d< Type > point2() const
vgl_triangle_3d_intersection_t vgl_triangle_3d_triangle_intersection(const vgl_point_3d< double > &a_p1, const vgl_point_3d< double > &a_p2, const vgl_point_3d< double > &a_p3, const vgl_point_3d< double > &b_p1, const vgl_point_3d< double > &b_p2, const vgl_point_3d< double > &b_p3, vgl_line_segment_3d< double > &i_line, unsigned &i_line_point1_edge, unsigned &i_line_point2_edge)
Compute the intersection line of the given triangles.
vgl_vector_3d< T > normal() const
Return the normal direction, i.e., a unit vector orthogonal to this plane.
direction vector in Euclidean 3D space
void vgl_closest_point_to_linesegment(T &ret_x, T &ret_y, T x1, T y1, T x2, T y2, T x, T y)
Closest point to (x,y) on the line segment (x1,y1)-(x2,y2).
vgl_point_3d< double > vgl_triangle_3d_closest_point(const vgl_point_3d< double > &q, const vgl_point_3d< double > &p1, const vgl_point_3d< double > &p2, const vgl_point_3d< double > &p3)
Compute the closest point on a triangle to a reference point.
Represents a cartesian 3D point.
vgl_triangle_3d_intersection_t vgl_triangle_3d_line_intersection(const vgl_line_segment_3d< double > &line, const vgl_point_3d< double > &p1, const vgl_point_3d< double > &p2, const vgl_point_3d< double > &p3, vgl_point_3d< double > &i_pnt, bool ignore_coplanar)
Compute the intersection point between the line segment and triangle.
bool concurrent(l const &l1, l const &l2, l const &l3)
Are three lines concurrent, i.e., do they pass through a common point?.
bool vgl_triangle_3d_test_inside_simple(const vgl_point_3d< double > &i_pnt, const vgl_point_3d< double > &p1, const vgl_point_3d< double > &p2, const vgl_point_3d< double > &p3)
Check if point i_pnt is inside the triangle.
vgl_triangle_3d_intersection_t vgl_triangle_3d_plane_intersection(const vgl_point_3d< double > &p1, const vgl_point_3d< double > &p2, const vgl_point_3d< double > &p3, const vgl_plane_3d< double > &i_plane, vgl_line_segment_3d< double > &i_line)
Compute the line of intersection of the given triangle and plane.
double vgl_triangle_3d_longest_side(const vgl_point_3d< double > &p1, const vgl_point_3d< double > &p2, const vgl_point_3d< double > &p3)
Compute the longest side of the given triangle.
vgl_point_3d< T > vgl_intersection(const std::vector< vgl_plane_3d< T > > &p)
Return the intersection point of vector of planes.
double length(v const &a)
Return the length of a vector.
vgl_triangle_3d_intersection_t
A class to hold a non-homogeneous representation of a 3D line.
Set of closest-point functions.
bool collinear(l const &l1, vgl_homg_point_3d< Type > const &p)
Does a line pass through a point, i.e., are the point and the line collinear?.
a point in 3D nonhomogeneous space
vgl_point_2d< T > vgl_closest_point(vgl_line_2d< T > const &l, vgl_point_2d< T > const &p)
Return the point on the given line closest to the given point.
double length() const
Return the length of this vector.
T cross_product(v const &a, v const &b)
cross product of two vectors (area of enclosed parallellogram).
bool contains(const vgl_point_3d< Type > &p) const
Check if point p is on the line segment.
Represents a Euclidean 3D plane.
Represents a 3D line segment using two points.
T d() const
Return constant coefficient.
bool vgl_triangle_3d_triangle_coplanar(const vgl_point_3d< double > &a_p1, const vgl_point_3d< double > &a_p2, const vgl_point_3d< double > &a_p3, const vgl_point_3d< double > &b_p1, const vgl_point_3d< double > &b_p2, const vgl_point_3d< double > &b_p3)
Check if the two triangles are coplanar.
bool coplanar(l const &l1, l const &l2)
Are two lines coplanar, i.e., do they intersect?.
Direction vector in Euclidean 3D space, templated by type of element.
Some helpful functions when working with triangles.
void set(T vx, T vy, T vz)
Assignment.
double vgl_distance(vgl_point_2d< T >const &p1, vgl_point_2d< T >const &p2)
return the distance between two points.
void set(Type px, Type py, Type pz)
Set x, y and z.
a plane in 3D nonhomogeneous space
non-homogeneous 3D line, represented by 2 points.
Set of distance functions.
double vgl_triangle_3d_shortest_side(const vgl_point_3d< double > &p1, const vgl_point_3d< double > &p2, const vgl_point_3d< double > &p3)
Compute the shortest side of the given triangle.