diff --git a/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h b/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h index d131a15eba9..e035a0562b1 100644 --- a/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h +++ b/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h @@ -20,6 +20,7 @@ #include #include #include +#include #include namespace CGAL { @@ -201,11 +202,7 @@ bool is_short() const bool is_long() const /*{\Mop a segment is long iff it is longer than a halfcircle.}*/ -{ return R().orientation_3_object()(CGAL::ORIGIN, - source(), - target(), - orthogonal_pole()) - == CGAL::NEGATIVE; } +{ return is_long(orthogonal_pole()); } bool is_degenerate() const { return source() == target(); } /*{\Mop return true iff |\Mvar| is degenerate.}*/ @@ -231,23 +228,51 @@ bool operator!=(const Sphere_segment& so) const private: -Point_3 orthogonal_pole() const +template +friend bool do_intersect_internally(const Sphere_segment& s1, + const Sphere_segment& s2, + Sphere_point& p); + +template +friend bool do_intersect_internally(const Sphere_circle& c1, + const Sphere_segment& s2, + Sphere_point& p); + +Sphere_point orthogonal_pole() const { return CGAL::ORIGIN + sphere_circle().orthogonal_vector(); } -CGAL::Orientation source_orientation(const CGAL::Sphere_point& p) const +inline CGAL::Orientation source_orientation(const CGAL::Sphere_point& p, + const CGAL::Sphere_point& pole) const { return R().orientation_3_object()(CGAL::ORIGIN, - orthogonal_pole(), + pole, source(), p); } -CGAL::Orientation target_orientation(const CGAL::Sphere_point& p) const +inline CGAL::Orientation target_orientation(const CGAL::Sphere_point& p, + const CGAL::Sphere_point& pole) const { return R().orientation_3_object()(CGAL::ORIGIN, target(), - orthogonal_pole(), + pole, p); } +bool is_long(const Sphere_point& pole) const +{ return R().orientation_3_object()(CGAL::ORIGIN, + source(), + target(), + pole) + == CGAL::NEGATIVE; } + +bool has_in_relative_interior(const CGAL::Sphere_point& p, + const CGAL::Sphere_point& pole, + bool long_segment, + bool check_has_on = true) const; + +bool has_in_relative_interior(const CGAL::Sphere_point& p, + std::unique_ptr>& pole, + std::unique_ptr& long_segment, + bool check_has_on = true) const; }; template @@ -305,35 +330,59 @@ template bool Sphere_segment:: has_on(const CGAL::Sphere_point& p) const { if ( !sphere_circle().has_on(p) ) return false; - if ( !is_long() ) { - return source_orientation(p) != CGAL::NEGATIVE && - target_orientation(p) != CGAL::NEGATIVE; + const Sphere_point& pole = orthogonal_pole(); + if ( !is_long(pole) ) { + return source_orientation(p, pole) != CGAL::NEGATIVE && + target_orientation(p, pole) != CGAL::NEGATIVE; } else { - return source_orientation(p) != CGAL::NEGATIVE || - target_orientation(p) != CGAL::NEGATIVE; + return source_orientation(p, pole) != CGAL::NEGATIVE || + target_orientation(p, pole) != CGAL::NEGATIVE; } } template bool Sphere_segment:: has_on_after_intersection(const CGAL::Sphere_point& p) const -{ return source_orientation(p) != CGAL::NEGATIVE && - target_orientation(p) != CGAL::NEGATIVE; +{ const Sphere_point& pole = orthogonal_pole(); + return source_orientation(p, pole) != CGAL::NEGATIVE && + target_orientation(p, pole) != CGAL::NEGATIVE; } template bool Sphere_segment:: has_in_relative_interior(const CGAL::Sphere_point& p, bool check_has_on) const { if (check_has_on &&( !sphere_circle().has_on(p) ) ) return false; - if ( !is_long() ) { - return source_orientation(p) == CGAL::POSITIVE && - target_orientation(p) == CGAL::POSITIVE; + const Sphere_point& pole = orthogonal_pole(); + return has_in_relative_interior(p, pole, is_long(pole), false); +} + +template +bool Sphere_segment:: +has_in_relative_interior(const CGAL::Sphere_point& p, + const CGAL::Sphere_point& pole, + bool long_segment, + bool check_has_on) const +{ if (check_has_on &&( !sphere_circle().has_on(p) ) ) return false; + if (!long_segment) { + return source_orientation(p, pole) == CGAL::POSITIVE && + target_orientation(p, pole) == CGAL::POSITIVE; } else { - return source_orientation(p) == CGAL::POSITIVE || - target_orientation(p) == CGAL::POSITIVE; + return source_orientation(p, pole) == CGAL::POSITIVE || + target_orientation(p, pole) == CGAL::POSITIVE; } } +template +bool Sphere_segment:: +has_in_relative_interior(const CGAL::Sphere_point& p, + std::unique_ptr>& pole, + std::unique_ptr& long_segment, + bool check_has_on) const +{ if (check_has_on &&( !sphere_circle().has_on(p) ) ) return false; + if(!pole) pole = std::make_unique>(orthogonal_pole()); + if(!long_segment) long_segment = std::make_unique(is_long(*pole)); + return has_in_relative_interior(p, *pole, *long_segment, false); +} /* Intersection of two sphere segments. It does not work if the two @@ -358,11 +407,15 @@ bool do_intersect_internally(const Sphere_segment& s1, if ( equal_as_sets(s1.sphere_circle(),s2.sphere_circle()) ) return false; p = CGAL::intersection(s1.sphere_circle(),s2.sphere_circle()); - if ( s1.has_in_relative_interior(p, false) && - s2.has_in_relative_interior(p, false) ) return true; + + std::unique_ptr> s1_pole,s2_pole; + std::unique_ptr s1_long,s2_long; + + if ( s1.has_in_relative_interior(p, s1_pole, s1_long, false) && + s2.has_in_relative_interior(p, s2_pole, s2_long, false) ) return true; p = p.antipode(); - if ( s1.has_in_relative_interior(p, false) && - s2.has_in_relative_interior(p, false) ) return true; + if ( s1.has_in_relative_interior(p, s1_pole, s1_long, false) && + s2.has_in_relative_interior(p, s2_pole, s2_long, false) ) return true; return false; } @@ -375,9 +428,13 @@ bool do_intersect_internally(const Sphere_circle& c1, if ( equal_as_sets(c1,s2.sphere_circle()) ) return false; p = CGAL::intersection(c1,s2.sphere_circle()); - if ( s2.has_in_relative_interior(p, false) ) return true; + + const Sphere_point& s2_pole = s2.orthogonal_pole(); + bool s2_long = s2.is_long(s2_pole); + + if ( s2.has_in_relative_interior(p, s2_pole, s2_long, false) ) return true; p = p.antipode(); - if ( s2.has_in_relative_interior(p, false) ) return true; + if ( s2.has_in_relative_interior(p, s2_pole, s2_long, false) ) return true; return false; }