BWAPI
|
00001 // Copyright (c) 1999-2004 Utrecht University (The Netherlands), 00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany), 00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg 00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria), 00005 // and Tel-Aviv University (Israel). All rights reserved. 00006 // 00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00008 // modify it under the terms of the GNU Lesser General Public License as 00009 // published by the Free Software Foundation; version 2.1 of the License. 00010 // See the file LICENSE.LGPL distributed with CGAL. 00011 // 00012 // Licensees holding a valid commercial license may use this file in 00013 // accordance with the commercial license agreement provided with the software. 00014 // 00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00017 // 00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Homogeneous_kernel/include/CGAL/Homogeneous/function_objects.h $ 00019 // $Id: function_objects.h 50388 2009-07-06 11:36:23Z afabri $ 00020 // 00021 // 00022 // Author(s) : Stefan Schirra, Sylvain Pion, Michael Hoffmann 00023 00024 #ifndef CGAL_HOMOGENEOUS_FUNCTION_OBJECTS_H 00025 #define CGAL_HOMOGENEOUS_FUNCTION_OBJECTS_H 00026 00027 #include <CGAL/Kernel/function_objects.h> 00028 #include <CGAL/Cartesian/function_objects.h> 00029 #include <CGAL/Kernel/Return_base_tag.h> 00030 #include <CGAL/predicates/sign_of_determinant.h> 00031 00032 CGAL_BEGIN_NAMESPACE 00033 00034 namespace HomogeneousKernelFunctors { 00035 00036 using namespace CommonKernelFunctors; 00037 00038 // For lazyness... 00039 using CartesianKernelFunctors::Are_parallel_2; 00040 using CartesianKernelFunctors::Are_parallel_3; 00041 using CartesianKernelFunctors::Compute_squared_area_3; 00042 using CartesianKernelFunctors::Compare_squared_radius_3; 00043 using CartesianKernelFunctors::Collinear_3; 00044 using CartesianKernelFunctors::Construct_line_3; 00045 using CartesianKernelFunctors::Construct_equidistant_line_3; 00046 using CartesianKernelFunctors::Construct_barycenter_2; 00047 using CartesianKernelFunctors::Construct_barycenter_3; 00048 00049 using CartesianKernelFunctors::Compute_approximate_area_3; 00050 using CartesianKernelFunctors::Compute_approximate_squared_length_3; 00051 using CartesianKernelFunctors::Compute_area_divided_by_pi_3; 00052 using CartesianKernelFunctors::Compute_squared_length_divided_by_pi_square_3; 00053 using CartesianKernelFunctors::Construct_radical_plane_3; 00054 00055 template <typename K> 00056 class Angle_2 00057 { 00058 typedef typename K::Point_2 Point_2; 00059 typedef typename K::Construct_vector_2 Construct_vector_2; 00060 Construct_vector_2 c; 00061 public: 00062 typedef typename K::Angle result_type; 00063 00064 Angle_2() {} 00065 Angle_2(const Construct_vector_2& c_) : c(c_) {} 00066 00067 result_type 00068 operator()(const Point_2& p, const Point_2& q, const Point_2& r) const 00069 { return enum_cast<Angle>(CGAL_NTS sign(c(q,p) * c(q,r))); } 00070 // FIXME: scalar product 00071 }; 00072 00073 template <typename K> 00074 class Angle_3 00075 { 00076 typedef typename K::Point_3 Point_3; 00077 typedef typename K::Construct_vector_3 Construct_vector_3; 00078 Construct_vector_3 c; 00079 public: 00080 typedef typename K::Angle result_type; 00081 00082 Angle_3() {} 00083 Angle_3(const Construct_vector_3& c_) : c(c_) {} 00084 00085 result_type 00086 operator()(const Point_3& p, const Point_3& q, const Point_3& r) const 00087 { return enum_cast<Angle>(CGAL_NTS sign(c(q,p) * c(q,r))); } 00088 // FIXME: scalar product 00089 }; 00090 00091 00092 template <typename K> 00093 class Bounded_side_2 00094 { 00095 typedef typename K::Point_2 Point_2; 00096 typedef typename K::Circle_2 Circle_2; 00097 typedef typename K::Triangle_2 Triangle_2; 00098 typedef typename K::Iso_rectangle_2 Iso_rectangle_2; 00099 public: 00100 typedef typename K::Bounded_side result_type; 00101 00102 result_type 00103 operator()( const Circle_2& c, const Point_2& p) const 00104 { 00105 typename K::Compute_squared_distance_2 squared_distance; 00106 return enum_cast<Bounded_side>(CGAL_NTS compare(c.squared_radius(), 00107 squared_distance(c.center(),p))); 00108 } 00109 00110 result_type 00111 operator()( const Triangle_2& t, const Point_2& p) const 00112 { 00113 typename K::Collinear_are_ordered_along_line_2 00114 collinear_are_ordered_along_line; 00115 typename K::Orientation_2 orientation; 00116 typename K::Orientation o1 = orientation(t.vertex(0), t.vertex(1), p), 00117 o2 = orientation(t.vertex(1), t.vertex(2), p), 00118 o3 = orientation(t.vertex(2), t.vertex(3), p); 00119 00120 if (o2 == o1 && o3 == o1) 00121 return ON_BOUNDED_SIDE; 00122 return 00123 (o1 == COLLINEAR 00124 && collinear_are_ordered_along_line(t.vertex(0), p, t.vertex(1))) || 00125 (o2 == COLLINEAR 00126 && collinear_are_ordered_along_line(t.vertex(1), p, t.vertex(2))) || 00127 (o3 == COLLINEAR 00128 && collinear_are_ordered_along_line(t.vertex(2), p, t.vertex(3))) 00129 ? ON_BOUNDARY 00130 : ON_UNBOUNDED_SIDE; 00131 } 00132 00133 result_type 00134 operator()( const Iso_rectangle_2& r, const Point_2& p) const 00135 { 00136 return r.rep().bounded_side(p); 00137 } 00138 }; 00139 00140 template <typename K> 00141 class Bounded_side_3 00142 { 00143 typedef typename K::RT RT; 00144 typedef typename K::Point_3 Point_3; 00145 typedef typename K::Vector_3 Vector_3; 00146 typedef typename K::Sphere_3 Sphere_3; 00147 typedef typename K::Tetrahedron_3 Tetrahedron_3; 00148 typedef typename K::Iso_cuboid_3 Iso_cuboid_3; 00149 public: 00150 typedef typename K::Bounded_side result_type; 00151 00152 result_type 00153 operator()( const Sphere_3& s, const Point_3& p) const 00154 { return s.rep().bounded_side(p); } 00155 00156 result_type 00157 operator()( const Tetrahedron_3& t, const Point_3& p) const 00158 { 00159 Vector_3 v1 = t.vertex(1)-t.vertex(0); 00160 Vector_3 v2 = t.vertex(2)-t.vertex(0); 00161 Vector_3 v3 = t.vertex(3)-t.vertex(0); 00162 00163 Vector_3 vp = p - t.vertex(0); 00164 00165 // want to solve alpha*v1 + beta*v2 + gamma*v3 == vp 00166 // let vi' == vi*vi.hw() 00167 // we solve alpha'*v1' + beta'*v2' + gamma'*v3' == vp' / vp.hw() 00168 // muliplied by vp.hw() 00169 // then we have alpha = alpha'*v1.hw() / vp.hw() 00170 // and beta = beta' *v2.hw() / vp.hw() 00171 // and gamma = gamma'*v3.hw() / vp.hw() 00172 00173 const RT & v1x = v1.hx(); 00174 const RT & v1y = v1.hy(); 00175 const RT & v1z = v1.hz(); 00176 const RT & v2x = v2.hx(); 00177 const RT & v2y = v2.hy(); 00178 const RT & v2z = v2.hz(); 00179 const RT & v3x = v3.hx(); 00180 const RT & v3y = v3.hy(); 00181 const RT & v3z = v3.hz(); 00182 const RT & vpx = vp.hx(); 00183 const RT & vpy = vp.hy(); 00184 const RT & vpz = vp.hz(); 00185 00186 RT alpha = determinant( vpx, v2x, v3x, 00187 vpy, v2y, v3y, 00188 vpz, v2z, v3z ); 00189 RT beta = determinant( v1x, vpx, v3x, 00190 v1y, vpy, v3y, 00191 v1z, vpz, v3z ); 00192 RT gamma = determinant( v1x, v2x, vpx, 00193 v1y, v2y, vpy, 00194 v1z, v2z, vpz ); 00195 RT det = determinant( v1x, v2x, v3x, 00196 v1y, v2y, v3y, 00197 v1z, v2z, v3z ); 00198 00199 CGAL_kernel_assertion( det != 0 ); 00200 if (det < 0 ) 00201 { 00202 alpha = - alpha; 00203 beta = - beta ; 00204 gamma = - gamma; 00205 det = - det ; 00206 } 00207 00208 bool t1 = ( alpha < 0 ); 00209 bool t2 = ( beta < 0 ); 00210 bool t3 = ( gamma < 0 ); 00211 // t1 || t2 || t3 == not contained in cone 00212 00213 RT lhs = alpha*v1.hw() + beta*v2.hw() + gamma*v3.hw(); 00214 RT rhs = det * vp.hw(); 00215 00216 bool t4 = ( lhs > rhs ); 00217 // alpha + beta + gamma > 1 ? 00218 bool t5 = ( lhs < rhs ); 00219 // alpha + beta + gamma < 1 ? 00220 bool t6 = ( (alpha > 0) && (beta > 0) && (gamma > 0) ); 00221 00222 if ( t1 || t2 || t3 || t4 ) 00223 { 00224 return ON_UNBOUNDED_SIDE; 00225 } 00226 return (t5 && t6) ? ON_BOUNDED_SIDE : ON_BOUNDARY; 00227 } 00228 00229 result_type 00230 operator()( const Iso_cuboid_3& c, const Point_3& p) const 00231 { return c.rep().bounded_side(p); } 00232 }; 00233 00234 template <typename K> 00235 class Collinear_are_ordered_along_line_2 00236 { 00237 typedef typename K::RT RT; 00238 typedef typename K::Point_2 Point_2; 00239 #ifdef CGAL_kernel_exactness_preconditions 00240 typedef typename K::Collinear_2 Collinear_2; 00241 Collinear_2 c; 00242 #endif // CGAL_kernel_exactness_preconditions 00243 public: 00244 typedef typename K::Boolean result_type; 00245 00246 #ifdef CGAL_kernel_exactness_preconditions 00247 Collinear_are_ordered_along_line_2() {} 00248 Collinear_are_ordered_along_line_2(const Collinear_2& c_) : c(c_) {} 00249 #endif // CGAL_kernel_exactness_preconditions 00250 00251 result_type 00252 operator()(const Point_2& p, const Point_2& q, const Point_2& r) const 00253 { 00254 CGAL_kernel_exactness_precondition( c(p, q, r) ); 00255 00256 const RT& phx = p.hx(); 00257 const RT& phy = p.hy(); 00258 const RT& phw = p.hw(); 00259 const RT& qhx = q.hx(); 00260 const RT& qhy = q.hy(); 00261 const RT& qhw = q.hw(); 00262 const RT& rhx = r.hx(); 00263 const RT& rhy = r.hy(); 00264 const RT& rhw = r.hw(); 00265 00266 if ( !(phx * rhw == rhx * phw ) ) // non-vertical ? 00267 { 00268 return !( ( ( phx * qhw < qhx * phw) 00269 &&( rhx * qhw < qhx * rhw)) 00270 ||( ( qhx * phw < phx * qhw) 00271 &&( qhx * rhw < rhx * qhw)) ); 00272 } 00273 else if ( !(phy * rhw == rhy * phw ) ) 00274 { 00275 return !( ( ( phy * qhw < qhy * phw) 00276 &&( rhy * qhw < qhy * rhw)) 00277 ||( ( qhy * phw < phy * qhw) 00278 &&( qhy * rhw < rhy * qhw)) ); 00279 } 00280 else 00281 return (( phx*qhw == qhx*phw) && ( phy*qhw == qhy*phw)); 00282 } 00283 }; 00284 00285 template <typename K> 00286 class Collinear_are_ordered_along_line_3 00287 { 00288 typedef typename K::Point_3 Point_3; 00289 #ifdef CGAL_kernel_exactness_preconditions 00290 typedef typename K::Collinear_3 Collinear_3; 00291 Collinear_3 c; 00292 #endif // CGAL_kernel_exactness_preconditions 00293 public: 00294 typedef typename K::Boolean result_type; 00295 00296 #ifdef CGAL_kernel_exactness_preconditions 00297 Collinear_are_ordered_along_line_3() {} 00298 Collinear_are_ordered_along_line_3(const Collinear_3& c_) : c(c_) {} 00299 #endif // CGAL_kernel_exactness_preconditions 00300 00301 result_type 00302 operator()(const Point_3& p, const Point_3& q, const Point_3& r) const 00303 { 00304 CGAL_kernel_exactness_precondition( c(p, q, r) ); 00305 typedef typename K::RT RT; 00306 const RT & phx = p.hx(); 00307 const RT & phw = p.hw(); 00308 const RT & qhx = q.hx(); 00309 const RT & qhw = q.hw(); 00310 const RT & rhx = r.hx(); 00311 const RT & rhw = r.hw(); 00312 00313 const RT pqx = phx*qhw; 00314 const RT qpx = qhx*phw; 00315 const RT prx = phx*rhw; 00316 const RT qrx = qhx*rhw; 00317 const RT rqx = rhx*qhw; 00318 const RT rpx = rhx*phw; 00319 00320 if ( prx != rpx ) // px != rx 00321 { 00322 // (px <= qx)&&(qx <= rx) || (px >= qx)&&(qx >= rx) 00323 // !(((qx < px)||(rx < qx))&&((px < qx)||(qx < rx))) 00324 return ! ( ((qpx < pqx) || (rqx < qrx)) 00325 && ((pqx < qpx) || (qrx < rqx)) ); 00326 } 00327 00328 const RT & phy = p.hy(); 00329 const RT & qhy = q.hy(); 00330 const RT & rhy = r.hy(); 00331 00332 const RT pqy = phy*qhw; 00333 const RT qpy = qhy*phw; 00334 const RT pry = phy*rhw; 00335 const RT qry = qhy*rhw; 00336 const RT rqy = rhy*qhw; 00337 const RT rpy = rhy*phw; 00338 00339 if ( pry != rpy ) 00340 { 00341 return ! ( ((qpy < pqy) || (rqy < qry)) 00342 && ((pqy < qpy) || (qry < rqy)) ); 00343 } 00344 00345 const RT & phz = p.hz(); 00346 const RT & qhz = q.hz(); 00347 const RT & rhz = r.hz(); 00348 00349 const RT pqz = phz*qhw; 00350 const RT qpz = qhz*phw; 00351 const RT prz = phz*rhw; 00352 const RT qrz = qhz*rhw; 00353 const RT rqz = rhz*qhw; 00354 const RT rpz = rhz*phw; 00355 00356 if ( prz != rpz ) 00357 { 00358 return ! ( ((qpz < pqz) || (rqz < qrz)) 00359 && ((pqz < qpz) || (qrz < rqz)) ); 00360 } 00361 // p == r 00362 return ((rqx == qrx) && (rqy == qry) && (rqz == qrz)); 00363 } 00364 }; 00365 00366 template <typename K> 00367 class Collinear_are_strictly_ordered_along_line_2 00368 { 00369 typedef typename K::Point_2 Point_2; 00370 #ifdef CGAL_kernel_exactness_preconditions 00371 typedef typename K::Collinear_2 Collinear_2; 00372 Collinear_2 c; 00373 #endif // CGAL_kernel_exactness_preconditions 00374 public: 00375 typedef typename K::Boolean result_type; 00376 00377 #ifdef CGAL_kernel_exactness_preconditions 00378 Collinear_are_strictly_ordered_along_line_2() {} 00379 Collinear_are_strictly_ordered_along_line_2(const Collinear_2& c_) : c(c_) 00380 {} 00381 #endif // CGAL_kernel_exactness_preconditions 00382 00383 result_type 00384 operator()(const Point_2& p, const Point_2& q, const Point_2& r) const 00385 { 00386 CGAL_kernel_exactness_precondition( c(p, q, r) ); 00387 typedef typename K::RT RT; 00388 00389 const RT& phx = p.hx(); 00390 const RT& phy = p.hy(); 00391 const RT& phw = p.hw(); 00392 const RT& qhx = q.hx(); 00393 const RT& qhy = q.hy(); 00394 const RT& qhw = q.hw(); 00395 const RT& rhx = r.hx(); 00396 const RT& rhy = r.hy(); 00397 const RT& rhw = r.hw(); 00398 00399 if ( !(phx * rhw == rhx * phw ) ) 00400 { 00401 return ( ( phx * qhw < qhx * phw) 00402 &&( qhx * rhw < rhx * qhw)) 00403 ||( ( qhx * phw < phx * qhw) // ( phx * qhw > qhx * phw) 00404 &&( rhx * qhw < qhx * rhw)); // ( qhx * rhw > rhx * qhw) 00405 } 00406 else 00407 { 00408 return ( ( phy * qhw < qhy * phw) 00409 &&( qhy * rhw < rhy * qhw)) 00410 ||( ( qhy * phw < phy * qhw) // ( phy * qhw > qhy * phw) 00411 &&( rhy * qhw < qhy * rhw)); // ( qhy * rhw > rhy * qhw) 00412 } 00413 } 00414 }; 00415 00416 template <typename K> 00417 class Collinear_are_strictly_ordered_along_line_3 00418 { 00419 typedef typename K::Point_3 Point_3; 00420 typedef typename K::Direction_3 Direction_3; 00421 #ifdef CGAL_kernel_exactness_preconditions 00422 typedef typename K::Collinear_3 Collinear_3; 00423 Collinear_3 c; 00424 #endif // CGAL_kernel_exactness_preconditions 00425 public: 00426 typedef typename K::Boolean result_type; 00427 00428 #ifdef CGAL_kernel_exactness_preconditions 00429 Collinear_are_strictly_ordered_along_line_3() {} 00430 Collinear_are_strictly_ordered_along_line_3(const Collinear_3& c_) : c(c_) 00431 {} 00432 #endif // CGAL_kernel_exactness_preconditions 00433 00434 result_type 00435 operator()(const Point_3& p, const Point_3& q, const Point_3& r) const 00436 { 00437 CGAL_kernel_exactness_precondition( c(p, q, r) ); 00438 if ( p == r) return false; 00439 Direction_3 dir_pq = (p - q).direction(); 00440 Direction_3 dir_rq = (r - q).direction(); 00441 return (dir_pq == -dir_rq); 00442 } // FIXME 00443 }; 00444 00445 template <typename K> 00446 class Collinear_has_on_2 00447 { 00448 typedef typename K::Point_2 Point_2; 00449 typedef typename K::Direction_2 Direction_2; 00450 typedef typename K::Ray_2 Ray_2; 00451 typedef typename K::Segment_2 Segment_2; 00452 typedef typename K::Construct_point_on_2 Construct_point_on_2; 00453 typedef typename K::Compare_xy_2 Compare_xy_2; 00454 typedef typename K::Collinear_are_ordered_along_line_2 00455 Collinear_are_ordered_along_line_2; 00456 Collinear_are_ordered_along_line_2 co; 00457 Construct_point_on_2 cp; 00458 Compare_xy_2 cxy; 00459 public: 00460 typedef typename K::Boolean result_type; 00461 00462 Collinear_has_on_2() {} 00463 Collinear_has_on_2(const Construct_point_on_2& cp_, 00464 const Compare_xy_2& cxy_) 00465 : cp(cp_), cxy(cxy_) 00466 {} 00467 00468 result_type 00469 operator()( const Ray_2& r, const Point_2& p) const 00470 { 00471 const Point_2 & source = cp(r,0); 00472 return p == source || Direction_2(p - source) == r.direction(); 00473 } // FIXME 00474 00475 result_type 00476 operator()( const Segment_2& s, const Point_2& p) const 00477 { 00478 return co(cp(s,0), p, cp(s,1)); 00479 } 00480 }; 00481 00482 template <typename K> 00483 class Collinear_2 00484 { 00485 typedef typename K::Point_2 Point_2; 00486 typedef typename K::Orientation_2 Orientation_2; 00487 Orientation_2 o; 00488 public: 00489 typedef typename K::Boolean result_type; 00490 00491 Collinear_2() {} 00492 Collinear_2(const Orientation_2 o_) : o(o_) {} 00493 00494 result_type 00495 operator()(const Point_2& p, const Point_2& q, const Point_2& r) const 00496 { 00497 typedef typename K::RT RT; 00498 00499 const RT& phx = p.hx(); 00500 const RT& phy = p.hy(); 00501 const RT& phw = p.hw(); 00502 const RT& qhx = q.hx(); 00503 const RT& qhy = q.hy(); 00504 const RT& qhw = q.hw(); 00505 const RT& rhx = r.hx(); 00506 const RT& rhy = r.hy(); 00507 const RT& rhw = r.hw(); 00508 00509 // | A B | 00510 // | C D | 00511 00512 RT A = phx*rhw - phw*rhx; 00513 RT B = phy*rhw - phw*rhy; 00514 RT C = qhx*rhw - qhw*rhx; 00515 RT D = qhy*rhw - qhw*rhy; 00516 00517 RT det = A*D - B*C; 00518 00519 /* 00520 RT det_old = p.hx() * (q.hy()*r.hw() - q.hw()*r.hy() ) 00521 + p.hy() * (q.hw()*r.hx() - q.hx()*r.hw() ) 00522 + p.hw() * (q.hx()*r.hy() - q.hy()*r.hx() ); 00523 00524 if ( !(CGAL_NTS sign(det) == CGAL_NTS sign(det_old)) ) 00525 { 00526 std::cerr << "det: " << det << " det_old: " << det_old << flush; 00527 } 00528 */ 00529 00530 return CGAL_NTS is_zero(det); 00531 } 00532 }; 00533 00534 template <typename K> 00535 class Compare_angle_with_x_axis_2 00536 { 00537 typedef typename K::Point_2 Point_2; 00538 typedef typename K::Vector_2 Vector_2; 00539 typedef typename K::Direction_2 Direction_2; 00540 public: 00541 typedef typename K::Comparison_result result_type; 00542 00543 result_type 00544 operator()(const Direction_2& d1, const Direction_2& d2) const 00545 { 00546 typedef typename K::RT RT; 00547 CGAL_kernel_precondition( 00548 static_cast<int>(COUNTERCLOCKWISE) == static_cast<int>(LARGER) 00549 && static_cast<int>(COLLINEAR) == static_cast<int>(EQUAL) 00550 && static_cast<int>(CLOCKWISE) == static_cast<int>(SMALLER) ); 00551 00552 const RT RT0(0); 00553 00554 Vector_2 dirvec1(d1.x(), d1.y()); // Added 00555 Point_2 p1 = CGAL::ORIGIN + dirvec1; // Added 00556 Vector_2 dirvec2(d2.x(), d2.y()); // Added 00557 Point_2 p2 = ORIGIN + dirvec2; // Added 00558 // Point_2 p1 = ORIGIN + d1.vector(); // Commented out 00559 // Point_2 p2 = ORIGIN + d2.vector(); // Commented out 00560 00561 CGAL_kernel_precondition( RT0 < p1.hw() ); 00562 CGAL_kernel_precondition( RT0 < p2.hw() ); 00563 00564 int x_sign1 = static_cast<int>(CGAL_NTS sign( p1.hx() )); 00565 int x_sign2 = static_cast<int>(CGAL_NTS sign( p2.hx() )); 00566 int y_sign1 = static_cast<int>(CGAL_NTS sign( p1.hy() )); 00567 int y_sign2 = static_cast<int>(CGAL_NTS sign( p2.hy() )); 00568 00569 if ( y_sign1 * y_sign2 < 0) 00570 { 00571 return (0 < y_sign1 ) ? SMALLER : LARGER; 00572 } 00573 00574 Point_2 origin( RT0 , RT0 ); 00575 00576 if ( 0 < y_sign1 * y_sign2 ) 00577 { 00578 return orientation(origin, p2, p1); 00579 00580 // Precondition on the enums: 00581 // COUNTERCLOCKWISE == LARGER ( == 1 ) 00582 // COLLINEAR == EQUAL ( == 0 ) 00583 // CLOCKWISE == SMALLER ( == -1 ) 00584 } 00585 00586 // ( y_sign1 * y_sign2 == 0 ) 00587 00588 bool b1 = (y_sign1 == 0) && (x_sign1 >= 0); 00589 bool b2 = (y_sign2 == 0) && (x_sign2 >= 0); 00590 00591 if ( b1 ) { return b2 ? EQUAL : SMALLER; } 00592 if ( b2 ) { return b1 ? EQUAL : LARGER; } 00593 if ( y_sign1 == y_sign2 ) // == 0 00594 return EQUAL; 00595 else 00596 return (orientation(origin, p1, p2) == COUNTERCLOCKWISE) ? 00597 SMALLER : LARGER; 00598 } 00599 }; 00600 00601 template <typename K> 00602 class Compare_distance_2 00603 { 00604 typedef typename K::Point_2 Point_2; 00605 public: 00606 typedef typename K::Comparison_result result_type; 00607 00608 result_type 00609 operator()(const Point_2& p, const Point_2& q, const Point_2& r) const 00610 { 00611 typedef typename K::RT RT; 00612 00613 const RT & phx = p.hx(); 00614 const RT & phy = p.hy(); 00615 const RT & phw = p.hw(); 00616 const RT & qhx = q.hx(); 00617 const RT & qhy = q.hy(); 00618 const RT & qhw = q.hw(); 00619 const RT & rhx = r.hx(); 00620 const RT & rhy = r.hy(); 00621 const RT & rhw = r.hw(); 00622 00623 RT dosd = // difference of squared distances 00624 00625 // phx * phx * qhw * qhw * rhw * rhw 00626 // -RT(2) * phx * qhx * phw * qhw * rhw * rhw 00627 // + qhx * qhx * phw * phw * rhw * rhw 00628 // 00629 // + phy * phy * qhw * qhw * rhw * rhw 00630 // -RT(2) * phy * qhy * phw * qhw * rhw * rhw 00631 // + qhy * qhy * phw * phw * rhw * rhw 00632 // 00633 // - ( phx * phx * qhw * qhw * rhw * rhw 00634 // -RT(2) * phx * rhx * phw * qhw * qhw * rhw 00635 // + rhx * rhx * phw * phw * qhw * qhw 00636 // 00637 // + phy * phy * qhw * qhw * rhw * rhw 00638 // -RT(2) * phy * rhy * phw * qhw * qhw * rhw 00639 // + rhy * rhy * phw * phw * qhw * qhw 00640 00641 rhw*rhw * ( phw * ( qhx*qhx + qhy*qhy ) 00642 - 2 * qhw * ( phx*qhx + phy*qhy ) 00643 ) 00644 - qhw*qhw * ( phw * ( rhx*rhx + rhy*rhy ) 00645 - 2 * rhw * ( phx*rhx + phy*rhy ) 00646 ); 00647 00648 return CGAL_NTS sign(dosd); 00649 } 00650 }; 00651 00652 template <typename K> 00653 class Compare_squared_distance_2 00654 { 00655 typedef typename K::Point_2 Point_2; 00656 typedef typename K::FT FT; 00657 public: 00658 typedef typename K::Comparison_result result_type; 00659 00660 result_type 00661 operator()(const Point_2& p, const Point_2& q, const FT& d2) const 00662 { 00663 return CGAL_NTS compare(squared_distance(p, q), d2); 00664 } 00665 }; 00666 00667 template <typename K> 00668 class Compare_distance_3 00669 { 00670 typedef typename K::Point_3 Point_3; 00671 public: 00672 typedef typename K::Comparison_result result_type; 00673 00674 result_type 00675 operator()(const Point_3& p, const Point_3& q, const Point_3& r) const 00676 { 00677 typedef typename K::RT RT; 00678 00679 const RT & phx = p.hx(); 00680 const RT & phy = p.hy(); 00681 const RT & phz = p.hz(); 00682 const RT & phw = p.hw(); 00683 const RT & qhx = q.hx(); 00684 const RT & qhy = q.hy(); 00685 const RT & qhz = q.hz(); 00686 const RT & qhw = q.hw(); 00687 const RT & rhx = r.hx(); 00688 const RT & rhy = r.hy(); 00689 const RT & rhz = r.hz(); 00690 const RT & rhw = r.hw(); 00691 00692 RT dosd = // difference of squared distances 00693 00694 rhw*rhw * ( phw * ( qhx*qhx + qhy*qhy + qhz*qhz ) 00695 - 2 * qhw * ( phx*qhx + phy*qhy + phz*qhz ) 00696 ) 00697 - qhw*qhw * ( phw * ( rhx*rhx + rhy*rhy + rhz*rhz ) 00698 - 2 * rhw * ( phx*rhx + phy*rhy + phz*rhz ) 00699 ); 00700 00701 return CGAL_NTS sign(dosd); 00702 } 00703 }; 00704 00705 template <typename K> 00706 class Compare_squared_distance_3 00707 { 00708 typedef typename K::Point_3 Point_3; 00709 typedef typename K::FT FT; 00710 public: 00711 typedef typename K::Comparison_result result_type; 00712 00713 result_type 00714 operator()(const Point_3& p, const Point_3& q, const FT& d2) const 00715 { 00716 return CGAL_NTS compare(squared_distance(p, q), d2); 00717 } 00718 }; 00719 00720 template <typename K> 00721 class Compare_slope_2 00722 { 00723 typedef typename K::Line_2 Line_2; 00724 typedef typename K::Segment_2 Segment_2; 00725 public: 00726 typedef typename K::Comparison_result result_type; 00727 00728 result_type 00729 operator()(const Line_2& l1, const Line_2& l2) const 00730 { 00731 typedef typename K::RT RT; 00732 if (l1.is_horizontal()) 00733 return l2.is_vertical() ? 00734 SMALLER : CGAL_NTS sign(l2.a()) * CGAL_NTS sign(l2.b()); 00735 if (l2.is_horizontal()) 00736 return l1.is_vertical() ? 00737 LARGER : - CGAL_NTS sign(l1.a()) * CGAL_NTS sign(l1.b()); 00738 if (l1.is_vertical()) return l2.is_vertical() ? EQUAL : LARGER; 00739 if (l2.is_vertical()) return SMALLER; 00740 int l1_sign = CGAL_NTS sign(-l1.a() * l1.b()); 00741 int l2_sign = CGAL_NTS sign(-l2.a() * l2.b()); 00742 00743 if (l1_sign < l2_sign) return SMALLER; 00744 if (l1_sign > l2_sign) return LARGER; 00745 00746 if (l1_sign > 0) 00747 return CGAL_NTS compare( CGAL_NTS abs(l1.a() * l2.b()), 00748 CGAL_NTS abs(l2.a() * l1.b()) ); 00749 00750 return CGAL_NTS compare( CGAL_NTS abs(l2.a() * l1.b()), 00751 CGAL_NTS abs(l1.a() * l2.b()) ); 00752 } // FIXME 00753 00754 result_type 00755 operator()(const Segment_2& s1, const Segment_2& s2) const 00756 { 00757 typedef typename K::FT FT; 00758 00759 typename K::Comparison_result cmp_y1 = compare_y(s1.source(), s1.target()); 00760 if (cmp_y1 == EQUAL) // horizontal 00761 { 00762 typename K::Comparison_result cmp_x2 = compare_x(s2.source(), s2.target()); 00763 00764 if (cmp_x2 == EQUAL) return SMALLER; 00765 FT s_hw = s2.source().hw(); 00766 FT t_hw = s2.target().hw(); 00767 return - CGAL_NTS sign(s2.source().hy()*t_hw - s2.target().hy()*s_hw) * 00768 CGAL_NTS sign(s2.source().hx()*t_hw - s2.target().hx()*s_hw); 00769 } 00770 00771 typename K::Comparison_result cmp_y2 = compare_y(s2.source(), s2.target()); 00772 if (cmp_y2 == EQUAL) 00773 { 00774 typename K::Comparison_result cmp_x1 = compare_x(s1.source(), s1.target()); 00775 00776 if (cmp_x1 == EQUAL) return LARGER; 00777 FT s_hw = s1.source().hw(); 00778 FT t_hw = s1.target().hw(); 00779 return CGAL_NTS sign(s1.source().hy()*t_hw - s1.target().hy()*s_hw) * 00780 CGAL_NTS sign(s1.source().hx()*t_hw - s1.target().hx()*s_hw); 00781 } 00782 00783 typename K::Comparison_result cmp_x1 = compare_x(s1.source(), s1.target()); 00784 typename K::Comparison_result cmp_x2 = compare_x(s2.source(), s2.target()); 00785 if (cmp_x1 == EQUAL) 00786 return cmp_x2 == EQUAL ? EQUAL : LARGER; 00787 00788 if (cmp_x2 == EQUAL) return SMALLER; 00789 00790 FT s1_s_hw = s1.source().hw(); 00791 FT s1_t_hw = s1.target().hw(); 00792 FT s2_s_hw = s2.source().hw(); 00793 FT s2_t_hw = s2.target().hw(); 00794 FT s1_xdiff = s1.source().hx()*s1_t_hw - s1.target().hx()*s1_s_hw; 00795 FT s1_ydiff = s1.source().hy()*s1_t_hw - s1.target().hy()*s1_s_hw; 00796 FT s2_xdiff = s2.source().hx()*s2_t_hw - s2.target().hx()*s2_s_hw; 00797 FT s2_ydiff = s2.source().hy()*s2_t_hw - s2.target().hy()*s2_s_hw; 00798 typename K::Sign s1_sign = CGAL_NTS sign(s1_ydiff * s1_xdiff); 00799 typename K::Sign s2_sign = CGAL_NTS sign(s2_ydiff * s2_xdiff); 00800 00801 if (s1_sign < s2_sign) return SMALLER; 00802 if (s1_sign > s2_sign) return LARGER; 00803 00804 if (s1_sign > 0) 00805 return CGAL_NTS sign(CGAL_NTS abs(s1_ydiff * s2_xdiff) - 00806 CGAL_NTS abs(s2_ydiff * s1_xdiff)); 00807 00808 return CGAL_NTS sign(CGAL_NTS abs(s2_ydiff * s1_xdiff) - 00809 CGAL_NTS abs(s1_ydiff * s2_xdiff)); 00810 } 00811 }; 00812 00813 template <typename K> 00814 class Compare_x_at_y_2 00815 { 00816 typedef typename K::Point_2 Point_2; 00817 typedef typename K::Line_2 Line_2; 00818 public: 00819 typedef typename K::Comparison_result result_type; 00820 00821 result_type 00822 operator()( const Point_2& p, const Line_2& h) const 00823 { 00824 typedef typename K::RT RT; 00825 CGAL_kernel_precondition( ! h.is_horizontal() ); 00826 typename K::Oriented_side ors = h.oriented_side( p ); 00827 if ( h.a() < RT(0) ) 00828 ors = -ors; 00829 if ( ors == ON_POSITIVE_SIDE ) 00830 return LARGER; 00831 return ( ors == ON_NEGATIVE_SIDE ) ? SMALLER : EQUAL; 00832 } // FIXME 00833 00834 result_type 00835 operator()( const Point_2& p, const Line_2& h1, const Line_2& h2) const 00836 { return CGAL_NTS compare(h1.x_at_y( p.y() ), h2.x_at_y( p.y() )); } 00837 // FIXME 00838 00839 result_type 00840 operator()( const Line_2& l1, const Line_2& l2, const Line_2& h) const 00841 { return compare_x_at_y( gp_linear_intersection( l1, l2 ), h); } 00842 // FIXME 00843 00844 result_type 00845 operator()( const Line_2& l1, const Line_2& l2, 00846 const Line_2& h1, const Line_2& h2) const 00847 { return compare_x_at_y( gp_linear_intersection( l1, l2 ), h1, h2 ); } 00848 // FIXME 00849 }; 00850 00851 template <typename K> 00852 class Compare_xyz_3 00853 { 00854 typedef typename K::Point_3 Point_3; 00855 public: 00856 typedef typename K::Comparison_result result_type; 00857 00858 result_type 00859 operator()( const Point_3& p, const Point_3& q) const 00860 { 00861 typedef typename K::RT RT; 00862 RT pV = p.hx()*q.hw(); 00863 RT qV = q.hx()*p.hw(); 00864 if ( pV < qV ) 00865 { 00866 return SMALLER; 00867 } 00868 if ( qV < pV ) // ( pV > qV ) 00869 { 00870 return LARGER; 00871 } 00872 // same x 00873 pV = p.hy()*q.hw(); 00874 qV = q.hy()*p.hw(); 00875 if ( pV < qV ) 00876 { 00877 return SMALLER; 00878 } 00879 if ( qV < pV ) // ( pV > qV ) 00880 { 00881 return LARGER; 00882 } 00883 // same x and y 00884 pV = p.hz()*q.hw(); 00885 qV = q.hz()*p.hw(); 00886 return CGAL_NTS compare(pV, qV); 00887 } 00888 }; 00889 00890 template <typename K> 00891 class Compare_xy_2 00892 { 00893 typedef typename K::Point_2 Point_2; 00894 public: 00895 typedef typename K::Comparison_result result_type; 00896 00897 result_type 00898 operator()( const Point_2& p, const Point_2& q) const 00899 { 00900 typedef typename K::RT RT; 00901 00902 const RT& phx = p.hx(); 00903 const RT& phy = p.hy(); 00904 const RT& phw = p.hw(); 00905 const RT& qhx = q.hx(); 00906 const RT& qhy = q.hy(); 00907 const RT& qhw = q.hw(); 00908 00909 RT pV = phx*qhw; 00910 RT qV = qhx*phw; 00911 if ( pV == qV ) 00912 { 00913 pV = phy*qhw; 00914 qV = qhy*phw; 00915 } 00916 return CGAL_NTS compare(pV, qV); 00917 } 00918 }; 00919 00920 template <typename K> 00921 class Compare_yx_2 00922 { 00923 typedef typename K::Point_2 Point_2; 00924 public: 00925 typedef typename K::Comparison_result result_type; 00926 00927 result_type 00928 operator()( const Point_2& p, const Point_2& q) const 00929 { 00930 typedef typename K::RT RT; 00931 00932 const RT& phx = p.hx(); 00933 const RT& phy = p.hy(); 00934 const RT& phw = p.hw(); 00935 const RT& qhx = q.hx(); 00936 const RT& qhy = q.hy(); 00937 const RT& qhw = q.hw(); 00938 00939 RT pV = phy*qhw; 00940 RT qV = qhy*phw; 00941 if ( pV == qV ) 00942 { 00943 pV = phx*qhw; 00944 qV = qhx*phw; 00945 } 00946 return CGAL_NTS compare(pV, qV); 00947 } 00948 }; 00949 00950 template <typename K> 00951 class Compare_xy_3 00952 { 00953 typedef typename K::Point_3 Point_3; 00954 public: 00955 typedef typename K::Comparison_result result_type; 00956 00957 result_type 00958 operator()( const Point_3& p, const Point_3& q) const 00959 { 00960 typedef typename K::RT RT; 00961 RT pV = p.hx()*q.hw(); 00962 RT qV = q.hx()*p.hw(); 00963 if ( pV < qV ) 00964 { 00965 return SMALLER; 00966 } 00967 if ( qV < pV ) // ( pV > qV ) 00968 { 00969 return LARGER; 00970 } 00971 // same x 00972 pV = p.hy()*q.hw(); 00973 qV = q.hy()*p.hw(); 00974 return CGAL_NTS compare(pV, qV); 00975 } 00976 }; 00977 00978 template <typename K> 00979 class Compare_x_2 00980 { 00981 typedef typename K::Point_2 Point_2; 00982 typedef typename K::Line_2 Line_2; 00983 public: 00984 typedef typename K::Comparison_result result_type; 00985 00986 result_type 00987 operator()( const Point_2& p, const Point_2& q) const 00988 { 00989 return CGAL_NTS compare(p.hx()*q.hw(), q.hx()*p.hw()); 00990 } 00991 00992 result_type 00993 operator()( const Point_2& p, const Line_2& l1, const Line_2& l2) const 00994 { 00995 Point_2 ip = gp_linear_intersection( l1, l2 ); 00996 return this->operator()(p, ip); 00997 } // FIXME 00998 00999 result_type 01000 operator()( const Line_2& l, const Line_2& h1, const Line_2& h2) const 01001 { 01002 return this->operator()(l, h1, l, h2); 01003 } // FIXME 01004 01005 result_type 01006 operator()( const Line_2& l1, const Line_2& l2, 01007 const Line_2& h1, const Line_2& h2) const 01008 { 01009 Point_2 lip = gp_linear_intersection( l1, l2 ); 01010 Point_2 hip = gp_linear_intersection( h1, h2 ); 01011 return this->operator()(lip, hip); 01012 } // FIXME 01013 }; 01014 01015 template <typename K> 01016 class Compare_x_3 01017 { 01018 typedef typename K::Point_3 Point_3; 01019 public: 01020 typedef typename K::Comparison_result result_type; 01021 01022 result_type 01023 operator()( const Point_3& p, const Point_3& q) const 01024 { return CGAL_NTS compare(p.hx() * q.hw(), q.hx() * p.hw() ); } 01025 }; 01026 01027 template <typename K> 01028 class Compare_y_at_x_2 01029 { 01030 typedef typename K::Point_2 Point_2; 01031 typedef typename K::Line_2 Line_2; 01032 typedef typename K::Segment_2 Segment_2; 01033 public: 01034 typedef typename K::Comparison_result result_type; 01035 01036 result_type 01037 operator()( const Point_2& p, const Line_2& h) const 01038 { 01039 typedef typename K::RT RT; 01040 CGAL_kernel_precondition( ! h.is_vertical() ); 01041 typename K::Oriented_side ors = h.oriented_side( p ); 01042 if ( h.b() < 0 ) 01043 ors = -ors; 01044 return ors; 01045 } // FIXME 01046 01047 result_type 01048 operator()( const Point_2& p, const Line_2& h1, const Line_2& h2) const 01049 { return CGAL_NTS compare(h1.y_at_x( p.x() ), h2.y_at_x( p.x() )); } 01050 // FIXME 01051 01052 result_type 01053 operator()( const Line_2& l1, const Line_2& l2, const Line_2& h) const 01054 { return compare_y_at_x( gp_linear_intersection( l1, l2 ), h); } 01055 // FIXME 01056 01057 result_type 01058 operator()( const Line_2& l1, const Line_2& l2, 01059 const Line_2& h1, const Line_2& h2) const 01060 { return compare_y_at_x( gp_linear_intersection( l1, l2 ), h1, h2 ); } 01061 // FIXME 01062 01063 result_type 01064 operator()( const Point_2& p, const Segment_2& s) const 01065 { 01066 // compares the y-coordinates of p and the vertical projection of p on s. 01067 // Precondition : p is in the x-range of s. 01068 01069 if (compare_x(s.source(), s.target()) == SMALLER) { 01070 CGAL_kernel_precondition(compare_x(s.source(), p) != LARGER 01071 && compare_x(p, s.target()) != LARGER); 01072 return (Comparison_result) orientation(p, s.source(), s.target()); 01073 } 01074 else if (compare_x(s.source(), s.target()) == LARGER) { 01075 CGAL_kernel_precondition(compare_x(s.target(), p) != LARGER 01076 && compare_x(p, s.source()) != LARGER); 01077 return (Comparison_result) orientation(p, s.target(), s.source()); 01078 } 01079 else { 01080 CGAL_kernel_precondition(compare_x(s.target(), p) == EQUAL); 01081 if (compare_y(p, s.source()) == SMALLER && 01082 compare_y(p, s.target()) == SMALLER) 01083 return SMALLER; 01084 if (compare_y(p, s.source()) == LARGER && 01085 compare_y(p, s.target()) == LARGER) 01086 return LARGER; 01087 return EQUAL; 01088 } 01089 } // FIXME 01090 01091 result_type 01092 operator()( const Point_2& p, 01093 const Segment_2& s1, const Segment_2& s2) const 01094 { 01095 // compares the y-coordinates of the vertical projections 01096 // of p on s1 and s2 01097 // Precondition : p is in the x-range of s1 and s2. 01098 // - if one or two segments are vertical : 01099 // - if the segments intersect, return EQUAL 01100 // - if not, return the obvious SMALLER/LARGER. 01101 01102 typedef typename K::FT FT; 01103 FT px = p.x(); 01104 FT s1sx = s1.source().x(); 01105 FT s1sy = s1.source().y(); 01106 FT s1tx = s1.target().x(); 01107 FT s1ty = s1.target().y(); 01108 FT s2sx = s2.source().x(); 01109 FT s2sy = s2.source().y(); 01110 FT s2tx = s2.target().x(); 01111 FT s2ty = s2.target().y(); 01112 01113 CGAL_kernel_precondition(px >= (CGAL::min)(s1sx, s1tx) && 01114 px <= (CGAL::max)(s1sx, s1tx)); 01115 CGAL_kernel_precondition(px >= (CGAL::min)(s2sx, s2tx) && 01116 px <= (CGAL::max)(s2sx, s2tx)); 01117 01118 if (s1sx != s1tx && s2sx != s2tx) { 01119 FT s1stx = s1sx-s1tx; 01120 FT s2stx = s2sx-s2tx; 01121 01122 return CGAL_NTS compare(s1sx, s1tx) * 01123 CGAL_NTS compare(s2sx, s2tx) * 01124 CGAL_NTS compare(-(s1sx-px)*(s1sy-s1ty)*s2stx, 01125 (s2sy-s1sy)*s2stx*s1stx 01126 -(s2sx-px)*(s2sy-s2ty)*s1stx); 01127 } 01128 else { 01129 if (s1sx == s1tx) { // s1 is vertical 01130 typename K::Comparison_result c1, c2; 01131 c1 = compare_y_at_x(s1.source(), s2); 01132 c2 = compare_y_at_x(s1.target(), s2); 01133 if (c1 == c2) 01134 return c1; 01135 return EQUAL; 01136 } 01137 // s2 is vertical 01138 typename K::Comparison_result c3, c4; 01139 c3 = compare_y_at_x(s2.source(), s1); 01140 c4 = compare_y_at_x(s2.target(), s1); 01141 if (c3 == c4) 01142 return -c3; 01143 return EQUAL; 01144 } 01145 } // FIXME 01146 }; 01147 01148 template <typename K> 01149 class Compare_y_2 01150 { 01151 typedef typename K::Point_2 Point_2; 01152 typedef typename K::Line_2 Line_2; 01153 public: 01154 typedef typename K::Comparison_result result_type; 01155 01156 result_type 01157 operator()( const Point_2& p, const Point_2& q) const 01158 { 01159 typedef typename K::RT RT; 01160 01161 const RT& phy = p.hy(); 01162 const RT& phw = p.hw(); 01163 const RT& qhy = q.hy(); 01164 const RT& qhw = q.hw(); 01165 return CGAL_NTS compare(phy * qhw, qhy * phw); 01166 } 01167 01168 result_type 01169 operator()( const Point_2& p, const Line_2& l1, const Line_2& l2) const 01170 { 01171 Point_2 ip = gp_linear_intersection( l1, l2 ); 01172 return compare_y( p, ip ); 01173 } // FIXME 01174 01175 result_type 01176 operator()( const Line_2& l, const Line_2& h1, const Line_2& h2) const 01177 { 01178 return this->operator()(l, h1, l, h2); 01179 } 01180 01181 result_type 01182 operator()( const Line_2& l1, const Line_2& l2, 01183 const Line_2& h1, const Line_2& h2) const 01184 { 01185 Point_2 lip = gp_linear_intersection( l1, l2 ); 01186 Point_2 hip = gp_linear_intersection( h1, h2 ); 01187 return this->operator()( lip, hip ); 01188 } // FIXME 01189 }; 01190 01191 template <typename K> 01192 class Compare_y_3 01193 { 01194 typedef typename K::Point_3 Point_3; 01195 public: 01196 typedef typename K::Comparison_result result_type; 01197 01198 result_type 01199 operator()( const Point_3& p, const Point_3& q) const 01200 { return CGAL_NTS compare(p.hy() * q.hw(), q.hy() * p.hw() ); } 01201 }; 01202 01203 template <typename K> 01204 class Compare_z_3 01205 { 01206 typedef typename K::Point_3 Point_3; 01207 public: 01208 typedef typename K::Comparison_result result_type; 01209 01210 result_type 01211 operator()( const Point_3& p, const Point_3& q) const 01212 { return CGAL_NTS compare(p.hz() * q.hw(), q.hz() * p.hw() ); } 01213 }; 01214 01215 template <typename K> 01216 class Compute_area_2 01217 { 01218 typedef typename K::RT RT; 01219 typedef typename K::FT FT; 01220 typedef typename K::Iso_rectangle_2 Iso_rectangle_2; 01221 typedef typename K::Triangle_2 Triangle_2; 01222 typedef typename K::Point_2 Point_2; 01223 typedef typename K::Vector_2 Vector_2; 01224 typedef typename K::Construct_vector_2 Construct_vector_2; 01225 Construct_vector_2 co; 01226 public: 01227 typedef FT result_type; 01228 01229 FT 01230 operator()( const Point_2& p, const Point_2& q, const Point_2& r ) const 01231 { 01232 Vector_2 v1 = co(p, q); 01233 Vector_2 v2 = co(p, r); 01234 01235 RT num = v1.hx()*v2.hy() - v2.hx()*v1.hy(); 01236 RT den = RT(2) * v1.hw() * v2.hw(); 01237 return FT(num)/FT(den); 01238 } 01239 01240 FT 01241 operator()( const Iso_rectangle_2& r ) const 01242 { return (r.xmax()-r.xmin()) * (r.ymax()-r.ymin()); } 01243 01244 FT 01245 operator()( const Triangle_2& t ) const 01246 { return t.area(); } 01247 }; 01248 01249 template <typename K> 01250 class Compute_determinant_2 01251 { 01252 typedef typename K::FT FT; 01253 typedef typename K::Vector_2 Vector_2; 01254 public: 01255 typedef FT result_type; 01256 01257 result_type 01258 operator()(const Vector_2& v, const Vector_2& w) const 01259 { 01260 return determinant(v.hx(), v.hy(), 01261 w.hx(), w.hy()) / FT(v.hw() * w.hw()); 01262 } 01263 }; 01264 01265 template <typename K> 01266 class Compute_determinant_3 01267 { 01268 typedef typename K::FT FT; 01269 typedef typename K::Vector_3 Vector_3; 01270 public: 01271 typedef FT result_type; 01272 01273 result_type 01274 operator()(const Vector_3& v, const Vector_3& w, const Vector_3& t) const 01275 { 01276 return determinant(v.hx(), v.hy(), v.hz(), 01277 w.hx(), w.hy(), w.hz(), 01278 t.hx(), t.hy(), t.hz()) 01279 / FT(v.hw() * w.hw() * t.hw()); 01280 } 01281 }; 01282 01283 template <typename K> 01284 class Compute_scalar_product_2 01285 { 01286 typedef typename K::RT RT; 01287 typedef typename K::FT FT; 01288 typedef typename K::Vector_2 Vector_2; 01289 public: 01290 typedef FT result_type; 01291 01292 FT 01293 operator()(const Vector_2& v, const Vector_2& w) const 01294 { 01295 return FT( RT(v.hx()*w.hx() + v.hy()*w.hy()) ) / 01296 FT( RT(v.hw()*w.hw() ) ); 01297 } 01298 }; 01299 01300 template <typename K> 01301 class Compute_scalar_product_3 01302 { 01303 typedef typename K::RT RT; 01304 typedef typename K::FT FT; 01305 typedef typename K::Vector_3 Vector_3; 01306 public: 01307 typedef FT result_type; 01308 01309 FT 01310 operator()(const Vector_3& v, const Vector_3& w) const 01311 { 01312 return FT( RT(v.hx()*w.hx() + v.hy()*w.hy()) + v.hz()*w.hz() ) / 01313 FT( RT(v.hw()*w.hw() ) ); 01314 } 01315 }; 01316 01317 // TODO ... 01318 template <typename K> 01319 class Compute_squared_radius_2 01320 { 01321 typedef typename K::FT FT; 01322 typedef typename K::Point_2 Point_2; 01323 typedef typename K::Circle_2 Circle_2; 01324 public: 01325 typedef FT result_type; 01326 01327 FT 01328 operator()( const Circle_2& c) const 01329 { return c.rep().squared_radius(); } 01330 01331 FT 01332 operator()( const Point_2& p) const 01333 { return FT(0); } 01334 01335 FT 01336 operator()( const Point_2& p, const Point_2& q) const 01337 { 01338 typedef typename K::FT FT; 01339 return squared_distance(p, q)/FT(4); 01340 } // FIXME 01341 01342 FT 01343 operator()( const Point_2& p, const Point_2& q, const Point_2& r) const 01344 { return squared_distance(p, circumcenter(p, q, r)); } 01345 // FIXME 01346 }; 01347 01348 template <typename K> 01349 class Compute_squared_radius_3 01350 { 01351 typedef typename K::FT FT; 01352 typedef typename K::Point_3 Point_3; 01353 typedef typename K::Sphere_3 Sphere_3; 01354 public: 01355 typedef FT result_type; 01356 01357 FT 01358 operator()( const Sphere_3& s) const 01359 { return s.rep().squared_radius(); } 01360 01361 FT 01362 operator()( const Point_3& p) const 01363 { return FT(0); } 01364 01365 FT 01366 operator()( const Point_3& p, const Point_3& q) const 01367 { 01368 typedef typename K::FT FT; 01369 return squared_distance(p, q) / FT(4); 01370 } // FIXME 01371 01372 FT 01373 operator()( const Point_3& p, const Point_3& q, const Point_3& r) const 01374 { 01375 return squared_distance(p, circumcenter(p, q, r)); 01376 } // FIXME 01377 01378 FT 01379 operator()( const Point_3& p, const Point_3& q, 01380 const Point_3& r, const Point_3& s) const 01381 { 01382 return squared_distance(p, circumcenter(p, q, r, s)); 01383 } // FIXME 01384 }; 01385 01386 template <typename K> 01387 class Compute_volume_3 01388 { 01389 typedef typename K::FT FT; 01390 typedef typename K::Point_3 Point_3; 01391 typedef typename K::Vector_3 Vector_3; 01392 typedef typename K::Tetrahedron_3 Tetrahedron_3; 01393 typedef typename K::Iso_cuboid_3 Iso_cuboid_3; 01394 public: 01395 typedef FT result_type; 01396 01397 FT 01398 operator()(const Point_3& p0, const Point_3& p1, 01399 const Point_3& p2, const Point_3& p3) const 01400 { 01401 Vector_3 vec1 = p1 - p0; 01402 Vector_3 vec2 = p2 - p0; 01403 Vector_3 vec3 = p3 - p0; 01404 01405 // first compute (vec1.hw * vec2.hw * vec3.hw * det(vec1, vec2, vec3)) 01406 // then divide by (6 * vec1.hw * vec2.hw * vec3.hw) 01407 const FT w123 (vec1.hw() * vec2.hw() * vec3.hw()); 01408 const FT& hx1 = vec1.hx(); 01409 const FT& hy1 = vec1.hy(); 01410 const FT& hz1 = vec1.hz(); 01411 const FT& hx2 = vec2.hx(); 01412 const FT& hy2 = vec2.hy(); 01413 const FT& hz2 = vec2.hz(); 01414 const FT& hx3 = vec3.hx(); 01415 const FT& hy3 = vec3.hy(); 01416 const FT& hz3 = vec3.hz(); 01417 01418 return ( (hx1 * (hy2 * hz3 - hy3 * hz2)) 01419 - (hy1 * (hx2 * hz3 - hx3 * hz2)) 01420 + (hz1 * (hx2 * hy3 - hx3 * hy2)))/ (6 * w123); 01421 } 01422 01423 FT 01424 operator()( const Tetrahedron_3& t ) const 01425 { 01426 return this->operator()(t.vertex(0), t.vertex(1), 01427 t.vertex(2), t.vertex(3)); 01428 } 01429 01430 FT 01431 operator()( const Iso_cuboid_3& c ) const 01432 { return c.rep().volume(); } 01433 }; 01434 01435 01436 template <typename K> 01437 class Compute_x_2 01438 { 01439 typedef typename K::FT FT; 01440 typedef typename K::Point_2 Point_2; 01441 typedef typename K::Vector_2 Vector_2; 01442 01443 public: 01444 typedef FT result_type; 01445 01446 FT 01447 operator()(const Point_2& p) const 01448 { 01449 return p.rep().x(); 01450 } 01451 01452 FT 01453 operator()(const Vector_2& v) const 01454 { 01455 return v.rep().x(); 01456 } 01457 }; 01458 01459 template <typename K> 01460 class Compute_x_3 01461 { 01462 typedef typename K::FT FT; 01463 typedef typename K::Point_3 Point_3; 01464 typedef typename K::Vector_3 Vector_3; 01465 01466 public: 01467 typedef FT result_type; 01468 01469 FT 01470 operator()(const Point_3& p) const 01471 { 01472 return p.rep().x(); 01473 } 01474 01475 FT 01476 operator()(const Vector_3& v) const 01477 { 01478 return v.rep().x(); 01479 } 01480 }; 01481 01482 template <typename K> 01483 class Compute_y_2 01484 { 01485 typedef typename K::FT FT; 01486 typedef typename K::Point_2 Point_2; 01487 typedef typename K::Vector_2 Vector_2; 01488 01489 public: 01490 typedef FT result_type; 01491 01492 FT 01493 operator()(const Point_2& p) const 01494 { 01495 return p.rep().y(); 01496 } 01497 01498 FT 01499 operator()(const Vector_2& v) const 01500 { 01501 return v.rep().y(); 01502 } 01503 }; 01504 01505 template <typename K> 01506 class Compute_y_3 01507 { 01508 typedef typename K::FT FT; 01509 typedef typename K::Point_3 Point_3; 01510 typedef typename K::Vector_3 Vector_3; 01511 01512 public: 01513 typedef FT result_type; 01514 01515 FT 01516 operator()(const Point_3& p) const 01517 { 01518 return p.rep().y(); 01519 } 01520 01521 FT 01522 operator()(const Vector_3& v) const 01523 { 01524 return v.rep().y(); 01525 } 01526 }; 01527 01528 template <typename K> 01529 class Compute_z_3 01530 { 01531 typedef typename K::FT FT; 01532 typedef typename K::Point_3 Point_3; 01533 typedef typename K::Vector_3 Vector_3; 01534 01535 public: 01536 typedef FT result_type; 01537 01538 FT 01539 operator()(const Point_3& p) const 01540 { 01541 return p.rep().z(); 01542 } 01543 01544 FT 01545 operator()(const Vector_3& v) const 01546 { 01547 return v.rep().z(); 01548 } 01549 }; 01550 01551 template <typename K> 01552 class Compute_dx_2 : public Has_qrt 01553 { 01554 typedef typename K::RT RT; 01555 typedef typename K::Direction_2 Direction_2; 01556 01557 public: 01558 typedef RT result_type; 01559 01560 const result_type & 01561 operator()(const Direction_2& d) const 01562 { 01563 return d.rep().dx(); 01564 } 01565 }; 01566 01567 template <typename K> 01568 class Compute_dx_3 : public Has_qrt 01569 { 01570 typedef typename K::RT RT; 01571 typedef typename K::Direction_3 Direction_3; 01572 01573 public: 01574 typedef RT result_type; 01575 01576 const result_type & 01577 operator()(const Direction_3& d) const 01578 { 01579 return d.rep().dx(); 01580 } 01581 }; 01582 01583 template <typename K> 01584 class Compute_dy_2 : public Has_qrt 01585 { 01586 typedef typename K::RT RT; 01587 typedef typename K::Direction_2 Direction_2; 01588 01589 public: 01590 typedef RT result_type; 01591 01592 const result_type & 01593 operator()(const Direction_2& d) const 01594 { 01595 return d.rep().dy(); 01596 } 01597 }; 01598 01599 template <typename K> 01600 class Compute_dy_3 : public Has_qrt 01601 { 01602 typedef typename K::RT RT; 01603 typedef typename K::Direction_3 Direction_3; 01604 01605 public: 01606 typedef RT result_type; 01607 01608 const result_type & 01609 operator()(const Direction_3& d) const 01610 { 01611 return d.rep().dy(); 01612 } 01613 }; 01614 01615 template <typename K> 01616 class Compute_dz_3 : public Has_qrt 01617 { 01618 typedef typename K::RT RT; 01619 typedef typename K::Direction_3 Direction_3; 01620 01621 public: 01622 typedef RT result_type; 01623 01624 const result_type & 01625 operator()(const Direction_3& d) const 01626 { 01627 return d.rep().dz(); 01628 } 01629 }; 01630 01631 template <typename K> 01632 class Compute_hx_2 : public Has_qrt 01633 { 01634 typedef typename K::FT FT; 01635 typedef typename K::RT RT; 01636 typedef typename K::Point_2 Point_2; 01637 typedef typename K::Vector_2 Vector_2; 01638 01639 public: 01640 typedef RT result_type; 01641 01642 const result_type & 01643 operator()(const Point_2& p) const 01644 { 01645 return p.rep().hx(); 01646 } 01647 01648 const result_type & 01649 operator()(const Vector_2& v) const 01650 { 01651 return v.rep().hx(); 01652 } 01653 }; 01654 01655 template <typename K> 01656 class Compute_hx_3 : public Has_qrt 01657 { 01658 typedef typename K::FT FT; 01659 typedef typename K::RT RT; 01660 typedef typename K::Point_3 Point_3; 01661 typedef typename K::Vector_3 Vector_3; 01662 01663 public: 01664 typedef RT result_type; 01665 01666 const result_type & 01667 operator()(const Point_3& p) const 01668 { 01669 return p.rep().hx(); 01670 } 01671 01672 const result_type & 01673 operator()(const Vector_3& v) const 01674 { 01675 return v.rep().hx(); 01676 } 01677 }; 01678 01679 template <typename K> 01680 class Compute_hy_2 : public Has_qrt 01681 { 01682 typedef typename K::FT FT; 01683 typedef typename K::RT RT; 01684 typedef typename K::Point_2 Point_2; 01685 typedef typename K::Vector_2 Vector_2; 01686 01687 public: 01688 typedef RT result_type; 01689 01690 const result_type & 01691 operator()(const Point_2& p) const 01692 { 01693 return p.rep().hy(); 01694 } 01695 01696 const result_type & 01697 operator()(const Vector_2& v) const 01698 { 01699 return v.rep().hy(); 01700 } 01701 }; 01702 01703 template <typename K> 01704 class Compute_hy_3 : public Has_qrt 01705 { 01706 typedef typename K::FT FT; 01707 typedef typename K::RT RT; 01708 typedef typename K::Point_3 Point_3; 01709 typedef typename K::Vector_3 Vector_3; 01710 01711 public: 01712 typedef RT result_type; 01713 01714 const result_type & 01715 operator()(const Point_3& p) const 01716 { 01717 return p.rep().hy(); 01718 } 01719 01720 const result_type & 01721 operator()(const Vector_3& v) const 01722 { 01723 return v.rep().hy(); 01724 } 01725 }; 01726 01727 template <typename K> 01728 class Compute_hz_3 : public Has_qrt 01729 { 01730 typedef typename K::FT FT; 01731 typedef typename K::RT RT; 01732 typedef typename K::Point_3 Point_3; 01733 typedef typename K::Vector_3 Vector_3; 01734 01735 public: 01736 typedef RT result_type; 01737 01738 const result_type & 01739 operator()(const Point_3& p) const 01740 { 01741 return p.rep().hz(); 01742 } 01743 01744 const result_type & 01745 operator()(const Vector_3& v) const 01746 { 01747 return v.rep().hz(); 01748 } 01749 }; 01750 01751 template <typename K> 01752 class Compute_hw_2 : public Has_qrt 01753 { 01754 typedef typename K::FT FT; 01755 typedef typename K::RT RT; 01756 typedef typename K::Point_2 Point_2; 01757 typedef typename K::Vector_2 Vector_2; 01758 01759 public: 01760 typedef RT result_type; 01761 01762 const result_type & 01763 operator()(const Point_2& p) const 01764 { 01765 return p.rep().hw(); 01766 } 01767 01768 const result_type & 01769 operator()(const Vector_2& v) const 01770 { 01771 return v.rep().hw(); 01772 } 01773 }; 01774 01775 template <typename K> 01776 class Compute_hw_3 : public Has_qrt 01777 { 01778 typedef typename K::FT FT; 01779 typedef typename K::RT RT; 01780 typedef typename K::Point_3 Point_3; 01781 typedef typename K::Vector_3 Vector_3; 01782 01783 public: 01784 typedef RT result_type; 01785 01786 const result_type & 01787 operator()(const Point_3& p) const 01788 { 01789 return p.rep().hw(); 01790 } 01791 01792 const result_type & 01793 operator()(const Vector_3& v) const 01794 { 01795 return v.rep().hw(); 01796 } 01797 }; 01798 01799 template <typename K> 01800 class Construct_base_vector_3 01801 { 01802 typedef typename K::Vector_3 Vector_3; 01803 typedef typename K::Plane_3 Plane_3; 01804 typedef typename K::RT RT; 01805 typedef typename K::Construct_orthogonal_vector_3 01806 Construct_orthogonal_vector_3; 01807 Construct_orthogonal_vector_3 co; 01808 public: 01809 typedef Vector_3 result_type; 01810 01811 Construct_base_vector_3() {} 01812 Construct_base_vector_3(const Construct_orthogonal_vector_3& co_) 01813 : co(co_) 01814 {} 01815 01816 Vector_3 01817 operator()( const Plane_3& h, int index ) const 01818 { 01819 if (index == 1) { 01820 // point(): 01821 // a() != RT0 : Point_3( -d(), RT0, RT0, a() ); 01822 // b() != RT0 : Point_3( RT0, -d(), RT0, b() ); 01823 // : Point_3( RT0, RT0, -d(), c() ); 01824 // point1(): 01825 // a() != RT0 : Point_3( -b()-d(), a(), RT0, a() ); 01826 // b() != RT0 : Point_3( RT0, -c()-d(), b(), b() ); 01827 // : Point_3( c(), RT0, -a()-d(), c() ); 01828 01829 const RT RT0(0); 01830 if ( h.a() != RT0 ) 01831 { 01832 return Vector_3( -h.b(), h.a(), RT0, h.a() ); 01833 } 01834 if ( h.b() != RT0 ) 01835 { 01836 return Vector_3( RT0, -h.c(), h.b(), h.b() ); 01837 } 01838 CGAL_kernel_assertion ( h.c() != RT(0) ); 01839 return Vector_3( h.c(), RT0, -h.a(), h.c() ); 01840 } else { 01841 Vector_3 a = co(h); 01842 Vector_3 b = this->operator()(h, 1); 01843 return Vector_3(a.hy()*b.hz() - a.hz()*b.hy(), 01844 a.hz()*b.hx() - a.hx()*b.hz(), 01845 a.hx()*b.hy() - a.hy()*b.hx(), 01846 a.hw()*b.hw() ); 01847 } 01848 } 01849 }; 01850 01851 template <typename K> 01852 class Construct_bbox_2 01853 { 01854 typedef typename K::Point_2 Point_2; 01855 typedef typename K::Segment_2 Segment_2; 01856 typedef typename K::Iso_rectangle_2 Iso_rectangle_2; 01857 typedef typename K::Triangle_2 Triangle_2; 01858 typedef typename K::Circle_2 Circle_2; 01859 public: 01860 typedef Bbox_2 result_type; 01861 01862 Bbox_2 01863 operator()( const Point_2& p) const 01864 { 01865 Interval_nt<> ihx = CGAL_NTS to_interval(p.hx()); 01866 Interval_nt<> ihy = CGAL_NTS to_interval(p.hy()); 01867 Interval_nt<> ihw = CGAL_NTS to_interval(p.hw()); 01868 01869 Interval_nt<> ix = ihx/ihw; 01870 Interval_nt<> iy = ihy/ihw; 01871 01872 return Bbox_2(ix.inf(), iy.inf(), ix.sup(), iy.sup()); 01873 } 01874 01875 Bbox_2 01876 operator()( const Segment_2& s) const 01877 { return s.source().bbox() + s.target().bbox(); } 01878 01879 Bbox_2 01880 operator()( const Triangle_2& t) const 01881 { 01882 typename K::Construct_bbox_2 construct_bbox_2; 01883 return construct_bbox_2(t.vertex(0)) 01884 + construct_bbox_2(t.vertex(1)) 01885 + construct_bbox_2(t.vertex(2)); 01886 } 01887 01888 Bbox_2 01889 operator()( const Iso_rectangle_2& r) const 01890 { 01891 typename K::Construct_bbox_2 construct_bbox_2; 01892 return construct_bbox_2((r.min)()) + construct_bbox_2((r.max)()); 01893 } 01894 01895 Bbox_2 01896 operator()( const Circle_2& c) const 01897 { 01898 typename K::Construct_bbox_2 construct_bbox_2; 01899 Bbox_2 b = construct_bbox_2(c.center()); 01900 01901 Interval_nt<> x (b.xmin(), b.xmax()); 01902 Interval_nt<> y (b.ymin(), b.ymax()); 01903 01904 Interval_nt<> sqr = CGAL_NTS to_interval(c.squared_radius()); 01905 Interval_nt<> r = CGAL::sqrt(sqr); 01906 Interval_nt<> minx = x-r; 01907 Interval_nt<> maxx = x+r; 01908 Interval_nt<> miny = y-r; 01909 Interval_nt<> maxy = y+r; 01910 01911 return Bbox_2(minx.inf(), miny.inf(), maxx.sup(), maxy.sup()); } 01912 }; 01913 01914 01915 template <typename K> 01916 class Construct_bbox_3 01917 { 01918 typedef typename K::Point_3 Point_3; 01919 typedef typename K::Segment_3 Segment_3; 01920 typedef typename K::Triangle_3 Triangle_3; 01921 typedef typename K::Tetrahedron_3 Tetrahedron_3; 01922 typedef typename K::Iso_cuboid_3 Iso_cuboid_3; 01923 typedef typename K::Sphere_3 Sphere_3; 01924 public: 01925 typedef Bbox_3 result_type; 01926 01927 Bbox_3 01928 operator()(const Point_3& p) const 01929 { 01930 Interval_nt<> ihx = CGAL_NTS to_interval(p.hx()); 01931 Interval_nt<> ihy = CGAL_NTS to_interval(p.hy()); 01932 Interval_nt<> ihz = CGAL_NTS to_interval(p.hz()); 01933 Interval_nt<> ihw = CGAL_NTS to_interval(p.hw()); 01934 01935 Interval_nt<> ix = ihx/ihw; 01936 Interval_nt<> iy = ihy/ihw; 01937 Interval_nt<> iz = ihz/ihw; 01938 01939 return Bbox_3(ix.inf(), iy.inf(), iz.inf(), 01940 ix.sup(), iy.sup(), iz.sup()); 01941 } 01942 01943 Bbox_3 01944 operator()(const Segment_3& s) const 01945 { return s.source().bbox() + s.target().bbox(); } 01946 01947 Bbox_3 01948 operator()(const Triangle_3& t) const 01949 { 01950 typename K::Construct_bbox_3 construct_bbox; 01951 return construct_bbox(t.vertex(0)) 01952 + construct_bbox(t.vertex(1)) 01953 + construct_bbox(t.vertex(2)); 01954 } 01955 01956 Bbox_3 01957 operator()(const Iso_cuboid_3& r) const 01958 { 01959 typename K::Construct_bbox_3 construct_bbox; 01960 return construct_bbox((r.min)()) + construct_bbox((r.max)()); 01961 } 01962 01963 Bbox_3 01964 operator()(const Tetrahedron_3& t) const 01965 { 01966 typename K::Construct_bbox_3 construct_bbox_3; 01967 return construct_bbox_3(t.vertex(0)) + construct_bbox_3(t.vertex(1)) 01968 + construct_bbox_3(t.vertex(2)) + construct_bbox_3(t.vertex(3)); 01969 } 01970 01971 Bbox_3 01972 operator()(const Sphere_3& s) const 01973 { 01974 Bbox_3 b = s.center().bbox(); 01975 01976 Interval_nt<> x (b.xmin(), b.xmax()); 01977 Interval_nt<> y (b.ymin(), b.ymax()); 01978 Interval_nt<> z (b.zmin(), b.zmax()); 01979 01980 Interval_nt<> sqr = CGAL_NTS to_interval(s.squared_radius()); 01981 Interval_nt<> r = CGAL::sqrt(sqr); 01982 Interval_nt<> minx = x-r; 01983 Interval_nt<> maxx = x+r; 01984 Interval_nt<> miny = y-r; 01985 Interval_nt<> maxy = y+r; 01986 Interval_nt<> minz = z-r; 01987 Interval_nt<> maxz = z+r; 01988 01989 return Bbox_3(minx.inf(), miny.inf(), minz.inf(), 01990 maxx.sup(), maxy.sup(), maxz.sup()); 01991 } 01992 }; 01993 01994 01995 template <typename K> 01996 class Construct_bisector_2 01997 { 01998 typedef typename K::RT RT; 01999 typedef typename K::FT FT; 02000 typedef typename K::Point_2 Point_2; 02001 typedef typename K::Line_2 Line_2; 02002 public: 02003 typedef Line_2 result_type; 02004 02005 Line_2 02006 operator()(const Point_2& p, const Point_2& q) const 02007 { 02008 // Bisector equation is based on equation 02009 // ( X - p.x())^2 + (Y - p.y())^2 == ( X - q.x())^2 + (Y - q.y()) 02010 // and x() = hx()/hw() ... 02011 02012 const RT &phx = p.hx(); 02013 const RT &phy = p.hy(); 02014 const RT &phw = p.hw(); 02015 const RT &qhx = q.hx(); 02016 const RT &qhy = q.hy(); 02017 const RT &qhw = q.hw(); 02018 02019 RT a = RT(2) * ( phx*phw*qhw*qhw - qhx*qhw*phw*phw ); 02020 RT b = RT(2) * ( phy*phw*qhw*qhw - qhy*qhw*phw*phw ); 02021 RT c = qhx*qhx*phw*phw + qhy*qhy*phw*phw 02022 - phx*phx*qhw*qhw - phy*phy*qhw*qhw; 02023 02024 return Line_2( a, b, c ); 02025 } 02026 02027 Line_2 02028 operator()(const Line_2& p, const Line_2& q) const 02029 { 02030 RT a, b, c; 02031 bisector_of_linesC2(p.a(), p.b(), p.c(), 02032 q.a(), q.b(), q.c(), 02033 a, b, c); 02034 return Line_2(a, b, c); 02035 } 02036 }; 02037 02038 template <typename K> 02039 class Construct_bisector_3 02040 { 02041 typedef typename K::RT RT; 02042 typedef typename K::FT FT; 02043 typedef typename K::Point_3 Point_3; 02044 typedef typename K::Plane_3 Plane_3; 02045 public: 02046 typedef Plane_3 result_type; 02047 02048 Plane_3 02049 operator()(const Point_3& p, const Point_3& q) const 02050 { 02051 // Bisector equation is based on equation 02052 // ( X - p.x())^2 + (Y - p.y())^2 == ( X - q.x())^2 + (Y - q.y()) 02053 // and x() = hx()/hw() ... 02054 02055 const RT& phx = p.hx(); 02056 const RT& phy = p.hy(); 02057 const RT& phz = p.hz(); 02058 const RT& phw = p.hw(); 02059 const RT& qhx = q.hx(); 02060 const RT& qhy = q.hy(); 02061 const RT& qhz = q.hz(); 02062 const RT& qhw = q.hw(); 02063 02064 RT a = RT(2) * ( phx*phw*qhw*qhw - qhx*qhw*phw*phw ); 02065 RT b = RT(2) * ( phy*phw*qhw*qhw - qhy*qhw*phw*phw ); 02066 RT c = RT(2) * ( phz*phw*qhw*qhw - qhz*qhw*phw*phw ); 02067 RT d = qhx*qhx*phw*phw + qhy*qhy*phw*phw + qhz*qhz*phw*phw 02068 - phx*phx*qhw*qhw - phy*phy*qhw*qhw - phz*phz*qhw*qhw; 02069 02070 return Plane_3( a, b, c, d ); 02071 } 02072 02073 Plane_3 02074 operator()(const Plane_3& p, const Plane_3& q) const 02075 { 02076 RT a, b, c, d; 02077 bisector_of_planesC3(p.a(), p.b(), p.c(), p.d(), 02078 q.a(), q.b(), q.c(), q.d(), 02079 a, b, c, d); 02080 return Plane_3(a, b, c, d); 02081 } 02082 }; 02083 02084 02085 template <typename K> 02086 class Construct_centroid_2 02087 { 02088 typedef typename K::FT FT; 02089 typedef typename K::Point_2 Point_2; 02090 typedef typename K::Triangle_2 Triangle_2; 02091 public: 02092 typedef Point_2 result_type; 02093 02094 Point_2 02095 operator()(const Point_2& p, const Point_2& q, const Point_2& r) const 02096 { 02097 typedef typename K::RT RT; 02098 const RT phw(p.hw()); 02099 const RT qhw(q.hw()); 02100 const RT rhw(r.hw()); 02101 RT hx(p.hx()*qhw*rhw + q.hx()*phw*rhw + r.hx()*phw*qhw); 02102 RT hy(p.hy()*qhw*rhw + q.hy()*phw*rhw + r.hy()*phw*qhw); 02103 RT hw( phw*qhw*rhw * 3); 02104 return Point_2(hx, hy, hw); 02105 } 02106 02107 Point_2 02108 operator()(const Triangle_2& t) const 02109 { 02110 return this->operator()(t.vertex(0), t.vertex(1), t.vertex(2)); 02111 } 02112 02113 Point_2 02114 operator()(const Point_2& p, const Point_2& q, 02115 const Point_2& r, const Point_2& s) const 02116 { 02117 typedef typename K::RT RT; 02118 const RT phw(p.hw()); 02119 const RT qhw(q.hw()); 02120 const RT rhw(r.hw()); 02121 const RT shw(s.hw()); 02122 RT hx(p.hx()*qhw*rhw*shw + q.hx()*phw*rhw*shw + r.hx()*phw*qhw*shw 02123 + s.hx()*phw*qhw*rhw); 02124 RT hy(p.hy()*qhw*rhw*shw + q.hy()*phw*rhw*shw + r.hy()*phw*qhw*shw 02125 + s.hy()*phw*qhw*rhw); 02126 RT hw( phw*qhw*rhw*shw * 4); 02127 return Point_2(hx, hy, hw); 02128 } 02129 }; 02130 02131 template <typename K> 02132 class Construct_centroid_3 02133 { 02134 typedef typename K::RT RT; 02135 typedef typename K::Point_3 Point_3; 02136 typedef typename K::Triangle_3 Triangle_3; 02137 typedef typename K::Tetrahedron_3 Tetrahedron_3; 02138 public: 02139 typedef Point_3 result_type; 02140 02141 Point_3 02142 operator()(const Point_3& p, const Point_3& q, const Point_3& r) const 02143 { 02144 const RT& phw = p.hw(); 02145 const RT& qhw = q.hw(); 02146 const RT& rhw = r.hw(); 02147 RT hx(p.hx()*qhw*rhw + q.hx()*phw*rhw + r.hx()*phw*qhw); 02148 RT hy(p.hy()*qhw*rhw + q.hy()*phw*rhw + r.hy()*phw*qhw); 02149 RT hz(p.hz()*qhw*rhw + q.hz()*phw*rhw + r.hz()*phw*qhw); 02150 RT hw( phw*qhw*rhw * RT(3)); 02151 return Point_3(hx, hy, hz, hw); 02152 } 02153 02154 Point_3 02155 operator()(const Point_3& p, const Point_3& q, 02156 const Point_3& r, const Point_3& s) const 02157 { 02158 const RT& phw = p.hw(); 02159 const RT& qhw = q.hw(); 02160 const RT& rhw = r.hw(); 02161 const RT& shw = s.hw(); 02162 RT hx(p.hx()*qhw*rhw*shw + q.hx()*phw*rhw*shw + r.hx()*phw*qhw*shw 02163 + s.hx()*phw*qhw*rhw); 02164 RT hy(p.hy()*qhw*rhw*shw + q.hy()*phw*rhw*shw + r.hy()*phw*qhw*shw 02165 + s.hy()*phw*qhw*rhw); 02166 RT hz(p.hz()*qhw*rhw*shw + q.hz()*phw*rhw*shw + r.hz()*phw*qhw*shw 02167 + s.hz()*phw*qhw*rhw); 02168 RT hw( phw*qhw*rhw*shw * RT(4)); 02169 return Point_3(hx, hy, hz, hw); 02170 } 02171 02172 Point_3 02173 operator()(const Triangle_3& t) const 02174 { 02175 return this->operator()(t.vertex(0), t.vertex(1), t.vertex(2)); 02176 } 02177 02178 Point_3 02179 operator()(const Tetrahedron_3& t) const 02180 { 02181 return this->operator()(t.vertex(0), t.vertex(1), 02182 t.vertex(2), t.vertex(3)); 02183 } 02184 }; 02185 02186 template <typename K> 02187 class Construct_circumcenter_2 02188 { 02189 typedef typename K::FT FT; 02190 typedef typename K::Point_2 Point_2; 02191 typedef typename K::Triangle_2 Triangle_2; 02192 public: 02193 typedef Point_2 result_type; 02194 02195 Point_2 02196 operator()(const Point_2& p, const Point_2& q) const 02197 { 02198 typename K::Construct_midpoint_2 construct_midpoint_2; 02199 return construct_midpoint_2(p, q); 02200 } 02201 02202 Point_2 02203 operator()(const Point_2& p, const Point_2& q, const Point_2& r) const 02204 { 02205 typedef typename K::RT RT; 02206 const RT & phx = p.hx(); 02207 const RT & phy = p.hy(); 02208 const RT & phw = p.hw(); 02209 const RT & qhx = q.hx(); 02210 const RT & qhy = q.hy(); 02211 const RT & qhw = q.hw(); 02212 const RT & rhx = r.hx(); 02213 const RT & rhy = r.hy(); 02214 const RT & rhw = r.hw(); 02215 02216 #ifdef CGAL_EXPANDED_CIRCUMCENTER_COMPUTATION 02217 RT vvx = 02218 ( qhy*qhw*phw*phw - phy*phw*qhw*qhw ) 02219 *( phx*phx*rhw*rhw + phy*phy*rhw*rhw - 02220 rhx*rhx*phw*phw - rhy*rhy*phw*phw ) 02221 - ( rhy*rhw*phw*phw - phy*phw*rhw*rhw ) 02222 *( phx*phx*qhw*qhw + phy*phy*qhw*qhw - 02223 qhx*qhx*phw*phw - qhy*qhy*phw*phw ); 02224 02225 RT vvy = 02226 - ( qhx*qhw*phw*phw - phx*phw*qhw*qhw ) 02227 *( phx*phx*rhw*rhw + phy*phy*rhw*rhw - 02228 rhx*rhx*phw*phw - rhy*rhy*phw*phw ) 02229 + ( rhx*rhw*phw*phw - phx*phw*rhw*rhw ) 02230 *( phx*phx*qhw*qhw + phy*phy*qhw*qhw - 02231 qhx*qhx*phw*phw - qhy*qhy*phw*phw ); 02232 02233 RT vvw = RT(2) * 02234 ( ( qhx*qhw*phw*phw - phx*phw*qhw*qhw ) 02235 *( rhy*rhw*phw*phw - phy*phw*rhw*rhw ) 02236 - ( rhx*rhw*phw*phw - phx*phw*rhw*rhw ) 02237 *( qhy*qhw*phw*phw - phy*phw*qhw*qhw ) ); 02238 #endif // CGAL_EXPANDED_CIRCUMCENTER_COMPUTATION 02239 02240 RT qy_py = ( qhy*qhw*phw*phw - phy*phw*qhw*qhw ); 02241 RT qx_px = ( qhx*qhw*phw*phw - phx*phw*qhw*qhw ); 02242 RT rx_px = ( rhx*rhw*phw*phw - phx*phw*rhw*rhw ); 02243 RT ry_py = ( rhy*rhw*phw*phw - phy*phw*rhw*rhw ); 02244 02245 RT px2_py2_rx2_ry_2 = 02246 phx*phx*rhw*rhw + phy*phy*rhw*rhw - 02247 rhx*rhx*phw*phw - rhy*rhy*phw*phw ; 02248 RT px2_py2_qx2_qy_2 = 02249 phx*phx*qhw*qhw + phy*phy*qhw*qhw - 02250 qhx*qhx*phw*phw - qhy*qhy*phw*phw ; 02251 02252 RT vvx = qy_py * px2_py2_rx2_ry_2 - ry_py * px2_py2_qx2_qy_2; 02253 RT vvy = rx_px * px2_py2_qx2_qy_2 - qx_px * px2_py2_rx2_ry_2; 02254 RT vvw = RT(2) * ( qx_px * ry_py - rx_px * qy_py ); 02255 02256 return Point_2( vvx, vvy, vvw ); 02257 } 02258 02259 Point_2 02260 operator()(const Triangle_2& t) const 02261 { 02262 return this->operator()(t.vertex(0), t.vertex(1), t.vertex(2)); 02263 } 02264 }; 02265 02266 template <typename K> 02267 class Construct_circumcenter_3 02268 { 02269 typedef typename K::FT FT; 02270 typedef typename K::Point_3 Point_3; 02271 typedef typename K::Triangle_3 Triangle_3; 02272 typedef typename K::Tetrahedron_3 Tetrahedron_3; 02273 typedef typename K::Plane_3 Plane_3; 02274 public: 02275 typedef Point_3 result_type; 02276 02277 Point_3 02278 operator()(const Point_3& p, const Point_3& q) const 02279 { 02280 typename K::Construct_midpoint_3 construct_midpoint_3; 02281 return construct_midpoint_3(p, q); 02282 } 02283 02284 Point_3 02285 operator()(const Point_3& p, const Point_3& q, const Point_3& r) const 02286 { 02287 return gp_linear_intersection( Plane_3(p,q,r), 02288 bisector(p,q), 02289 bisector(p,r)); 02290 } // FIXME 02291 02292 Point_3 02293 operator()(const Triangle_3& t) const 02294 { 02295 return this->operator()(t.vertex(0), t.vertex(1), t.vertex(2)); 02296 } 02297 02298 Point_3 02299 operator()(const Point_3& p, const Point_3& q, 02300 const Point_3& r, const Point_3& s) const 02301 { 02302 typedef typename K::RT RT; 02303 02304 RT phw( p.hw() ); 02305 RT qhw( q.hw() ); 02306 RT rhw( r.hw() ); 02307 RT shw( s.hw() ); 02308 02309 RT phx( p.hx() ); 02310 RT phy( p.hy() ); 02311 RT phz( p.hz() ); 02312 RT qhx( q.hx() ); 02313 RT qhy( q.hy() ); 02314 RT qhz( q.hz() ); 02315 RT rhx( r.hx() ); 02316 RT rhy( r.hy() ); 02317 RT rhz( r.hz() ); 02318 RT shx( s.hx() ); 02319 RT shy( s.hy() ); 02320 RT shz( s.hz() ); 02321 02322 RT pssq( phx*phx + phy*phy + phz*phz ); 02323 RT qssq( qhx*qhx + qhy*qhy + qhz*qhz ); 02324 RT rssq( rhx*rhx + rhy*rhy + rhz*rhz ); 02325 RT sssq( shx*shx + shy*shy + shz*shz ); 02326 02327 phx *= phw; 02328 phy *= phw; 02329 phz *= phw; 02330 phw *= phw; 02331 qhx *= qhw; 02332 qhy *= qhw; 02333 qhz *= qhw; 02334 qhw *= qhw; 02335 rhx *= rhw; 02336 rhy *= rhw; 02337 rhz *= rhw; 02338 rhw *= rhw; 02339 shx *= shw; 02340 shy *= shw; 02341 shz *= shw; 02342 shw *= shw; 02343 02344 RT chx = determinant(phy, phz, pssq, phw, 02345 qhy, qhz, qssq, qhw, 02346 rhy, rhz, rssq, rhw, 02347 shy, shz, sssq, shw ); 02348 RT chy = determinant(phx, phz, pssq, phw, 02349 qhx, qhz, qssq, qhw, 02350 rhx, rhz, rssq, rhw, 02351 shx, shz, sssq, shw ); 02352 RT chz = determinant(phx, phy, pssq, phw, 02353 qhx, qhy, qssq, qhw, 02354 rhx, rhy, rssq, rhw, 02355 shx, shy, sssq, shw ); 02356 RT chw = determinant(phx, phy, phz, phw, 02357 qhx, qhy, qhz, qhw, 02358 rhx, rhy, rhz, rhw, 02359 shx, shy, shz, shw ); 02360 02361 return Point_3( chx, -chy, chz, RT(2)*chw); 02362 } 02363 02364 Point_3 02365 operator()(const Tetrahedron_3& t) const 02366 { 02367 return this->operator()(t.vertex(0), t.vertex(1), 02368 t.vertex(2), t.vertex(3)); 02369 } 02370 }; 02371 02372 template <typename K> 02373 class Construct_cross_product_vector_3 02374 { 02375 typedef typename K::Vector_3 Vector_3; 02376 public: 02377 typedef Vector_3 result_type; 02378 02379 Vector_3 02380 operator()(const Vector_3& a, const Vector_3& b) const 02381 { 02382 return Vector_3(a.hy()*b.hz() - a.hz()*b.hy(), 02383 a.hz()*b.hx() - a.hx()*b.hz(), 02384 a.hx()*b.hy() - a.hy()*b.hx(), 02385 a.hw()*b.hw() ); 02386 } 02387 }; 02388 02389 template <typename K> 02390 class Construct_difference_of_vectors_2 02391 { 02392 typedef typename K::Vector_2 Vector_2; 02393 public: 02394 typedef Vector_2 result_type; 02395 02396 Vector_2 02397 operator()(const Vector_2& v, const Vector_2& w) const 02398 { 02399 return Vector_2( v.hx()*w.hw() - w.hx()*v.hw(), 02400 v.hy()*w.hw() - w.hy()*v.hw(), 02401 v.hw()*w.hw() ); 02402 } 02403 }; 02404 02405 template <typename K> 02406 class Construct_difference_of_vectors_3 02407 { 02408 typedef typename K::Vector_3 Vector_3; 02409 public: 02410 typedef Vector_3 result_type; 02411 02412 Vector_3 02413 operator()(const Vector_3& v, const Vector_3& w) const 02414 { 02415 return Vector_3( v.hx()*w.hw() - w.hx()*v.hw(), 02416 v.hy()*w.hw() - w.hy()*v.hw(), 02417 v.hz()*w.hw() - w.hz()*v.hw(), 02418 v.hw()*w.hw() ); 02419 } 02420 }; 02421 02422 02423 template <typename K> 02424 class Construct_direction_2 02425 { 02426 typedef typename K::Direction_2 Direction_2; 02427 typedef typename Direction_2::Rep Rep; 02428 typedef typename K::Point_2 Point_2; 02429 typedef typename K::Vector_2 Vector_2; 02430 typedef typename K::Line_2 Line_2; 02431 typedef typename K::Ray_2 Ray_2; 02432 typedef typename K::Segment_2 Segment_2; 02433 typedef typename K::RT RT; 02434 02435 public: 02436 typedef Direction_2 result_type; 02437 02438 Rep // Direction_2 02439 operator()(Return_base_tag, const RT& x, const RT& y) const 02440 { return Rep(x, y); } 02441 02442 Rep // Direction_2 02443 operator()(Return_base_tag, const Vector_2& v) const 02444 { return Rep(v.hx(),v.hy()); } 02445 02446 Rep // Direction_2 02447 operator()(Return_base_tag, const Line_2& l) const 02448 { return Rep(l.b(), -l.a()); } 02449 02450 Rep // Direction_2 02451 operator()(Return_base_tag, const Ray_2& r) const 02452 { return this->operator()(Return_base_tag(), r.source(), r.second_point()); } 02453 02454 Rep // Direction_2 02455 operator()(Return_base_tag, const Segment_2& s) const 02456 { return this->operator()(Return_base_tag(), s.source(), s.target()); } 02457 02458 Rep // Direction_2 02459 operator()(Return_base_tag, const Point_2& q, const Point_2& p) const 02460 { 02461 return Rep( p.hx()*q.hw() - q.hx()*p.hw(), 02462 p.hy()*q.hw() - q.hy()*p.hw() ); 02463 } 02464 02465 02466 Direction_2 02467 operator()(const RT& x, const RT& y) const 02468 { return this->operator()(Return_base_tag(), x, y); } 02469 02470 Direction_2 02471 operator()(const Vector_2& v) const 02472 { return this->operator()(Return_base_tag(), v); } 02473 02474 Direction_2 02475 operator()(const Line_2& l) const 02476 { return this->operator()(Return_base_tag(), l); } 02477 02478 Direction_2 02479 operator()(const Ray_2& r) const 02480 { return this->operator()(Return_base_tag(), r); } 02481 02482 Direction_2 02483 operator()(const Segment_2& s) const 02484 { return this->operator()(Return_base_tag(), s); } 02485 02486 Direction_2 02487 operator()(const Point_2& q, const Point_2& p) const 02488 { 02489 return this->operator()(Return_base_tag(), p, q); 02490 } 02491 }; 02492 02493 template <typename K> 02494 class Construct_direction_3 02495 { 02496 typedef typename K::Direction_3 Direction_3; 02497 typedef typename K::Vector_3 Vector_3; 02498 typedef typename K::Line_3 Line_3; 02499 typedef typename K::Ray_3 Ray_3; 02500 typedef typename K::Segment_3 Segment_3; 02501 typedef typename K::RT RT; 02502 typedef typename Direction_3::Rep Rep; 02503 public: 02504 typedef Direction_3 result_type; 02505 02506 Rep // Direction_3 02507 operator()(Return_base_tag, const RT& x, const RT& y, const RT& z) const 02508 { return Rep(x, y, z); } 02509 02510 Rep // Direction_3 02511 operator()(Return_base_tag, const Vector_3& v) const 02512 { return Rep(v.hx(), v.hy(), v.hz()); } 02513 02514 Rep // Direction_3 02515 operator()(Return_base_tag, const Line_3& l) const 02516 { return Rep(l); } 02517 02518 Rep // Direction_3 02519 operator()(Return_base_tag, const Ray_3& r) const 02520 { return Rep(r); } 02521 02522 Rep // Direction_3 02523 operator()(Return_base_tag, const Segment_3& s) const 02524 { return Rep(s); } 02525 02526 02527 Direction_3 02528 operator()(const RT& x, const RT& y, const RT& z) const 02529 { return this->operator()(Return_base_tag(), x, y, z); } 02530 02531 Direction_3 02532 operator()(const Vector_3& v) const 02533 { return this->operator()(Return_base_tag(), v); } 02534 02535 Direction_3 02536 operator()(const Line_3& l) const 02537 { return this->operator()(Return_base_tag(), l); } 02538 02539 Direction_3 02540 operator()(const Ray_3& r) const 02541 { return this->operator()(Return_base_tag(), r); } 02542 02543 Direction_3 02544 operator()(const Segment_3& s) const 02545 { return this->operator()(Return_base_tag(), s); } 02546 }; 02547 02548 02549 template <typename K> 02550 class Construct_sum_of_vectors_2 02551 { 02552 typedef typename K::Vector_2 Vector_2; 02553 public: 02554 typedef Vector_2 result_type; 02555 02556 Vector_2 02557 operator()(const Vector_2& v, const Vector_2& w) const 02558 { 02559 return Vector_2(v.hx()*w.hw() + w.hx()*v.hw(), 02560 v.hy()*w.hw() + w.hy()*v.hw(), 02561 v.hw()*w.hw()); 02562 } 02563 }; 02564 02565 template <typename K> 02566 class Construct_sum_of_vectors_3 02567 { 02568 typedef typename K::Vector_3 Vector_3; 02569 public: 02570 typedef Vector_3 result_type; 02571 02572 Vector_3 02573 operator()(const Vector_3& v, const Vector_3& w) const 02574 { 02575 return Vector_3(v.hx()*w.hw() + w.hx()*v.hw(), 02576 v.hy()*w.hw() + w.hy()*v.hw(), 02577 v.hz()*w.hw() + w.hz()*v.hw(), 02578 v.hw()*w.hw()); 02579 } 02580 }; 02581 02582 template <typename K> 02583 class Construct_divided_vector_2 02584 { 02585 typedef typename K::FT FT; 02586 typedef typename K::RT RT; 02587 typedef typename K::Vector_2 Vector_2; 02588 public: 02589 typedef Vector_2 result_type; 02590 02591 Vector_2 02592 operator()(const Vector_2& v, const FT& f ) const 02593 { 02594 return Vector_2( v.hx()*f.denominator(), v.hy()*f.denominator(), 02595 v.hw()*f.numerator() ); 02596 } 02597 02598 Vector_2 02599 operator()(const Vector_2& v, const RT& f ) const 02600 { 02601 return Vector_2( v.hx(), v.hy(), v.hw()*f ); 02602 } 02603 }; 02604 02605 template <typename K> 02606 class Construct_divided_vector_3 02607 { 02608 typedef typename K::FT FT; 02609 typedef typename K::RT RT; 02610 typedef typename K::Vector_3 Vector_3; 02611 public: 02612 typedef Vector_3 result_type; 02613 02614 Vector_3 02615 operator()(const Vector_3& v, const FT& f ) const 02616 { 02617 return Vector_3( v.hx()*f.denominator(), v.hy()*f.denominator(), 02618 v.hz()*f.denominator(), v.hw()*f.numerator() ); 02619 } 02620 02621 Vector_3 02622 operator()(const Vector_3& v, const RT& f ) const 02623 { 02624 return Vector_3( v.hx(), v.hy(), v.hz(), v.hw()*f ); 02625 } 02626 }; 02627 02628 02629 template <typename K> 02630 class Construct_iso_rectangle_2 02631 { 02632 typedef typename K::RT RT; 02633 typedef typename K::FT FT; 02634 typedef typename K::Point_2 Point_2; 02635 typedef typename K::Iso_rectangle_2 Iso_rectangle_2; 02636 typedef typename Iso_rectangle_2::Rep Rep; 02637 02638 public: 02639 typedef Iso_rectangle_2 result_type; 02640 02641 Rep // Iso_rectangle_2 02642 operator()(Return_base_tag, const Point_2& p, const Point_2& q, int) const 02643 { 02644 // I have to remove the assertions, because of Cartesian_converter. 02645 // CGAL_kernel_assertion(p.x()<=q.x()); 02646 // CGAL_kernel_assertion(p.y()<=q.y()); 02647 return Rep(p, q, 0); 02648 } 02649 02650 Rep // Iso_rectangle_2 02651 operator()(Return_base_tag, const Point_2& p, const Point_2& q) const 02652 { 02653 bool px_g_qx = ( p.hx()*q.hw() > q.hx()*p.hw() ); 02654 bool py_g_qy = ( p.hy()*q.hw() > q.hy()*p.hw() ); 02655 02656 if ( px_g_qx || py_g_qy) 02657 { 02658 if ( px_g_qx && py_g_qy ) 02659 { 02660 return Rep(q, p, 0); 02661 } 02662 else 02663 { 02664 if ( px_g_qx ) 02665 { 02666 return Rep( 02667 Point_2(q.hx()*p.hw(), p.hy()*q.hw(), q.hw()*p.hw() ), 02668 Point_2(p.hx()*q.hw(), q.hy()*p.hw(), q.hw()*p.hw() ), 0); 02669 } 02670 if ( py_g_qy ) 02671 { 02672 return Rep( 02673 Point_2(p.hx()*q.hw(), q.hy()*p.hw(), q.hw()*p.hw() ), 02674 Point_2(q.hx()*p.hw(), p.hy()*q.hw(), q.hw()*p.hw() ), 0); 02675 } 02676 } 02677 } 02678 return Rep(p, q, 0); 02679 } 02680 02681 Rep // Iso_rectangle_2 02682 operator()(Return_base_tag, const Point_2 &left, const Point_2 &right, 02683 const Point_2 &bottom, const Point_2 &top) const 02684 { 02685 CGAL_kernel_assertion_code(typename K::Less_x_2 less_x;) 02686 CGAL_kernel_assertion_code(typename K::Less_y_2 less_y;) 02687 CGAL_kernel_assertion(!less_x(right, left)); 02688 CGAL_kernel_assertion(!less_y(top, bottom)); 02689 return Rep(Point_2(left.hx() * bottom.hw(), 02690 bottom.hy() * left.hw(), 02691 left.hw() * bottom.hw()), 02692 Point_2(right.hx() * top.hw(), 02693 top.hy() * right.hw(), 02694 right.hw() * top.hw()), 0); 02695 } 02696 02697 Rep // Iso_rectangle_2 02698 operator()(Return_base_tag, const RT& min_hx, const RT& min_hy, 02699 const RT& max_hx, const RT& max_hy) const 02700 { 02701 CGAL_kernel_precondition(min_hx <= max_hx); 02702 CGAL_kernel_precondition(min_hy <= max_hy); 02703 return Rep(Point_2(min_hx, min_hy), 02704 Point_2(max_hx, max_hy), 0); 02705 } 02706 02707 Rep // Iso_rectangle_2 02708 operator()(Return_base_tag, const RT& min_hx, const RT& min_hy, 02709 const RT& max_hx, const RT& max_hy, const RT& hw) const 02710 { 02711 return Rep(Point_2(min_hx, min_hy, hw), 02712 Point_2(max_hx, max_hy, hw), 0); 02713 } 02714 02715 02716 Iso_rectangle_2 02717 operator()(const Point_2& p, const Point_2& q, int i) const 02718 { 02719 return this->operator()(Return_base_tag(), p, q, i); 02720 } 02721 02722 Iso_rectangle_2 02723 operator()(const Point_2& p, const Point_2& q) const 02724 { 02725 return this->operator()(Return_base_tag(), p, q); 02726 } 02727 02728 Iso_rectangle_2 02729 operator()(const Point_2 &left, const Point_2 &right, 02730 const Point_2 &bottom, const Point_2 &top) const 02731 { 02732 return this->operator()(Return_base_tag(), left, right, bottom, top); 02733 } 02734 02735 Iso_rectangle_2 02736 operator()(const RT& min_hx, const RT& min_hy, 02737 const RT& max_hx, const RT& max_hy) const 02738 { 02739 return this->operator()(Return_base_tag(), min_hx, min_hy, max_hx, max_hy); 02740 } 02741 02742 Iso_rectangle_2 02743 operator()(const RT& min_hx, const RT& min_hy, 02744 const RT& max_hx, const RT& max_hy, const RT& hw) const 02745 { 02746 return this->operator()(Return_base_tag(), min_hx, min_hy, max_hx, max_hy, hw); 02747 } 02748 }; 02749 02750 02751 template <typename K> 02752 class Construct_lifted_point_3 02753 { 02754 typedef typename K::RT RT; 02755 typedef typename K::Point_2 Point_2; 02756 typedef typename K::Point_3 Point_3; 02757 typedef typename K::Plane_3 Plane_3; 02758 public: 02759 typedef Point_3 result_type; 02760 02761 Point_3 02762 operator()(const Plane_3& h, const Point_2& p) const 02763 { 02764 Point_3 hp( p.hx(), p.hy(), RT(0.0), p.hw()); 02765 return hp.transform( h.transform_to_2d().inverse() ); 02766 } 02767 }; 02768 02769 template <typename K> 02770 class Construct_line_2 02771 { 02772 typedef typename K::RT RT; 02773 typedef typename K::FT FT; 02774 typedef typename K::Point_2 Point_2; 02775 typedef typename K::Vector_2 Vector_2; 02776 typedef typename K::Direction_2 Direction_2; 02777 typedef typename K::Segment_2 Segment_2; 02778 typedef typename K::Ray_2 Ray_2; 02779 typedef typename K::Line_2 Line_2; 02780 typedef typename Line_2::Rep Rep; 02781 typedef typename K::Construct_point_on_2 Construct_point_on_2; 02782 Construct_point_on_2 cp; 02783 public: 02784 typedef Line_2 result_type; 02785 02786 Construct_line_2() {} 02787 Construct_line_2(const Construct_point_on_2& cp_) : cp(cp_) {} 02788 02789 Rep // Line_2 02790 operator()(Return_base_tag, const RT& a, const RT& b, const RT& c) const 02791 { return Rep(a, b, c); } 02792 02793 Rep // Line_2 02794 operator()(Return_base_tag, const Point_2& p, const Point_2& q) const 02795 { 02796 return Rep( 02797 // a() * X + b() * Y + c() * W() == 0 02798 // | X Y W | 02799 // | p.hx() p.hy() p.hw() | 02800 // | q.hx() q.hy() q.hw() | 02801 02802 p.hy()*q.hw() - p.hw()*q.hy(), 02803 p.hw()*q.hx() - p.hx()*q.hw(), 02804 p.hx()*q.hy() - p.hy()*q.hx() ); 02805 } 02806 02807 Rep // Line_2 02808 operator()(Return_base_tag, const Point_2& p, const Vector_2& v) const 02809 { 02810 Point_2 q = p + v; 02811 return Rep( p.hy()*q.hw() - p.hw()*q.hy(), 02812 p.hw()*q.hx() - p.hx()*q.hw(), 02813 p.hx()*q.hy() - p.hy()*q.hx() ); 02814 } 02815 02816 Rep // Line_2 02817 operator()(Return_base_tag, const Point_2& p, const Direction_2& d) const 02818 { 02819 Point_2 q = p + d.to_vector(); 02820 return Rep( p.hy()*q.hw() - p.hw()*q.hy(), 02821 p.hw()*q.hx() - p.hx()*q.hw(), 02822 p.hx()*q.hy() - p.hy()*q.hx() ); 02823 } 02824 02825 Rep // Line_2 02826 operator()(Return_base_tag, const Segment_2& s) const 02827 { return this->operator()(Return_base_tag(), cp(s, 0), cp(s, 1)); } 02828 02829 Rep // Line_2 02830 operator()(Return_base_tag, const Ray_2& r) const 02831 { return this->operator()(Return_base_tag(), cp(r, 0), cp(r, 1)); } 02832 02833 02834 Line_2 02835 operator()(const RT& a, const RT& b, const RT& c) const 02836 { return this->operator()(Return_base_tag(), a, b, c); } 02837 02838 Line_2 02839 operator()(const Point_2& p, const Point_2& q) const 02840 { return this->operator()(Return_base_tag(), p, q); } 02841 02842 Line_2 02843 operator()(const Point_2& p, const Vector_2& v) const 02844 { return this->operator()(Return_base_tag(), p, v); } 02845 02846 Line_2 02847 operator()(const Point_2& p, const Direction_2& d) const 02848 { return this->operator()(Return_base_tag(), p, d); } 02849 02850 Line_2 02851 operator()(const Segment_2& s) const 02852 { return this->operator()(Return_base_tag(), s); } 02853 02854 Line_2 02855 operator()(const Ray_2& r) const 02856 { return this->operator()(Return_base_tag(), r); } 02857 }; 02858 02859 template <typename K> 02860 class Construct_midpoint_2 02861 { 02862 typedef typename K::FT FT; 02863 typedef typename K::Point_2 Point_2; 02864 public: 02865 typedef Point_2 result_type; 02866 02867 Point_2 02868 operator()(const Point_2& p, const Point_2& q) const 02869 { 02870 typedef typename K::RT RT; 02871 const RT& phw = p.hw(); 02872 const RT& qhw = q.hw(); 02873 return Point_2( p.hx()*qhw + q.hx()*phw, 02874 p.hy()*qhw + q.hy()*phw, 02875 phw * qhw * RT( 2)); 02876 } 02877 }; 02878 02879 template <typename K> 02880 class Construct_midpoint_3 02881 { 02882 typedef typename K::FT FT; 02883 typedef typename K::Point_3 Point_3; 02884 public: 02885 typedef Point_3 result_type; 02886 02887 Point_3 02888 operator()(const Point_3& p, const Point_3& q) const 02889 { 02890 typedef typename K::RT RT; 02891 RT phw = p.hw(); 02892 RT qhw = q.hw(); 02893 return Point_3( p.hx()*qhw + q.hx()*phw, 02894 p.hy()*qhw + q.hy()*phw, 02895 p.hz()*qhw + q.hz()*phw, 02896 RT(2) * phw * qhw ); 02897 } 02898 }; 02899 02900 // TODO ... 02901 template <typename K> 02902 class Construct_opposite_vector_2 02903 { 02904 typedef typename K::Vector_2 Vector_2; 02905 public: 02906 typedef Vector_2 result_type; 02907 02908 Vector_2 02909 operator()( const Vector_2& v) const 02910 { return Vector_2(-v.hx(), -v.hy(), v.hw()); } 02911 }; 02912 02913 template <typename K> 02914 class Construct_opposite_vector_3 02915 { 02916 typedef typename K::Vector_3 Vector_3; 02917 public: 02918 typedef Vector_3 result_type; 02919 02920 Vector_3 02921 operator()( const Vector_3& v) const 02922 { return Vector_3(-v.hx(), -v.hy(), -v.hz(), v.hw()); } 02923 }; 02924 02925 template <typename K> 02926 class Construct_orthogonal_vector_3 02927 { 02928 typedef typename K::Point_3 Point_3; 02929 typedef typename K::Vector_3 Vector_3; 02930 typedef typename K::Plane_3 Plane_3; 02931 public: 02932 typedef Vector_3 result_type; 02933 02934 Vector_3 02935 operator()( const Plane_3& p ) const 02936 { return p.rep().orthogonal_vector(); } 02937 02938 Vector_3 02939 operator()( const Point_3& p, const Point_3& q, const Point_3& r ) const 02940 { 02941 return operator()(Plane_3(p, q, r)); 02942 } 02943 }; 02944 02945 template <typename K> 02946 class Construct_perpendicular_vector_2 02947 { 02948 typedef typename K::Vector_2 Vector_2; 02949 public: 02950 typedef Vector_2 result_type; 02951 02952 Vector_2 02953 operator()( const Vector_2& v, Orientation o) const 02954 { 02955 CGAL_kernel_precondition( o != COLLINEAR ); 02956 if (o == COUNTERCLOCKWISE) 02957 return K().construct_vector_2_object()(-v.hy(), v.hx(), v.hw()); 02958 else 02959 return K().construct_vector_2_object()(v.hy(), -v.hx(), v.hw()); 02960 } 02961 }; 02962 02963 template <typename K> 02964 class Construct_perpendicular_direction_2 02965 { 02966 typedef typename K::Direction_2 Direction_2; 02967 public: 02968 typedef Direction_2 result_type; 02969 02970 Direction_2 02971 operator()( const Direction_2& d, Orientation o) const 02972 { 02973 CGAL_kernel_precondition(o != COLLINEAR); 02974 if (o == COUNTERCLOCKWISE) { 02975 return Direction_2(-d.dy(), d.dx()); 02976 } else { 02977 return Direction_2(d.dy(), -d.dx()); 02978 } 02979 } 02980 }; 02981 02982 02983 template <typename K> 02984 class Construct_perpendicular_line_2 02985 { 02986 typedef typename K::Line_2 Line_2; 02987 typedef typename K::Point_2 Point_2; 02988 public: 02989 typedef Line_2 result_type; 02990 02991 Line_2 02992 operator()( const Line_2& l, const Point_2& p) const 02993 { return typename K::Line_2( -l.b()*p.hw(), l.a()*p.hw(), l.b()*p.hx() - l.a()*p.hy()); } 02994 }; 02995 02996 02997 template <typename K> 02998 class Construct_point_2 02999 { 03000 typedef typename K::RT RT; 03001 typedef typename K::FT FT; 03002 typedef typename K::Point_2 Point_2; 03003 typedef typename K::Vector_2 Vector_2; 03004 typedef typename K::Line_2 Line_2; 03005 typedef typename Point_2::Rep Rep; 03006 public: 03007 typedef Point_2 result_type; 03008 03009 Rep // Point_2 03010 operator()(Return_base_tag, Origin o) const 03011 { return Rep(o); } 03012 03013 template < typename Tx, typename Ty > 03014 Rep // Point_2 03015 operator()(Return_base_tag, const Tx & x, const Ty & y) const 03016 { return Rep(x, y); } 03017 03018 Rep // Point_2 03019 operator()(Return_base_tag, const RT& x, const RT& y, const RT& w) const 03020 { return Rep(x, y, w); } 03021 03022 Point_2 03023 operator()(const Line_2& l) const 03024 { 03025 CGAL_kernel_precondition( ! l.is_degenerate() ); 03026 if (l.is_vertical() ) 03027 { 03028 return Rep(-l.c(), RT(0) , l.a() ); 03029 } else { 03030 return Rep(RT(0) , -l.c(), l.b() ); 03031 } 03032 } 03033 03034 Point_2 03035 operator()(const Line_2& l, int i) const 03036 { 03037 Point_2 p = K().construct_point_2_object()(l); 03038 Vector_2 v = K().construct_vector_2_object()(l); 03039 return K().construct_translated_point_2_object() 03040 (p, K().construct_scaled_vector_2_object()(v, RT(i))); 03041 } 03042 03043 03044 Point_2 03045 operator()(Origin o) const 03046 { return this->operator()(Return_base_tag(), o); } 03047 03048 template < typename Tx, typename Ty > 03049 Point_2 03050 operator()(const Tx & x, const Ty & y) const 03051 { return this->operator()(Return_base_tag(), x, y); } 03052 03053 Point_2 03054 operator()(const RT& x, const RT& y, const RT& w) const 03055 { return this->operator()(Return_base_tag(), x, y, w); } 03056 }; 03057 03058 template <typename K> 03059 class Construct_point_3 03060 { 03061 typedef typename K::RT RT; 03062 typedef typename K::FT FT; 03063 typedef typename K::Point_3 Point_3; 03064 typedef typename Point_3::Rep Rep; 03065 public: 03066 typedef Point_3 result_type; 03067 03068 Rep // Point_3 03069 operator()(Return_base_tag, Origin o) const 03070 { return Rep(o); } 03071 03072 template < typename Tx, typename Ty, typename Tz > 03073 Rep // Point_3 03074 operator()(Return_base_tag, const Tx& x, const Ty& y, const Tz& z) const 03075 { return Rep(x, y, z); } 03076 03077 Rep // Point_3 03078 operator()(Return_base_tag, const FT& x, const FT& y, const FT& z) const 03079 { return Rep(x, y, z); } 03080 03081 Rep // Point_3 03082 operator()(Return_base_tag, const RT& x, const RT& y, const RT& z, const RT& w) const 03083 { return Rep(x, y, z, w); } 03084 03085 03086 Point_3 03087 operator()(Origin o) const 03088 { return this->operator()(Return_base_tag(), o); } 03089 03090 template < typename Tx, typename Ty, typename Tz > 03091 Point_3 03092 operator()(const Tx& x, const Ty& y, const Tz& z) const 03093 { return this->operator()(Return_base_tag(), x, y, z); } 03094 03095 Point_3 03096 operator()(const FT& x, const FT& y, const FT& z) const 03097 { return this->operator()(Return_base_tag(), x, y, z); } 03098 03099 Point_3 03100 operator()(const RT& x, const RT& y, const RT& z, const RT& w) const 03101 { return this->operator()(Return_base_tag(), x, y, z, w); } 03102 }; 03103 03104 03105 template <typename K> 03106 class Construct_projected_point_2 03107 { 03108 typedef typename K::Point_2 Point_2; 03109 typedef typename K::Direction_2 Direction_2; 03110 typedef typename K::Line_2 Line_2; 03111 public: 03112 typedef Point_2 result_type; 03113 03114 Point_2 03115 operator()( const Line_2& l, const Point_2& p ) const 03116 { 03117 CGAL_kernel_precondition( ! l.is_degenerate() ); 03118 Line_2 l2( p, Direction_2( l.a(), l.b() )); 03119 return Point_2( l.b()*l2.c() - l2.b()*l.c(), 03120 l2.a()*l.c() - l.a()*l2.c(), 03121 l.a()*l2.b() - l2.a()*l.b() ); 03122 } 03123 }; 03124 03125 template <typename K> 03126 class Construct_projected_point_3 03127 { 03128 typedef typename K::RT RT; 03129 typedef typename K::Point_3 Point_3; 03130 typedef typename K::Plane_3 Plane_3; 03131 typedef typename K::Line_3 Line_3; 03132 typedef typename K::Vector_3 Vector_3; 03133 public: 03134 typedef Point_3 result_type; 03135 03136 Point_3 03137 operator()( const Line_3& l, const Point_3& p ) const 03138 { 03139 if ( l.has_on(p) ) 03140 return p; 03141 Vector_3 v = p - l.point(); 03142 const RT& vx = v.hx(); 03143 const RT& vy = v.hy(); 03144 const RT& vz = v.hz(); 03145 const RT& vw = v.hw(); 03146 Vector_3 dir = l.to_vector(); 03147 const RT& dx = dir.hx(); 03148 const RT& dy = dir.hy(); 03149 const RT& dz = dir.hz(); 03150 const RT& dw = dir.hw(); 03151 03152 RT lambda_num = (vx*dx + vy*dy + vz*dz)*dw; // *dw 03153 RT lambda_den = (dx*dx + dy*dy + dz*dz)*vw; // *dw 03154 03155 return l.point() + ( (lambda_num * dir)/lambda_den ); 03156 } 03157 03158 Point_3 03159 operator()( const Plane_3& h, const Point_3& p ) const 03160 { return h.rep().projection(p); } 03161 }; 03162 03163 template <class K> 03164 class Construct_radical_line_2 03165 { 03166 typedef typename K::Line_2 Line_2; 03167 typedef typename K::Circle_2 Circle_2; 03168 typedef typename K::RT RT; 03169 typedef typename K::FT FT; 03170 03171 public: 03172 03173 typedef Line_2 result_type; 03174 03175 result_type 03176 operator() (const Circle_2 & c1, const Circle_2 & c2) const 03177 { 03178 // Concentric Circles don't have radical line 03179 CGAL_kernel_precondition (c1.center() != c2.center()); 03180 const FT a = 2*(c2.center().x() - c1.center().x()); 03181 const FT b = 2*(c2.center().y() - c1.center().y()); 03182 const FT c = CGAL::square(c1.center().x()) + 03183 CGAL::square(c1.center().y()) - c1.squared_radius() - 03184 CGAL::square(c2.center().x()) - 03185 CGAL::square(c2.center().y()) + c2.squared_radius(); 03186 const RT aa = a.numerator() * b.denominator() * c.denominator(); 03187 const RT bb = a.denominator() * b.numerator() * c.denominator(); 03188 const RT cc = a.denominator() * b.denominator() * c.numerator(); 03189 return Line_2(aa, bb, cc); 03190 } 03191 }; 03192 03193 03194 template <typename K> 03195 class Construct_scaled_vector_2 03196 { 03197 typedef typename K::RT RT; 03198 typedef typename K::FT FT; 03199 typedef typename K::Vector_2 Vector_2; 03200 public: 03201 typedef Vector_2 result_type; 03202 03203 Vector_2 03204 operator()( const Vector_2& v, const RT& c) const 03205 { 03206 return Vector_2(c * v.hx(), c * v.hy(), v.hw()); 03207 } 03208 03209 Vector_2 03210 operator()( const Vector_2& v, const FT& c) const 03211 { 03212 return Vector_2( v.hx()*c.numerator(), v.hy()*c.numerator(), 03213 v.hw()*c.denominator() ); } 03214 }; 03215 03216 template <typename K> 03217 class Construct_scaled_vector_3 03218 { 03219 typedef typename K::RT RT; 03220 typedef typename K::FT FT; 03221 typedef typename K::Vector_3 Vector_3; 03222 public: 03223 typedef Vector_3 result_type; 03224 03225 Vector_3 03226 operator()( const Vector_3& v, const RT& c) const 03227 { 03228 return Vector_3(c * v.hx(), c * v.hy(), c * v.hz(), v.hw()); 03229 } 03230 03231 Vector_3 03232 operator()( const Vector_3& v, const FT& c) const 03233 { 03234 return Vector_3( v.hx()*c.numerator(), v.hy()*c.numerator(), 03235 v.hz()*c.numerator(), v.hw()*c.denominator() ); } 03236 }; 03237 03238 template <typename K> 03239 class Construct_translated_point_2 03240 { 03241 typedef typename K::Point_2 Point_2; 03242 typedef typename K::Vector_2 Vector_2; 03243 public: 03244 typedef Point_2 result_type; 03245 03246 Point_2 03247 operator()( const Point_2& p, const Vector_2& v) const 03248 { 03249 return Point_2( p.hx()*v.hw() + v.hx()*p.hw(), 03250 p.hy()*v.hw() + v.hy()*p.hw(), 03251 p.hw()*v.hw() ); 03252 } 03253 03254 Point_2 03255 operator()( const Origin&, const Vector_2& v) const 03256 { 03257 return Point_2( v.hx(), v.hy(), v.hw() ); 03258 } 03259 }; 03260 03261 template <typename K> 03262 class Construct_translated_point_3 03263 { 03264 typedef typename K::Point_3 Point_3; 03265 typedef typename K::Vector_3 Vector_3; 03266 public: 03267 typedef Point_3 result_type; 03268 03269 Point_3 03270 operator()( const Point_3& p, const Vector_3& v) const 03271 { 03272 return Point_3(p.hx()*v.hw() + v.hx()*p.hw(), 03273 p.hy()*v.hw() + v.hy()*p.hw(), 03274 p.hz()*v.hw() + v.hz()*p.hw(), 03275 p.hw()*v.hw() ); 03276 } 03277 03278 Point_3 03279 operator()( const Origin&, const Vector_3& v) const 03280 { 03281 return Point_3( v.hx(), v.hy(), v.hz(), v.hw() ); 03282 } 03283 }; 03284 03285 template <typename K> 03286 class Construct_vector_2 03287 { 03288 typedef typename K::RT RT; 03289 typedef typename K::FT FT; 03290 typedef typename K::Segment_2 Segment_2; 03291 typedef typename K::Ray_2 Ray_2; 03292 typedef typename K::Line_2 Line_2; 03293 typedef typename K::Vector_2 Vector_2; 03294 typedef typename K::Point_2 Point_2; 03295 typedef typename K::Direction_2 Direction_2; 03296 typedef typename Vector_2::Rep Rep; 03297 public: 03298 typedef Vector_2 result_type; 03299 03300 Rep // Vector_2 03301 operator()(Return_base_tag, const Point_2& p, const Point_2& q) const 03302 { 03303 return Rep( q.hx()*p.hw() - p.hx()*q.hw(), 03304 q.hy()*p.hw() - p.hy()*q.hw(), 03305 p.hw()*q.hw() ); 03306 } 03307 03308 Rep // Vector_2 03309 operator()(Return_base_tag, const Origin& , const Point_2& q) const 03310 { 03311 return Rep( q.hx(), q.hy(), q.hw() ); 03312 } 03313 03314 Rep // Vector_2 03315 operator()(Return_base_tag, const Point_2& p, const Origin& ) const 03316 { 03317 return Rep( - p.hx(), - p.hy(), p.hw() ); 03318 } 03319 03320 Rep // Vector_2 03321 operator()(Return_base_tag, const Direction_2& d ) const 03322 { return Rep(d.dx(), d.dy()); } 03323 03324 Rep // Vector_2 03325 operator()(Return_base_tag, const Segment_2& s) const 03326 { return K().construct_vector_2_object()(s.source(), s.target()); } 03327 03328 Rep // Vector_2 03329 operator()(Return_base_tag, const Ray_2& r) const 03330 { return K().construct_vector_2_object()(r.source(), r.point(1)); } 03331 03332 Rep // Vector_2 03333 operator()(Return_base_tag, const Line_2& l) const 03334 { return K().construct_vector_2_object()( l.b(), -l.a()); } 03335 03336 Rep // Vector_2 03337 operator()(Return_base_tag, Null_vector) const 03338 { return Rep(RT(0), RT(0), RT(1)); } 03339 03340 template < typename Tx, typename Ty > 03341 Rep // Vector_2 03342 operator()(Return_base_tag, const Tx & x, const Ty & y) const 03343 { return Rep(x, y); } 03344 03345 Rep // Vector_2 03346 operator()(Return_base_tag, const RT& x, const RT& y, const RT& w) const 03347 { return Rep(x, y, w); } 03348 03349 03350 Vector_2 03351 operator()( const Point_2& p, const Point_2& q) const 03352 { return this->operator()(Return_base_tag(), p, q); } 03353 03354 Vector_2 03355 operator()( const Origin& o, const Point_2& q) const 03356 { return this->operator()(Return_base_tag(), o, q); } 03357 03358 Vector_2 03359 operator()( const Point_2& p, const Origin& o) const 03360 { return this->operator()(Return_base_tag(), p, o); } 03361 03362 Vector_2 03363 operator()( const Direction_2& d ) const 03364 { return this->operator()(Return_base_tag(), d); } 03365 03366 Vector_2 03367 operator()( const Segment_2& s) const 03368 { return this->operator()(Return_base_tag(), s); } 03369 03370 Vector_2 03371 operator()( const Ray_2& r) const 03372 { return this->operator()(Return_base_tag(), r); } 03373 03374 Vector_2 03375 operator()( const Line_2& l) const 03376 { return this->operator()(Return_base_tag(), l); } 03377 03378 Vector_2 03379 operator()( Null_vector n) const 03380 { return this->operator()(Return_base_tag(), n); } 03381 03382 template < typename Tx, typename Ty > 03383 Vector_2 03384 operator()(const Tx & x, const Ty & y) const 03385 { return this->operator()(Return_base_tag(), x, y); } 03386 03387 Vector_2 03388 operator()( const RT& x, const RT& y, const RT& w) const 03389 { return this->operator()(Return_base_tag(), x, y, w); } 03390 }; 03391 03392 template <typename K> 03393 class Construct_vector_3 03394 { 03395 typedef typename K::RT RT; 03396 typedef typename K::FT FT; 03397 typedef typename K::Direction_3 Direction_3; 03398 typedef typename K::Segment_3 Segment_3; 03399 typedef typename K::Ray_3 Ray_3; 03400 typedef typename K::Line_3 Line_3; 03401 typedef typename K::Vector_3 Vector_3; 03402 typedef typename K::Point_3 Point_3; 03403 typedef typename Vector_3::Rep Rep; 03404 public: 03405 typedef Vector_3 result_type; 03406 03407 Rep // Vector_3 03408 operator()(Return_base_tag, const Point_3& p, const Point_3& q) const 03409 { 03410 return Rep(q.hx()*p.hw() - p.hx()*q.hw(), 03411 q.hy()*p.hw() - p.hy()*q.hw(), 03412 q.hz()*p.hw() - p.hz()*q.hw(), 03413 q.hw()*p.hw() ); 03414 } 03415 03416 Rep // Vector_3 03417 operator()(Return_base_tag, const Origin&, const Point_3& q) const 03418 { 03419 return Rep( q.hx(), q.hy(), q.hz(), q.hw()); 03420 } 03421 03422 Rep // Vector_3 03423 operator()(Return_base_tag, const Point_3& p, const Origin& ) const 03424 { 03425 return Rep( - p.hx(), - p.hy(), - p.hz(), p.hw() ); 03426 } 03427 03428 Rep // Vector_3 03429 operator()(Return_base_tag, const Direction_3& d) const 03430 { return d.rep().to_vector(); } 03431 03432 Rep // Vector_3 03433 operator()(Return_base_tag, const Segment_3& s) const 03434 { return s.rep().to_vector(); } 03435 // { return this->operator()(s.start(), s.end()); } 03436 03437 Rep // Vector_3 03438 operator()(Return_base_tag, const Ray_3& r) const 03439 { return r.rep().to_vector(); } 03440 03441 Rep // Vector_3 03442 operator()(Return_base_tag, const Line_3& l) const 03443 { return l.rep().to_vector(); } 03444 03445 Rep // Vector_3 03446 operator()(Return_base_tag, const Null_vector&) const 03447 { return Rep(RT(0), RT(0), RT(0), RT(1)); } 03448 03449 template < typename Tx, typename Ty, typename Tz > 03450 Rep // Vector_3 03451 operator()(Return_base_tag, const Tx & x, const Ty & y, const Tz & z) const 03452 { return Rep(x, y, z); } 03453 03454 Rep // Vector_3 03455 operator()(Return_base_tag, const RT& x, const RT& y, const RT& z, const RT& w) const 03456 { return Rep(x, y, z, w); } 03457 03458 03459 Vector_3 03460 operator()( const Point_3& p, const Point_3& q) const 03461 { return this->operator()(Return_base_tag(), p, q); } 03462 03463 Vector_3 03464 operator()( const Origin& o, const Point_3& q) const 03465 { return this->operator()(Return_base_tag(), o, q); } 03466 03467 Vector_3 03468 operator()( const Point_3& p, const Origin& q) const 03469 { return this->operator()(Return_base_tag(), p, q); } 03470 03471 Vector_3 03472 operator()( const Direction_3& d) const 03473 { return this->operator()(Return_base_tag(), d); } 03474 03475 Vector_3 03476 operator()( const Segment_3& s) const 03477 { return this->operator()(Return_base_tag(), s); } 03478 03479 Vector_3 03480 operator()( const Ray_3& r) const 03481 { return this->operator()(Return_base_tag(), r); } 03482 03483 Vector_3 03484 operator()( const Line_3& l) const 03485 { return this->operator()(Return_base_tag(), l); } 03486 03487 Vector_3 03488 operator()( const Null_vector& n) const 03489 { return this->operator()(Return_base_tag(), n); } 03490 03491 template < typename Tx, typename Ty, typename Tz > 03492 Vector_3 03493 operator()(const Tx & x, const Ty & y, const Tz & z) const 03494 { return this->operator()(Return_base_tag(), x, y, z); } 03495 03496 Vector_3 03497 operator()( const RT& x, const RT& y, const RT& z, const RT& w) const 03498 { return this->operator()(Return_base_tag(), x, y, z, w); } 03499 }; 03500 03501 template <typename K> 03502 class Construct_vertex_2 03503 { 03504 typedef typename K::Point_2 Point_2; 03505 typedef typename K::Segment_2 Segment_2; 03506 typedef typename K::Iso_rectangle_2 Iso_rectangle_2; 03507 typedef typename K::Triangle_2 Triangle_2; 03508 public: 03509 typedef Point_2 result_type; 03510 03511 const Point_2 & 03512 operator()( const Segment_2& s, int i) const 03513 { return s.vertex(i); } 03514 03515 const Point_2 & 03516 operator()( const Triangle_2& t, int i) const 03517 { return t.rep().vertex(i); } 03518 03519 const Point_2 03520 operator()( const Iso_rectangle_2& r, int i) const 03521 { 03522 switch (i%4) { 03523 case 0: return (r.min)(); 03524 case 1: 03525 return Point_2( (r.max)().hx()*(r.min)().hw(), 03526 (r.min)().hy()*(r.max)().hw(), 03527 (r.min)().hw()*(r.max)().hw() ); 03528 case 2: return (r.max)(); 03529 default: return Point_2( (r.min)().hx()*(r.max)().hw(), 03530 (r.max)().hy()*(r.min)().hw(), 03531 (r.min)().hw()*(r.max)().hw() ); 03532 } 03533 } 03534 }; 03535 03536 } //namespace HomogeneousKernelFunctors 03537 03538 03539 #ifndef CGAL_CFG_DONT_OVERLOAD_TOO_MUCH 03540 template < typename K> 03541 struct Qualified_result_of<HomogeneousKernelFunctors::Construct_vertex_2<K>, typename K::Segment_2, int > 03542 { 03543 typedef typename K::Point_2 const & type; 03544 }; 03545 03546 template < typename K> 03547 struct Qualified_result_of<HomogeneousKernelFunctors::Construct_vertex_2<K>, typename K::Triangle_2, int > 03548 { 03549 typedef typename K::Point_2 const & type; 03550 }; 03551 #endif 03552 03553 // For Iso_rectangle the non specialized template will do the right thing, namely return a copy of a point 03554 03555 namespace HomogeneousKernelFunctors { 03556 03557 template <typename K> 03558 class Coplanar_orientation_3 03559 { 03560 typedef typename K::Point_3 Point_3; 03561 #ifdef CGAL_kernel_exactness_preconditions 03562 typedef typename K::Coplanar_3 Coplanar_3; 03563 typedef typename K::Collinear_3 Collinear_3; 03564 Coplanar_3 cp; 03565 Collinear_3 cl; 03566 #endif // CGAL_kernel_exactness_preconditions 03567 public: 03568 typedef typename K::Orientation result_type; 03569 03570 #ifdef CGAL_kernel_exactness_preconditions 03571 Coplanar_orientation_3() {} 03572 Coplanar_orientation_3(const Coplanar_3& cp_, const Collinear_3& cl_) 03573 : cp(cp_), cl(cl_) {} 03574 #endif // CGAL_kernel_exactness_preconditions 03575 03576 result_type 03577 operator()(const Point_3& p, const Point_3& q, const Point_3& r) const 03578 { 03579 Orientation oxy_pqr = sign_of_determinant(p.hx(), p.hy(), p.hw(), 03580 q.hx(), q.hy(), q.hw(), 03581 r.hx(), r.hy(), r.hw()); 03582 if (oxy_pqr != COLLINEAR) 03583 return oxy_pqr; 03584 03585 Orientation oyz_pqr = sign_of_determinant(p.hy(), p.hz(), p.hw(), 03586 q.hy(), q.hz(), q.hw(), 03587 r.hy(), r.hz(), r.hw()); 03588 if (oyz_pqr != COLLINEAR) 03589 return oyz_pqr; 03590 03591 return sign_of_determinant(p.hx(), p.hz(), p.hw(), 03592 q.hx(), q.hz(), q.hw(), 03593 r.hx(), r.hz(), r.hw()); 03594 } 03595 03596 result_type 03597 operator()( const Point_3& p, const Point_3& q, 03598 const Point_3& r, const Point_3& s) const 03599 { 03600 // p,q,r,s supposed to be coplanar 03601 // p,q,r supposed to be non collinear 03602 // tests whether s is on the same side of p,q as r 03603 // returns : 03604 // COLLINEAR if pqr collinear 03605 // POSITIVE if qrp and qrs have the same orientation 03606 // NEGATIVE if qrp and qrs have opposite orientations 03607 CGAL_kernel_exactness_precondition( ! cl(p, q, r) ); 03608 CGAL_kernel_exactness_precondition( cp(p, q, r, s) ); 03609 03610 // compute orientation of p,q,s in this plane P: 03611 Orientation save; 03612 if ( (save = sign_of_determinant(p.hy(), p.hz(), p.hw(), 03613 q.hy(), q.hz(), q.hw(), 03614 r.hy(), r.hz(), r.hw())) != COLLINEAR) 03615 { return save * sign_of_determinant(p.hy(), p.hz(), p.hw(), 03616 q.hy(), q.hz(), q.hw(), 03617 s.hy(), s.hz(), s.hw()); 03618 } 03619 if ( (save = sign_of_determinant(p.hx(), p.hz(), p.hw(), 03620 q.hx(), q.hz(), q.hw(), 03621 r.hx(), r.hz(), r.hw())) != COLLINEAR) 03622 { return save * sign_of_determinant(p.hx(), p.hz(), p.hw(), 03623 q.hx(), q.hz(), q.hw(), 03624 s.hx(), s.hz(), s.hw()); 03625 } 03626 if ( (save = sign_of_determinant(p.hx(), p.hy(), p.hw(), 03627 q.hx(), q.hy(), q.hw(), 03628 r.hx(), r.hy(), r.hw())) != COLLINEAR) 03629 { return save * sign_of_determinant( p.hx(), p.hy(), p.hw(), 03630 q.hx(), q.hy(), q.hw(), 03631 s.hx(), s.hy(), s.hw()); 03632 } 03633 CGAL_kernel_assertion( false); 03634 return COLLINEAR; 03635 } 03636 }; 03637 03638 template <typename K> 03639 class Coplanar_side_of_bounded_circle_3 03640 { 03641 typedef typename K::Point_3 Point_3; 03642 #ifdef CGAL_kernel_exactness_preconditions 03643 typedef typename K::Coplanar_3 Coplanar_3; 03644 typedef typename K::Collinear_3 Collinear_3; 03645 Coplanar_3 cp; 03646 Collinear_3 cl; 03647 #endif // CGAL_kernel_exactness_preconditions 03648 public: 03649 typedef typename K::Bounded_side result_type; 03650 03651 #ifdef CGAL_kernel_exactness_preconditions 03652 Coplanar_side_of_bounded_circle_3() {} 03653 Coplanar_side_of_bounded_circle_3(const Coplanar_3& cp_, 03654 const Collinear_3& cl_) 03655 : cp(cp_), cl(cl_) {} 03656 #endif // CGAL_kernel_exactness_preconditions 03657 03658 result_type 03659 operator()( const Point_3& p, const Point_3& q, 03660 const Point_3& r, const Point_3& t) const 03661 { 03662 // p,q,r,t are supposed to be coplanar. 03663 // p,q,r determine an orientation of this plane (not collinear). 03664 // returns the equivalent of side_of_bounded_circle(p,q,r,t) 03665 // in this plane 03666 CGAL_kernel_exactness_precondition( cp(p,q,r,t) ); 03667 CGAL_kernel_exactness_precondition( !cl(p,q,r) ); 03668 return enum_cast<Bounded_side>( 03669 side_of_oriented_sphere(p, q, r, t+cross_product(q-p, r-p), t)); 03670 } // FIXME 03671 }; 03672 03673 template <typename K> 03674 class Equal_xy_3 03675 { 03676 typedef typename K::Point_3 Point_3; 03677 public: 03678 typedef typename K::Boolean result_type; 03679 03680 result_type 03681 operator()( const Point_3& p, const Point_3& q) const 03682 { 03683 return (p.hx() * q.hw() == q.hx() * p.hw() ) 03684 && (p.hy() * q.hw() == q.hy() * p.hw() ); 03685 } 03686 }; 03687 03688 template <typename K> 03689 class Equal_x_2 03690 { 03691 typedef typename K::Point_2 Point_2; 03692 public: 03693 typedef typename K::Boolean result_type; 03694 03695 result_type 03696 operator()( const Point_2& p, const Point_2& q) const 03697 { return p.hx()*q.hw() == q.hx()*p.hw(); } 03698 }; 03699 03700 template <typename K> 03701 class Equal_x_3 03702 { 03703 typedef typename K::Point_3 Point_3; 03704 public: 03705 typedef typename K::Boolean result_type; 03706 03707 result_type 03708 operator()( const Point_3& p, const Point_3& q) const 03709 { return p.hx()*q.hw() == q.hx()*p.hw(); } 03710 }; 03711 03712 template <typename K> 03713 class Equal_y_2 03714 { 03715 typedef typename K::Point_2 Point_2; 03716 public: 03717 typedef typename K::Boolean result_type; 03718 03719 result_type 03720 operator()( const Point_2& p, const Point_2& q) const 03721 { return p.hy()*q.hw() == q.hy()*p.hw(); } 03722 }; 03723 03724 template <typename K> 03725 class Equal_y_3 03726 { 03727 typedef typename K::Point_3 Point_3; 03728 public: 03729 typedef typename K::Boolean result_type; 03730 03731 result_type 03732 operator()( const Point_3& p, const Point_3& q) const 03733 { return p.hy()*q.hw() == q.hy()*p.hw(); } 03734 }; 03735 03736 template <typename K> 03737 class Equal_z_3 03738 { 03739 typedef typename K::Point_3 Point_3; 03740 public: 03741 typedef typename K::Boolean result_type; 03742 03743 result_type 03744 operator()( const Point_3& p, const Point_3& q) const 03745 { return p.hz()*q.hw() == q.hz()*p.hw(); } 03746 }; 03747 03748 template <typename K> 03749 class Has_on_3 03750 { 03751 typedef typename K::Point_3 Point_3; 03752 typedef typename K::Line_3 Line_3; 03753 typedef typename K::Ray_3 Ray_3; 03754 typedef typename K::Segment_3 Segment_3; 03755 typedef typename K::Plane_3 Plane_3; 03756 typedef typename K::Triangle_3 Triangle_3; 03757 typedef typename K::Tetrahedron_3 Tetrahedron_3; 03758 public: 03759 typedef typename K::Boolean result_type; 03760 03761 result_type 03762 operator()( const Line_3& l, const Point_3& p) const 03763 { return l.rep().has_on(p); } 03764 03765 result_type 03766 operator()( const Ray_3& r, const Point_3& p) const 03767 { return r.rep().has_on(p); } 03768 03769 result_type 03770 operator()( const Segment_3& s, const Point_3& p) const 03771 { return s.has_on(p); } 03772 03773 result_type 03774 operator()( const Plane_3& pl, const Point_3& p) const 03775 { return pl.rep().has_on(p); } 03776 03777 result_type 03778 operator()( const Plane_3& pl, const Line_3& l) const 03779 { return pl.rep().has_on(l); } 03780 03781 result_type 03782 operator()( const Triangle_3& t, const Point_3& p) const 03783 { 03784 if (!t.is_degenerate() ) 03785 { 03786 Plane_3 sup_pl = t.supporting_plane(); 03787 if ( !sup_pl.has_on(p) ) 03788 { 03789 return false; 03790 } 03791 Tetrahedron_3 tetrapak( t.vertex(0), 03792 t.vertex(1), 03793 t.vertex(2), 03794 t.vertex(0) + sup_pl.orthogonal_vector()); 03795 return tetrapak.has_on_boundary(p); 03796 } 03797 Point_3 minp( t.vertex(0) ); 03798 Point_3 maxp( t.vertex(1) ); 03799 if (lexicographically_xyz_smaller(t.vertex(1),t.vertex(0)) ) 03800 { 03801 minp = t.vertex(1); 03802 maxp = t.vertex(0); 03803 } 03804 if (lexicographically_xyz_smaller(t.vertex(2),minp ) ) 03805 { 03806 minp = t.vertex(2); 03807 } 03808 if (lexicographically_xyz_smaller(maxp, t.vertex(2)) ) 03809 { 03810 maxp = t.vertex(2); 03811 } 03812 if (minp == maxp) 03813 { 03814 return (p == maxp); 03815 } 03816 Segment_3 s(minp,maxp); 03817 return s.has_on(p); 03818 } 03819 }; 03820 03821 template <typename K> 03822 class Less_distance_to_point_2 03823 { 03824 typedef typename K::Point_2 Point_2; 03825 public: 03826 typedef typename K::Boolean result_type; 03827 03828 result_type 03829 operator()(const Point_2& p, const Point_2& q, const Point_2& r) const 03830 { 03831 typedef typename K::RT RT; 03832 03833 const RT & phx = p.hx(); 03834 const RT & phy = p.hy(); 03835 const RT & phw = p.hw(); 03836 const RT & qhx = q.hx(); 03837 const RT & qhy = q.hy(); 03838 const RT & qhw = q.hw(); 03839 const RT & rhx = r.hx(); 03840 const RT & rhy = r.hy(); 03841 const RT & rhw = r.hw(); 03842 03843 RT dosd = // difference of squared distances 03844 03845 // phx * phx * qhw * qhw * rhw * rhw 03846 // -RT(2) * phx * qhx * phw * qhw * rhw * rhw 03847 // + qhx * qhx * phw * phw * rhw * rhw 03848 // 03849 // + phy * phy * qhw * qhw * rhw * rhw 03850 // -RT(2) * phy * qhy * phw * qhw * rhw * rhw 03851 // + qhy * qhy * phw * phw * rhw * rhw 03852 // 03853 // - ( phx * phx * qhw * qhw * rhw * rhw 03854 // -RT(2) * phx * rhx * phw * qhw * qhw * rhw 03855 // + rhx * rhx * phw * phw * qhw * qhw 03856 // 03857 // + phy * phy * qhw * qhw * rhw * rhw 03858 // -RT(2) * phy * rhy * phw * qhw * qhw * rhw 03859 // + rhy * rhy * phw * phw * qhw * qhw 03860 03861 rhw*rhw * ( phw * ( qhx*qhx + qhy*qhy ) 03862 - 2 * qhw * ( phx*qhx + phy*qhy ) 03863 ) 03864 - qhw*qhw * ( phw * ( rhx*rhx + rhy*rhy ) 03865 - 2 * rhw * ( phx*rhx + phy*rhy ) 03866 ); 03867 03868 03869 return dosd < 0; 03870 } 03871 }; 03872 03873 template <typename K> 03874 class Less_distance_to_point_3 03875 { 03876 typedef typename K::Point_3 Point_3; 03877 public: 03878 typedef typename K::Boolean result_type; 03879 03880 result_type 03881 operator()(const Point_3& p, const Point_3& q, const Point_3& r) const 03882 { 03883 typedef typename K::RT RT; 03884 03885 const RT & phx = p.hx(); 03886 const RT & phy = p.hy(); 03887 const RT & phz = p.hz(); 03888 const RT & phw = p.hw(); 03889 const RT & qhx = q.hx(); 03890 const RT & qhy = q.hy(); 03891 const RT & qhz = q.hz(); 03892 const RT & qhw = q.hw(); 03893 const RT & rhx = r.hx(); 03894 const RT & rhy = r.hy(); 03895 const RT & rhz = r.hz(); 03896 const RT & rhw = r.hw(); 03897 03898 RT dosd = // difference of squared distances 03899 rhw*rhw * ( phw * ( qhx*qhx + qhy*qhy + qhz*qhz ) 03900 - 2 * qhw * ( phx*qhx + phy*qhy + phz*qhz ) 03901 ) 03902 - qhw*qhw * ( phw * ( rhx*rhx + rhy*rhy + rhz*rhz ) 03903 - 2 * rhw * ( phx*rhx + phy*rhy + phz*rhz ) 03904 ); 03905 03906 return dosd < 0; 03907 } 03908 }; 03909 03910 template <typename K> 03911 class Less_signed_distance_to_line_2 03912 { 03913 typedef typename K::Point_2 Point_2; 03914 typedef typename K::Line_2 Line_2; 03915 public: 03916 typedef typename K::Boolean result_type; 03917 03918 result_type 03919 operator()(const Point_2& p, const Point_2& q, 03920 const Point_2& r, const Point_2& s) const 03921 { 03922 typedef typename K::RT RT; 03923 03924 const RT & phx= p.hx(); 03925 const RT & phy= p.hy(); 03926 const RT & phw= p.hw(); 03927 const RT & qhx= q.hx(); 03928 const RT & qhy= q.hy(); 03929 const RT & qhw= q.hw(); 03930 const RT & rhx= r.hx(); 03931 const RT & rhy= r.hy(); 03932 const RT & rhw= r.hw(); 03933 const RT & shx= s.hx(); 03934 const RT & shy= s.hy(); 03935 const RT & shw= s.hw(); 03936 03937 RT scaled_dist_r_minus_scaled_dist_s = 03938 ( rhx*shw - shx*rhw ) * (phy*qhw - qhy*phw) 03939 - ( rhy*shw - shy*rhw ) * (phx*qhw - qhx*phw); 03940 03941 return scaled_dist_r_minus_scaled_dist_s < 0; 03942 } 03943 03944 result_type 03945 operator()(const Line_2& l, const Point_2& p, 03946 const Point_2& q) const 03947 { 03948 typedef typename K::RT RT; 03949 03950 const RT & la = l.a(); 03951 const RT & lb = l.b(); 03952 const RT & phx= p.hx(); 03953 const RT & phy= p.hy(); 03954 const RT & phw= p.hw(); 03955 const RT & qhx= q.hx(); 03956 const RT & qhy= q.hy(); 03957 const RT & qhw= q.hw(); 03958 03959 RT scaled_dist_p_minus_scaled_dist_q = 03960 la*( phx*qhw - qhx*phw ) 03961 + lb*( phy*qhw - qhy*phw ); 03962 03963 return scaled_dist_p_minus_scaled_dist_q < 0; 03964 } 03965 }; 03966 03967 template <typename K> 03968 class Less_signed_distance_to_plane_3 03969 { 03970 typedef typename K::RT RT; 03971 typedef typename K::Point_3 Point_3; 03972 typedef typename K::Plane_3 Plane_3; 03973 typedef typename K::Construct_plane_3 Construct_plane_3; 03974 public: 03975 typedef typename K::Boolean result_type; 03976 03977 result_type 03978 operator()( const Plane_3& pl, const Point_3& p, const Point_3& q) const 03979 { 03980 const RT & pla = pl.a(); 03981 const RT & plb = pl.b(); 03982 const RT & plc = pl.c(); 03983 const RT & phx = p.hx(); 03984 const RT & phy = p.hy(); 03985 const RT & phz = p.hz(); 03986 const RT & phw = p.hw(); 03987 const RT & qhx = q.hx(); 03988 const RT & qhy = q.hy(); 03989 const RT & qhz = q.hz(); 03990 const RT & qhw = q.hw(); 03991 03992 RT scaled_dist_p_minus_scaled_dist_q = 03993 pla*( phx*qhw - qhx*phw ) 03994 + plb*( phy*qhw - qhy*phw ) 03995 + plc*( phz*qhw - qhz*phw ); 03996 03997 return scaled_dist_p_minus_scaled_dist_q < 0; 03998 } 03999 04000 result_type 04001 operator()(const Point_3& plp, const Point_3& plq, const Point_3& plr, 04002 const Point_3& p, const Point_3& q) const 04003 { 04004 Construct_plane_3 construct_plane_3; 04005 return operator()(construct_plane_3(plp, plq, plr), p, q); 04006 } 04007 }; 04008 04009 template <typename K> 04010 class Less_xyz_3 04011 { 04012 typedef typename K::Point_3 Point_3; 04013 typedef typename K::Compare_xyz_3 Compare_xyz_3; 04014 Compare_xyz_3 c; 04015 public: 04016 typedef typename K::Boolean result_type; 04017 04018 Less_xyz_3() {} 04019 Less_xyz_3(const Compare_xyz_3& c_) : c(c_) {} 04020 04021 result_type 04022 operator()( const Point_3& p, const Point_3& q) const 04023 { return c(p, q) == SMALLER; } 04024 }; 04025 04026 template <typename K> 04027 class Less_xy_2 04028 { 04029 typedef typename K::Point_2 Point_2; 04030 typedef typename K::Compare_xy_2 Compare_xy_2; 04031 Compare_xy_2 c; 04032 public: 04033 typedef typename K::Boolean result_type; 04034 04035 Less_xy_2() {} 04036 Less_xy_2(const Compare_xy_2& c_) : c(c_) {} 04037 04038 result_type 04039 operator()( const Point_2& p, const Point_2& q) const 04040 { return c(p, q) == SMALLER; } 04041 }; 04042 04043 template <typename K> 04044 class Less_xy_3 04045 { 04046 typedef typename K::Point_3 Point_3; 04047 typedef typename K::Compare_xy_3 Compare_xy_3; 04048 Compare_xy_3 c; 04049 public: 04050 typedef typename K::Boolean result_type; 04051 04052 Less_xy_3() {} 04053 Less_xy_3(const Compare_xy_3& c_) : c(c_) {} 04054 04055 result_type 04056 operator()( const Point_3& p, const Point_3& q) const 04057 { return c(p, q) == SMALLER; } 04058 }; 04059 04060 template <typename K> 04061 class Less_x_2 04062 { 04063 typedef typename K::Point_2 Point_2; 04064 public: 04065 typedef typename K::Boolean result_type; 04066 04067 result_type 04068 operator()( const Point_2& p, const Point_2& q) const 04069 { return ( p.hx()*q.hw() < q.hx()*p.hw() ); } 04070 }; 04071 04072 template <typename K> 04073 class Less_x_3 04074 { 04075 typedef typename K::Point_3 Point_3; 04076 public: 04077 typedef typename K::Boolean result_type; 04078 04079 result_type 04080 operator()( const Point_3& p, const Point_3& q) const 04081 { return ( p.hx()*q.hw() < q.hx()*p.hw() ); } 04082 }; 04083 04084 template <typename K> 04085 class Less_yx_2 04086 { 04087 typedef typename K::Point_2 Point_2; 04088 public: 04089 typedef typename K::Boolean result_type; 04090 04091 result_type 04092 operator()( const Point_2& p, const Point_2& q) const 04093 { 04094 typedef typename K::RT RT; 04095 04096 const RT& phx = p.hx(); 04097 const RT& phy = p.hy(); 04098 const RT& phw = p.hw(); 04099 const RT& qhx = q.hx(); 04100 const RT& qhy = q.hy(); 04101 const RT& qhw = q.hw(); 04102 04103 RT pV = phy * qhw; 04104 RT qV = qhy * phw; 04105 if ( qV < pV ) 04106 { 04107 return false; 04108 } 04109 else if ( pV < qV ) 04110 { 04111 return true; 04112 } 04113 pV = phx * qhw; 04114 qV = qhx * phw; 04115 return ( pV < qV ); 04116 } 04117 }; 04118 04119 template <typename K> 04120 class Less_y_2 04121 { 04122 typedef typename K::Point_2 Point_2; 04123 public: 04124 typedef typename K::Boolean result_type; 04125 04126 result_type 04127 operator()( const Point_2& p, const Point_2& q) const 04128 { return ( p.hy()*q.hw() < q.hy()*p.hw() ); } 04129 }; 04130 04131 template <typename K> 04132 class Less_y_3 04133 { 04134 typedef typename K::Point_3 Point_3; 04135 public: 04136 typedef typename K::Boolean result_type; 04137 04138 result_type 04139 operator()( const Point_3& p, const Point_3& q) const 04140 { return ( p.hy()*q.hw() < q.hy()*p.hw() ); } 04141 }; 04142 04143 template <typename K> 04144 class Less_z_3 04145 { 04146 typedef typename K::Point_3 Point_3; 04147 public: 04148 typedef typename K::Boolean result_type; 04149 04150 result_type 04151 operator()( const Point_3& p, const Point_3& q) const 04152 { return (p.hz() * q.hw() < q.hz() * p.hw() ); } 04153 }; 04154 04155 template <typename K> 04156 class Orientation_2 04157 { 04158 typedef typename K::Point_2 Point_2; 04159 typedef typename K::Vector_2 Vector_2; 04160 typedef typename K::Circle_2 Circle_2; 04161 public: 04162 typedef typename K::Orientation result_type; 04163 04164 result_type 04165 operator()(const Point_2& p, const Point_2& q, const Point_2& r) const 04166 { 04167 typedef typename K::RT RT; 04168 04169 const RT& phx = p.hx(); 04170 const RT& phy = p.hy(); 04171 const RT& phw = p.hw(); 04172 const RT& qhx = q.hx(); 04173 const RT& qhy = q.hy(); 04174 const RT& qhw = q.hw(); 04175 const RT& rhx = r.hx(); 04176 const RT& rhy = r.hy(); 04177 const RT& rhw = r.hw(); 04178 04179 // | A B | 04180 // | C D | 04181 04182 RT A = phx*rhw - phw*rhx; 04183 RT B = phy*rhw - phw*rhy; 04184 RT C = qhx*rhw - qhw*rhx; 04185 RT D = qhy*rhw - qhw*rhy; 04186 04187 return CGAL_NTS compare(A*D, B*C); 04188 } 04189 04190 result_type 04191 operator()(const Vector_2& u, const Vector_2& v) const 04192 { 04193 return sign_of_determinant(u.hx(), u.hy(), 04194 v.hx(), v.hy()); 04195 } 04196 04197 result_type 04198 operator()(const Circle_2& c) const 04199 { 04200 return c.rep().orientation(); 04201 } 04202 }; 04203 04204 template <typename K> 04205 class Orientation_3 04206 { 04207 typedef typename K::Point_3 Point_3; 04208 typedef typename K::Vector_3 Vector_3; 04209 typedef typename K::Tetrahedron_3 Tetrahedron_3; 04210 typedef typename K::Sphere_3 Sphere_3; 04211 public: 04212 typedef typename K::Orientation result_type; 04213 04214 result_type 04215 operator()( const Point_3& p, const Point_3& q, 04216 const Point_3& r, const Point_3& s) const 04217 { 04218 // Two rows are switched, because of the homogeneous column. 04219 return sign_of_determinant( p.hx(), p.hy(), p.hz(), p.hw(), 04220 r.hx(), r.hy(), r.hz(), r.hw(), 04221 q.hx(), q.hy(), q.hz(), q.hw(), 04222 s.hx(), s.hy(), s.hz(), s.hw()); 04223 } 04224 04225 result_type 04226 operator()( const Vector_3& u, const Vector_3& v, const Vector_3& w) const 04227 { 04228 return sign_of_determinant( u.hx(), u.hy(), u.hz(), 04229 v.hx(), v.hy(), v.hz(), 04230 w.hx(), w.hy(), w.hz()); 04231 } 04232 04233 result_type 04234 operator()( const Tetrahedron_3& t) const 04235 { 04236 return t.rep().orientation(); 04237 } 04238 04239 result_type 04240 operator()(const Sphere_3& s) const 04241 { 04242 return s.rep().orientation(); 04243 } 04244 }; 04245 04246 04247 template <typename K> 04248 class Oriented_side_2 04249 { 04250 typedef typename K::RT RT; 04251 typedef typename K::Point_2 Point_2; 04252 typedef typename K::Circle_2 Circle_2; 04253 typedef typename K::Line_2 Line_2; 04254 typedef typename K::Triangle_2 Triangle_2; 04255 public: 04256 typedef typename K::Oriented_side result_type; 04257 04258 result_type 04259 operator()( const Circle_2& c, const Point_2& p) const 04260 { return Oriented_side(c.bounded_side(p) * c.orientation()); } 04261 04262 result_type 04263 operator()( const Line_2& l, const Point_2& p) const 04264 { 04265 CGAL_kernel_precondition( ! l.is_degenerate() ); 04266 RT v = l.a()*p.hx() + l.b()*p.hy() + l.c()*p.hw(); 04267 return CGAL_NTS sign(v); 04268 } 04269 04270 result_type 04271 operator()( const Triangle_2& t, const Point_2& p) const 04272 { 04273 typename K::Collinear_are_ordered_along_line_2 04274 collinear_are_ordered_along_line; 04275 typename K::Orientation_2 orientation; 04276 // depends on the orientation of the vertices 04277 Orientation o1 = orientation(t.vertex(0), t.vertex(1), p), 04278 o2 = orientation(t.vertex(1), t.vertex(2), p), 04279 o3 = orientation(t.vertex(2), t.vertex(3), p), 04280 ot = orientation(t.vertex(0), t.vertex(1), t.vertex(2)); 04281 04282 if (o1 == ot && o2 == ot && o3 == ot) // ot cannot be COLLINEAR 04283 return ot; 04284 return 04285 (o1 == COLLINEAR 04286 && collinear_are_ordered_along_line(t.vertex(0), p, t.vertex(1))) || 04287 (o2 == COLLINEAR 04288 && collinear_are_ordered_along_line(t.vertex(1), p, t.vertex(2))) || 04289 (o3 == COLLINEAR 04290 && collinear_are_ordered_along_line(t.vertex(2), p, t.vertex(3))) 04291 ? ON_ORIENTED_BOUNDARY 04292 : -ot; 04293 } 04294 }; 04295 04296 04297 template <typename K> 04298 class Side_of_bounded_circle_2 04299 { 04300 typedef typename K::Point_2 Point_2; 04301 public: 04302 typedef typename K::Bounded_side result_type; 04303 04304 result_type 04305 operator()( const Point_2& p, const Point_2& q, const Point_2& t) const 04306 { 04307 typedef typename K::RT RT; 04308 04309 const RT& phx = p.hx(); 04310 const RT& phy = p.hy(); 04311 const RT& phw = p.hw(); 04312 const RT& qhx = q.hx(); 04313 const RT& qhy = q.hy(); 04314 const RT& qhw = q.hw(); 04315 const RT& thx = t.hx(); 04316 const RT& thy = t.hy(); 04317 const RT& thw = t.hw(); 04318 04319 return enum_cast<Bounded_side>( 04320 CGAL_NTS compare((thx*phw-phx*thw)*(qhx*thw-thx*qhw), 04321 (thy*phw-phy*thw)*(thy*qhw-qhy*thw)) ); 04322 } 04323 04324 result_type 04325 operator()( const Point_2& q, const Point_2& r, 04326 const Point_2& s, const Point_2& t) const 04327 { 04328 typedef typename K::RT RT; 04329 04330 const RT& qhx = q.hx(); 04331 const RT& qhy = q.hy(); 04332 const RT& qhw = q.hw(); 04333 const RT& rhx = r.hx(); 04334 const RT& rhy = r.hy(); 04335 const RT& rhw = r.hw(); 04336 const RT& shx = s.hx(); 04337 const RT& shy = s.hy(); 04338 const RT& shw = s.hw(); 04339 const RT& thx = t.hx(); 04340 const RT& thy = t.hy(); 04341 const RT& thw = t.hw(); 04342 04343 CGAL_kernel_precondition( ! collinear(q,r,s) ); 04344 04345 // compute sign of |qx qy qx^2+qy^2 1 | | a b c d | 04346 // | -- r -- | = | e f g h | 04347 // determinant | -- s -- | = | i j k l | 04348 // | -- t -- | | m n o p | 04349 // where 04350 04351 RT a = qhx*qhw; 04352 RT b = qhy*qhw; 04353 RT c = qhx*qhx + qhy*qhy; 04354 RT d = qhw*qhw; 04355 04356 RT e = rhx*rhw; 04357 RT f = rhy*rhw; 04358 RT g = rhx*rhx + rhy*rhy; 04359 RT h = rhw*rhw; 04360 04361 RT i = shx*shw; 04362 RT j = shy*shw; 04363 RT k = shx*shx + shy*shy; 04364 RT l = shw*shw; 04365 04366 RT m = thx*thw; 04367 RT n = thy*thw; 04368 RT o = thx*thx + thy*thy; 04369 RT p = thw*thw; 04370 04371 RT det = a * ( f*(k*p - l*o) + j*(h*o - g*p) + n*(g*l - h*k) ) 04372 - e * ( b*(k*p - l*o) + j*(d*o - c*p) + n*(c*l - d*k) ) 04373 + i * ( b*(g*p - h*o) + f*(d*o - c*p) + n*(c*h - d*g) ) 04374 - m * ( b*(g*l - h*k) + f*(d*k - c*l) + j*(c*h - d*g) ); 04375 04376 if ( det == 0 ) 04377 return ON_BOUNDARY; 04378 else 04379 { 04380 if (orientation(q,r,s) == CLOCKWISE) 04381 det = -det; 04382 return (0 < det ) ? ON_BOUNDED_SIDE : ON_UNBOUNDED_SIDE; 04383 } 04384 } 04385 }; 04386 04387 template <typename K> 04388 class Side_of_bounded_sphere_3 04389 { 04390 typedef typename K::Point_3 Point_3; 04391 public: 04392 typedef typename K::Bounded_side result_type; 04393 04394 result_type 04395 operator()( const Point_3& p, const Point_3& q, const Point_3& t) const 04396 { 04397 typedef typename K::RT RT; 04398 04399 const RT& phx = p.hx(); 04400 const RT& phy = p.hy(); 04401 const RT& phz = p.hz(); 04402 const RT& phw = p.hw(); 04403 const RT& qhx = q.hx(); 04404 const RT& qhy = q.hy(); 04405 const RT& qhz = q.hz(); 04406 const RT& qhw = q.hw(); 04407 const RT& thx = t.hx(); 04408 const RT& thy = t.hy(); 04409 const RT& thz = t.hz(); 04410 const RT& thw = t.hw(); 04411 04412 return enum_cast<Bounded_side>( 04413 CGAL_NTS sign((thx*phw-phx*thw)*(qhx*thw-thx*qhw) 04414 + (thy*phw-phy*thw)*(qhy*thw-thy*qhw) 04415 + (thz*phw-phz*thw)*(qhz*thw-thz*qhw))); 04416 } 04417 04418 result_type 04419 operator()( const Point_3& p, const Point_3& q, 04420 const Point_3& r, const Point_3& t) const 04421 { 04422 Point_3 center = circumcenter(p, q, r); 04423 return enum_cast<Bounded_side>( compare_distance_to_point(center, p, t) ); 04424 } // FIXME 04425 04426 result_type 04427 operator()( const Point_3& p, const Point_3& q, const Point_3& r, 04428 const Point_3& s, const Point_3& test) const 04429 { 04430 Oriented_side oside = side_of_oriented_sphere(p,q,r,s,test); 04431 if ( are_positive_oriented( p,q,r,s) ) 04432 { 04433 switch (oside) 04434 { 04435 case ON_POSITIVE_SIDE : return ON_BOUNDED_SIDE; 04436 case ON_ORIENTED_BOUNDARY: return ON_BOUNDARY; 04437 case ON_NEGATIVE_SIDE : return ON_UNBOUNDED_SIDE; 04438 } 04439 } 04440 else 04441 { 04442 switch (oside) 04443 { 04444 case ON_POSITIVE_SIDE : return ON_UNBOUNDED_SIDE; 04445 case ON_ORIENTED_BOUNDARY: return ON_BOUNDARY; 04446 case ON_NEGATIVE_SIDE : return ON_BOUNDED_SIDE; 04447 } 04448 } 04449 return ON_BOUNDARY; // Pls, no warnings anylonger 04450 } // FIXME 04451 }; 04452 04453 template <typename K> 04454 class Side_of_oriented_circle_2 04455 { 04456 typedef typename K::Point_2 Point_2; 04457 public: 04458 typedef typename K::Oriented_side result_type; 04459 04460 result_type 04461 operator()( const Point_2& q, const Point_2& r, 04462 const Point_2& s, const Point_2& t) const 04463 { 04464 typedef typename K::RT RT; 04465 04466 const RT& qhx = q.hx(); 04467 const RT& qhy = q.hy(); 04468 const RT& qhw = q.hw(); 04469 const RT& rhx = r.hx(); 04470 const RT& rhy = r.hy(); 04471 const RT& rhw = r.hw(); 04472 const RT& shx = s.hx(); 04473 const RT& shy = s.hy(); 04474 const RT& shw = s.hw(); 04475 const RT& thx = t.hx(); 04476 const RT& thy = t.hy(); 04477 const RT& thw = t.hw(); 04478 04479 CGAL_kernel_precondition( ! collinear(q,r,s) ); 04480 04481 // compute sign of |qx qy qx^2+qy^2 1 | | a b c d | 04482 // | -- r -- | = | e f g h | 04483 // determinant | -- s -- | = | i j k l | 04484 // | -- t -- | | m n o p | 04485 // where 04486 04487 RT a = qhx*qhw; 04488 RT b = qhy*qhw; 04489 RT c = qhx*qhx + qhy*qhy; 04490 RT d = qhw*qhw; 04491 04492 RT e = rhx*rhw; 04493 RT f = rhy*rhw; 04494 RT g = rhx*rhx + rhy*rhy; 04495 RT h = rhw*rhw; 04496 04497 RT i = shx*shw; 04498 RT j = shy*shw; 04499 RT k = shx*shx + shy*shy; 04500 RT l = shw*shw; 04501 04502 RT m = thx*thw; 04503 RT n = thy*thw; 04504 RT o = thx*thx + thy*thy; 04505 RT p = thw*thw; 04506 04507 RT det = a * ( f*(k*p - l*o) + j*(h*o - g*p) + n*(g*l - h*k) ) 04508 - e * ( b*(k*p - l*o) + j*(d*o - c*p) + n*(c*l - d*k) ) 04509 + i * ( b*(g*p - h*o) + f*(d*o - c*p) + n*(c*h - d*g) ) 04510 - m * ( b*(g*l - h*k) + f*(d*k - c*l) + j*(c*h - d*g) ); 04511 04512 return CGAL_NTS sign(det); 04513 } 04514 }; 04515 04516 template <typename K> 04517 class Side_of_oriented_sphere_3 04518 { 04519 typedef typename K::Point_3 Point_3; 04520 public: 04521 typedef typename K::Oriented_side result_type; 04522 04523 result_type 04524 operator()( const Point_3& p, const Point_3& q, const Point_3& r, 04525 const Point_3& s, const Point_3& t) const 04526 { 04527 typedef typename K::RT RT; 04528 CGAL_kernel_precondition( !coplanar(p,q,r,s) ); 04529 const RT & phx = p.hx(); 04530 const RT & phy = p.hy(); 04531 const RT & phz = p.hz(); 04532 const RT & phw = p.hw(); 04533 const RT phw2 = phw*phw; 04534 04535 const RT & qhx = q.hx(); 04536 const RT & qhy = q.hy(); 04537 const RT & qhz = q.hz(); 04538 const RT & qhw = q.hw(); 04539 const RT qhw2 = qhw*qhw; 04540 04541 const RT & rhx = r.hx(); 04542 const RT & rhy = r.hy(); 04543 const RT & rhz = r.hz(); 04544 const RT & rhw = r.hw(); 04545 const RT rhw2 = rhw*rhw; 04546 04547 const RT & shx = s.hx(); 04548 const RT & shy = s.hy(); 04549 const RT & shz = s.hz(); 04550 const RT & shw = s.hw(); 04551 const RT shw2 = shw*shw; 04552 04553 const RT & thx = t.hx(); 04554 const RT & thy = t.hy(); 04555 const RT & thz = t.hz(); 04556 const RT & thw = t.hw(); 04557 const RT thw2 = thw*thw; 04558 04559 const RT det = determinant<RT>( 04560 phx*phw, phy*phw, phz*phw, phx*phx + phy*phy + phz*phz, phw2, 04561 qhx*qhw, qhy*qhw, qhz*qhw, qhx*qhx + qhy*qhy + qhz*qhz, qhw2, 04562 rhx*rhw, rhy*rhw, rhz*rhw, rhx*rhx + rhy*rhy + rhz*rhz, rhw2, 04563 shx*shw, shy*shw, shz*shw, shx*shx + shy*shy + shz*shz, shw2, 04564 thx*thw, thy*thw, thz*thw, thx*thx + thy*thy + thz*thz, thw2); 04565 return - CGAL_NTS sign(det); 04566 } 04567 }; 04568 04569 } // namespace HomogeneousKernelFunctors 04570 04571 CGAL_END_NAMESPACE 04572 04573 #endif // CGAL_HOMOGENEOUS_FUNCTION_OBJECTS_H