From 1546446137199d0e1717f729e655634053e62a49 Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Sun, 15 Jan 2023 11:09:04 +0000 Subject: [PATCH 1/4] Reduce re-calculation of is_long and orthogonal_pole --- Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h | 80 ++++++++++++++------- 1 file changed, 55 insertions(+), 25 deletions(-) diff --git a/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h b/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h index e6ff36dd0ce..3643b273d5b 100644 --- a/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h +++ b/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h @@ -196,10 +196,13 @@ bool is_short() const bool is_long() const /*{\Mop a segment is long iff it is longer than a halfcircle.}*/ +{ return is_long(orthogonal_pole()); } + +bool is_long(const Sphere_point& pole) const { return R().orientation_3_object()(CGAL::ORIGIN, source(), target(), - orthogonal_pole()) + pole) == CGAL::NEGATIVE; } bool is_degenerate() const { return source() == target(); } @@ -216,6 +219,11 @@ bool has_on_after_intersection(const Sphere_point& p) const; /*{\Mop return true iff |\Mvar| contains |p| in its relative interior.}*/ +bool has_in_relative_interior(const CGAL::Sphere_point& p, + const CGAL::Sphere_point& pole, + bool is_long, + bool check_has_on = true) const; + bool operator==(const Sphere_segment& so) const { return source() == so.source() && target() == so.target() && (source() == target() || @@ -224,22 +232,24 @@ bool operator==(const Sphere_segment& so) const bool operator!=(const Sphere_segment& so) const { return !operator==(so); } -private: - Point_3 orthogonal_pole() const { return CGAL::ORIGIN + sphere_circle().orthogonal_vector(); } -CGAL::Orientation source_orientation(const CGAL::Sphere_point& p) const +private: + +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); } @@ -300,35 +310,47 @@ 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; - } else { - 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), check_has_on); } +template +bool Sphere_segment:: +has_in_relative_interior(const CGAL::Sphere_point& p, + const CGAL::Sphere_point& pole, + bool is_long, + bool check_has_on) const +{ if (check_has_on &&( !sphere_circle().has_on(p) ) ) return false; + if (!is_long) { + return source_orientation(p, pole) == CGAL::POSITIVE && + target_orientation(p, pole) == CGAL::POSITIVE; + } else { + return source_orientation(p, pole) == CGAL::POSITIVE || + target_orientation(p, pole) == CGAL::POSITIVE; + } +} /* Intersection of two sphere segments. It does not work if the two @@ -353,10 +375,14 @@ 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) && + + const Sphere_point& s1_pole = s1.orthogonal_pole(); + bool s1_long = s1.is_long(s1_pole); + + if ( s1.has_in_relative_interior(p, s1_pole, s1_long, false) && s2.has_in_relative_interior(p, false) ) return true; p = p.antipode(); - if ( s1.has_in_relative_interior(p, false) && + if ( s1.has_in_relative_interior(p, s1_pole, s1_long, false) && s2.has_in_relative_interior(p, false) ) return true; return false; } @@ -370,9 +396,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; } From eb09571d4aaf67affeed0fd83e5cce3b9aa7cd7e Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Sun, 15 Jan 2023 11:09:04 +0000 Subject: [PATCH 2/4] Orthogonal pole is Sphere_point not Point_3 --- Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h b/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h index 3643b273d5b..78c4f76e23d 100644 --- a/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h +++ b/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h @@ -232,7 +232,7 @@ bool operator==(const Sphere_segment& so) const bool operator!=(const Sphere_segment& so) const { return !operator==(so); } -Point_3 orthogonal_pole() const +Sphere_point orthogonal_pole() const { return CGAL::ORIGIN + sphere_circle().orthogonal_vector(); } private: From 63b4ec73253860403e067eedc7b84463a4b8c944 Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Sun, 15 Jan 2023 11:09:05 +0000 Subject: [PATCH 3/4] check_has_on should be false if its already been checked --- Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h b/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h index 78c4f76e23d..4b51ac9bb5d 100644 --- a/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h +++ b/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h @@ -333,7 +333,7 @@ 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; const Sphere_point& pole = orthogonal_pole(); - return has_in_relative_interior(p, pole, is_long(pole), check_has_on); + return has_in_relative_interior(p, pole, is_long(pole), false); } template From 1bc86ce8e8d281b0ab904116cf0fc2daf8ca5513 Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Mon, 16 Jan 2023 08:25:48 +0000 Subject: [PATCH 4/4] Additional overload, and make methods private --- Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h | 67 +++++++++++++++------ 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h b/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h index 4b51ac9bb5d..c3f80710ffe 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 { @@ -198,13 +199,6 @@ bool is_long() const /*{\Mop a segment is long iff it is longer than a halfcircle.}*/ { return is_long(orthogonal_pole()); } -bool is_long(const Sphere_point& pole) const -{ return R().orientation_3_object()(CGAL::ORIGIN, - source(), - target(), - pole) - == CGAL::NEGATIVE; } - bool is_degenerate() const { return source() == target(); } /*{\Mop return true iff |\Mvar| is degenerate.}*/ @@ -219,11 +213,6 @@ bool has_on_after_intersection(const Sphere_point& p) const; /*{\Mop return true iff |\Mvar| contains |p| in its relative interior.}*/ -bool has_in_relative_interior(const CGAL::Sphere_point& p, - const CGAL::Sphere_point& pole, - bool is_long, - bool check_has_on = true) const; - bool operator==(const Sphere_segment& so) const { return source() == so.source() && target() == so.target() && (source() == target() || @@ -232,11 +221,21 @@ bool operator==(const Sphere_segment& so) const bool operator!=(const Sphere_segment& so) const { return !operator==(so); } +private: + +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(); } -private: - inline CGAL::Orientation source_orientation(const CGAL::Sphere_point& p, const CGAL::Sphere_point& pole) const { return R().orientation_3_object()(CGAL::ORIGIN, @@ -253,6 +252,22 @@ inline CGAL::Orientation target_orientation(const CGAL::Sphere_point& p, 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 @@ -340,10 +355,10 @@ template bool Sphere_segment:: has_in_relative_interior(const CGAL::Sphere_point& p, const CGAL::Sphere_point& pole, - bool is_long, + bool long_segment, bool check_has_on) const { if (check_has_on &&( !sphere_circle().has_on(p) ) ) return false; - if (!is_long) { + if (!long_segment) { return source_orientation(p, pole) == CGAL::POSITIVE && target_orientation(p, pole) == CGAL::POSITIVE; } else { @@ -352,6 +367,18 @@ has_in_relative_interior(const CGAL::Sphere_point& p, } } +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 involved planes are equal as sets. */ @@ -376,14 +403,14 @@ bool do_intersect_internally(const Sphere_segment& s1, return false; p = CGAL::intersection(s1.sphere_circle(),s2.sphere_circle()); - const Sphere_point& s1_pole = s1.orthogonal_pole(); - bool s1_long = s1.is_long(s1_pole); + 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, false) ) return true; + s2.has_in_relative_interior(p, s2_pole, s2_long, false) ) return true; p = p.antipode(); if ( s1.has_in_relative_interior(p, s1_pole, s1_long, false) && - s2.has_in_relative_interior(p, false) ) return true; + s2.has_in_relative_interior(p, s2_pole, s2_long, false) ) return true; return false; }