svd_voronoi_vertex_sqrt_field_h2.h
来自「CGAL is a collaborative effort of severa」· C头文件 代码 · 共 1,028 行 · 第 1/2 页
H
1,028 行
// Copyright (c) 2003,2004 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.//// $Source: /CVSROOT/CGAL/Packages/Segment_Voronoi_diagram_2/include/CGAL/predicates/Svd_Voronoi_vertex_sqrt_field_H2.h,v $// $Revision: 1.5 $ $Date: 2004/02/23 22:18:43 $// $Name: $//// Author(s) : Menelaos Karavelas <mkaravel@cse.nd.edu>#ifndef CGAL_SEGMENT_VORONOI_DIAGRAM_VORONOI_VERTEX_SQRT_FIELD_H2_H#define CGAL_SEGMENT_VORONOI_DIAGRAM_VORONOI_VERTEX_SQRT_FIELD_H2_H#include <CGAL/enum.h>#include <CGAL/determinant.h>#include <CGAL/predicates/Svd_basic_predicates_H2.h>CGAL_BEGIN_NAMESPACEtemplate<class K>class Svd_voronoi_vertex_sqrt_field_H2 : public Svd_basic_predicates_H2<K>{public: typedef Svd_basic_predicates_H2<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::Homogeneous_point_2 Homogeneous_point_2;private: //-------------------------------------------------------------------------- void compute_ppp(const Point_2& p, const Point_2& q, const Point_2& r) { v_type = PPP; RT np = CGAL::square(p.hx()) + CGAL::square(p.hy()); RT nq = CGAL::square(q.hx()) + CGAL::square(q.hy()); RT nr = CGAL::square(r.hx()) + CGAL::square(r.hy()); RT p_xw = p.hx() * p.hw(); RT q_xw = q.hx() * q.hw(); RT r_xw = r.hx() * r.hw(); RT p_yw = p.hy() * p.hw(); RT q_yw = q.hy() * q.hw(); RT r_yw = r.hy() * r.hw(); RT p_hw_sq = CGAL::square( p.hw() ); RT q_hw_sq = CGAL::square( q.hw() ); RT r_hw_sq = CGAL::square( r.hw() ); ux = -det3x3_by_formula(p_yw, np, p_hw_sq, q_yw, nq, q_hw_sq, r_yw, nr, r_hw_sq); uy = det3x3_by_formula(p_xw, np, p_hw_sq, q_xw, nq, q_hw_sq, r_xw, nr, r_hw_sq); uz = RT(2) * det3x3_by_formula(p_xw, p_yw, p_hw_sq, q_xw, q_yw, q_hw_sq, r_xw, r_yw, r_hw_sq); } //-------------------------------------------------------------------------- void compute_pss(const Point_2& p, const Segment_2& q, const Segment_2& r) { v_type = PSS; bool pq = (p == q.source() || p == q.target()); bool pr = (p == r.source() || p == r.target()); if ( pq && pr ) { ux = p.hx(); uy = p.hy(); uz = p.hw(); return; } RT a1, b1, c1, a2, b2, c2; compute_supporting_line(q, a1, b1, c1); compute_supporting_line(r, a2, b2, c2); RT c1_ = a1 * p.hx() + b1 * p.hy() + c1 * p.hw(); RT c2_ = a2 * p.hx() + b2 * p.hy() + c2 * p.hw(); 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 ( p == q.target() ) { 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 ( p == r.source() ) { 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; uz = p.hw() * (-a1 * a2 - b1 * b2 + CGAL::sqrt(D1D2)); ux = J + p.hx() * uz; uy = I + p.hy() * uz; } 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; uz = p.hw() * (-a1 * a2 - b1 * b2 + CGAL::sqrt(D1D2)); ux = J + p.hx() * uz; uy = I + p.hy() * uz; } else { Line_2 lq(a1, b1, c1_); Line_2 lr(a2, b2, c2_); compute_pll(p, 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_ >= FT(0) ); CGAL_precondition( c2_ >= FT(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; Sign s_pw = CGAL::sign( p.hw() ); // compute sigma RT sigma_expr = b1 * CGAL::sqrt(n2) - b2 * CGAL::sqrt(n1); Sign s_sigma = s_pw * CGAL::sign(sigma_expr); int i_sigma(s_sigma); RT sigma(i_sigma); // compute rho RT rho_expr = a1 * CGAL::sqrt(n2) - a2 * CGAL::sqrt(n1); Sign s_rho = s_pw * CGAL::sign(rho_expr); int i_rho(s_rho); RT rho(i_rho); RT sqrt_D1D2 = CGAL::sqrt(D1D2); RT A = a1a2 - b1b2; RT u1 = c1c2 * (sqrt_D1D2 + A); RT u2 = c1c2 * (sqrt_D1D2 - A); uz = p.hw() * (-a1a2 - b1b2 + CGAL::sqrt(D1D2)); ux = J + p.hx() * uz + sigma * CGAL::sqrt(u1); uy = I + p.hy() * uz - rho * CGAL::sqrt(u2); } //-------------------------------------------------------------------------- void compute_pps(const Point_2& p, const Point_2& q, const Segment_2& r) { v_type = PPS; RT a, b, c; compute_supporting_line(r, a, b, c); RT c_ = a * p.hx() + b * p.hy() + c * p.hw(); RT cq_ = a * q.hx() + b * q.hy() + c * q.hw(); if ( p == r.source() || p == r.target() ) { c_ = RT(0); } if ( q == r.source() || q == r.target() ) { cq_ = RT(0); } Sign s_pw = CGAL::sign( p.hw() ); Sign s_qw = CGAL::sign( q.hw() ); Sign s = s_pw * CGAL::sign(c_); if ( s == NEGATIVE ) { a = -a; b = -b; c = -c; c_ = -c_; cq_ = -cq_; } else if ( s == ZERO ) { Sign s1 = s_qw * 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_ = q.hx() * p.hw() - p.hx() * q.hw(); RT y_ = q.hy() * p.hw() - p.hy() * q.hw(); RT n_ = CGAL::square(x_) + CGAL::square(y_); // old equality of distcne check // ------------------------------ // Comparison_result res = CGAL::compare( c_, cq_); // checking equality of distance through the quantity X: Comparison_result res = CGAL::compare(a * x_, -b * y_); if ( res == EQUAL ) { RT qw_sq = CGAL::square( q.hw() ); RT e1 = CGAL::square(c_); RT J = nl * (a * n_ + RT(4) * c_ * x_ * q.hw()) - RT(4) * a * e1 * qw_sq; RT I = nl * (b * n_ + RT(4) * c_ * y_ * q.hw()) - RT(4) * b * e1 * qw_sq; RT X = RT(8) * nl * c_ * qw_sq * p.hw(); ux = J + p.hx() * X; uy = I + p.hy() * X; uz = p.hw() * X; return; } FT e1 = a * x_ + b * y_; FT e2 = b * x_ - a * y_; FT e3 = n_ * e1; FT e4 = FT(2) * c_ * e2 * q.hw(); FT X = FT(2) * CGAL::square(e1); FT I = b * e3 + x_ * e4; FT J = a * e3 - y_ * e4; FT sqrt_S = CGAL::sqrt(p.hw() * q.hw() * n_ * nl * c_ * cq_); ux = J + p.hx() * X - FT(2) * y_ * sqrt_S; uy = I + p.hy() * X + FT(2) * x_ * sqrt_S; uz = p.hw() * X; } //-------------------------------------------------------------------------- bool is_consistent(const Segment_2& p, const Segment_2& q, const Segment_2& r, RT a[], RT b[], RT c[]) const { Line_2 l[3] = {Line_2(a[0], b[0], c[0]), Line_2(a[1], b[1], c[1]), Line_2(a[2], b[2], c[2])}; int num_oriented(0); if ( is_on_positive_halfspace(l[0], q) || is_on_positive_halfspace(l[0], r) ) { num_oriented++; } if ( is_on_positive_halfspace(l[1], p) || is_on_positive_halfspace(l[1], r) ) { num_oriented++; } if ( is_on_positive_halfspace(l[2], p) || is_on_positive_halfspace(l[2], q) ) { num_oriented++; } return ( num_oriented >= 2 ); } void orient_lines(const Segment_2& p, const Segment_2& q, const Segment_2& r, RT a[], RT b[], RT c[]) const { Line_2 l[3]; l[0] = compute_supporting_line(p); l[1] = compute_supporting_line(q); l[2] = compute_supporting_line(r); bool is_oriented[3] = {false, false, false}; if ( is_on_positive_halfspace(l[0], q) || is_on_positive_halfspace(l[0], r) ) { is_oriented[0] = true; } else { l[0] = opposite_line(l[0]); if ( is_on_positive_halfspace(l[0], q) || is_on_positive_halfspace(l[0], r) ) { is_oriented[0] = true; } else { l[0] = opposite_line(l[0]); } } if ( is_on_positive_halfspace(l[1], p) || is_on_positive_halfspace(l[1], r) ) { is_oriented[1] = true; } else { l[1] = opposite_line(l[1]); if ( is_on_positive_halfspace(l[1], p) || is_on_positive_halfspace(l[1], r) ) { is_oriented[1] = true; } else { l[1] = opposite_line(l[1]); } } if ( is_on_positive_halfspace(l[2], p) || is_on_positive_halfspace(l[2], q) ) { is_oriented[2] = true; } else { l[2] = opposite_line(l[2]); if ( is_on_positive_halfspace(l[2], p) || is_on_positive_halfspace(l[2], q) ) { 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 sqrt_d[3]; for (int i = 0; i < 3; i++) { RT d1 = CGAL::square(l[i].a()) + CGAL::square(l[i].b()); sqrt_d[i] = CGAL::sqrt(d1); } 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(); } RT vz = z[0] * sqrt_d[0] + z[1] * sqrt_d[1] + z[2] * sqrt_d[2]; Sign s_minus_vz = CGAL::sign(vz); CGAL_assertion( s_minus_vz != ZERO ); if ( s_minus_vz == NEGATIVE ) { l[i_no] = opposite_line(l[i_no]); for (int i = 0; i < 3; i++) { a[i] = l[i].a(); b[i] = l[i].b(); c[i] = l[i].c(); } return; } // now we have to check if the other orientation of l[i_no] // corresponds to a CCW triangle as well. z[(i_no+1)%3] = -z[(i_no+1)%3]; z[(i_no+2)%3] = -z[(i_no+2)%3]; vz = z[0] * sqrt_d[0] + z[1] * sqrt_d[1] + z[2] * sqrt_d[2]; Sign s_minus_vz_2 = CGAL::sign(vz); CGAL_assertion( s_minus_vz_2 != ZERO ); if ( s_minus_vz_2 == NEGATIVE ) { // the other orientation does not correspond to a CCW triangle. for (int i = 0; i < 3; i++) { a[i] = l[i].a(); b[i] = l[i].b(); c[i] = l[i].c(); } return; } // now compute the Voronoi vertex; for (int i = 0; i < 3; i++) { a[i] = l[i].a(); b[i] = l[i].b(); c[i] = l[i].c(); } RT x[3], y[3], w[3]; for (int i = 0; i < 3; i++) { x[i] = c[(i+1)%3] * b[(i+2)%3] - c[(i+2)%3] * b[(i+1)%3]; y[i] = -(c[(i+1)%3] * a[(i+2)%3] - c[(i+2)%3] * a[(i+1)%3]); w[i] = -(a[(i+1)%3] * b[(i+2)%3] - a[(i+2)%3] * b[(i+1)%3]); } RT vx = RT(0), vy = RT(0), vw = RT(0); for (int i = 0; i < 3; i++) { vx += x[i] * sqrt_d[i]; vy += y[i] * sqrt_d[i]; vw += w[i] * sqrt_d[i]; } Sign s_vw = CGAL::sign(vw); RT dist = a[(i_no+1)%3] * vx + b[(i_no+1)%3] * vy + c[(i_no+1)%3] * vw; Sign sgn_dist = Sign(s_vw * CGAL::sign(dist)); CGAL_assertion( sgn_dist != ZERO ); if ( sgn_dist == NEGATIVE ) { a[i_no] = -a[i_no]; b[i_no] = -b[i_no]; c[i_no] = -c[i_no]; } } void compute_sss(const Segment_2& p, const Segment_2& q, const Segment_2& r) { v_type = SSS;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?