BWAPI
|
00001 // Copyright (c) 2000 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/Cartesian_kernel/include/CGAL/constructions/kernel_ftC2.h $ 00019 // $Id: kernel_ftC2.h 42900 2008-04-15 15:13:17Z spion $ 00020 // 00021 // 00022 // Author(s) : Sven Schoenherr, Herve Bronnimann, Sylvain Pion 00023 00024 #ifndef CGAL_CONSTRUCTIONS_KERNEL_FTC2_H 00025 #define CGAL_CONSTRUCTIONS_KERNEL_FTC2_H 00026 00027 #include <CGAL/determinant.h> 00028 00029 CGAL_BEGIN_NAMESPACE 00030 00031 template < class FT > 00032 CGAL_KERNEL_INLINE 00033 void 00034 midpointC2( const FT &px, const FT &py, 00035 const FT &qx, const FT &qy, 00036 FT &x, FT &y ) 00037 { 00038 x = (px+qx) / 2; 00039 y = (py+qy) / 2; 00040 } 00041 00042 template < class FT > 00043 CGAL_KERNEL_LARGE_INLINE 00044 void 00045 circumcenter_translateC2(const FT &dqx, const FT &dqy, 00046 const FT &drx, const FT &dry, 00047 FT &dcx, FT &dcy) 00048 { 00049 // Given 3 points P, Q, R, this function takes as input: 00050 // qx-px, qy-py, rx-px, ry-py. And returns cx-px, cy-py, 00051 // where (cx, cy) are the coordinates of the circumcenter C. 00052 00053 // What we do is intersect the bisectors. 00054 FT r2 = CGAL_NTS square(drx) + CGAL_NTS square(dry); 00055 FT q2 = CGAL_NTS square(dqx) + CGAL_NTS square(dqy); 00056 FT den = 2 * determinant(dqx, dqy, drx, dry); 00057 00058 // The 3 points aren't collinear. 00059 // Hopefully, this is already checked at the upper level. 00060 CGAL_kernel_assertion ( ! CGAL_NTS is_zero(den) ); 00061 00062 // One possible optimization here is to precompute 1/den, to avoid one 00063 // division. However, we loose precision, and it's maybe not worth it (?). 00064 dcx = determinant (dry, dqy, r2, q2) / den; 00065 dcy = - determinant (drx, dqx, r2, q2) / den; 00066 } 00067 00068 template < class FT > 00069 CGAL_KERNEL_MEDIUM_INLINE 00070 void 00071 circumcenterC2( const FT &px, const FT &py, 00072 const FT &qx, const FT &qy, 00073 const FT &rx, const FT &ry, 00074 FT &x, FT &y ) 00075 { 00076 circumcenter_translateC2<FT>(qx-px, qy-py, rx-px, ry-py, x, y); 00077 x += px; 00078 y += py; 00079 } 00080 00081 template < class FT > 00082 void 00083 barycenterC2(const FT &p1x, const FT &p1y, const FT &w1, 00084 const FT &p2x, const FT &p2y, 00085 FT &x, FT &y) 00086 { 00087 FT w2 = 1 - w1; 00088 x = w1 * p1x + w2 * p2x; 00089 y = w1 * p1y + w2 * p2y; 00090 } 00091 00092 template < class FT > 00093 void 00094 barycenterC2(const FT &p1x, const FT &p1y, const FT &w1, 00095 const FT &p2x, const FT &p2y, const FT &w2, 00096 FT &x, FT &y) 00097 { 00098 FT sum = w1 + w2; 00099 CGAL_kernel_assertion(sum != 0); 00100 x = (w1 * p1x + w2 * p2x) / sum; 00101 y = (w1 * p1y + w2 * p2y) / sum; 00102 } 00103 00104 template < class FT > 00105 void 00106 barycenterC2(const FT &p1x, const FT &p1y, const FT &w1, 00107 const FT &p2x, const FT &p2y, const FT &w2, 00108 const FT &p3x, const FT &p3y, 00109 FT &x, FT &y) 00110 { 00111 FT w3 = 1 - w1 - w2; 00112 x = w1 * p1x + w2 * p2x + w3 * p3x; 00113 y = w1 * p1y + w2 * p2y + w3 * p3y; 00114 } 00115 00116 template < class FT > 00117 void 00118 barycenterC2(const FT &p1x, const FT &p1y, const FT &w1, 00119 const FT &p2x, const FT &p2y, const FT &w2, 00120 const FT &p3x, const FT &p3y, const FT &w3, 00121 FT &x, FT &y) 00122 { 00123 FT sum = w1 + w2 + w3; 00124 CGAL_kernel_assertion(sum != 0); 00125 x = (w1 * p1x + w2 * p2x + w3 * p3x) / sum; 00126 y = (w1 * p1y + w2 * p2y + w3 * p3y) / sum; 00127 } 00128 00129 template < class FT > 00130 void 00131 barycenterC2(const FT &p1x, const FT &p1y, const FT &w1, 00132 const FT &p2x, const FT &p2y, const FT &w2, 00133 const FT &p3x, const FT &p3y, const FT &w3, 00134 const FT &p4x, const FT &p4y, 00135 FT &x, FT &y) 00136 { 00137 FT w4 = 1 - w1 - w2 - w3; 00138 x = w1 * p1x + w2 * p2x + w3 * p3x + w4 * p4x; 00139 y = w1 * p1y + w2 * p2y + w3 * p3y + w4 * p4y; 00140 } 00141 00142 template < class FT > 00143 void 00144 barycenterC2(const FT &p1x, const FT &p1y, const FT &w1, 00145 const FT &p2x, const FT &p2y, const FT &w2, 00146 const FT &p3x, const FT &p3y, const FT &w3, 00147 const FT &p4x, const FT &p4y, const FT &w4, 00148 FT &x, FT &y) 00149 { 00150 FT sum = w1 + w2 + w3 + w4; 00151 CGAL_kernel_assertion(sum != 0); 00152 x = (w1 * p1x + w2 * p2x + w3 * p3x + w4 * p4x) / sum; 00153 y = (w1 * p1y + w2 * p2y + w3 * p3y + w4 * p4y) / sum; 00154 } 00155 00156 template < class FT > 00157 CGAL_KERNEL_MEDIUM_INLINE 00158 void 00159 centroidC2( const FT &px, const FT &py, 00160 const FT &qx, const FT &qy, 00161 const FT &rx, const FT &ry, 00162 FT &x, FT &y) 00163 { 00164 x = (px + qx + rx) / 3; 00165 y = (py + qy + ry) / 3; 00166 } 00167 00168 template < class FT > 00169 CGAL_KERNEL_MEDIUM_INLINE 00170 void 00171 centroidC2( const FT &px, const FT &py, 00172 const FT &qx, const FT &qy, 00173 const FT &rx, const FT &ry, 00174 const FT &sx, const FT &sy, 00175 FT &x, FT &y) 00176 { 00177 x = (px + qx + rx + sx) / 4; 00178 y = (py + qy + ry + sy) / 4; 00179 } 00180 00181 template < class FT > 00182 inline 00183 void 00184 line_from_pointsC2(const FT &px, const FT &py, 00185 const FT &qx, const FT &qy, 00186 FT &a, FT &b, FT &c) 00187 { 00188 // The horizontal and vertical line get a special treatment 00189 // in order to make the intersection code robust for doubles 00190 if(py == qy){ 00191 a = 0 ; 00192 if(qx > px){ 00193 b = 1; 00194 c = -py; 00195 } else if(qx == px){ 00196 b = 0; 00197 c = 0; 00198 }else{ 00199 b = -1; 00200 c = py; 00201 } 00202 } else if(qx == px){ 00203 b = 0; 00204 if(qy > py){ 00205 a = -1; 00206 c = px; 00207 } else if (qy == py){ 00208 a = 0; 00209 c = 0; 00210 } else { 00211 a = 1; 00212 c = -px; 00213 } 00214 } else { 00215 a = py - qy; 00216 b = qx - px; 00217 c = -px*a - py*b; 00218 } 00219 } 00220 00221 template < class FT > 00222 inline 00223 void 00224 line_from_point_directionC2(const FT &px, const FT &py, 00225 const FT &dx, const FT &dy, 00226 FT &a, FT &b, FT &c) 00227 { 00228 a = - dy; 00229 b = dx; 00230 c = px*dy - py*dx; 00231 } 00232 00233 template < class FT > 00234 CGAL_KERNEL_INLINE 00235 void 00236 bisector_of_pointsC2(const FT &px, const FT &py, 00237 const FT &qx, const FT &qy, 00238 FT &a, FT &b, FT& c ) 00239 { 00240 a = 2 * (px - qx); 00241 b = 2 * (py - qy); 00242 c = CGAL_NTS square(qx) + CGAL_NTS square(qy) - 00243 CGAL_NTS square(px) - CGAL_NTS square(py); 00244 } 00245 00246 template < class FT > 00247 CGAL_KERNEL_INLINE 00248 void 00249 bisector_of_linesC2(const FT &pa, const FT &pb, const FT &pc, 00250 const FT &qa, const FT &qb, const FT &qc, 00251 FT &a, FT &b, FT &c) 00252 { 00253 // We normalize the equations of the 2 lines, and we then add them. 00254 FT n1 = CGAL_NTS sqrt(CGAL_NTS square(pa) + CGAL_NTS square(pb)); 00255 FT n2 = CGAL_NTS sqrt(CGAL_NTS square(qa) + CGAL_NTS square(qb)); 00256 a = n2 * pa + n1 * qa; 00257 b = n2 * pb + n1 * qb; 00258 c = n2 * pc + n1 * qc; 00259 00260 // Care must be taken for the case when this produces a degenerate line. 00261 if (a == 0 && b == 0) { 00262 a = n2 * pa - n1 * qa; 00263 b = n2 * pb - n1 * qb; 00264 c = n2 * pc - n1 * qc; 00265 } 00266 } 00267 00268 template < class FT > 00269 inline 00270 FT 00271 line_y_at_xC2(const FT &a, const FT &b, const FT &c, const FT &x) 00272 { 00273 return (-a*x-c) / b; 00274 } 00275 00276 template < class FT > 00277 inline 00278 void 00279 line_get_pointC2(const FT &a, const FT &b, const FT &c, int i, 00280 FT &x, FT &y) 00281 { 00282 if (CGAL_NTS is_zero(b)) 00283 { 00284 x = (-b-c)/a + i * b; 00285 y = 1 - i * a; 00286 } 00287 else 00288 { 00289 x = 1 + i * b; 00290 y = -(a+c)/b - i * a; 00291 } 00292 } 00293 00294 template < class FT > 00295 inline 00296 void 00297 perpendicular_through_pointC2(const FT &la, const FT &lb, 00298 const FT &px, const FT &py, 00299 FT &a, FT &b, FT &c) 00300 { 00301 a = -lb; 00302 b = la; 00303 c = lb * px - la * py; 00304 } 00305 00306 template < class FT > 00307 CGAL_KERNEL_MEDIUM_INLINE 00308 void 00309 line_project_pointC2(const FT &la, const FT &lb, const FT &lc, 00310 const FT &px, const FT &py, 00311 FT &x, FT &y) 00312 { 00313 #if 1 // FIXME 00314 // Original old version 00315 if (CGAL_NTS is_zero(la)) // horizontal line 00316 { 00317 x = px; 00318 y = -lc/lb; 00319 } 00320 else if (CGAL_NTS is_zero(lb)) // vertical line 00321 { 00322 x = -lc/la; 00323 y = py; 00324 } 00325 else 00326 { 00327 FT ab = la/lb, ba = lb/la, ca = lc/la; 00328 y = ( -px + ab*py - ca ) / ( ba + ab ); 00329 x = -ba * y - ca; 00330 } 00331 #else 00332 // New version, with more multiplications, but less divisions and tests. 00333 // Let's compare the results of the 2, benchmark them, as well as check 00334 // the precision with the intervals. 00335 FT a2 = CGAL_NTS square(la); 00336 FT b2 = CGAL_NTS square(lb); 00337 FT d = a2 + b2; 00338 x = (la * (lb * py - lc) - px * b2) / d; 00339 y = (lb * (lc - la * px) + py * a2) / d; 00340 #endif 00341 } 00342 00343 template < class FT > 00344 CGAL_KERNEL_MEDIUM_INLINE 00345 FT 00346 squared_radiusC2(const FT &px, const FT &py, 00347 const FT &qx, const FT &qy, 00348 const FT &rx, const FT &ry, 00349 FT &x, FT &y ) 00350 { 00351 circumcenter_translateC2(qx-px, qy-py, rx-px, ry-py, x, y); 00352 FT r2 = CGAL_NTS square(x) + CGAL_NTS square(y); 00353 x += px; 00354 y += py; 00355 return r2; 00356 } 00357 00358 template < class FT > 00359 CGAL_KERNEL_MEDIUM_INLINE 00360 FT 00361 squared_radiusC2(const FT &px, const FT &py, 00362 const FT &qx, const FT &qy, 00363 const FT &rx, const FT &ry) 00364 { 00365 FT x, y; 00366 circumcenter_translateC2<FT>(qx-px, qy-py, rx-px, ry-py, x, y); 00367 return CGAL_NTS square(x) + CGAL_NTS square(y); 00368 } 00369 00370 template < class FT > 00371 inline 00372 FT 00373 squared_distanceC2( const FT &px, const FT &py, 00374 const FT &qx, const FT &qy) 00375 { 00376 return CGAL_NTS square(px-qx) + CGAL_NTS square(py-qy); 00377 } 00378 00379 template < class FT > 00380 inline 00381 FT 00382 squared_radiusC2(const FT &px, const FT &py, 00383 const FT &qx, const FT &qy) 00384 { 00385 return squared_distanceC2(px, py,qx, qy) / 4; 00386 } 00387 00388 template < class FT > 00389 CGAL_KERNEL_INLINE 00390 FT 00391 scaled_distance_to_lineC2( const FT &la, const FT &lb, const FT &lc, 00392 const FT &px, const FT &py) 00393 { 00394 // for comparisons, use distance_to_directionsC2 instead 00395 // since lc is irrelevant 00396 return la*px + lb*py + lc; 00397 } 00398 00399 template < class FT > 00400 CGAL_KERNEL_INLINE 00401 FT 00402 scaled_distance_to_directionC2( const FT &la, const FT &lb, 00403 const FT &px, const FT &py) 00404 { 00405 // scalar product with direction 00406 return la*px + lb*py; 00407 } 00408 00409 template < class FT > 00410 CGAL_KERNEL_MEDIUM_INLINE 00411 FT 00412 scaled_distance_to_lineC2( const FT &px, const FT &py, 00413 const FT &qx, const FT &qy, 00414 const FT &rx, const FT &ry) 00415 { 00416 return determinant<FT>(px-rx, py-ry, qx-rx, qy-ry); 00417 } 00418 00419 CGAL_END_NAMESPACE 00420 00421 #endif // CGAL_CONSTRUCTIONS_KERNEL_FTC2_H