BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/constructions/kernel_ftC2.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines