00001 #include "vgl_triangle_3d.h"
00002
00003
00004
00005
00006
00007
00008 #include <vcl_limits.h>
00009 #include <vgl/vgl_distance.h>
00010 #include <vgl/vgl_intersection.h>
00011 #include <vgl/vgl_line_3d_2_points.h>
00012 #include <vgl/vgl_plane_3d.h>
00013 #include <vgl/vgl_point_3d.h>
00014 #include <vgl/vgl_vector_3d.h>
00015 #include <vgl/vgl_closest_point.h>
00016
00017
00018
00019 static const double vgl_nan = vcl_sqrt(-1.0);
00020 static const double sqrteps = vcl_sqrt(vcl_numeric_limits<double>::epsilon());
00021 static const double pi = 3.14159265358979323846;
00022
00023
00024
00025
00026 vcl_vector<vcl_pair<unsigned,unsigned> > vgl_triangle_3d_coincident_edges(
00027 const vgl_point_3d<double>& a_p1,
00028 const vgl_point_3d<double>& a_p2,
00029 const vgl_point_3d<double>& a_p3,
00030 const vgl_point_3d<double>& b_p1,
00031 const vgl_point_3d<double>& b_p2,
00032 const vgl_point_3d<double>& b_p3)
00033 {
00034 vcl_vector<vcl_pair<unsigned,unsigned> > coinc_edges;
00035
00036
00037 vgl_point_3d<double> a[3] = {a_p1, a_p2, a_p3};
00038 vgl_point_3d<double> b[3] = {b_p1, b_p2, b_p3};
00039 vcl_pair<unsigned,unsigned> e[3] = { vcl_make_pair(0,1),
00040 vcl_make_pair(1,2),
00041 vcl_make_pair(2,0) };
00042
00043
00044 for (unsigned j = 0; j < 3; ++j)
00045 {
00046 for (unsigned i = 0; i < 3; ++i)
00047 {
00048
00049
00050 double e1_len = length(a[e[j].first] - a[e[j].second]);
00051 double b1_dist = length(a[e[j].first] - b[e[i].first]) +
00052 length(a[e[j].second] - b[e[i].first]);
00053 double b2_dist = length(a[e[j].first] - b[e[i].second]) +
00054 length(a[e[j].second] - b[e[i].second]);
00055
00056 double e2_len = length(b[e[i].first] - b[e[i].second]);
00057 double a1_dist = length(b[e[i].first] - a[e[j].first]) +
00058 length(b[e[i].second] - a[e[j].first]);
00059 double a2_dist = length(b[e[i].first] - a[e[j].second]) +
00060 length(b[e[i].second] - a[e[j].second]);
00061
00062 if ((vcl_fabs(e1_len - b1_dist) < sqrteps &&
00063 vcl_fabs(e1_len - b2_dist) < sqrteps) ||
00064 (vcl_fabs(e2_len - a1_dist) < sqrteps &&
00065 vcl_fabs(e2_len - a2_dist) < sqrteps))
00066 {
00067 coinc_edges.push_back(vcl_make_pair(j,i));
00068 break;
00069 }
00070 }
00071 }
00072
00073 return coinc_edges;
00074 }
00075
00076
00077
00078
00079
00080 bool vgl_triangle_3d_test_inside(const vgl_point_3d<double>& i_pnt,
00081 const vgl_point_3d<double>& p1,
00082 const vgl_point_3d<double>& p2,
00083 const vgl_point_3d<double>& p3 )
00084 {
00085
00086 if (collinear(p1,p2,p3))
00087 {
00088
00089 if (p1==p2&&p2==p3&&p1==p3)
00090 {
00091 return i_pnt == p1;
00092 }
00093
00094 return vgl_line_segment_3d<double>(p1,p2).contains(i_pnt) ||
00095 vgl_line_segment_3d<double>(p2,p3).contains(i_pnt) ||
00096 vgl_line_segment_3d<double>(p1,p3).contains(i_pnt);
00097 }
00098
00099
00100
00101
00102
00103
00104 vgl_plane_3d<double> plane(p1,p2,p3);
00105
00106
00107 if (vcl_fabs(vgl_distance(plane,i_pnt)) > sqrteps)
00108 return false;
00109
00110 vgl_vector_3d<double> norm = plane.normal();
00111 norm.set(vcl_fabs(norm.x()),vcl_fabs(norm.y()),vcl_fabs(norm.z()));
00112
00113 unsigned i1 = 0;
00114 unsigned i2 = 1;
00115 if (norm.y()>=norm.x() && norm.y()>=norm.z())
00116 {
00117 i2 = 2;
00118 }
00119 else if (norm.x()>=norm.y() && norm.x()>=norm.z())
00120 {
00121 i1 = 2;
00122 }
00123
00124 double point[3] = {i_pnt.x(), i_pnt.y(), i_pnt.z()};
00125 double vert0[3] = {p1.x(), p1.y(), p1.z()};
00126 double vert1[3] = {p2.x(), p2.y(), p2.z()};
00127 double vert2[3] = {p3.x(), p3.y(), p3.z()};
00128
00129 double beta = 0.0;
00130 double alpha = 0.0;
00131
00132
00133 double u0 = (vcl_fabs(point[i1]) < sqrteps ? 0 : point[i1]) - (vcl_fabs(vert0[i1]) < sqrteps ? 0 : vert0[i1]);
00134 double v0 = (vcl_fabs(point[i2]) < sqrteps ? 0 : point[i2]) - (vcl_fabs(vert0[i2]) < sqrteps ? 0 : vert0[i2]);
00135
00136 double u1 = (vcl_fabs(vert1[i1]) < sqrteps ? 0 : vert1[i1]) - (vcl_fabs(vert0[i1]) < sqrteps ? 0 : vert0[i1]);
00137 double u2 = (vcl_fabs(vert2[i1]) < sqrteps ? 0 : vert2[i1]) - (vcl_fabs(vert0[i1]) < sqrteps ? 0 : vert0[i1]);
00138 double v1 = (vcl_fabs(vert1[i2]) < sqrteps ? 0 : vert1[i2]) - (vcl_fabs(vert0[i2]) < sqrteps ? 0 : vert0[i2]);
00139 double v2 = (vcl_fabs(vert2[i2]) < sqrteps ? 0 : vert2[i2]) - (vcl_fabs(vert0[i2]) < sqrteps ? 0 : vert0[i2]);
00140
00141
00142 if (u1 == 0)
00143 {
00144 beta = u0 / u2;
00145 if (beta < -sqrteps/*0*/ || beta > 1+sqrteps)
00146 return false;
00147 alpha = (v0 - beta * v2) / v1;
00148 }
00149 else
00150 {
00151 beta = (v0 * u1 - u0 * v1) / (v2 * u1 - u2 * v1);
00152 if (beta < -sqrteps/*0*/ || beta > 1+sqrteps)
00153 return false;
00154 alpha = (u0 - beta * u2) / u1;
00155 }
00156
00157 return alpha >= -sqrteps
00158 && alpha + beta <= 1.0+sqrteps;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167 bool vgl_triangle_3d_test_inside_simple(const vgl_point_3d<double>& i_pnt,
00168 const vgl_point_3d<double>& p1,
00169 const vgl_point_3d<double>& p2,
00170 const vgl_point_3d<double>& p3 )
00171 {
00172 vgl_vector_3d<double> vec1 = normalized(i_pnt - p1);
00173 vgl_vector_3d<double> vec2 = normalized(i_pnt - p2);
00174 vgl_vector_3d<double> vec3 = normalized(i_pnt - p3);
00175
00176 double int_ang = vcl_acos(dot_product(vec1,vec2)) + vcl_acos(dot_product(vec2,vec3)) + vcl_acos(dot_product(vec3,vec1));
00177 double test_val = vcl_fabs(int_ang-(2*pi));
00178
00179 return test_val < sqrteps;
00180 }
00181
00182
00183
00184
00185 static vgl_triangle_3d_intersection_t same_side(
00186 const vgl_point_3d<double>& A,
00187 const vgl_point_3d<double>& B,
00188 const vgl_point_3d<double>& C,
00189 const vgl_point_3d<double>& D,
00190 const vgl_point_3d<double>& E)
00191 {
00192 vgl_vector_3d<double> b = B - A;
00193 vgl_vector_3d<double> c = C - A;
00194
00195 vgl_vector_3d<double> n = cross_product(b, c);
00196
00197 vgl_vector_3d<double> d = D - A;
00198 double d_dot = dot_product(d, n);
00199 vgl_vector_3d<double> e = E - A;
00200 double e_dot = dot_product(e, n);
00201
00202 if (vcl_abs(d_dot) < vcl_sqrt(
00203 vcl_numeric_limits<double>::epsilon()) *
00204 vcl_max(1.0e-100, vcl_max(vcl_sqrt(A.x()*A.x()+A.y()*A.y()+A.z()*A.z()),
00205 vcl_sqrt(D.x()*D.x()+D.y()*D.y()+D.z()*D.z()) ) ) )
00206 {
00207 return Coplanar;
00208 }
00209
00210 if (d_dot * e_dot >= 0)
00211 return Skew;
00212 else
00213 return None;
00214 }
00215
00216
00217
00218
00219
00220
00221 vgl_triangle_3d_intersection_t vgl_triangle_3d_line_intersection(
00222 const vgl_line_segment_3d<double>& line,
00223 const vgl_point_3d<double>& p1,
00224 const vgl_point_3d<double>& p2,
00225 const vgl_point_3d<double>& p3,
00226 vgl_point_3d<double>& i_pnt,
00227 bool ignore_coplanar)
00228 {
00229 vgl_point_3d<double> line_p1 = line.point1();
00230 vgl_point_3d<double> line_p2 = line.point2();
00231
00232
00233 if (line_p1 == line_p2)
00234 {
00235 if (!ignore_coplanar && vgl_triangle_3d_test_inside(line_p1,p1,p2,p3))
00236 return Coplanar;
00237
00238 return None;
00239 }
00240
00241 if (collinear(p1,p2,p3))
00242 {
00243 if (p1==p2&&p2==p3&&p1==p3)
00244 {
00245 return !ignore_coplanar && line.contains(p1) ? Coplanar : None;
00246 }
00247
00248 vgl_line_3d_2_points<double> i_line(line_p1,line_p2);
00249 if ( !ignore_coplanar && (
00250 ( p1!=p2 && concurrent(vgl_line_3d_2_points<double>(p1,p2), i_line) &&
00251 vgl_intersection(line,vgl_line_segment_3d<double>(p1,p2),i_pnt) ) ||
00252 ( p2!=p3 && concurrent(vgl_line_3d_2_points<double>(p2,p3), i_line) &&
00253 vgl_intersection(line,vgl_line_segment_3d<double>(p2,p3),i_pnt) ) ||
00254 ( p1!=p3 && concurrent(vgl_line_3d_2_points<double>(p1,p3), i_line) &&
00255 vgl_intersection(line,vgl_line_segment_3d<double>(p1,p3),i_pnt) ) ) )
00256 {
00257 return Coplanar;
00258 }
00259
00260 return None;
00261 }
00262
00263 vgl_triangle_3d_intersection_t rv1 = same_side(line.point1(), p1, p2, p3, line.point2());
00264 if (rv1 == None) return None;
00265
00266 vgl_triangle_3d_intersection_t rv2 = same_side(line.point1(), p2, p3, p1, line.point2());
00267 if (rv2 == None) return None;
00268
00269 vgl_triangle_3d_intersection_t rv3 = same_side(line.point1(), p3, p1, p2, line.point2());
00270 if (rv3 == None) return None;
00271
00272 if (rv1 == Coplanar || rv2 == Coplanar || rv3==Coplanar)
00273 {
00274 if (ignore_coplanar)
00275 return None;
00276
00277
00278
00279
00280 vgl_line_3d_2_points<double> i_line(line_p1,line_p2);
00281 vgl_line_segment_3d<double> edge1(p1,p2);
00282
00283 vgl_point_3d<double> test_pt;
00284 if (concurrent(vgl_line_3d_2_points<double>(p1,p2),i_line) &&
00285 vgl_intersection(edge1,line,test_pt))
00286 {
00287 i_pnt = test_pt;
00288 return Coplanar;
00289 }
00290 vgl_line_segment_3d<double> edge2(p1,p3);
00291 if (concurrent(vgl_line_3d_2_points<double>(p1,p3),i_line) &&
00292 vgl_intersection(edge2,line,test_pt))
00293 {
00294 i_pnt = test_pt;
00295 return Coplanar;
00296 }
00297 vgl_line_segment_3d<double> edge3(p2,p3);
00298 if (concurrent(vgl_line_3d_2_points<double>(p2,p3),i_line) &&
00299 vgl_intersection(edge3,line,test_pt))
00300 {
00301 i_pnt = test_pt;
00302 return Coplanar;
00303 }
00304
00305
00306 if (vgl_triangle_3d_test_inside(line_p2, p1, p2, p3))
00307 {
00308 i_pnt.set(vgl_nan, vgl_nan, vgl_nan);
00309 return Coplanar;
00310 }
00311
00312 return None;
00313 }
00314
00315 if (same_side(p1, p2, p3, line_p1, line_p2) == Skew)
00316 return None;
00317
00318 i_pnt = vgl_intersection(vgl_line_3d_2_points<double>(line_p1, line_p2),
00319 vgl_plane_3d<double>(p1, p2, p3) );
00320 return Skew;
00321 }
00322
00323
00324
00325
00326
00327 vgl_triangle_3d_intersection_t vgl_triangle_3d_triangle_intersection(
00328 const vgl_point_3d<double>& a_p1,
00329 const vgl_point_3d<double>& a_p2,
00330 const vgl_point_3d<double>& a_p3,
00331 const vgl_point_3d<double>& b_p1,
00332 const vgl_point_3d<double>& b_p2,
00333 const vgl_point_3d<double>& b_p3,
00334 vgl_line_segment_3d<double>& i_line)
00335 {
00336
00337
00338
00339
00340 if (collinear(a_p1,a_p2,a_p3))
00341 {
00342 if (a_p1 == a_p2 && a_p2==a_p3 && a_p1 == a_p3)
00343 {
00344 if (vgl_triangle_3d_test_inside(a_p1,b_p1,b_p2,b_p3))
00345 {
00346 i_line.set(a_p1,a_p1);
00347 return Coplanar;
00348 }
00349 return None;
00350 }
00351
00352 vgl_triangle_3d_intersection_t ret = None;
00353 vgl_point_3d<double> i_pnt;
00354 if ( ( a_p1 != a_p2 && (ret = vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(a_p1,a_p2), b_p1,b_p2,b_p3,i_pnt)) != None ) ||
00355 ( a_p2 != a_p3 && (ret = vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(a_p2,a_p3), b_p1,b_p2,b_p3,i_pnt)) != None ) ||
00356 ( a_p1 != a_p3 && (ret = vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(a_p1,a_p3), b_p1,b_p2,b_p3,i_pnt)) != None ) )
00357 {
00358 i_line.set(i_pnt,i_pnt);
00359 return ret;
00360 }
00361
00362 return None;
00363 }
00364 if (collinear(b_p1,b_p2,b_p3))
00365 {
00366 if (b_p1 == b_p2 && b_p2==b_p3 && b_p1 == b_p3)
00367 {
00368 if (vgl_triangle_3d_test_inside(b_p1,a_p1,a_p2,a_p3))
00369 {
00370 i_line.set(b_p1,b_p1);
00371 return Coplanar;
00372 }
00373 return None;
00374 }
00375
00376 vgl_triangle_3d_intersection_t ret = None;
00377 vgl_point_3d<double> i_pnt;
00378 if ( ( b_p1 != b_p2 && (ret = vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(b_p1,b_p2), a_p1,a_p2,a_p3,i_pnt)) != None ) ||
00379 ( b_p2 != b_p3 && (ret = vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(b_p2,b_p3), a_p1,a_p2,a_p3,i_pnt)) != None ) ||
00380 ( b_p1 != b_p3 && (ret = vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(b_p1,b_p3), a_p1,a_p2,a_p3,i_pnt)) != None ) )
00381 {
00382 i_line.set(i_pnt,i_pnt);
00383 return ret;
00384 }
00385
00386 return None;
00387 }
00388
00389
00390 vgl_vector_3d<double> edge1,edge2;
00391 vgl_vector_3d<double> a_norm, b_norm, int_line;
00392
00393 double a_d, b_d;
00394 double d_b[3], d_a[3];
00395 double isect1[2], isect2[2];
00396 double d_b1d_b2, d_b1d_b3, d_a1d_a2, d_a1d_a3;
00397
00398 double p_a[3];
00399 double p_b[3];
00400 bool coplanar = false;
00401
00402 double TRI_TRI_EPS = 1000000*vcl_numeric_limits<double>::epsilon();
00403
00404
00405
00406
00407
00408 edge1 = a_p2 - a_p1;
00409 edge2 = a_p3 - a_p1;
00410
00411 a_norm = normalized(cross_product(edge1, edge2));
00412 a_d = -( a_norm.x()*a_p1.x() + a_norm.y()*a_p1.y() +a_norm.z()*a_p1.z() );
00413
00414
00415
00416 d_b[0] = ( a_norm.x()*b_p1.x() + a_norm.y()*b_p1.y() + a_norm.z()*b_p1.z() ) + a_d;
00417 d_b[1] = ( a_norm.x()*b_p2.x() + a_norm.y()*b_p2.y() + a_norm.z()*b_p2.z() ) + a_d;
00418 d_b[2] = ( a_norm.x()*b_p3.x() + a_norm.y()*b_p3.y() + a_norm.z()*b_p3.z() ) + a_d;
00419 #if 0
00420 d_b[0] = (a_plane.nx()*b_p1.x() + a_plane.ny()*b_p1.y() + a_plane.nz()*b_p1.z() ) + a_plane.d();
00421 d_b[1] = (a_plane.nx()*b_p2.x() + a_plane.ny()*b_p2.y() + a_plane.nz()*b_p2.z() ) + a_plane.d();
00422 d_b[2] = (a_plane.nx()*b_p3.x() + a_plane.ny()*b_p3.y() + a_plane.nz()*b_p3.z() ) + a_plane.d();
00423 #endif // 0
00424
00425
00426 if (vcl_fabs(d_b[0]) < TRI_TRI_EPS) d_b[0] = 0.0;
00427 if (vcl_fabs(d_b[1]) < TRI_TRI_EPS) d_b[1] = 0.0;
00428 if (vcl_fabs(d_b[2]) < TRI_TRI_EPS) d_b[2] = 0.0;
00429
00430 d_b1d_b2 = d_b[0]*d_b[1];
00431 d_b1d_b3 = d_b[0]*d_b[2];
00432
00433
00434 if (d_b1d_b2 > 0 && d_b1d_b3 > 0)
00435 {
00436 return None;
00437 }
00438
00439
00440 edge1 = b_p2 - b_p1;
00441 edge2 = b_p3 - b_p1;
00442
00443 b_norm = normalized(cross_product(edge1,edge2));
00444 b_d = -( b_norm.x()*b_p1.x() + b_norm.y()*b_p1.y() + b_norm.z()*b_p1.z() );
00445
00446
00447
00448 d_a[0] = ( b_norm.x()*a_p1.x() + b_norm.y()*a_p1.y() + b_norm.z()*a_p1.z() ) + b_d;
00449 d_a[1] = ( b_norm.x()*a_p2.x() + b_norm.y()*a_p2.y() + b_norm.z()*a_p2.z() ) + b_d;
00450 d_a[2] = ( b_norm.x()*a_p3.x() + b_norm.y()*a_p3.y() + b_norm.z()*a_p3.z() ) + b_d;
00451 #if 0
00452 d_a[0] = (b_plane.nx()*a_p1.x() + b_plane.ny()*a_p1.y() + b_plane.nz()*a_p1.z() ) + b_plane.d();
00453 d_a[1] = (b_plane.nx()*a_p2.x() + b_plane.ny()*a_p2.y() + b_plane.nz()*a_p2.z() ) + b_plane.d();
00454 d_a[2] = (b_plane.nx()*a_p3.x() + b_plane.ny()*a_p3.y() + b_plane.nz()*a_p3.z() ) + b_plane.d();
00455 #endif // 0
00456
00457
00458 if (vcl_fabs(d_a[0]) < TRI_TRI_EPS) d_a[0] = 0.0;
00459 if (vcl_fabs(d_a[1]) < TRI_TRI_EPS) d_a[1] = 0.0;
00460 if (vcl_fabs(d_a[2]) < TRI_TRI_EPS) d_a[2] = 0.0;
00461
00462 d_a1d_a2 = d_a[0]*d_a[1];
00463 d_a1d_a3 = d_a[0]*d_a[2];
00464
00465
00466 if (d_a1d_a2 > 0 && d_a1d_a3 > 0)
00467 {
00468 return None;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477 int_line = cross_product(a_norm,b_norm);
00478
00479
00480
00481
00482 int_line.set(vcl_fabs(int_line.x()),vcl_fabs(int_line.y()),vcl_fabs(int_line.z()));
00483
00484 if (int_line.y()>=int_line.x() && int_line.y()>=int_line.z())
00485 {
00486 p_a[0] = a_p1.y();
00487 p_a[1] = a_p2.y();
00488 p_a[2] = a_p3.y();
00489
00490 p_b[0] = b_p1.y();
00491 p_b[1] = b_p2.y();
00492 p_b[2] = b_p3.y();
00493 }
00494 else if (int_line.x()>=int_line.y() && int_line.x()>=int_line.z())
00495 {
00496 p_a[0] = a_p1.x();
00497 p_a[1] = a_p2.x();
00498 p_a[2] = a_p3.x();
00499
00500 p_b[0] = b_p1.x();
00501 p_b[1] = b_p2.x();
00502 p_b[2] = b_p3.x();
00503 }
00504 else {
00505 p_a[0] = a_p1.z();
00506 p_a[1] = a_p2.z();
00507 p_a[2] = a_p3.z();
00508
00509 p_b[0] = b_p1.z();
00510 p_b[1] = b_p2.z();
00511 p_b[2] = b_p3.z();
00512 }
00513
00514 int a_ival[3] = {0,1,2};
00515
00516 if (d_a1d_a2 > 0)
00517 {
00518 a_ival[0] = 2;
00519 a_ival[1] = 0;
00520 a_ival[2] = 1;
00521 }
00522 else if (d_a1d_a3 > 0)
00523 {
00524 a_ival[0] = 1;
00525 a_ival[1] = 0;
00526 a_ival[2] = 2;
00527 }
00528 else if (d_a[1]*d_a[2] > 0 || d_a[0] != 0)
00529 {
00530 a_ival[0] = 0;
00531 a_ival[1] = 1;
00532 a_ival[2] = 2;
00533 }
00534 else if (d_a[1] != 0)
00535 {
00536 a_ival[0] = 1;
00537 a_ival[1] = 0;
00538 a_ival[2] = 2;
00539 }
00540 else if (d_a[2] != 0)
00541 {
00542 a_ival[0] = 2;
00543 a_ival[1] = 0;
00544 a_ival[2] = 1;
00545 }
00546 else
00547 {
00548
00549 coplanar = true;
00550 }
00551
00552 int b_ival[3] = {0,1,2};
00553 if (!coplanar)
00554 {
00555
00556 if (d_b1d_b2 > 0)
00557 {
00558 b_ival[0] = 2;
00559 b_ival[1] = 0;
00560 b_ival[2] = 1;
00561 }
00562 else if (d_b1d_b3 > 0)
00563 {
00564 b_ival[0] = 1;
00565 b_ival[1] = 0;
00566 b_ival[2] = 2;
00567 }
00568 else if (d_b[1]*d_b[2] > 0 || d_b[0] != 0)
00569 {
00570 b_ival[0] = 0;
00571 b_ival[1] = 1;
00572 b_ival[2] = 2;
00573 }
00574 else if (d_b[1] != 0)
00575 {
00576 b_ival[0] = 1;
00577 b_ival[1] = 0;
00578 b_ival[2] = 2;
00579 }
00580 else if (d_b[2] != 0)
00581 {
00582 b_ival[0] = 2;
00583 b_ival[1] = 0;
00584 b_ival[2] = 1;
00585 }
00586 else
00587 {
00588 coplanar = true;
00589 }
00590 }
00591
00592
00593 if (coplanar)
00594 {
00595
00596 vgl_point_3d<double> i_pnt1, i_pnt2, i_pnt3;
00597 bool isect1 = vgl_triangle_3d_line_intersection(
00598 vgl_line_segment_3d<double>(a_p1,a_p2), b_p1, b_p2, b_p3, i_pnt1) != None;
00599 bool isect2 = vgl_triangle_3d_line_intersection(
00600 vgl_line_segment_3d<double>(a_p2,a_p3), b_p1, b_p2, b_p3, i_pnt2) != None;
00601 bool isect3 = vgl_triangle_3d_line_intersection(
00602 vgl_line_segment_3d<double>(a_p3,a_p1), b_p1, b_p2, b_p3, i_pnt3) != None;
00603
00604 if ( isect1 || isect2 || isect3 )
00605 {
00606 i_line.set( isect1 ? i_pnt1 : (isect2 ? i_pnt2 : i_pnt3),
00607 isect1 && isect2 ? i_pnt2 : (isect1 || isect2) && isect3 ? i_pnt3 :
00608 (isect1 ? i_pnt1 : (isect2 ? i_pnt2 : i_pnt3)) );
00609 return Coplanar;
00610 }
00611
00612
00613 if (vgl_triangle_3d_test_inside(a_p1, b_p1, b_p2, b_p3) ||
00614 vgl_triangle_3d_test_inside(b_p1, a_p1, a_p2, a_p3))
00615 {
00616 i_line.set(vgl_point_3d<double> (vgl_nan, vgl_nan, vgl_nan),vgl_point_3d<double> (vgl_nan,vgl_nan,vgl_nan));
00617 return Coplanar;
00618 }
00619
00620 return None;
00621 }
00622
00623 vgl_point_3d<double> i_pnts[4];
00624
00625 double tmp = d_a[a_ival[0]]/(d_a[a_ival[0]]-d_a[a_ival[1]]);
00626 isect1[0] = p_a[a_ival[0]] + (p_a[a_ival[1]] - p_a[a_ival[0]])*tmp;
00627 vgl_point_3d<double> a_vs[] = {a_p1,a_p2,a_p3};
00628 vgl_vector_3d<double> diff = a_vs[a_ival[1]] - a_vs[a_ival[0]];
00629 diff *= tmp;
00630 i_pnts[0] = a_vs[a_ival[0]] + diff ;
00631
00632 tmp = d_a[a_ival[0]]/(d_a[a_ival[0]]-d_a[a_ival[2]]);
00633 isect1[1] = p_a[a_ival[0]] + (p_a[a_ival[2]] - p_a[a_ival[0]])*tmp;
00634 diff = a_vs[a_ival[2]] - a_vs[a_ival[0]];
00635 diff *= tmp;
00636 i_pnts[1] = a_vs[a_ival[0]] + diff;
00637
00638
00639 tmp = d_b[b_ival[0]]/(d_b[b_ival[0]] - d_b[b_ival[1]]);
00640 isect2[0] = p_b[b_ival[0]] + (p_b[b_ival[1]] - p_b[b_ival[0]])*tmp;
00641 vgl_point_3d<double> b_vs[] = {b_p1,b_p2,b_p3};
00642 diff = b_vs[b_ival[1]] - b_vs[b_ival[0]];
00643 diff *= tmp;
00644 i_pnts[2] = b_vs[b_ival[0]] + diff ;
00645
00646 tmp = d_b[b_ival[0]]/(d_b[b_ival[0]]-d_b[b_ival[2]]);
00647 isect2[1] = p_b[b_ival[0]] + (p_b[b_ival[2]] - p_b[b_ival[0]])*tmp;
00648 diff = b_vs[b_ival[2]] - b_vs[b_ival[0]];
00649 diff *= tmp;
00650 i_pnts[3] = b_vs[b_ival[0]] + diff;
00651
00652 unsigned smallest1 = 0;
00653 if (isect1[0] > isect1[1])
00654 {
00655 tmp = isect1[0];
00656 isect1[0]= isect1[1];
00657 isect1[1] = tmp;
00658 smallest1 = 1;
00659 }
00660 unsigned smallest2 = 0;
00661 if (isect2[0] > isect2[1])
00662 {
00663 tmp = isect2[0];
00664 isect2[0]= isect2[1];
00665 isect2[1] = tmp;
00666 smallest2 = 1;
00667 }
00668
00669 if (isect1[1] < isect2[0] || isect2[1] < isect1[0])
00670 {
00671 return None;
00672 }
00673
00674 unsigned i_pt1,i_pt2;
00675
00676 if (isect2[0]<isect1[0])
00677 {
00678 if (smallest1==0)
00679 {
00680 i_pt1 = 0;
00681 }
00682 else
00683 {
00684 i_pt1 = 1;
00685 }
00686
00687 if (isect2[1]<isect1[1])
00688 {
00689 if (smallest2==0)
00690 {
00691 i_pt2 = 3;
00692 }
00693 else
00694 {
00695 i_pt2 = 2;
00696 }
00697 }
00698 else
00699 {
00700 if (smallest1==0)
00701 {
00702 i_pt2 = 1;
00703 }
00704 else
00705 {
00706 i_pt2 = 0;
00707 }
00708 }
00709 }
00710 else
00711 {
00712 if (smallest2==0)
00713 {
00714 i_pt1 = 2;
00715 }
00716 else
00717 {
00718 i_pt1 = 3;
00719 }
00720
00721 if (isect2[1]>isect1[1])
00722 {
00723 if (smallest1==0)
00724 {
00725 i_pt2 = 1;
00726 }
00727 else
00728 {
00729 i_pt2 = 0;
00730 }
00731 }
00732 else
00733 {
00734 if (smallest2==0)
00735 {
00736 i_pt2 = 3;
00737 }
00738 else
00739 {
00740 i_pt2 = 2;
00741 }
00742 }
00743 }
00744
00745 i_line.set(i_pnts[i_pt1],i_pnts[i_pt2]);
00746 return Skew;
00747 }
00748
00749
00750
00751
00752
00753
00754 vgl_triangle_3d_intersection_t vgl_triangle_3d_triangle_intersection(
00755 const vgl_point_3d<double>& a_p1,
00756 const vgl_point_3d<double>& a_p2,
00757 const vgl_point_3d<double>& a_p3,
00758 const vgl_point_3d<double>& b_p1,
00759 const vgl_point_3d<double>& b_p2,
00760 const vgl_point_3d<double>& b_p3)
00761 {
00762
00763
00764
00765
00766 if (collinear(a_p1,a_p2,a_p3))
00767 {
00768 if (a_p1 == a_p2 && a_p2==a_p3 && a_p1 == a_p3)
00769 {
00770 if (vgl_triangle_3d_test_inside(a_p1,b_p1,b_p2,b_p3))
00771 return Coplanar;
00772 return None;
00773 }
00774
00775 vgl_triangle_3d_intersection_t ret = None;
00776 vgl_point_3d<double> i_pnt;
00777 if ( ( a_p1 != a_p2 && (ret = vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(a_p1,a_p2), b_p1,b_p2,b_p3,i_pnt)) != None ) ||
00778 ( a_p2 != a_p3 && (ret = vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(a_p2,a_p3), b_p1,b_p2,b_p3,i_pnt)) != None ) ||
00779 ( a_p1 != a_p3 && (ret = vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(a_p1,a_p3), b_p1,b_p2,b_p3,i_pnt)) != None ) )
00780 return ret;
00781
00782 return None;
00783 }
00784 if (collinear(b_p1,b_p2,b_p3))
00785 {
00786 if (b_p1 == b_p2 && b_p2==b_p3 && b_p1 == b_p3)
00787 {
00788 if (vgl_triangle_3d_test_inside(b_p1,a_p1,a_p2,a_p3))
00789 return Coplanar;
00790 return None;
00791 }
00792
00793 vgl_triangle_3d_intersection_t ret = None;
00794 vgl_point_3d<double> i_pnt;
00795 if ( ( b_p1 != b_p2 && (ret = vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(b_p1,b_p2), a_p1,a_p2,a_p3,i_pnt)) != None ) ||
00796 ( b_p2 != b_p3 && (ret = vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(b_p2,b_p3), a_p1,a_p2,a_p3,i_pnt)) != None ) ||
00797 ( b_p1 != b_p3 && (ret = vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(b_p1,b_p3), a_p1,a_p2,a_p3,i_pnt)) != None ) )
00798 return ret;
00799
00800 return None;
00801 }
00802
00803
00804
00805 vgl_vector_3d<double> edge1,edge2;
00806 vgl_vector_3d<double> a_norm, b_norm, int_line;
00807
00808
00809 double a_d, b_d;
00810 double d_b1, d_b2, d_b3, d_a1, d_a2, d_a3;
00811 double isect1[2], isect2[2];
00812 double d_b1d_b2, d_b1d_b3, d_a1d_a2, d_a1d_a3;
00813
00814 double p_a1, p_a2, p_a3;
00815 double p_b1, p_b2, p_b3;
00816 bool coplanar = false;
00817
00818 double a, b, c, x0, x1;
00819 double d, e, f, y0, y1;
00820 double xx, yy, xxyy, tmp;
00821 double TRI_TRI_EPS = 100000*vcl_numeric_limits<double>::epsilon();
00822
00823
00824
00825
00826
00827 edge1 = a_p2 - a_p1;
00828 edge2 = a_p3 - a_p1;
00829
00830 a_norm = normalized(cross_product(edge1, edge2));
00831
00832 a_d = -( a_norm.x()*a_p1.x() + a_norm.y()*a_p1.y() +a_norm.z()*a_p1.z() );
00833
00834
00835
00836 d_b1 = ( a_norm.x()*b_p1.x() + a_norm.y()*b_p1.y() + a_norm.z()*b_p1.z() ) + a_d;
00837 d_b2 = ( a_norm.x()*b_p2.x() + a_norm.y()*b_p2.y() + a_norm.z()*b_p2.z() ) + a_d;
00838 d_b3 = ( a_norm.x()*b_p3.x() + a_norm.y()*b_p3.y() + a_norm.z()*b_p3.z() ) + a_d;
00839 #if 0
00840 d_b1 = (a_plane.nx()*b_p1.x() + a_plane.ny()*b_p1.y() + a_plane.nz()*b_p1.z() ) + a_plane.d();
00841 d_b2 = (a_plane.nx()*b_p2.x() + a_plane.ny()*b_p2.y() + a_plane.nz()*b_p2.z() ) + a_plane.d();
00842 d_b3 = (a_plane.nx()*b_p3.x() + a_plane.ny()*b_p3.y() + a_plane.nz()*b_p3.z() ) + a_plane.d();
00843 #endif // 0
00844
00845
00846 if (vcl_fabs(d_b1) < TRI_TRI_EPS) d_b1 = 0.0;
00847 if (vcl_fabs(d_b2) < TRI_TRI_EPS) d_b2 = 0.0;
00848 if (vcl_fabs(d_b3) < TRI_TRI_EPS) d_b3 = 0.0;
00849
00850 d_b1d_b2 = d_b1*d_b2;
00851 d_b1d_b3 = d_b1*d_b3;
00852
00853
00854 if (d_b1d_b2 > 0 && d_b1d_b3 > 0)
00855 {
00856 return None;
00857 }
00858
00859
00860 edge1 = b_p2 - b_p1;
00861 edge2 = b_p3 - b_p1;
00862
00863 b_norm = normalized(cross_product(edge1,edge2));
00864
00865 b_d = -( b_norm.x()*b_p1.x() + b_norm.y()*b_p1.y() + b_norm.z()*b_p1.z() );
00866
00867
00868
00869 d_a1 = ( b_norm.x()*a_p1.x() + b_norm.y()*a_p1.y() + b_norm.z()*a_p1.z() ) + b_d;
00870 d_a2 = ( b_norm.x()*a_p2.x() + b_norm.y()*a_p2.y() + b_norm.z()*a_p2.z() ) + b_d;
00871 d_a3 = ( b_norm.x()*a_p3.x() + b_norm.y()*a_p3.y() + b_norm.z()*a_p3.z() ) + b_d;
00872 #if 0
00873 d_a1 = (b_plane.nx()*a_p1.x() + b_plane.ny()*a_p1.y() + b_plane.nz()*a_p1.z() ) + b_plane.d();
00874 d_a2 = (b_plane.nx()*a_p2.x() + b_plane.ny()*a_p2.y() + b_plane.nz()*a_p2.z() ) + b_plane.d();
00875 d_a3 = (b_plane.nx()*a_p3.x() + b_plane.ny()*a_p3.y() + b_plane.nz()*a_p3.z() ) + b_plane.d();
00876 #endif // 0
00877
00878
00879 if (vcl_fabs(d_a1) < TRI_TRI_EPS) d_a1 = 0.0;
00880 if (vcl_fabs(d_a2) < TRI_TRI_EPS) d_a2 = 0.0;
00881 if (vcl_fabs(d_a3) < TRI_TRI_EPS) d_a3 = 0.0;
00882
00883 d_a1d_a2 = d_a1*d_a2;
00884 d_a1d_a3 = d_a1*d_a3;
00885
00886
00887 if (d_a1d_a2 > 0 && d_a1d_a3 > 0)
00888 {
00889 return None;
00890 }
00891
00892
00893
00894
00895
00896
00897
00898 int_line = cross_product(a_norm,b_norm);
00899
00900
00901
00902
00903 int_line.set(vcl_fabs(int_line.x()),vcl_fabs(int_line.y()),vcl_fabs(int_line.z()));
00904
00905 if (int_line.y()>=int_line.x() && int_line.y()>=int_line.z())
00906 {
00907 p_a1 = a_p1.y();
00908 p_a2 = a_p2.y();
00909 p_a3 = a_p3.y();
00910
00911 p_b1 = b_p1.y();
00912 p_b2 = b_p2.y();
00913 p_b3 = b_p3.y();
00914 }
00915 else if (int_line.x()>=int_line.y() && int_line.x()>=int_line.z())
00916 {
00917 p_a1 = a_p1.x();
00918 p_a2 = a_p2.x();
00919 p_a3 = a_p3.x();
00920
00921 p_b1 = b_p1.x();
00922 p_b2 = b_p2.x();
00923 p_b3 = b_p3.x();
00924 }
00925 else {
00926 p_a1 = a_p1.z();
00927 p_a2 = a_p2.z();
00928 p_a3 = a_p3.z();
00929
00930 p_b1 = b_p1.z();
00931 p_b2 = b_p2.z();
00932 p_b3 = b_p3.z();
00933 }
00934
00935
00936 if (d_a1d_a2 > 0)
00937 {
00938 a = p_a3;
00939 b = (p_a1-p_a3)*d_a3;
00940 c = (p_a2-p_a3)*d_a3;
00941
00942 x0 = d_a3-d_a1;
00943 x1 = d_a3-d_a2;
00944 }
00945 else if (d_a1d_a3 > 0)
00946 {
00947 a = p_a2;
00948 b = (p_a1-p_a2)*d_a2;
00949 c = (p_a3-p_a2)*d_a2;
00950
00951 x0 = d_a2-d_a1;
00952 x1 = d_a2-d_a3;
00953 }
00954 else if (d_a2*d_a3 > 0 || d_a1 != 0)
00955 {
00956 a = p_a1;
00957 b = (p_a2-p_a1)*d_a1;
00958 c = (p_a3-p_a1)*d_a1;
00959
00960 x0 = d_a1-d_a2;
00961 x1 = d_a1-d_a3;
00962 }
00963 else if (d_a2 != 0)
00964 {
00965 a = p_a2;
00966 b = (p_a1-p_a2)*d_a2;
00967 c = (p_a3-p_a2)*d_a2;
00968
00969 x0 = d_a2-d_a1;
00970 x1 = d_a2-d_a3;
00971 }
00972 else if (d_a3 != 0)
00973 {
00974 a = p_a3;
00975 b = (p_a1-p_a3)*d_a3;
00976 c = (p_a2-p_a3)*d_a3;
00977
00978 x0 = d_a3-d_a1;
00979 x1 = d_a3-d_a2;
00980 }
00981 else
00982 {
00983
00984 coplanar = true;
00985 }
00986
00987 if (!coplanar)
00988 {
00989
00990 if (d_b1d_b2 > 0)
00991 {
00992 d = p_b3;
00993 e = (p_b1-p_b3)*d_b3;
00994 f = (p_b2-p_b3)*d_b3;
00995
00996 y0 = d_b3-d_b1;
00997 y1 = d_b3-d_b2;
00998 }
00999 else if (d_b1d_b3 > 0)
01000 {
01001 d = p_b2;
01002 e=(p_b1-p_b2)*d_b2;
01003 f=(p_b3-p_b2)*d_b2;
01004
01005 y0=d_b2-d_b1;
01006 y1=d_b2-d_b3;
01007 }
01008 else if (d_b2*d_b3 > 0 || d_b1 != 0)
01009 {
01010 d = p_b1;
01011 e = (p_b2-p_b1)*d_b1;
01012 f = (p_b3-p_b1)*d_b1;
01013
01014 y0 = d_b1-d_b2;
01015 y1 = d_b1-d_b3;
01016 }
01017 else if (d_b2 != 0)
01018 {
01019 d = p_b2;
01020 e = (p_b1-p_b2)*d_b2;
01021 f = (p_b3-p_b2)*d_b2;
01022
01023 y0 = d_b2-d_b1;
01024 y1 = d_b2-d_b3;
01025 }
01026 else if (d_b3 != 0)
01027 {
01028 d = p_b3;
01029 e = (p_b1-p_b3)*d_b3;
01030 f = (p_b2-p_b3)*d_b3;
01031
01032 y0 = d_b3-d_b1;
01033 y1 = d_b3-d_b2;
01034 }
01035 else
01036 {
01037 coplanar = true;
01038 }
01039 }
01040
01041
01042 if (coplanar)
01043 {
01044
01045 vgl_point_3d<double> i_pnt;
01046 if (vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(a_p1,a_p2), b_p1, b_p2, b_p3, i_pnt) ||
01047 vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(a_p2,a_p3), b_p1, b_p2, b_p3, i_pnt) ||
01048 vgl_triangle_3d_line_intersection(vgl_line_segment_3d<double>(a_p3,a_p1), b_p1, b_p2, b_p3, i_pnt) )
01049 {
01050 return Coplanar;
01051 }
01052
01053
01054 if (vgl_triangle_3d_test_inside(a_p1, b_p1, b_p2, b_p3) ||
01055 vgl_triangle_3d_test_inside(b_p1, a_p1, a_p2, a_p3))
01056 {
01057 return Coplanar;
01058 }
01059
01060 return None;
01061 }
01062
01063
01064
01065 xx = x0*x1;
01066 yy = y0*y1;
01067 xxyy = xx*yy;
01068
01069 tmp = a*xxyy;
01070 isect1[0] = tmp+b*x1*yy;
01071 isect1[1] = tmp+c*x0*yy;
01072
01073 tmp = d*xxyy;
01074 isect2[0] = tmp+e*xx*y1;
01075 isect2[1] = tmp+f*xx*y0;
01076
01077 if (isect1[0] > isect1[1])
01078 {
01079 tmp = isect1[0];
01080 isect1[0] = isect1[1];
01081 isect1[1] = tmp;
01082 }
01083
01084 if (isect2[0] > isect2[1])
01085 {
01086 tmp = isect2[0];
01087 isect2[0] = isect2[1];
01088 isect2[1] = tmp;
01089 }
01090
01091 if (isect1[1] < isect2[0] || isect2[1] < isect1[0])
01092 {
01093 return None;
01094 }
01095
01096 return Skew;
01097 }
01098
01099
01100
01101
01102
01103
01104 vgl_triangle_3d_intersection_t vgl_triangle_3d_plane_intersection(
01105 const vgl_point_3d<double>& p1,
01106 const vgl_point_3d<double>& p2,
01107 const vgl_point_3d<double>& p3,
01108 const vgl_plane_3d<double>& i_plane,
01109 vgl_line_segment_3d<double>& i_line)
01110 {
01111
01112
01113
01114
01115 double p1_d = i_plane.nx()*p1.x() + i_plane.ny()*p1.y() + i_plane.nz()*p1.z() + i_plane.d();
01116 double p2_d = i_plane.nx()*p2.x() + i_plane.ny()*p2.y() + i_plane.nz()*p2.z() + i_plane.d();
01117 double p3_d = i_plane.nx()*p3.x() + i_plane.ny()*p3.y() + i_plane.nz()*p3.z() + i_plane.d();
01118
01119
01120 if (vcl_fabs(p1_d) < sqrteps) p1_d = 0.0;
01121 if (vcl_fabs(p2_d) < sqrteps) p2_d = 0.0;
01122 if (vcl_fabs(p3_d) < sqrteps) p3_d = 0.0;
01123
01124 vgl_line_3d_2_points<double> edge;
01125
01126 if (p1_d*p2_d > 0 && p1_d*p3_d > 0)
01127 {
01128 i_line.set(vgl_point_3d<double>(),vgl_point_3d<double>());
01129 return None;
01130 }
01131 else if (p1_d == 0 && p2_d == 0 && p3_d == 0)
01132 {
01133 vgl_point_3d<double> i_pnt1; i_pnt1.set(vgl_nan, vgl_nan, vgl_nan);
01134 i_line.set(i_pnt1,i_pnt1);
01135 return Coplanar;
01136 }
01137 else if (p1_d*p2_d > 0)
01138 {
01139 edge.set(p1,p3);
01140 vgl_point_3d<double> i_pnt1 = vgl_intersection(edge, i_plane);
01141 edge.set(p2,p3);
01142 vgl_point_3d<double> i_pnt2 = vgl_intersection(edge, i_plane);
01143 i_line.set(i_pnt1,i_pnt2);
01144 }
01145 else if (p1_d*p3_d > 0)
01146 {
01147 edge.set(p1,p2);
01148 vgl_point_3d<double> i_pnt1 = vgl_intersection(edge, i_plane);
01149 edge.set(p3,p2);
01150 vgl_point_3d<double> i_pnt2 = vgl_intersection(edge, i_plane);
01151 i_line.set(i_pnt1,i_pnt2);
01152 }
01153 else if (p2_d*p3_d > 0)
01154 {
01155 edge.set(p2,p1);
01156 vgl_point_3d<double> i_pnt1 = vgl_intersection(edge, i_plane);
01157 edge.set(p3,p1);
01158 vgl_point_3d<double> i_pnt2 = vgl_intersection(edge, i_plane);
01159 i_line.set(i_pnt1,i_pnt2);
01160 }
01161 else if (p1_d == 0 && p2_d == 0)
01162 {
01163 i_line.set(p1,p2);
01164 }
01165 else if (p1_d == 0 && p3_d == 0)
01166 {
01167 i_line.set(p1,p3);
01168 }
01169 else if (p3_d == 0 && p2_d == 0)
01170 {
01171 i_line.set(p2,p3);
01172 }
01173 else if (p1_d == 0)
01174 {
01175 edge.set(p3,p2);
01176 vgl_point_3d<double> i_pnt2 = vgl_intersection(edge, i_plane);
01177 i_line.set(p1,i_pnt2);
01178 }
01179 else if (p2_d == 0)
01180 {
01181 edge.set(p3,p1);
01182 vgl_point_3d<double> i_pnt2 = vgl_intersection(edge, i_plane);
01183 i_line.set(p2,i_pnt2);
01184 }
01185 else if (p3_d == 0)
01186 {
01187 edge.set(p2,p1);
01188 vgl_point_3d<double> i_pnt2 = vgl_intersection(edge, i_plane);
01189 i_line.set(p3,i_pnt2);
01190 }
01191 return Skew;
01192 }
01193
01194
01195
01196
01197
01198 vgl_point_3d<double> vgl_triangle_3d_closest_point(
01199 const vgl_point_3d<double>& q,
01200 const vgl_point_3d<double>& p1,
01201 const vgl_point_3d<double>& p2,
01202 const vgl_point_3d<double>& p3)
01203 {
01204
01205 if (p1 == p2)
01206 {
01207 if (p2 == p3) return p3;
01208 return vgl_closest_point(vgl_line_3d_2_points<double>(p3, p1), q);
01209 }
01210 if (p2 == p3)
01211 return vgl_closest_point(vgl_line_3d_2_points<double>(p1, p2), q);
01212 if (p3 == p1)
01213 return vgl_closest_point(vgl_line_3d_2_points<double>(p2, p3), q);
01214
01215
01216 vgl_plane_3d<double> plane(p1, p2, p3);
01217
01218
01219 vgl_point_3d<double> cp = vgl_closest_point<double>(plane, q);
01220
01221
01222 if (vgl_triangle_3d_test_inside(cp, p1, p2, p3))
01223 {
01224 return cp;
01225 }
01226 else
01227 {
01228
01229
01230
01231 double cp1x, cp1y, cp1z;
01232 vgl_closest_point_to_linesegment(
01233 cp1x, cp1y, cp1z,
01234 p1.x(), p1.y(), p1.z(),
01235 p2.x(), p2.y(), p2.z(),
01236 q.x(), q.y(), q.z());
01237 vgl_point_3d<double> cp1(cp1x, cp1y, cp1z);
01238 double d1 = vgl_distance(cp1, q);
01239
01240
01241 double cp2x, cp2y, cp2z;
01242 vgl_closest_point_to_linesegment(
01243 cp2x, cp2y, cp2z,
01244 p2.x(), p2.y(), p2.z(),
01245 p3.x(), p3.y(), p3.z(),
01246 q.x(), q.y(), q.z());
01247 vgl_point_3d<double> cp2(cp2x, cp2y, cp2z);
01248 double d2 = vgl_distance(cp2, q);
01249
01250
01251 double cp3x, cp3y, cp3z;
01252 vgl_closest_point_to_linesegment(
01253 cp3x, cp3y, cp3z,
01254 p1.x(), p1.y(), p1.z(),
01255 p3.x(), p3.y(), p3.z(),
01256 q.x(), q.y(), q.z());
01257 vgl_point_3d<double> cp3(cp3x, cp3y, cp3z);
01258 double d3 = vgl_distance(cp3, q);
01259
01260
01261 if (d1<=d2 && d1<=d3)
01262 return cp1;
01263 else if (d2<=d1 && d2<=d3)
01264 return cp2;
01265 else
01266 return cp3;
01267 }
01268 }
01269
01270
01271
01272
01273
01274 double vgl_triangle_3d_distance(const vgl_point_3d<double>& q,
01275 const vgl_point_3d<double>& p1,
01276 const vgl_point_3d<double>& p2,
01277 const vgl_point_3d<double>& p3)
01278 {
01279 vgl_point_3d<double> c = vgl_triangle_3d_closest_point(q, p1, p2, p3);
01280 return vgl_distance(c, q);
01281 }
01282
01283
01284
01285
01286
01287 bool vgl_triangle_3d_triangle_coplanar(
01288 const vgl_point_3d<double>& a_p1,
01289 const vgl_point_3d<double>& a_p2,
01290 const vgl_point_3d<double>& a_p3,
01291 const vgl_point_3d<double>& b_p1,
01292 const vgl_point_3d<double>& b_p2,
01293 const vgl_point_3d<double>& b_p3)
01294 {
01295 return coplanar(a_p1,b_p1,b_p2,b_p3)
01296 && coplanar(a_p2,b_p1,b_p2,b_p3)
01297 && coplanar(a_p3,b_p1,b_p2,b_p3);
01298 }
01299
01300
01301
01302
01303 double vgl_triangle_3d_area(const vgl_point_3d<double> &p0,
01304 const vgl_point_3d<double> &p1,
01305 const vgl_point_3d<double> &p2 )
01306 {
01307 vgl_vector_3d<double> edge_vector0;
01308 edge_vector0 = p0 - p1;
01309 vgl_vector_3d<double> edge_vector1;
01310 edge_vector1 = p0 - p2;
01311
01312 vgl_vector_3d<double> area_vector;
01313 area_vector = cross_product( edge_vector0, edge_vector1 );
01314
01315 double area;
01316 area = area_vector.length();
01317 area /= 2;
01318
01319 return area;
01320 }
01321
01322
01323
01324
01325 double vgl_triangle_3d_aspect_ratio(
01326 const vgl_point_3d<double> &p0,
01327 const vgl_point_3d<double> &p1,
01328 const vgl_point_3d<double> &p2 )
01329 {
01330 return vgl_triangle_3d_longest_side( p0, p1, p2 ) / vgl_triangle_3d_shortest_side( p0, p1, p2 );
01331 }
01332