diff --git a/Packages/Distance_2/changes.txt b/Packages/Distance_2/changes.txt index 66b2957f211..e2d106a3621 100644 --- a/Packages/Distance_2/changes.txt +++ b/Packages/Distance_2/changes.txt @@ -1,3 +1,18 @@ +2.7 (7 August 2003) +A first step towards the extendible Kernel: + +* All functionality is moved into namespace CGALi, in namespace CGAL + there remain forward functions for the geometric types from the CGAL + kernel thereby fully maintaining backwards compatibility; nothing + changes on the user level. + +* In the CGALi part, all types are referred to as K::Type rather than + Type. + +* In the CGALi part, all functions have a kernel object as last + argument, not only to ease the matching (no explicit template + argument needed), but also to be able to handle kernels with state. + 2.6 (4 April 2003) - reflected the changes of 2.5.7 in web directory diff --git a/Packages/Distance_2/include/CGAL/squared_distance_2_1.h b/Packages/Distance_2/include/CGAL/squared_distance_2_1.h index 2c4edfbfad2..14885193fe0 100644 --- a/Packages/Distance_2/include/CGAL/squared_distance_2_1.h +++ b/Packages/Distance_2/include/CGAL/squared_distance_2_1.h @@ -37,700 +37,822 @@ CGAL_BEGIN_NAMESPACE -template -inline typename R::FT -squared_distance( - const Point_2 & pt1, - const Point_2 & pt2) -{ - Vector_2 vec(pt1-pt2); - return (typename R::FT)(vec*vec); -} +namespace CGALi { + + template + inline typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Point_2 & pt1, + const typename CGAL_WRAP(K)::Point_2 & pt2, + const K& k) + { + typename K::Vector_2 vec = k.construct_vector_2_object()(pt2, pt1); + return (typename K::FT)(vec*vec); + } - -template -class Squared_distance_to_line { - typename R::RT a, b, c, sqnorm; - public: - Squared_distance_to_line(typename R::Line_2 const &line) - : a(line.a()), b(line.b()), c(line.c()) - { - sqnorm = a*a+b*b; - } - typename R::FT operator()(typename R::Point_2 const &pt) const - { - typedef typename R::RT RT; - RT w = pt.hw(); - RT n = a*pt.hx() + b*pt.hy() + wmult((R*)0, c, w); - RT d = wmult((R*)0, sqnorm, w, w); - return R::make_FT(n*n, d); - } -}; - -template -typename R::FT -squared_distance( - const Point_2 &pt, - const Line_2 &line) -{ - typedef typename R::RT RT; + template + typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Point_2 &pt, + const typename CGAL_WRAP(K)::Line_2 &line, + const K&) + { + typedef typename K::RT RT; RT a = line.a(); RT b = line.b(); RT w = pt.hw(); - RT n = a*pt.hx() + b*pt.hy() + wmult((R*)0, line.c(), w); - RT d = wmult((R*)0, RT(a*a+b*b), w, w); - return R::make_FT(n*n, d); -} - - -template -inline typename R::FT -squared_distance( - const Line_2 & line, - const Point_2 & pt) -{ - return squared_distance(pt, line); -} - -template -class Squared_distance_to_ray { - typename R::Vector_2 ray_dir; - typename R::Point_2 ray_source; - Squared_distance_to_line supline_dist; - public: - Squared_distance_to_ray(typename R::Ray_2 const &ray) - : ray_dir(ray.direction().vector()), - ray_source(ray.source()), - supline_dist(ray.supporting_line()) - { } - typename R::FT operator()(typename R::Point_2 const &pt) const - { - Vector_2 diff = pt-ray_source; - if (!is_acute_angle(ray_dir,diff) ) - return (typename R::FT)(diff*diff); - return supline_dist(pt); - } -}; - - - -template -extern typename R::FT -squared_distance( - const Point_2 &pt, - const Ray_2 &ray) -{ - Vector_2 diff = pt-ray.source(); - const Vector_2 &dir = ray.direction().vector(); + RT n = a*pt.hx() + b*pt.hy() + wmult((K*)0, line.c(), w); + RT d = wmult((K*)0, RT(a*a+b*b), w, w); + return K::make_FT(n*n, d); + } + + template + inline typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Line_2 &line, + const typename CGAL_WRAP(K)::Point_2 &pt, + const K& k) + { + return CGALi::squared_distance(pt, line, k); + } + + template + extern typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Point_2 &pt, + const typename CGAL_WRAP(K)::Ray_2 &ray, + const K& k) + { + typedef typename K::Vector_2 Vector_2; + Vector_2 diff = pt-ray.source(); + const Vector_2 &dir = ray.direction().vector(); if (!is_acute_angle(dir,diff) ) - return (typename R::FT)(diff*diff); - return squared_distance(pt, ray.supporting_line()); -} + return (typename K::FT)(diff*diff); + return CGALi::squared_distance(pt, ray.supporting_line(), k); + } + template + inline typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Ray_2 &ray, + const typename CGAL_WRAP(K)::Point_2 &pt, + const K& k) + { + return CGALi::squared_distance(pt, ray, k); + } -template -inline typename R::FT -squared_distance( - const Ray_2 & ray, - const Point_2 & pt) -{ - return squared_distance(pt, ray); -} - - -template -extern void -distance_index( - int &ind, - const Point_2 &pt, - const Ray_2 &ray) -{ - if (!is_acute_angle(ray.direction().vector(),pt-ray.source())) { - ind = 0; - return; - } - ind = -1; -} - -template -typename R::FT -squared_distance_indexed(const Point_2 &pt, - const Ray_2 &ray, int ind) -{ - if (ind == 0) - return squared_distance(pt, ray.source()); - return squared_distance(pt, ray.supporting_line()); -} - - - -template -class Squared_distance_to_segment { - typename R::Point_2 seg_source, seg_target; - Squared_distance_to_line supline_dist; - typename R::Vector_2 segvec; - typename R::RT e; - public: - Squared_distance_to_segment(typename R::Segment_2 const &seg) - : seg_source(seg.source()), seg_target(seg.target()), - supline_dist(seg.supporting_line()) - { - segvec = seg_target-seg_source; - e = wdot(segvec,segvec); - } - typename R::FT operator()(typename R::Point_2 const &pt) const - { - typedef typename R::RT RT; - // assert that the segment is valid (non zero length). - Vector_2 diff = pt-seg_source; - RT d = wdot(diff,segvec); - if (d <= (RT)0) - return (typename R::FT)(diff*diff); - if (wmult((R*)0 ,d, segvec.hw()) > wmult((R*)0, e, diff.hw())) - return squared_distance(pt, seg_target); - return supline_dist(pt); - } -}; - - -template -typename R::FT -squared_distance( - const Point_2 &pt, - const Segment_2 &seg) -{ - typedef typename R::RT RT; + template + typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Point_2 &pt, + const typename CGAL_WRAP(K)::Segment_2 &seg, + const K& k) + { + typedef typename K::Vector_2 Vector_2; + typedef typename K::RT RT; // assert that the segment is valid (non zero length). - Vector_2 diff = pt-seg.source(); - Vector_2 segvec = seg.target()-seg.source(); + Vector_2 diff = pt-seg.source(); + Vector_2 segvec = seg.target()-seg.source(); RT d = wdot(diff,segvec); if (d <= (RT)0) - return (typename R::FT)(diff*diff); + return (typename K::FT)(diff*diff); RT e = wdot(segvec,segvec); - if (wmult((R*)0 ,d, segvec.hw()) > wmult((R*)0, e, diff.hw())) - return squared_distance(pt, seg.target()); - return squared_distance(pt, seg.supporting_line()); -} + if (wmult((K*)0 ,d, segvec.hw()) > wmult((K*)0, e, diff.hw())) + return CGALi::squared_distance(pt, seg.target(), k); + return CGALi::squared_distance(pt, seg.supporting_line(), k); + } + template + inline typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Segment_2 &seg, + const typename CGAL_WRAP(K)::Point_2 &pt, + const K& k) + { + return CGALi::squared_distance(pt, seg, k); + } -template -inline typename R::FT -squared_distance( - const Segment_2 & seg, - const Point_2 & pt) -{ - return squared_distance(pt, seg); -} - - - - -template -extern void -distance_index( - int &ind, - const Point_2 &pt, - const Segment_2 &seg) -{ - if (!is_acute_angle(seg.target(),seg.source(),pt)) { - ind = 0; - return; - } - if (!is_acute_angle(seg.source(),seg.target(),pt)) { - ind = 1; - return; - } - ind = -1; -} - -template -typename R::FT -squared_distance_indexed(const Point_2 &pt, - const Segment_2 &seg, int ind) -{ - if (ind == 0) - return squared_distance(pt, seg.source()); - if (ind == 1) - return squared_distance(pt, seg.target()); - return squared_distance(pt, seg.supporting_line()); -} - - - - - -template -typename R::FT -squared_distance_parallel( - const Segment_2 &seg1, - const Segment_2 &seg2) -{ + template + typename K::FT + squared_distance_parallel(const typename CGAL_WRAP(K)::Segment_2 &seg1, + const typename CGAL_WRAP(K)::Segment_2 &seg2, + const K& k) + { + typedef typename K::Vector_2 Vector_2; bool same_direction; - const Vector_2 &dir1 = seg1.direction().vector(); - const Vector_2 &dir2 = seg2.direction().vector(); + const Vector_2 &dir1 = seg1.direction().vector(); + const Vector_2 &dir2 = seg2.direction().vector(); if (CGAL_NTS abs(dir1.hx()) > CGAL_NTS abs(dir1.hy())) { - same_direction = (CGAL_NTS sign(dir1.hx()) == CGAL_NTS sign(dir2.hx())); + same_direction = (CGAL_NTS sign(dir1.hx()) == CGAL_NTS sign(dir2.hx())); } else { - same_direction = (CGAL_NTS sign(dir1.hy()) == CGAL_NTS sign(dir2.hy())); + same_direction = (CGAL_NTS sign(dir1.hy()) == CGAL_NTS sign(dir2.hy())); } if (same_direction) { - if (!is_acute_angle(seg1.source(), seg1.target(), seg2.source())) - return squared_distance(seg1.target(), seg2.source()); - if (!is_acute_angle(seg1.target(), seg1.source(), seg2.target())) - return squared_distance(seg1.source(), seg2.target()); + if (!is_acute_angle(seg1.source(), seg1.target(), seg2.source())) + return CGALi::squared_distance(seg1.target(), seg2.source(), k); + if (!is_acute_angle(seg1.target(), seg1.source(), seg2.target())) + return CGALi::squared_distance(seg1.source(), seg2.target(), k); } else { - if (!is_acute_angle(seg1.source(), seg1.target(), seg2.target())) - return squared_distance(seg1.target(), seg2.target()); - if (!is_acute_angle(seg1.target(), seg1.source(), seg2.source())) - return squared_distance(seg1.source(), seg2.source()); + if (!is_acute_angle(seg1.source(), seg1.target(), seg2.target())) + return CGALi::squared_distance(seg1.target(), seg2.target(), k); + if (!is_acute_angle(seg1.target(), seg1.source(), seg2.source())) + return CGALi::squared_distance(seg1.source(), seg2.source(), k); } - return squared_distance(seg2.source(), seg1.supporting_line()); -} + return CGALi::squared_distance(seg2.source(), seg1.supporting_line(), k); + } + template + inline typename K::RT + _distance_measure_sub(const typename K::RT &startwcross, + const typename K::RT &endwcross, + const typename CGAL_WRAP(K)::Point_2 &start, + const typename CGAL_WRAP(K)::Point_2 &end) + { + return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) - + CGAL_NTS abs(wmult((K*)0, endwcross, start.hw())); + } - -template -RT _distance_measure_sub(RT startwcross, RT endwcross, -const Point_2 &start, const Point_2 &end -) -{ - return CGAL_NTS abs(wmult((R*)0, startwcross, end.hw())) - - CGAL_NTS abs(wmult((R*)0, endwcross, start.hw())); -} - - - -template -typename R::FT -squared_distance( - const Segment_2 &seg1, - const Segment_2 &seg2) -{ - typedef typename R::RT RT; - typedef typename R::FT FT; + template + typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Segment_2 &seg1, + const typename CGAL_WRAP(K)::Segment_2 &seg2, + const K& k) + { + typedef typename K::RT RT; + typedef typename K::FT FT; bool crossing1, crossing2; RT c1s, c1e, c2s, c2e; if (seg1.source() == seg1.target()) - return squared_distance(seg1.source(), seg2); + return CGALi::squared_distance(seg1.source(), seg2, k); if (seg2.source() == seg2.target()) - return squared_distance(seg2.source(), seg1); + return CGALi::squared_distance(seg2.source(), seg1, k); c1s = wcross(seg2.source(), seg2.target(), seg1.source()); c1e = wcross(seg2.source(), seg2.target(), seg1.target()); c2s = wcross(seg1.source(), seg1.target(), seg2.source()); c2e = wcross(seg1.source(), seg1.target(), seg2.target()); if (c1s < RT(0)) { - crossing1 = (c1e >= RT(0)); + crossing1 = (c1e >= RT(0)); } else { - if (c1e <= RT(0)) { - if (c1s == RT(0) && c1e == RT(0)) - return squared_distance_parallel(seg1, seg2); - crossing1 = true; - } else { - crossing1 = (c1s == RT(0)); - } + if (c1e <= RT(0)) { + if (c1s == RT(0) && c1e == RT(0)) + return CGALi::squared_distance_parallel(seg1, seg2, k); + crossing1 = true; + } else { + crossing1 = (c1s == RT(0)); + } } if (c2s < RT(0)) { - crossing2 = (c2e >= RT(0)); + crossing2 = (c2e >= RT(0)); } else { - if (c2e <= RT(0)) { - if (c2s == RT(0) && c2e == RT(0)) - return squared_distance_parallel(seg1, seg2); - crossing2 = true; - } else { - crossing2 = (c2s == RT(0)); - } + if (c2e <= RT(0)) { + if (c2s == RT(0) && c2e == RT(0)) + return CGALi::squared_distance_parallel(seg1, seg2, k); + crossing2 = true; + } else { + crossing2 = (c2s == RT(0)); + } } if (crossing1) { - if (crossing2) - return (FT)0; - RT dm; - dm = _distance_measure_sub(c2s,c2e, seg2.source(), seg2.target()); - if (dm < RT(0)) { - return squared_distance(seg2.source(), seg1); - } else { - if (dm > RT(0)) { - return squared_distance(seg2.target(), seg1); - } else { - // parallel, should not happen (no crossing) - return squared_distance_parallel(seg1, seg2); - } - } + if (crossing2) + return (FT)0; + RT dm; + dm = _distance_measure_sub(c2s,c2e, seg2.source(), seg2.target()); + if (dm < RT(0)) { + return CGALi::squared_distance(seg2.source(), seg1, k); + } else { + if (dm > RT(0)) { + return CGALi::squared_distance(seg2.target(), seg1, k); + } else { + // parallel, should not happen (no crossing) + return CGALi::squared_distance_parallel(seg1, seg2, k); + } + } } else { - if (crossing2) { - RT dm; - dm = - _distance_measure_sub(c1s, c1e,seg1.source(),seg1.target()); - if (dm < RT(0)) { - return squared_distance(seg1.source(), seg2); - } else { - if (dm > RT(0)) { - return squared_distance(seg1.target(), seg2); - } else { - // parallel, should not happen (no crossing) - return squared_distance_parallel(seg1, seg2); - } - } - } else { + if (crossing2) { + RT dm; + dm = + _distance_measure_sub(c1s, c1e,seg1.source(),seg1.target()); + if (dm < RT(0)) { + return CGALi::squared_distance(seg1.source(), seg2, k); + } else { + if (dm > RT(0)) { + return CGALi::squared_distance(seg1.target(), seg2, k); + } else { + // parallel, should not happen (no crossing) + return CGALi::squared_distance_parallel(seg1, seg2, k); + } + } + } else { - FT min1, min2; - RT dm = _distance_measure_sub( - c1s, c1e, seg1.source(), seg1.target()); - if (dm == RT(0)) - return squared_distance_parallel(seg1, seg2); - min1 = (dm < RT(0)) ? - squared_distance(seg1.source(), seg2): - squared_distance(seg1.target(), seg2); - dm = _distance_measure_sub( - c2s, c2e, seg2.source(), seg2.target()); - if (dm == RT(0)) // should not happen. - return squared_distance_parallel(seg1, seg2); - min2 = (dm < RT(0)) ? - squared_distance(seg2.source(), seg1): - squared_distance(seg2.target(), seg1); - return (min1 < min2) ? min1 : min2; - } + FT min1, min2; + RT dm = _distance_measure_sub( + c1s, c1e, seg1.source(), seg1.target()); + if (dm == RT(0)) + return CGALi::squared_distance_parallel(seg1, seg2, k); + min1 = (dm < RT(0)) ? + CGALi::squared_distance(seg1.source(), seg2, k): + CGALi::squared_distance(seg1.target(), seg2, k); + dm = _distance_measure_sub( + c2s, c2e, seg2.source(), seg2.target()); + if (dm == RT(0)) // should not happen. + return CGALi::squared_distance_parallel(seg1, seg2, k); + min2 = (dm < RT(0)) ? + CGALi::squared_distance(seg2.source(), seg1, k): + CGALi::squared_distance(seg2.target(), seg1, k); + return (min1 < min2) ? min1 : min2; + } } -} + } + template + inline typename K::RT + _distance_measure_sub(const typename K::RT &startwcross, + const typename K::RT &endwcross, + const typename CGAL_WRAP(K)::Vector_2 &start, + const typename CGAL_WRAP(K)::Vector_2 &end) + { + return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) - + CGAL_NTS abs(wmult((K*)0, endwcross, start.hw())); + } - - - - -template -RT _distance_measure_sub(RT startwcross, RT endwcross, -const Vector_2 &start, const Vector_2 &end -) -{ - return CGAL_NTS abs(wmult((R*)0, startwcross, end.hw())) - - CGAL_NTS abs(wmult((R*)0, endwcross, start.hw())); -} - - -template -typename R::FT -squared_distance_parallel( - const Segment_2 &seg, - const Ray_2 &ray) -{ + template + typename K::FT + squared_distance_parallel(const typename CGAL_WRAP(K)::Segment_2 &seg, + const typename CGAL_WRAP(K)::Ray_2 &ray, + const K& k) + { + typedef typename K::Vector_2 Vector_2; bool same_direction; - const Vector_2 &dir1 = seg.direction().vector(); - const Vector_2 &dir2 = ray.direction().vector(); + const Vector_2 &dir1 = seg.direction().vector(); + const Vector_2 &dir2 = ray.direction().vector(); if (CGAL_NTS abs(dir1.hx()) > CGAL_NTS abs(dir1.hy())) { - same_direction = (CGAL_NTS sign(dir1.hx()) == CGAL_NTS sign(dir2.hx())); + same_direction = (CGAL_NTS sign(dir1.hx()) == CGAL_NTS sign(dir2.hx())); } else { - same_direction = (CGAL_NTS sign(dir1.hy()) == CGAL_NTS sign(dir2.hy())); + same_direction = (CGAL_NTS sign(dir1.hy()) == CGAL_NTS sign(dir2.hy())); } if (same_direction) { - if (!is_acute_angle(seg.source(), seg.target(), ray.source())) - return squared_distance(seg.target(), ray.source()); + if (!is_acute_angle(seg.source(), seg.target(), ray.source())) + return CGALi::squared_distance(seg.target(), ray.source(), k); } else { - if (!is_acute_angle(seg.target(), seg.source(), ray.source())) - return squared_distance(seg.source(), ray.source()); + if (!is_acute_angle(seg.target(), seg.source(), ray.source())) + return CGALi::squared_distance(seg.source(), ray.source(), k); } - return squared_distance(ray.source(), seg.supporting_line()); -} + return CGALi::squared_distance(ray.source(), seg.supporting_line(), k); + } - - -template -typename R::FT -squared_distance( - const Segment_2 &seg, - const Ray_2 &ray) -{ - typedef typename R::RT RT; - typedef typename R::FT FT; - const Vector_2 &raydir = ray.direction().vector(); - Vector_2 startvec(seg.source()-ray.source()); - Vector_2 endvec(seg.target()-ray.source()); + template + typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Segment_2 &seg, + const typename CGAL_WRAP(K)::Ray_2 &ray, + const K& k) + { + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + const Vector_2 &raydir = ray.direction().vector(); + Vector_2 startvec(seg.source()-ray.source()); + Vector_2 endvec(seg.target()-ray.source()); bool crossing1, crossing2; RT c1s, c1e; Orientation ray_s_side; if (seg.source() == seg.target()) - return squared_distance(seg.source(), ray); + return CGALi::squared_distance(seg.source(), ray, k); c1s = wcross(raydir, startvec); c1e = wcross(raydir, endvec); if (c1s < RT(0)) { - crossing1 = (c1e >= RT(0)); + crossing1 = (c1e >= RT(0)); } else { - if (c1e <= RT(0)) { - if (c1s == RT(0) && c1e == RT(0)) - return squared_distance_parallel(seg, ray); - crossing1 = true; - } else { - crossing1 = (c1s == RT(0)); - } + if (c1e <= RT(0)) { + if (c1s == RT(0) && c1e == RT(0)) + return CGALi::squared_distance_parallel(seg, ray, k); + crossing1 = true; + } else { + crossing1 = (c1s == RT(0)); + } } ray_s_side = orientation(seg.source(), seg.target(), ray.source()); switch (ray_s_side) { case LEFT_TURN: - crossing2 = right_turn(seg.target()-seg.source(), raydir); - break; + crossing2 = right_turn(seg.target()-seg.source(), raydir); + break; case RIGHT_TURN: - crossing2 = left_turn(seg.target()-seg.source(), raydir); - break; + crossing2 = left_turn(seg.target()-seg.source(), raydir); + break; case COLLINEAR: - crossing2 = true; - break; + crossing2 = true; + break; } if (crossing1) { - if (crossing2) - return FT(0); - return squared_distance(ray.source(), seg); + if (crossing2) + return FT(0); + return CGALi::squared_distance(ray.source(), seg, k); } else { - if (crossing2) { - RT dm; - dm = _distance_measure_sub(c1s, c1e, startvec, endvec); - if (dm < RT(0)) { - return squared_distance(seg.source(), ray); - } else { - if (dm > RT(0)) { - return squared_distance(seg.target(), ray); - } else { - // parallel, should not happen (no crossing) - return squared_distance_parallel(seg, ray); - } - } - } else { + if (crossing2) { + RT dm; + dm = _distance_measure_sub(c1s, c1e, startvec, endvec); + if (dm < RT(0)) { + return CGALi::squared_distance(seg.source(), ray, k); + } else { + if (dm > RT(0)) { + return CGALi::squared_distance(seg.target(), ray, k); + } else { + // parallel, should not happen (no crossing) + return CGALi::squared_distance_parallel(seg, ray, k); + } + } + } else { - FT min1, min2; - RT dm; - dm = _distance_measure_sub(c1s, c1e, startvec, endvec); - if (dm == RT(0)) - return squared_distance_parallel(seg, ray); - min1 = (dm < RT(0)) - ? squared_distance(seg.source(), ray) - : squared_distance(seg.target(), ray); - min2 = squared_distance(ray.source(), seg); - return (min1 < min2) ? min1 : min2; - } + FT min1, min2; + RT dm; + dm = _distance_measure_sub(c1s, c1e, startvec, endvec); + if (dm == RT(0)) + return CGALi::squared_distance_parallel(seg, ray, k); + min1 = (dm < RT(0)) + ? CGALi::squared_distance(seg.source(), ray, k) + : CGALi::squared_distance(seg.target(), ray, k); + min2 = CGALi::squared_distance(ray.source(), seg, k); + return (min1 < min2) ? min1 : min2; + } } -} + } + template + inline typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Ray_2 &ray, + const typename CGAL_WRAP(K)::Segment_2 &seg, + const K& k) + { + return CGALi::squared_distance(seg, ray, k); + } - -template -inline typename R::FT -squared_distance( - const Ray_2 & ray, - const Segment_2 & seg) -{ - return squared_distance(seg, ray); -} - - - - -template -typename R::FT -_sqd_to_line(const Vector_2 &diff, - const RT & wcross, const Vector_2 &dir ) -{ - typedef typename R::FT FT; + template + typename K::FT + _sqd_to_line(const typename CGAL_WRAP(K)::Vector_2 &diff, + const typename K::RT & wcross, + const typename CGAL_WRAP(K)::Vector_2 &dir ) + { + typedef typename K::RT RT; + typedef typename K::FT FT; RT numerator = wcross*wcross; - RT denominator = wmult((R*)0, RT(wdot(dir,dir)), - diff.hw(), diff.hw()); - FT result = R::make_FT(numerator, denominator); + RT denominator = wmult((K*)0, RT(wdot(dir,dir)), + diff.hw(), diff.hw()); + FT result = K::make_FT(numerator, denominator); return result; -} + } - - -template -typename R::FT -squared_distance( - const Segment_2 &seg, - const Line_2 &line) -{ - typedef typename R::RT RT; - typedef typename R::FT FT; - const Vector_2 &linedir = line.direction().vector(); - const Point_2 &linepoint = line.point(); - Vector_2 startvec(seg.source()-linepoint); - Vector_2 endvec(seg.target()-linepoint); + template + typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Segment_2 &seg, + const typename CGAL_WRAP(K)::Line_2 &line, + const K& k) + { + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + typedef typename K::Point_2 Point_2; + const Vector_2 &linedir = line.direction().vector(); + const Point_2 &linepoint = line.point(); + Vector_2 startvec(seg.source()-linepoint); + Vector_2 endvec(seg.target()-linepoint); bool crossing1; RT c1s, c1e; if (seg.source() == seg.target()) - return squared_distance(seg.source(), line); + return CGALi::squared_distance(seg.source(), line, k); c1s = wcross(linedir, startvec); c1e = wcross(linedir, endvec); if (c1s < RT(0)) { - crossing1 = (c1e >= RT(0)); + crossing1 = (c1e >= RT(0)); } else { - if (c1e <= RT(0)) { - crossing1 = true; - } else { - crossing1 = (c1s == RT(0)); - } + if (c1e <= RT(0)) { + crossing1 = true; + } else { + crossing1 = (c1s == RT(0)); + } } if (crossing1) { - return (FT)0; + return (FT)0; } else { - RT dm; - dm = _distance_measure_sub(c1s, c1e, startvec, endvec); - if (dm <= RT(0)) { - return _sqd_to_line(startvec, c1s, linedir); - } else { - return _sqd_to_line(endvec, c1e, linedir); - } + RT dm; + dm = _distance_measure_sub(c1s, c1e, startvec, endvec); + if (dm <= RT(0)) { + return _sqd_to_line(startvec, c1s, linedir); + } else { + return _sqd_to_line(endvec, c1e, linedir); + } } -} + } + template + inline typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Line_2 &line, + const typename CGAL_WRAP(K)::Segment_2 &seg, + const K& k) + { + return CGALi::squared_distance(seg, line, k); + } - -template -inline typename R::FT -squared_distance( - const Line_2 & line, - const Segment_2 & seg) -{ - return squared_distance(seg, line); -} - - - -template -typename R::FT -ray_ray_squared_distance_parallel( - const Vector_2 &ray1dir, - const Vector_2 &ray2dir, - const Vector_2 &from1to2) -{ - typedef typename R::RT RT; - typedef typename R::FT FT; + template + typename K::FT + ray_ray_squared_distance_parallel( + const typename CGAL_WRAP(K)::Vector_2 &ray1dir, + const typename CGAL_WRAP(K)::Vector_2 &ray2dir, + const typename CGAL_WRAP(K)::Vector_2 &from1to2, + const K&) + { + typedef typename K::RT RT; + typedef typename K::FT FT; if (!is_acute_angle(ray1dir, from1to2)) { - bool same_direction; - if (CGAL_NTS abs(ray1dir.hx()) > CGAL_NTS abs(ray1dir.hy())) { - same_direction = - (CGAL_NTS sign(ray1dir.hx()) == CGAL_NTS sign(ray2dir.hx())); - } else { - same_direction = - (CGAL_NTS sign(ray1dir.hy()) == CGAL_NTS sign(ray2dir.hy())); - } - if (!same_direction) - return (typename R::FT)(from1to2*from1to2); + bool same_direction; + if (CGAL_NTS abs(ray1dir.hx()) > CGAL_NTS abs(ray1dir.hy())) { + same_direction = + (CGAL_NTS sign(ray1dir.hx()) == CGAL_NTS sign(ray2dir.hx())); + } else { + same_direction = + (CGAL_NTS sign(ray1dir.hy()) == CGAL_NTS sign(ray2dir.hy())); + } + if (!same_direction) + return (typename K::FT)(from1to2*from1to2); } RT wcr, w; wcr = wcross(ray1dir, from1to2); w = from1to2.hw(); - return (typename R::FT)(FT(wcr*wcr) - / FT(wmult((R*)0, RT(wdot(ray1dir, ray1dir)), w, w))); -} + return (typename K::FT)(FT(wcr*wcr) + / FT(wmult((K*)0, RT(wdot(ray1dir, ray1dir)), w, w))); + } - - -template -typename R::FT -squared_distance( - const Ray_2 &ray1, - const Ray_2 &ray2) -{ - typedef typename R::FT FT; - const Vector_2 &ray1dir = ray1.direction().vector(); - const Vector_2 &ray2dir = ray2.direction().vector(); - Vector_2 diffvec(ray2.source()-ray1.source()); + template + typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Ray_2 &ray1, + const typename CGAL_WRAP(K)::Ray_2 &ray2, + const K& k) + { + typedef typename K::FT FT; + const Vector_2 &ray1dir = ray1.direction().vector(); + const Vector_2 &ray2dir = ray2.direction().vector(); + Vector_2 diffvec(ray2.source()-ray1.source()); bool crossing1, crossing2; Orientation dirorder; dirorder = orientation(ray1dir, ray2dir); switch (dirorder) { case COUNTERCLOCKWISE: - crossing1 = !clockwise(diffvec, ray2dir); - crossing2 = !counterclockwise(ray1dir, diffvec); - break; + crossing1 = !clockwise(diffvec, ray2dir); + crossing2 = !counterclockwise(ray1dir, diffvec); + break; case CLOCKWISE: - crossing1 = !counterclockwise(diffvec, ray2dir); - crossing2 = !clockwise(ray1dir, diffvec); - break; + crossing1 = !counterclockwise(diffvec, ray2dir); + crossing2 = !clockwise(ray1dir, diffvec); + break; case COLLINEAR: - return ray_ray_squared_distance_parallel(ray1dir,ray2dir,diffvec); + return ray_ray_squared_distance_parallel(ray1dir,ray2dir,diffvec,k); } if (crossing1) { - if (crossing2) - return (FT)0; - return squared_distance(ray2.source(), ray1); + if (crossing2) + return (FT)0; + return CGALi::squared_distance(ray2.source(), ray1, k); } else { - if (crossing2) { - return squared_distance(ray1.source(), ray2); - } else { + if (crossing2) { + return CGALi::squared_distance(ray1.source(), ray2, k); + } else { - FT min1, min2; - min1 = squared_distance(ray1.source(), ray2); - min2 = squared_distance(ray2.source(), ray1); - return (min1 < min2) ? min1 : min2; - } + FT min1, min2; + min1 = CGALi::squared_distance(ray1.source(), ray2, k); + min2 = CGALi::squared_distance(ray2.source(), ray1, k); + return (min1 < min2) ? min1 : min2; + } } -} - - - - - -template -extern typename R::FT -squared_distance( - const Line_2 &line, - const Ray_2 &ray) -{ - typedef typename R::FT FT; - Vector_2 normalvec(line.a(), line.b()); - Vector_2 diff = ray.source()-line.point(); + } + + template + extern typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Line_2 &line, + const typename CGAL_WRAP(K)::Ray_2 &ray, + const K&) + { + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + Vector_2 normalvec(line.a(), line.b()); + Vector_2 diff = ray.source()-line.point(); FT sign_dist = diff*normalvec; if (sign_dist < FT(0)) { - if (is_acute_angle(normalvec, ray.direction().vector()) ) - return (FT)0; + if (is_acute_angle(normalvec, ray.direction().vector()) ) + return (FT)0; } else { - if (is_obtuse_angle(normalvec, ray.direction().vector()) ) - return (FT)0; + if (is_obtuse_angle(normalvec, ray.direction().vector()) ) + return (FT)0; } - return (typename R::FT)((sign_dist*sign_dist)/(normalvec*normalvec)); -} + return (typename K::FT)((sign_dist*sign_dist)/(normalvec*normalvec)); + } + template + inline typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Ray_2 &ray, + const typename CGAL_WRAP(K)::Line_2 &line, + const K& k) + { + return CGALi::squared_distance(line, ray, k); + } -template -inline typename R::FT -squared_distance( - const Ray_2 & ray, - const Line_2 & line) -{ - return squared_distance(line, ray); -} - - - -template -bool -_are_parallel( - const Line_2 &line1, - const Line_2 &line2) -{ + template + inline bool + _are_parallel(const typename CGAL_WRAP(K)::Line_2 &line1, + const typename CGAL_WRAP(K)::Line_2 &line2) + { return line1.a()*line2.b() == line2.a()*line1.b(); -} + } -template -typename R::FT -squared_distance( - const Line_2 &line1, - const Line_2 &line2) -{ - typedef typename R::FT FT; - if (_are_parallel(line1,line2)) - return squared_distance(line1.point(), line2); + template + inline typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Line_2 &line1, + const typename CGAL_WRAP(K)::Line_2 &line2, + const K& k) + { + typedef typename K::FT FT; + if (_are_parallel(line1,line2)) + return CGALi::squared_distance(line1.point(), line2, k); else - return (FT)0; + return (FT)0; + } + + template + extern void + distance_index(int &ind, + const typename CGAL_WRAP(K)::Point_2 &pt, + const typename CGAL_WRAP(K)::Ray_2 &ray) + { + if (!is_acute_angle(ray.direction().vector(),pt-ray.source())) { + ind = 0; + return; + } + ind = -1; + } + + template + extern void + distance_index(int &ind, + const typename CGAL_WRAP(K)::Point_2 &pt, + const typename CGAL_WRAP(K)::Segment_2 &seg) + { + if (!is_acute_angle(seg.target(),seg.source(),pt)) { + ind = 0; + return; + } + if (!is_acute_angle(seg.source(),seg.target(),pt)) { + ind = 1; + return; + } + ind = -1; + } + + template + inline typename K::FT + squared_distance_indexed(const typename CGAL_WRAP(K)::Point_2 &pt, + const typename CGAL_WRAP(K)::Ray_2 &ray, + int ind, + const K& k) + { + if (ind == 0) + return CGALi::squared_distance(pt, ray.source(), k); + return CGALi::squared_distance(pt, ray.supporting_line(), k); + } + + template + inline typename K::FT + squared_distance_indexed(const typename CGAL_WRAP(K)::Point_2 &pt, + const typename CGAL_WRAP(K)::Segment_2 &seg, + int ind, + const K& k) + { + if (ind == 0) + return CGALi::squared_distance(pt, seg.source(), k); + if (ind == 1) + return CGALi::squared_distance(pt, seg.target(), k); + return CGALi::squared_distance(pt, seg.supporting_line(), k); + } + +} // namespace CGALi + +template +inline typename K::FT +squared_distance( + const Point_2 & pt1, + const Point_2 & pt2) +{ + return CGALi::squared_distance(pt1, pt2, K()); +} + +template +class Squared_distance_to_line { + typename K::RT a, b, c, sqnorm; + public: + Squared_distance_to_line(typename K::Line_2 const &line) + : a(line.a()), b(line.b()), c(line.c()) + { + sqnorm = a*a+b*b; + } + typename K::FT operator()(typename K::Point_2 const &pt) const + { + typedef typename K::RT RT; + RT w = pt.hw(); + RT n = a*pt.hx() + b*pt.hy() + wmult((K*)0, c, w); + RT d = wmult((K*)0, sqnorm, w, w); + return K::make_FT(n*n, d); + } +}; + +template +inline typename K::FT +squared_distance( + const Point_2 &pt, + const Line_2 &line) +{ + return CGALi::squared_distance(pt, line, K()); } +template +inline typename K::FT +squared_distance( + const Line_2 & line, + const Point_2 & pt) +{ + return squared_distance(pt, line); +} + +template +class Squared_distance_to_ray { + typename K::Vector_2 ray_dir; + typename K::Point_2 ray_source; + Squared_distance_to_line supline_dist; + public: + Squared_distance_to_ray(typename K::Ray_2 const &ray) + : ray_dir(ray.direction().vector()), + ray_source(ray.source()), + supline_dist(ray.supporting_line()) + { } + typename K::FT operator()(typename K::Point_2 const &pt) const + { + Vector_2 diff = pt-ray_source; + if (!is_acute_angle(ray_dir,diff) ) + return (typename K::FT)(diff*diff); + return supline_dist(pt); + } +}; + + + +template +inline typename K::FT +squared_distance( + const Point_2 &pt, + const Ray_2 &ray) +{ + return CGALi::squared_distance(pt, ray, K()); +} + + +template +inline typename K::FT +squared_distance( + const Ray_2 & ray, + const Point_2 & pt) +{ + return squared_distance(pt, ray); +} + + + + +template +class Squared_distance_to_segment { + typename K::Point_2 seg_source, seg_target; + Squared_distance_to_line supline_dist; + typename K::Vector_2 segvec; + typename K::RT e; + public: + Squared_distance_to_segment(typename K::Segment_2 const &seg) + : seg_source(seg.source()), seg_target(seg.target()), + supline_dist(seg.supporting_line()) + { + segvec = seg_target-seg_source; + e = wdot(segvec,segvec); + } + typename K::FT operator()(typename K::Point_2 const &pt) const + { + typedef typename K::RT RT; + // assert that the segment is valid (non zero length). + Vector_2 diff = pt-seg_source; + RT d = wdot(diff,segvec); + if (d <= (RT)0) + return (typename K::FT)(diff*diff); + if (wmult((K*)0 ,d, segvec.hw()) > wmult((K*)0, e, diff.hw())) + return squared_distance(pt, seg_target); + return supline_dist(pt); + } +}; + + +template +inline typename K::FT +squared_distance( + const Point_2 &pt, + const Segment_2 &seg) +{ + return CGALi::squared_distance(pt, seg, K()); +} + + +template +inline typename K::FT +squared_distance( + const Segment_2 & seg, + const Point_2 & pt) +{ + return CGALi::squared_distance(pt, seg, K()); +} + + +template +inline typename K::FT +squared_distance( + const Segment_2 &seg1, + const Segment_2 &seg2) +{ + return CGALi::squared_distance(seg1, seg2, K()); +} + +template +inline typename K::FT +squared_distance( + const Segment_2 &seg, + const Ray_2 &ray) +{ + return CGALi::squared_distance(seg, ray, K()); +} + +template +inline typename K::FT +squared_distance( + const Ray_2 & ray, + const Segment_2 & seg) +{ + return CGALi::squared_distance(seg, ray, K()); +} + +template +inline typename K::FT +squared_distance( + const Segment_2 &seg, + const Line_2 &line) +{ + return CGALi::squared_distance(seg, line, K()); +} + +template +inline typename K::FT +squared_distance( + const Line_2 & line, + const Segment_2 & seg) +{ + return CGALi::squared_distance(seg, line, K()); +} + +template +inline typename K::FT +squared_distance( + const Ray_2 &ray1, + const Ray_2 &ray2) +{ + return CGALi::squared_distance(ray1, ray2, K()); +} + +template +inline typename K::FT +squared_distance( + const Line_2 &line, + const Ray_2 &ray) +{ + return CGALi::squared_distance(line, ray, K()); +} + +template +inline typename K::FT +squared_distance( + const Ray_2 & ray, + const Line_2 & line) +{ + return CGALi::squared_distance(line, ray, K()); +} + +template +inline typename K::FT +squared_distance( + const Line_2 &line1, + const Line_2 &line2) +{ + return CGALi::squared_distance(line1, line2, K()); +} CGAL_END_NAMESPACE - #endif diff --git a/Packages/Distance_2/include/CGAL/squared_distance_2_2.h b/Packages/Distance_2/include/CGAL/squared_distance_2_2.h index fe23351e246..f235f35f9ae 100644 --- a/Packages/Distance_2/include/CGAL/squared_distance_2_2.h +++ b/Packages/Distance_2/include/CGAL/squared_distance_2_2.h @@ -38,452 +38,530 @@ CGAL_BEGIN_NAMESPACE +namespace CGALi { - - -template -extern void -distance_index( - int &ind1, - int &ind2, - const Point_2 &pt, - const Triangle_2 &triangle) -{ - const Point_2 &vt0 = triangle.vertex(0); - const Point_2 &vt1 = triangle.vertex(1); - const Point_2 &vt2 = triangle.vertex(2); + template + extern void + distance_index(int &ind1, + int &ind2, + const typename CGAL_WRAP(K)::Point_2 &pt, + const typename CGAL_WRAP(K)::Triangle_2 &triangle) + { + typedef typename K::Point_2 Point_2; + const Point_2 &vt0 = triangle.vertex(0); + const Point_2 &vt1 = triangle.vertex(1); + const Point_2 &vt2 = triangle.vertex(2); if (left_turn(vt0, vt1, vt2)) { - if (right_turn(vt0, vt1, pt)) { - if (!is_acute_angle(vt0, vt1, pt)) { - if (right_turn(vt1, vt2, pt)) { - if (!is_acute_angle(vt1, vt2, pt)) { - ind1 = 2; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt1, pt)) { - ind1 = 1; ind2 = -1; - return; - } - ind1 = 1; ind2 = 2; - return; - } - ind1 = 1; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt0, pt)) { - if (right_turn(vt2, vt0, pt)) { - if (!is_acute_angle(vt0, vt2, pt)) { - ind1 = 2; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt0, pt)) { - ind1 = 0; ind2 = -1; - return; - } - ind1 = 2; ind2 = 0; - return; - } - ind1 = 0; ind2 = -1; - return; - } - ind1 = 0; ind2 = 1; - return; - } else { - if (right_turn(vt1, vt2, pt)) { - if (!is_acute_angle(vt1, vt2, pt)) { - if (right_turn(vt2, vt0, pt)) { - if (!is_acute_angle(vt0, vt2, pt)) { - ind1 = 2; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt0, pt)) { - ind1 = 0; ind2 = -1; - return; - } - ind1 = 2; ind2 = 0; - return; - } - ind1 = 0; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt1, pt)) { - ind1 = 1; ind2 = -1; - return; - } - ind1 = 1; ind2 = 2; - return; - } else { - if (right_turn(vt2, vt0, pt)) { - if (!is_acute_angle(vt2, vt0, pt)) { - ind1 = 0; ind2 = -1; - return; - } - if (!is_acute_angle(vt0, vt2, pt)) { - ind1 = 2; ind2 = -1; - return; - } - ind1 = 2; ind2 = 0; - return; - } else { - ind1 = -1; ind2 = -1; // point inside or on boundary. - return; - } - } - } + if (right_turn(vt0, vt1, pt)) { + if (!is_acute_angle(vt0, vt1, pt)) { + if (right_turn(vt1, vt2, pt)) { + if (!is_acute_angle(vt1, vt2, pt)) { + ind1 = 2; ind2 = -1; + return; + } + if (!is_acute_angle(vt2, vt1, pt)) { + ind1 = 1; ind2 = -1; + return; + } + ind1 = 1; ind2 = 2; + return; + } + ind1 = 1; ind2 = -1; + return; + } + if (!is_acute_angle(vt1, vt0, pt)) { + if (right_turn(vt2, vt0, pt)) { + if (!is_acute_angle(vt0, vt2, pt)) { + ind1 = 2; ind2 = -1; + return; + } + if (!is_acute_angle(vt2, vt0, pt)) { + ind1 = 0; ind2 = -1; + return; + } + ind1 = 2; ind2 = 0; + return; + } + ind1 = 0; ind2 = -1; + return; + } + ind1 = 0; ind2 = 1; + return; + } else { + if (right_turn(vt1, vt2, pt)) { + if (!is_acute_angle(vt1, vt2, pt)) { + if (right_turn(vt2, vt0, pt)) { + if (!is_acute_angle(vt0, vt2, pt)) { + ind1 = 2; ind2 = -1; + return; + } + if (!is_acute_angle(vt2, vt0, pt)) { + ind1 = 0; ind2 = -1; + return; + } + ind1 = 2; ind2 = 0; + return; + } + ind1 = 0; ind2 = -1; + return; + } + if (!is_acute_angle(vt2, vt1, pt)) { + ind1 = 1; ind2 = -1; + return; + } + ind1 = 1; ind2 = 2; + return; + } else { + if (right_turn(vt2, vt0, pt)) { + if (!is_acute_angle(vt2, vt0, pt)) { + ind1 = 0; ind2 = -1; + return; + } + if (!is_acute_angle(vt0, vt2, pt)) { + ind1 = 2; ind2 = -1; + return; + } + ind1 = 2; ind2 = 0; + return; + } else { + ind1 = -1; ind2 = -1; // point inside or on boundary. + return; + } + } + } } else { - if (right_turn(vt0, vt2, pt)) { - if (!is_acute_angle(vt0, vt2, pt)) { - if (right_turn(vt2, vt1, pt)) { - if (!is_acute_angle(vt2, vt1, pt)) { - ind1 = 1; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt2, pt)) { - ind1 = 2; ind2 = -1; - return; - } - ind1 = 2; ind2 = 1; - return; - } - ind1 = 2; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt0, pt)) { - if (right_turn(vt1, vt0, pt)) { - if (!is_acute_angle(vt0, vt1, pt)) { - ind1 = 1; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt0, pt)) { - ind1 = 0; ind2 = -1; - return; - } - ind1 = 1; ind2 = 0; - return; - } - ind1 = 0; ind2 = -1; - return; - } - ind1 = 0; ind2 = 2; - return; - } else { - if (right_turn(vt2, vt1, pt)) { - if (!is_acute_angle(vt2, vt1, pt)) { - if (right_turn(vt1, vt0, pt)) { - if (!is_acute_angle(vt0, vt1, pt)) { - ind1 = 1; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt0, pt)) { - ind1 = 0; ind2 = -1; - return; - } - ind1 = 1; ind2 = 0; - return; - } - ind1 = 0; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt2, pt)) { - ind1 = 2; ind2 = -1; - return; - } - ind1 = 2; ind2 = 1; - return; - } else { - if (right_turn(vt1, vt0, pt)) { - if (!is_acute_angle(vt1, vt0, pt)) { - ind1 = 0; ind2 = -1; - return; - } - if (!is_acute_angle(vt0, vt1, pt)) { - ind1 = 1; ind2 = -1; - return; - } - ind1 = 1; ind2 = 0; - return; - } else { - ind1 = -1; ind2 = -1; // point inside or on boundary. - return; - } - } - } + if (right_turn(vt0, vt2, pt)) { + if (!is_acute_angle(vt0, vt2, pt)) { + if (right_turn(vt2, vt1, pt)) { + if (!is_acute_angle(vt2, vt1, pt)) { + ind1 = 1; ind2 = -1; + return; + } + if (!is_acute_angle(vt1, vt2, pt)) { + ind1 = 2; ind2 = -1; + return; + } + ind1 = 2; ind2 = 1; + return; + } + ind1 = 2; ind2 = -1; + return; + } + if (!is_acute_angle(vt2, vt0, pt)) { + if (right_turn(vt1, vt0, pt)) { + if (!is_acute_angle(vt0, vt1, pt)) { + ind1 = 1; ind2 = -1; + return; + } + if (!is_acute_angle(vt1, vt0, pt)) { + ind1 = 0; ind2 = -1; + return; + } + ind1 = 1; ind2 = 0; + return; + } + ind1 = 0; ind2 = -1; + return; + } + ind1 = 0; ind2 = 2; + return; + } else { + if (right_turn(vt2, vt1, pt)) { + if (!is_acute_angle(vt2, vt1, pt)) { + if (right_turn(vt1, vt0, pt)) { + if (!is_acute_angle(vt0, vt1, pt)) { + ind1 = 1; ind2 = -1; + return; + } + if (!is_acute_angle(vt1, vt0, pt)) { + ind1 = 0; ind2 = -1; + return; + } + ind1 = 1; ind2 = 0; + return; + } + ind1 = 0; ind2 = -1; + return; + } + if (!is_acute_angle(vt1, vt2, pt)) { + ind1 = 2; ind2 = -1; + return; + } + ind1 = 2; ind2 = 1; + return; + } else { + if (right_turn(vt1, vt0, pt)) { + if (!is_acute_angle(vt1, vt0, pt)) { + ind1 = 0; ind2 = -1; + return; + } + if (!is_acute_angle(vt0, vt1, pt)) { + ind1 = 1; ind2 = -1; + return; + } + ind1 = 1; ind2 = 0; + return; + } else { + ind1 = -1; ind2 = -1; // point inside or on boundary. + return; + } + } + } } -} + } -template -extern typename R::FT -squared_distance_indexed(const Point_2 &pt, - const Triangle_2 &triangle, int ind1, int ind2) -{ - typedef typename R::FT FT; + template + extern typename K::FT + squared_distance_indexed(const typename CGAL_WRAP(K)::Point_2 &pt, + const typename CGAL_WRAP(K)::Triangle_2 &triangle, + int ind1, int ind2, + const K& k) + { + typedef typename K::FT FT; + typedef typename K::Line_2 Line_2; if (ind1 == -1) - return FT(0); + return FT(0); if (ind2 == -1) - return squared_distance(pt, triangle.vertex(ind1)); - return squared_distance(pt, - Line_2(triangle.vertex(ind1), triangle.vertex(ind2))); -} + return CGALi::squared_distance(pt, triangle.vertex(ind1), k); + return CGALi::squared_distance(pt, + Line_2(triangle.vertex(ind1), triangle.vertex(ind2)), + k); + } -template -extern typename R::FT -squared_distance( - const Point_2 &pt, - const Triangle_2 &triangle) -{ + template + extern typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Point_2 &pt, + const typename CGAL_WRAP(K)::Triangle_2 &triangle, + const K& k) + { int ind1,ind2; - distance_index(ind1, ind2, pt, triangle); - return squared_distance_indexed(pt, triangle, ind1, ind2); -} + distance_index(ind1, ind2, pt, triangle); + return squared_distance_indexed(pt, triangle, ind1, ind2, k); + } -template -inline typename R::FT -squared_distance( - const Triangle_2 & triangle, - const Point_2 & pt) -{ - return squared_distance(pt, triangle); -} + template + inline typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Triangle_2 & triangle, + const typename CGAL_WRAP(K)::Point_2 & pt, + const K& k) + { + return CGALi::squared_distance(pt, triangle, k); + } - -template -extern typename R::FT -squared_distance( - const Line_2 &line, - const Triangle_2 &triangle) -{ - typedef typename R::FT FT; + template + extern typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Line_2 &line, + const typename CGAL_WRAP(K)::Triangle_2 &triangle, + const K& k) + { + typedef typename K::FT FT; Oriented_side side0; side0 = line.oriented_side(triangle.vertex(0)); if (line.oriented_side(triangle.vertex(1)) != side0) - return FT(0); + return FT(0); if (line.oriented_side(triangle.vertex(2)) != side0) - return FT(0); + return FT(0); FT mindist, dist; int i; - mindist = squared_distance(triangle.vertex(0),line); + mindist = CGALi::squared_distance(triangle.vertex(0),line,k); for (i=1; i<3; i++) { - dist = squared_distance(triangle.vertex(i),line); - if (dist < mindist) - mindist = dist; + dist = CGALi::squared_distance(triangle.vertex(i),line,k); + if (dist < mindist) + mindist = dist; } return mindist; -} + } -template -inline typename R::FT -squared_distance( - const Triangle_2 & triangle, - const Line_2 & line) -{ - return squared_distance(line, triangle); -} + template + inline typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Triangle_2 & triangle, + const typename CGAL_WRAP(K)::Line_2 & line, + const K& k) + { + return CGALi::squared_distance(line, triangle, k); + } - -template -extern typename R::FT -squared_distance( - const Ray_2 &ray, - const Triangle_2 &triangle) -{ - typedef typename R::FT FT; + template + extern typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Ray_2 &ray, + const typename CGAL_WRAP(K)::Triangle_2 &triangle, + const K& k) + { + typedef typename K::FT FT; + typedef typename K::Point_2 Point_2; + typedef typename K::Line_2 Line_2; int i, ind_tr1, ind_tr2, ind_ray = 0, ind1; FT mindist, dist; - distance_index(ind_tr1, ind_tr2, ray.source(), triangle); + distance_index(ind_tr1, ind_tr2, ray.source(), triangle); mindist = - squared_distance_indexed(ray.source(), triangle, ind_tr1,ind_tr2); + squared_distance_indexed(ray.source(), triangle, ind_tr1, ind_tr2, k); for (i=0; i<3; i++) { - const Point_2& pt = triangle.vertex(i); - distance_index(ind1, pt, ray); - dist = squared_distance_indexed(pt, ray, ind1); - if (dist < mindist) { - ind_ray = ind1; - ind_tr1 = i; ind_tr2 = -1; - mindist = dist; - } + const Point_2& pt = triangle.vertex(i); + distance_index(ind1, pt, ray); + dist = squared_distance_indexed(pt, ray, ind1, k); + if (dist < mindist) { + ind_ray = ind1; + ind_tr1 = i; ind_tr2 = -1; + mindist = dist; + } } // now check if all vertices are on the right side of the separating line. // In case of vertex-vertex smallest distance this is the case. if (ind_tr2 == -1 && ind_ray != -1) - return mindist; + return mindist; if (ind_tr2 != -1) { -// Check if all the segment vertices lie at the same side of -// the triangle segment. - const Point_2 &vt1 = triangle.vertex(ind_tr1); - const Point_2 &vt2 = triangle.vertex(ind_tr2); - if (clockwise(ray.direction().vector(), vt2-vt1)) { - mindist = FT(0); - } + // Check if all the segment vertices lie at the same side of + // the triangle segment. + const Point_2 &vt1 = triangle.vertex(ind_tr1); + const Point_2 &vt2 = triangle.vertex(ind_tr2); + if (clockwise(ray.direction().vector(), vt2-vt1)) { + mindist = FT(0); + } } else { -// Check if all the triangle vertices lie at the same side of the segment. - const Line_2 &sl = ray.supporting_line(); - Oriented_side or_s = sl.oriented_side(triangle.vertex(0)); - for (i=1; i<3; i++) { - if (sl.oriented_side(triangle.vertex(i)) != or_s) { - mindist = FT(0); - break; - } - } + // Check if all the triangle vertices lie + // at the same side of the segment. + const Line_2 &sl = ray.supporting_line(); + Oriented_side or_s = sl.oriented_side(triangle.vertex(0)); + for (i=1; i<3; i++) { + if (sl.oriented_side(triangle.vertex(i)) != or_s) { + mindist = FT(0); + break; + } + } } return mindist; -} + } -template -inline typename R::FT -squared_distance( - const Triangle_2 & triangle, - const Ray_2 & ray) -{ - return squared_distance(ray, triangle); -} + template + inline typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Triangle_2 & triangle, + const typename CGAL_WRAP(K)::Ray_2 & ray, + const K& k) + { + return CGALi::squared_distance(ray, triangle, k); + } - -template -extern typename R::FT -squared_distance( - const Segment_2 &seg, - const Triangle_2 &triangle) -{ - typedef typename R::FT FT; + template + extern typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Segment_2 &seg, + const typename CGAL_WRAP(K)::Triangle_2 &triangle, + const K& k) + { + typedef typename K::FT FT; + typedef typename K::Point_2 Point_2; int i, ind_tr1 = 0, ind_tr2 = -1, ind_seg = 0, ind1, ind2; FT mindist, dist; - mindist = squared_distance(seg.source(), triangle.vertex(0)); + mindist = CGALi::squared_distance(seg.source(), triangle.vertex(0), k); for (i=0; i<2; i++) { - const Point_2 &pt = seg.vertex(i); - distance_index(ind1, ind2, pt, triangle); - dist = squared_distance_indexed(pt, triangle, ind1, ind2); - if (dist < mindist) { - ind_seg = i; - ind_tr1 = ind1; ind_tr2 = ind2; - mindist = dist; - } + const Point_2 &pt = seg.vertex(i); + distance_index(ind1, ind2, pt, triangle); + dist = CGALi::squared_distance_indexed(pt, triangle, ind1, ind2, k); + if (dist < mindist) { + ind_seg = i; + ind_tr1 = ind1; ind_tr2 = ind2; + mindist = dist; + } } for (i=0; i<3; i++) { - const Point_2& pt = triangle.vertex(i); - distance_index(ind1, pt, seg); - dist = squared_distance_indexed(pt, seg, ind1); - if (dist < mindist) { - ind_seg = ind1; - ind_tr1 = i; ind_tr2 = -1; - mindist = dist; - } + const Point_2& pt = triangle.vertex(i); + distance_index(ind1, pt, seg); + dist = CGALi::squared_distance_indexed(pt, seg, ind1, k); + if (dist < mindist) { + ind_seg = ind1; + ind_tr1 = i; ind_tr2 = -1; + mindist = dist; + } } // now check if all vertices are on the right side of the separating line. // In case of vertex-vertex smallest distance this is the case. if (ind_tr2 == -1 && ind_seg != -1) - return mindist; + return mindist; if (ind_tr2 != -1) { -// Check if all the segment vertices lie at the same side of -// the triangle segment. - const Point_2 &vt1 = triangle.vertex(ind_tr1); - const Point_2 &vt2 = triangle.vertex(ind_tr2); - Orientation or_s = orientation(vt1, vt2, seg.source()); - if (orientation(vt1, vt2, seg.target()) != or_s) { - mindist = FT(0); - } + // Check if all the segment vertices lie at the same side of + // the triangle segment. + const Point_2 &vt1 = triangle.vertex(ind_tr1); + const Point_2 &vt2 = triangle.vertex(ind_tr2); + Orientation or_s = orientation(vt1, vt2, seg.source()); + if (orientation(vt1, vt2, seg.target()) != or_s) { + mindist = FT(0); + } } else { -// Check if all the triangle vertices lie at the same side of the segment. - const Point_2 &vt1 = seg.source(); - const Point_2 &vt2 = seg.target(); - Orientation or_s = orientation(vt1, vt2, triangle.vertex(0)); - for (i=1; i<3; i++) { - if (orientation(vt1, vt2, triangle.vertex(i)) != or_s) { - mindist = FT(0); - break; - } - } + // Check if all the triangle vertices lie + // at the same side of the segment. + const Point_2 &vt1 = seg.source(); + const Point_2 &vt2 = seg.target(); + Orientation or_s = orientation(vt1, vt2, triangle.vertex(0)); + for (i=1; i<3; i++) { + if (orientation(vt1, vt2, triangle.vertex(i)) != or_s) { + mindist = FT(0); + break; + } + } } return mindist; -} + } -template -inline typename R::FT -squared_distance( - const Triangle_2 & triangle, - const Segment_2 & seg) -{ - return squared_distance(seg, triangle); -} + template + inline typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Triangle_2 & triangle, + const typename CGAL_WRAP(K)::Segment_2 & seg, + const K& k) + { + return CGALi::squared_distance(seg, triangle, k); + } -template -extern typename R::FT -squared_distance( - const Triangle_2 &triangle1, - const Triangle_2 &triangle2) -{ - typedef typename R::FT FT; + template + extern typename K::FT + squared_distance(const typename CGAL_WRAP(K)::Triangle_2 &triangle1, + const typename CGAL_WRAP(K)::Triangle_2 &triangle2, + const K& k) + { + typedef typename K::FT FT; + typedef typename K::Point_2 Point_2; int i, ind1_1 = 0,ind1_2 = -1, ind2_1 = 0, ind2_2 = -1, ind1, ind2; FT mindist, dist; mindist = - squared_distance(triangle1.vertex(0), triangle2.vertex(0)); + CGALi::squared_distance(triangle1.vertex(0), triangle2.vertex(0), k); for (i=0; i<3; i++) { - const Point_2& pt = triangle1.vertex(i); - distance_index(ind1, ind2, pt, triangle2); - dist = squared_distance_indexed(pt, triangle2, ind1, ind2); - if (dist < mindist) { - ind1_1 = i; ind1_2 = -1; - ind2_1 = ind1; ind2_2 = ind2; - mindist = dist; - } + const Point_2& pt = triangle1.vertex(i); + distance_index(ind1, ind2, pt, triangle2); + dist = squared_distance_indexed(pt, triangle2, ind1, ind2, k); + if (dist < mindist) { + ind1_1 = i; ind1_2 = -1; + ind2_1 = ind1; ind2_2 = ind2; + mindist = dist; + } } for (i=0; i<3; i++) { - const Point_2& pt = triangle2.vertex(i); - distance_index(ind1, ind2, pt, triangle1); - dist = squared_distance_indexed(pt, triangle1, ind1, ind2); - if (dist < mindist) { - ind1_1 = ind1; ind1_2 = ind2; - ind2_1 = i; ind2_2 = -1; - mindist = dist; - } + const Point_2& pt = triangle2.vertex(i); + distance_index(ind1, ind2, pt, triangle1); + dist = squared_distance_indexed(pt, triangle1, ind1, ind2, k); + if (dist < mindist) { + ind1_1 = ind1; ind1_2 = ind2; + ind2_1 = i; ind2_2 = -1; + mindist = dist; + } } - // now check if all vertices are on the right side of the separating line. + // now check if all vertices are on the right side of the + // separating line. if (ind1_2 == -1 && ind2_2 == -1) - return mindist; - // In case of point-segment closest distance, there is still the possibility - // of overlapping triangles. - // Check if all the vertices lie at the same side of the segment. + return mindist; + // In case of point-segment closest distance, there is still the + // possibility of overlapping triangles. Check if all the + // vertices lie at the same side of the segment. if (ind1_2 != -1) { - const Point_2 &vt1 = triangle1.vertex(ind1_1); - const Point_2 &vt2 = triangle1.vertex(ind1_2); - Orientation or_s = orientation(vt1, vt2, triangle2.vertex(0)); - for (i=1; i<3; i++) { - if (orientation(vt1, vt2, triangle2.vertex(i)) != or_s) { - mindist = FT(0); - break; - } - } + const Point_2 &vt1 = triangle1.vertex(ind1_1); + const Point_2 &vt2 = triangle1.vertex(ind1_2); + Orientation or_s = orientation(vt1, vt2, triangle2.vertex(0)); + for (i=1; i<3; i++) { + if (orientation(vt1, vt2, triangle2.vertex(i)) != or_s) { + mindist = FT(0); + break; + } + } } else { - const Point_2 &vt1 = triangle2.vertex(ind2_1); - const Point_2 &vt2 = triangle2.vertex(ind2_2); - Orientation or_s = orientation(vt1, vt2, triangle1.vertex(0)); - for (i=1; i<3; i++) { - if (orientation(vt1, vt2, triangle1.vertex(i)) != or_s) { - mindist = FT(0); - break; - } - } + const Point_2 &vt1 = triangle2.vertex(ind2_1); + const Point_2 &vt2 = triangle2.vertex(ind2_2); + Orientation or_s = orientation(vt1, vt2, triangle1.vertex(0)); + for (i=1; i<3; i++) { + if (orientation(vt1, vt2, triangle1.vertex(i)) != or_s) { + mindist = FT(0); + break; + } + } } return mindist; + } + +} // namespace CGALi + +template +inline typename K::FT +squared_distance(const Point_2 &pt, + const Triangle_2 &triangle) +{ + return CGALi::squared_distance(pt, triangle, K()); } +template +inline typename K::FT +squared_distance(const Triangle_2 &triangle, + const Point_2 &pt) +{ + return CGALi::squared_distance(pt, triangle, K()); +} +template +inline typename K::FT +squared_distance(const Line_2 &line, + const Triangle_2 &triangle) +{ + return CGALi::squared_distance(line, triangle, K()); +} + +template +inline typename K::FT +squared_distance(const Triangle_2 &triangle, + const Line_2 &line) +{ + return CGALi::squared_distance(line, triangle, K()); +} + +template +inline typename K::FT +squared_distance(const Ray_2 &ray, + const Triangle_2 &triangle) +{ + return CGALi::squared_distance(ray, triangle, K()); +} + +template +inline typename K::FT +squared_distance(const Triangle_2 &triangle, + const Ray_2 &ray) +{ + return CGALi::squared_distance(ray, triangle, K()); +} + +template +inline typename K::FT +squared_distance(const Segment_2 &seg, + const Triangle_2 &triangle) +{ + return CGALi::squared_distance(seg, triangle, K()); +} + +template +inline typename K::FT +squared_distance(const Triangle_2 &triangle, + const Segment_2 &seg) +{ + return CGALi::squared_distance(seg, triangle, K()); +} + +template +inline typename K::FT +squared_distance(const Triangle_2 &triangle1, + const Triangle_2 &triangle2) +{ + return CGALi::squared_distance(triangle1, triangle2, K()); +} CGAL_END_NAMESPACE - #endif