📄 finite_edge_interior_conflict_c2.h
字号:
// Copyright (c) 2003,2004,2005,2006 INRIA Sophia-Antipolis (France) and// Notre Dame University (U.S.A.). All rights reserved.//// This file is part of CGAL (www.cgal.org); you may redistribute it under// the terms of the Q Public License version 1.0.// See the file LICENSE.QPL distributed with CGAL.//// Licensees holding a valid commercial license may use this file in// accordance with the commercial license agreement provided with the software.//// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.//// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.3-branch/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Finite_edge_interior_conflict_C2.h $// $Id: Finite_edge_interior_conflict_C2.h 37157 2007-03-16 10:49:14Z afabri $// //// Author(s) : Menelaos Karavelas <mkaravel@cse.nd.edu>#ifndef CGAL_SEGMENT_DELAUNAY_GRAPH_2_FINITE_EDGE_INTERIOR_CONFLICT_C2_H#define CGAL_SEGMENT_DELAUNAY_GRAPH_2_FINITE_EDGE_INTERIOR_CONFLICT_C2_H#include <CGAL/Segment_Delaunay_graph_2/Basic_predicates_C2.h>#include <CGAL/Segment_Delaunay_graph_2/Voronoi_vertex_C2.h>#include <CGAL/Segment_Delaunay_graph_2/Are_same_points_C2.h>#include <CGAL/Segment_Delaunay_graph_2/Are_same_segments_C2.h>CGAL_BEGIN_NAMESPACECGAL_SEGMENT_DELAUNAY_GRAPH_2_BEGIN_NAMESPACE//-----------------------------------------------------------------------------template<class K, class Method_tag>class Finite_edge_interior_conflict_C2 : public Basic_predicates_C2<K>{public: typedef Basic_predicates_C2<K> Base; typedef Voronoi_vertex_C2<K,Method_tag> Voronoi_vertex_2; typedef typename Base::Point_2 Point_2; typedef typename Base::Segment_2 Segment_2; typedef typename Base::Line_2 Line_2; typedef typename Base::Site_2 Site_2; typedef typename Base::FT FT; typedef typename Base::RT RT; typedef typename Base::Comparison_result Comparison_result; typedef typename Base::Sign Sign; typedef typename Base::Orientation Orientation; typedef typename Base::Oriented_side Oriented_side; typedef typename Base::Homogeneous_point_2 Homogeneous_point_2;private: typedef Are_same_points_C2<K> Are_same_points_2; typedef Are_same_segments_C2<K> Are_same_segments_2; typedef typename K::Intersections_tag ITag;private: Are_same_points_2 same_points; Are_same_segments_2 same_segments;private: //-------------------------------------------------------------------- //-------------------------------------------------------------------- //-------------------------------------------------------------------- bool is_interior_in_conflict_both(const Site_2& p, const Site_2& q, const Site_2& r, const Site_2& s, const Site_2& t, Method_tag tag) const { bool in_conflict(false); if ( p.is_point() && q.is_point() ) { in_conflict = is_interior_in_conflict_both_pp(p, q, r, s, t, tag); } else if ( p.is_segment() && q.is_segment() ) { in_conflict = is_interior_in_conflict_both_ss(p, q, r, s, t, tag); } else if ( p.is_point() && q.is_segment() ) { in_conflict = is_interior_in_conflict_both_ps(p, q, r, s, t, tag); } else { // p is a segment and q is a point in_conflict = is_interior_in_conflict_both_sp(p, q, r, s, t, tag); } return in_conflict; } //-------------------------------------------------------------------- bool is_interior_in_conflict_both_pp(const Site_2& sp, const Site_2& sq, const Site_2& r, const Site_2& s, const Site_2& t, Method_tag ) const { CGAL_precondition( sp.is_point() && sq.is_point() ); Point_2 p = sp.point(), q = sq.point(); if ( t.is_point() ) { return true; } Line_2 lt = compute_supporting_line(t.supporting_site()); Oriented_side op, oq; if ( same_points(sp, t.source_site()) || same_points(sp, t.target_site()) ) { op = ON_ORIENTED_BOUNDARY; } else { op = oriented_side_of_line(lt, p); } if ( same_points(sq, t.source_site()) || same_points(sq, t.target_site()) ) { oq = ON_ORIENTED_BOUNDARY; } else { oq = oriented_side_of_line(lt, q); } if ((op == ON_POSITIVE_SIDE && oq == ON_NEGATIVE_SIDE) || (op == ON_NEGATIVE_SIDE && oq == ON_POSITIVE_SIDE) || (op == ON_ORIENTED_BOUNDARY || oq == ON_ORIENTED_BOUNDARY)) { return true; } Comparison_result res = compare_squared_distances_to_line(lt, p, q); if ( res == EQUAL ) { return true; } Voronoi_vertex_2 vpqr(sp, sq, r); Voronoi_vertex_2 vqps(sq, sp, s); Line_2 lperp; if ( res == SMALLER ) { // p is closer to lt than q lperp = compute_perpendicular(lt, p); } else { // q is closer to lt than p lperp = compute_perpendicular(lt, q); } Oriented_side opqr = vpqr.oriented_side(lperp); Oriented_side oqps = vqps.oriented_side(lperp); return ( opqr == oqps ); } //-------------------------------------------------------------------- bool is_interior_in_conflict_both_ss(const Site_2& p, const Site_2& q, const Site_2& , const Site_2& , const Site_2& , Method_tag) const { CGAL_precondition( p.is_segment() && q.is_segment() ); return true; } //-------------------------------------------------------------------- bool is_interior_in_conflict_both_ps(const Site_2& p, const Site_2& q, const Site_2& r, const Site_2& s, const Site_2& t, Method_tag tag) const { CGAL_precondition( p.is_point() && q.is_segment() ); if ( same_points(p, q.source_site()) || same_points(p, q.target_site()) ) { return false; } if ( t.is_point() ) { return is_interior_in_conflict_both_ps_p(p, q, r, s, t, tag); } return is_interior_in_conflict_both_ps_s(p, q, r, s, t, tag); } //-------------------------------------------------------------------- bool is_interior_in_conflict_both_ps_p(const Site_2& p, const Site_2& q, const Site_2& r, const Site_2& s, const Site_2& t, Method_tag ) const { CGAL_precondition( t.is_point() ); // Line_2 lq = compute_supporting_line(q); Line_2 lq = compute_supporting_line(q.supporting_site()); Comparison_result res = compare_squared_distances_to_line(lq, p.point(), t.point()); if ( res != SMALLER ) { return true; } Voronoi_vertex_2 vpqr(p, q, r); Voronoi_vertex_2 vqps(q, p, s); Line_2 lperp = compute_perpendicular(lq, p.point()); Oriented_side opqr = vpqr.oriented_side(lperp); Oriented_side oqps = vqps.oriented_side(lperp); return (opqr == oqps); } //-------------------------------------------------------------------- bool check_if_exact(const Site_2&, const Tag_false&) const { return true; } bool check_if_exact(const Site_2& t1, const Tag_true&) const { return t1.is_input(); } bool is_interior_in_conflict_both_ps_s(const Site_2& sp, const Site_2& sq, const Site_2& r, const Site_2& s, const Site_2& st, Method_tag ) const { CGAL_precondition( st.is_segment() ); Point_2 p = sp.point(); // Segment_2 q = sq.segment(), t = st.segment(); Line_2 lq = compute_supporting_line(sq.supporting_site()); if ( oriented_side_of_line(lq, p) == ON_NEGATIVE_SIDE ) { lq = opposite_line(lq); } if ( same_points(sp, st.source_site()) || same_points(sp, st.target_site()) ) { Line_2 lqperp = compute_perpendicular(lq, p); Voronoi_vertex_2 vpqr(sp, sq, r); Voronoi_vertex_2 vqps(sq, sp, s); Oriented_side opqr = vpqr.oriented_side(lqperp); Oriented_side oqps = vqps.oriented_side(lqperp); bool on_different_parabola_arcs = ((opqr == ON_NEGATIVE_SIDE && oqps == ON_POSITIVE_SIDE) || (opqr == ON_POSITIVE_SIDE && oqps == ON_NEGATIVE_SIDE)); if ( !on_different_parabola_arcs ) { return true; } Site_2 t1; if ( same_points(sp, st.source_site()) ) { t1 = st.target_site(); } else { t1 = st.source_site(); } Oriented_side o_t1; if ( same_points(t1, sq.source_site()) || same_points(t1, sq.target_site()) ) { o_t1 = ON_ORIENTED_BOUNDARY; } else if ( !check_if_exact(t1, ITag()) && ( same_segments(t1.supporting_site(0), sq.supporting_site()) || same_segments(t1.supporting_site(1), sq.supporting_site()) ) ) { o_t1 = ON_ORIENTED_BOUNDARY; } else { o_t1 = oriented_side_of_line(lq, t1.point()); } if ( o_t1 == ON_NEGATIVE_SIDE ) { return true; } Comparison_result res = compare_squared_distances_to_line(lq, p, t1.point()); return ( res == LARGER ); } Line_2 lt = compute_supporting_line(st.supporting_site()); if ( oriented_side_of_line(lt, p) == ON_NEGATIVE_SIDE ) { lt = opposite_line(lt); } Comparison_result res = CGAL::compare(lt.a() * lq.b(), lt.b() * lq.a()); bool are_parallel = (res == EQUAL); if ( are_parallel ) { Sign sgn = CGAL::sign(lt.a() * lq.a() + lt.b() * lq.b()); bool have_opposite_directions = (sgn == NEGATIVE); if ( have_opposite_directions ) { lq = opposite_line(lq); } if ( oriented_side_of_line(lq, p) == oriented_side_of_line(lt, p) ) { return true; } if ( have_opposite_directions ) { lq = opposite_line(lq); } } Line_2 l = compute_perpendicular(lt, p); Voronoi_vertex_2 vpqr(sp, sq, r); Voronoi_vertex_2 vqps(sq, sp, s); Oriented_side o_l_pqr = vpqr.oriented_side(l); Oriented_side o_l_qps = vqps.oriented_side(l); if ( o_l_pqr == ON_POSITIVE_SIDE && o_l_qps == ON_NEGATIVE_SIDE ) { return false; } if ( o_l_pqr == ON_NEGATIVE_SIDE && o_l_qps == ON_POSITIVE_SIDE ) { return true; } //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //>>>>>>>>>> HERE I NEED TO CHECK THE BOUNDARY CASES <<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Line_2 lqperp = compute_perpendicular(lq, p); Oriented_side opqr = vpqr.oriented_side(lqperp); Oriented_side oqps = vqps.oriented_side(lqperp); bool on_different_parabola_arcs = ((opqr == ON_NEGATIVE_SIDE && oqps == ON_POSITIVE_SIDE) || (opqr == ON_POSITIVE_SIDE && oqps == ON_NEGATIVE_SIDE)); if ( !on_different_parabola_arcs ) { return true; } Homogeneous_point_2 pv = projection_on_line(lq, p); Homogeneous_point_2 hp(p); pv = Base::midpoint(pv, hp); Oriented_side o_l_pv = oriented_side_of_line(l, pv); CGAL_assertion( o_l_pv != ON_ORIENTED_BOUNDARY ); CGAL_assertion( o_l_pqr != ON_ORIENTED_BOUNDARY ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -