📄 voronoi_vertex_ring_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/Voronoi_vertex_ring_C2.h $// $Id: Voronoi_vertex_ring_C2.h 37157 2007-03-16 10:49:14Z afabri $// //// Author(s) : Menelaos Karavelas <mkaravel@cse.nd.edu>#ifndef CGAL_SEGMENT_DELAUNAY_GRAPH_2_VORONOI_VERTEX_RING_C2_H#define CGAL_SEGMENT_DELAUNAY_GRAPH_2_VORONOI_VERTEX_RING_C2_H#include <CGAL/Segment_Delaunay_graph_2/Basic_predicates_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_NAMESPACEtemplate<class K>class Voronoi_vertex_ring_C2 : public Basic_predicates_C2<K>{public: typedef Basic_predicates_C2<K> Base; typedef enum {PPP = 0, PPS, PSS, SSS} vertex_t; struct PPP_Type {}; struct PPS_Type {}; struct PSS_Type {}; struct SSS_Type {}; 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::Sqrt_1 Sqrt_1; typedef typename Base::Sqrt_2 Sqrt_2; typedef typename Base::Sqrt_3 Sqrt_3; typedef typename Base::Homogeneous_point_2 Homogeneous_point_2; typedef typename Base::Orientation Orientation; typedef typename Base::Comparison_result Comparison_result; typedef typename Base::Oriented_side Oriented_side; typedef typename Base::Sign Sign;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; Are_same_points_2 same_points; Are_same_segments_2 same_segments;private: //-------------------------------------------------------------------------- void compute_ppp(const Site_2& sp, const Site_2& sq, const Site_2& sr) { CGAL_precondition( sp.is_point() && sq.is_point() && sr.is_point() ); Point_2 p = sp.point(), q = sq.point(), r = sr.point(); v_type = PPP; RT np = CGAL::square(p.x()) + CGAL::square(p.y()); RT nq = CGAL::square(q.x()) + CGAL::square(q.y()); RT nr = CGAL::square(r.x()) + CGAL::square(r.y()); ux_ppp = np * (q.y() - r.y()) + nq * (r.y() - p.y()) + nr * (p.y() - q.y()); uy_ppp = -(np * (q.x() - r.x()) + nq * (r.x() - p.x()) + nr * (p.x() - q.x())); uz_ppp = RT(2) * ( (q.x() * r.y() - r.x() * q.y()) + (r.x() * p.y() - p.x() * r.y()) + (p.x() * q.y() - q.x() * p.y()) ); } //-------------------------------------------------------------------------- void compute_pss(const Site_2& p, const Site_2& q, const Site_2& r) { CGAL_precondition( p.is_point() && q.is_segment() && r.is_segment() ); v_type = PSS; bool pq = same_points(p, q.source_site()) || same_points(p, q.target_site()); bool pr = same_points(p, r.source_site()) || same_points(p, r.target_site()); Point_2 pp = p.point(); if ( pq && pr ) { Sqrt_1 One(RT(1), RT(0), RT(0)); ux = Sqrt_3(pp.x() * One); uy = Sqrt_3(pp.y() * One); uz = Sqrt_3(One); return; } RT a1, b1, c1, a2, b2, c2; compute_supporting_line(q.supporting_site(), a1, b1, c1); compute_supporting_line(r.supporting_site(), a2, b2, c2); RT c1_ = a1 * pp.x() + b1 * pp.y() + c1; RT c2_ = a2 * pp.x() + b2 * pp.y() + c2; if ( pq ) { c1_ = RT(0); } if ( pr ) { c2_ = RT(0); } Sign sgn_c1_ = CGAL::sign(c1_); Sign sgn_c2_ = CGAL::sign(c2_); if ( sgn_c1_ == NEGATIVE ) { a1 = -a1; b1 = -b1; c1_ = -c1_; } else if ( sgn_c1_ == ZERO ) { CGAL_assertion( pq ); if ( same_points(p, q.target_site()) ) { a1 = -a1; b1 = -b1; c1_ = -c1_; } } if ( sgn_c2_ == NEGATIVE ) { a2 = -a2; b2 = -b2; c2_ = -c2_; } else if ( sgn_c2_ == ZERO ) { CGAL_assertion( pr ); if ( same_points(p, r.source_site()) ) { a2 = -a2; b2 = -b2; c2_ = -c2_; } } if ( pq ) { RT J = a1 * c2_; RT I = b1 * c2_; RT n1 = CGAL::square(a1) + CGAL::square(b1); RT n2 = CGAL::square(a2) + CGAL::square(b2); RT D1D2 = n1 * n2; Sqrt_1 Zero(RT(0), RT(0), D1D2); Sqrt_1 vz(-a1 * a2 - b1 * b2, RT(1), D1D2); ux = Sqrt_3(J + pp.x() * vz, Zero, Zero, Zero, Zero, Zero); uy = Sqrt_3(I + pp.y() * vz, Zero, Zero, Zero, Zero, Zero); uz = Sqrt_3(vz, Zero, Zero, Zero, Zero, Zero); } else if ( pr ) { RT J = a2 * c1_; RT I = b2 * c1_; RT n1 = CGAL::square(a1) + CGAL::square(b1); RT n2 = CGAL::square(a2) + CGAL::square(b2); RT D1D2 = n1 * n2; Sqrt_1 Zero(RT(0), RT(0), D1D2); Sqrt_1 vz(-a1 * a2 - b1 * b2, RT(1), D1D2); ux = Sqrt_3(J + pp.x() * vz, Zero, Zero, Zero, Zero, Zero); uy = Sqrt_3(I + pp.y() * vz, Zero, Zero, Zero, Zero, Zero); uz = Sqrt_3(vz, Zero, Zero, Zero, Zero, Zero); } else { Line_2 lq(a1, b1, c1_); Line_2 lr(a2, b2, c2_); compute_pll(pp, lq, lr); } } void compute_pll(const Point_2& p, const Line_2& lq, const Line_2& lr) { RT a1 = lq.a(), b1 = lq.b(), c1_ = lq.c(); RT a2 = lr.a(), b2 = lr.b(), c2_ = lr.c(); CGAL_precondition( c1_ >= RT(0) ); CGAL_precondition( c2_ >= RT(0) ); RT n1 = CGAL::square(a1) + CGAL::square(b1); RT n2 = CGAL::square(a2) + CGAL::square(b2); RT I = b1 * c2_ + b2 * c1_; RT J = a1 * c2_ + a2 * c1_; RT c1c2 = RT(2) * c1_ * c2_; RT a1a2 = a1 * a2; RT b1b2 = b1 * b2; RT D1D2 = n1 * n2; Sqrt_1 Zero(RT(0), RT(0), D1D2); Sqrt_1 One(RT(1), RT(0), D1D2); Sign s1, s2; // compute sigma Sign s_sigma(ZERO); s1 = CGAL::sign(b1); s2 = CGAL::sign(-b2); if ( s1 == ZERO ) { s_sigma = s2; } else if ( s2 == ZERO ) { s_sigma = s1; } else if ( s1 == s2 ) { s_sigma = s1; } else { RT e = CGAL::square(b1) * n2 - CGAL::square(b2) * n1; s_sigma = Sign(s1 * CGAL::sign(e)); } Sqrt_1 sigma = Zero; if ( s_sigma == POSITIVE ) { sigma = One; } else if ( s_sigma == NEGATIVE ) { sigma = -One; } // compute rho Sign s_rho(ZERO); s1 = CGAL::sign(a1); s2 = CGAL::sign(-a2); if ( s1 == ZERO ) { s_rho = s2; } else if ( s2 == ZERO ) { s_rho = s1; } else if ( s1 == s2 ) { s_rho = s1; } else { RT e = CGAL::square(a1) * n2 - CGAL::square(a2) * n1; s_rho = Sign(s1 * CGAL::sign(e)); } Sqrt_1 rho = Zero; if ( s_rho == POSITIVE ) { rho = One; } else if ( s_rho == NEGATIVE ) { rho = -One; } Sqrt_1 vz(-a1a2 - b1b2, RT(1), D1D2); RT A = a1a2 - b1b2; Sqrt_1 u1( c1c2 * A, c1c2, D1D2); Sqrt_1 u2(-c1c2 * A, c1c2, D1D2); ux = Sqrt_3(J + p.x() * vz, sigma, Zero, Zero, u1, u2); uy = Sqrt_3(I + p.y() * vz, Zero, -rho, Zero, u1, u2); uz = Sqrt_3(vz, Zero, Zero, Zero, u1, u2); } //-------------------------------------------------------------------------- void compute_pps(const Site_2& p, const Site_2& q, const Site_2& r) { CGAL_precondition( p.is_point() && q.is_point() && r.is_segment() ); v_type = PPS; RT a, b, c; compute_supporting_line(r.supporting_site(), a, b, c); Point_2 pp = p.point(), qq = q.point(); RT c_ = a * pp.x() + b * pp.y() + c; RT cq_ = a * qq.x() + b * qq.y() + c; if ( same_points(p, r.source_site()) || same_points(p, r.target_site()) ) { c_ = RT(0); } if ( same_points(q, r.source_site()) || same_points(q, r.target_site()) ) { cq_ = RT(0); } Sign s = CGAL::sign(c_); if ( s == NEGATIVE ) { a = -a; b = -b; c = -c; c_ = -c_; cq_ = -cq_; } else if ( s == ZERO ) { Sign s1 = CGAL::sign(cq_); CGAL_assertion( s1 != ZERO ); if ( s1 == NEGATIVE ) { a = -a; b = -b; c = -c; c_ = -c_; cq_ = -cq_; } } RT nl = CGAL::square(a) + CGAL::square(b); RT x_ = qq.x() - pp.x(); RT y_ = qq.y() - pp.y(); RT n_ = CGAL::square(x_) + CGAL::square(y_); Comparison_result res = CGAL::compare( c_, cq_ ); if ( res == EQUAL ) { RT e1 = CGAL::square(c_); RT J = nl * (a * n_ + RT(4) * c_ * x_) - RT(4) * a * e1; RT I = nl * (b * n_ + RT(4) * c_ * y_) - RT(4) * b * e1; RT X = RT(8) * nl * c_; ux_pps = Sqrt_1(J + pp.x() * X); uy_pps = Sqrt_1(I + pp.y() * X); uz_pps = Sqrt_1(X); return; } RT e1 = a * x_ + b * y_; RT e2 = b * x_ - a * y_; RT e3 = n_ * e1; RT e4 = RT(2) * c_ * e2; RT X = RT(2) * CGAL::square(e1); RT I = b * e3 + x_ * e4; RT J = a * e3 - y_ * e4; RT S = n_ * nl * c_ * cq_; ux_pps = Sqrt_1(J + pp.x() * X, RT(-2) * y_, S); uy_pps = Sqrt_1(I + pp.y() * X, RT( 2) * x_, S); uz_pps = Sqrt_1(X, RT(0), S); } //-------------------------------------------------------------------------- bool check_if_exact(const Site_2& , unsigned int , const Tag_false&) const { return true; } bool check_if_exact(const Site_2& s, unsigned int i, const Tag_true&) const { return s.is_input(i); } // determines of the segment s is on the positive halfspace as // defined by the supporting line of the segment supp; the line l // is supposed to be the supporting line of the segment supp and we // pass it so that we do not have to recompute it bool is_on_positive_halfspace(const Site_2& supp, const Site_2& s, const Line_2& l) const { CGAL_precondition( supp.is_segment() && s.is_segment() ); if ( same_segments(supp.supporting_site(), s.supporting_site()) ) { return false; } if ( same_points(supp.source_site(), s.source_site()) || same_points(supp.target_site(), s.source_site()) ) { return oriented_side_of_line(l, s.target()) == ON_POSITIVE_SIDE; } if ( same_points(supp.source_site(), s.target_site()) || same_points(supp.target_site(), s.target_site()) ) { return oriented_side_of_line(l, s.source()) == ON_POSITIVE_SIDE; } ITag itag; if ( !check_if_exact(s, 0, itag) && same_segments(supp.supporting_site(), s.crossing_site(0)) ) { return oriented_side_of_line(l, s.target()) == ON_POSITIVE_SIDE; } if ( !check_if_exact(s, 1, itag) && same_segments(supp.supporting_site(), s.crossing_site(1)) ) { return oriented_side_of_line(l, s.source()) == ON_POSITIVE_SIDE; } return Base::is_on_positive_halfspace(l, s.segment()); } //-------------------------------------------------------------------------- void orient_lines(const Site_2& p, const Site_2& q, const Site_2& r, RT a[], RT b[], RT c[]) const { CGAL_precondition( p.is_segment() && q.is_segment() && r.is_segment() ); Line_2 l[3]; l[0] = compute_supporting_line(p.supporting_site()); l[1] = compute_supporting_line(q.supporting_site()); l[2] = compute_supporting_line(r.supporting_site()); bool is_oriented[3] = {false, false, false}; if ( is_on_positive_halfspace(p, q, l[0]) || is_on_positive_halfspace(p, r, l[0]) ) { is_oriented[0] = true; } else { l[0] = opposite_line(l[0]); if ( is_on_positive_halfspace(p, q, l[0]) || is_on_positive_halfspace(p, r, l[0]) ) { is_oriented[0] = true; } else { l[0] = opposite_line(l[0]); } } if ( is_on_positive_halfspace(q, p, l[1]) || is_on_positive_halfspace(q, r, l[1]) ) { is_oriented[1] = true; } else { l[1] = opposite_line(l[1]); if ( is_on_positive_halfspace(q, p, l[1]) || is_on_positive_halfspace(q, r, l[1]) ) { is_oriented[1] = true; } else { l[1] = opposite_line(l[1]); } } if ( is_on_positive_halfspace(r, p, l[2]) || is_on_positive_halfspace(r, q, l[2]) ) { is_oriented[2] = true; } else { l[2] = opposite_line(l[2]); if ( is_on_positive_halfspace(r, p, l[2]) || is_on_positive_halfspace(r, q, l[2]) ) { is_oriented[2] = true; } else { l[2] = opposite_line(l[2]); } } if ( is_oriented[0] && is_oriented[1] && is_oriented[2] ) { for (int i = 0; i < 3; i++) { a[i] = l[i].a(); b[i] = l[i].b(); c[i] = l[i].c(); } return; } int i_no(-1); for (int i = 0; i < 3; i++) { if ( !is_oriented[i] ) { i_no = i; CGAL_assertion( is_oriented[(i+1)%3] && is_oriented[(i+2)%3] ); break; } } CGAL_assertion( i_no != -1 ); RT d[3]; for (int i = 0; i < 3; i++) { d[i] = CGAL::square(l[i].a()) + CGAL::square(l[i].b()); } RT z[3]; for (int i = 0; i < 3; i++) { z[i] = l[(i+1)%3].a() * l[(i+2)%3].b() - l[(i+2)%3].a() * l[(i+1)%3].b(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -