BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Parabola_2.h
Go to the documentation of this file.
00001 // Copyright (c) 2003,2004  INRIA Sophia-Antipolis (France).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under
00005 // the terms of the Q Public License version 1.0.
00006 // See the file LICENSE.QPL distributed with CGAL.
00007 //
00008 // Licensees holding a valid commercial license may use this file in
00009 // accordance with the commercial license agreement provided with the software.
00010 //
00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 //
00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Apollonius_graph_2/include/CGAL/Parabola_2.h $
00015 // $Id: Parabola_2.h 42811 2008-04-09 13:35:34Z spion $
00016 // 
00017 //
00018 // Author(s)     : Menelaos Karavelas <mkaravel@cse.nd.edu>
00019 
00020 
00021 
00022 #ifndef CGAL_PARABOLA_2_H
00023 #define CGAL_PARABOLA_2_H
00024 
00025 #include <CGAL/determinant.h>
00026 
00027 
00028 CGAL_BEGIN_NAMESPACE
00029 
00030 
00031 template < class Gt >
00032 class Parabola_2
00033 {
00034 private:
00035   typedef Parabola_2<Gt>  Self;
00036 public:
00037   typedef typename Gt::Site_2                 Site_2;
00038   typedef typename Gt::Point_2                Point_2;
00039   typedef typename Gt::Segment_2              Segment_2;
00040   typedef typename Gt::Line_2                 Line_2;
00041   typedef typename Gt::FT                     FT;
00042   //  typedef CGAL::Point_2< Cartesian<double> >      Point_2;
00043   //  typedef CGAL::Segment_2< Cartesian<double> >    Segment_2;
00044   //  typedef CGAL::Line_2< Cartesian<double> >       Line_2;
00045 private:
00046     typedef Algebraic_structure_traits<FT> AST;
00047 protected:
00048   // static stuff
00049 #if defined(__POWERPC__) && \
00050   defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ == 4)
00051   // hack to avoid nasty warning for G++ 3.4 on Darwin
00052   static FT STEP()
00053   {
00054     return FT(2);
00055   }
00056 #else
00057   static const FT& STEP()
00058   {
00059     static FT step_(2);
00060     return step_;
00061   }
00062 #endif
00063 
00064   //  inline static
00065   //  FT square(const FT &x)
00066   //  {
00067   //    return x * x;
00068   //  }
00069 
00070   inline static
00071   FT divide(const FT& x, const FT& y) {
00072       return CGAL::integral_division(x,y);
00073   }
00074   inline static
00075   FT sqrt(const FT& x, Integral_domain_without_division_tag) {
00076     return CGAL::sqrt(CGAL::to_double(x));
00077   }
00078 
00079   inline static
00080   FT sqrt(const FT& x, Field_with_sqrt_tag) {
00081     return CGAL::sqrt(x);
00082   }
00083 
00084   inline static
00085   FT sqrt(const FT& x) {
00086       return sqrt(x, typename AST::Algebraic_category());
00087   }
00088 
00089   inline static
00090   FT norm2(const Point_2& p)
00091   {
00092     return CGAL::square(p.x()) + CGAL::square(p.y());
00093   }
00094 
00095   inline static
00096   FT distance2(const Point_2& p1, const Point_2& p2)
00097   {
00098     FT dx = p1.x()-p2.x();
00099     FT dy = p1.y()-p2.y();
00100     return CGAL::square(dx) + CGAL::square(dy);
00101   }
00102 
00103   inline static
00104   FT distance(const Point_2& p1, const Point_2& p2)
00105   {
00106     return sqrt( distance2(p1, p2) );
00107   }
00108 
00109   inline static
00110   FT distance(const Point_2& p, const Line_2& l)
00111   {
00112     return divide( p.x() * l.a() + p.y() * l.b() + l.c(),
00113                    sqrt( CGAL::square(l.a()) + CGAL::square(l.b()) ) );
00114   }
00115 
00116   // instance stuff
00117   Point_2 c;
00118   Line_2 l;
00119   Point_2 o;
00120 
00121   inline
00122   Point_2 lchain(const FT &t) const
00123   {
00124     std::vector< Point_2 > p = compute_points(t);
00125     if ( right(p[0]) )  return p[1];
00126     return p[0];
00127   }
00128 
00129   inline
00130   Point_2 rchain(const FT &t) const
00131   {
00132     std::vector< Point_2 > p = compute_points(t);
00133     if ( right(p[0]) )  return p[0];
00134     return p[1]; 
00135   }
00136 
00137   std::vector< Point_2 > compute_points(const FT &d) const
00138   {
00139     CGAL_assertion(d >= 0);
00140     FT d1 = distance(o, c) + d;
00141     FT d2 = distance(o, l) + d;
00142     d2 = d1;
00143     d1 *= d1;
00144 
00145     std::vector< Point_2 > p;
00146 
00147     if ( l.a() == ZERO ) {
00148       FT y = d2 * CGAL::sign(l.b()) - divide(l.c(), l.b());
00149 
00150       FT C = CGAL::square(y) - FT(2) * c.y() * y + 
00151         CGAL::square(c.x()) + CGAL::square(c.y()) - d1;
00152 
00153       FT D = CGAL::square(c.x()) - C;
00154 
00155       D = CGAL::abs(D);
00156 
00157       FT x1 = sqrt(D) + c.x();
00158       FT x2 = -sqrt(D) + c.x();
00159 
00160       p.push_back(Point_2(x1, y));
00161       p.push_back(Point_2(x2, y));
00162 
00163       return p;
00164     }
00165 
00166     FT A = d2 * sqrt( CGAL::square(l.a()) + CGAL::square(l.b()) ) - l.c();
00167     FT B = CGAL::square(c.x()) + CGAL::square(c.y()) - d1;
00168 
00169     FT alpha = FT(1) + CGAL::square(divide(l.b(), l.a()));
00170     FT beta = divide(A * l.b(), CGAL::square(l.a())) + c.y()
00171       - divide(c.x() * l.b(), l.a());
00172     FT gamma = CGAL::square(divide(A, l.a())) + B
00173       - divide(FT(2) * c.x() * A, l.a());
00174 
00175     FT D = CGAL::square(beta) - alpha * gamma;
00176 
00177     D = CGAL::abs(D);
00178 
00179     FT y1 = divide((beta + sqrt(D)), alpha);
00180     FT y2 = divide((beta - sqrt(D)), alpha);
00181 
00182     FT x1 = divide(A - l.b() * y1, l.a());
00183     FT x2 = divide(A - l.b() * y2, l.a());
00184 
00185     p.push_back(Point_2(x1, y1));
00186     p.push_back(Point_2(x2, y2));
00187 
00188     return p;
00189   }
00190 
00191   bool right(const Point_2& p) const
00192   {
00193     return
00194       CGAL::is_positive( determinant<FT>(c.x(), c.y(), FT(1),
00195                                                o.x(), o.y(), FT(1),
00196                                                p.x(), p.y(), FT(1)) );
00197   }
00198 
00199   inline
00200   Point_2 midpoint(const Point_2& p1, const Point_2& p2) const
00201   {
00202     FT t1 = t(p1);
00203     FT t2 = t(p2);
00204     FT midt = divide(t1+t2, FT(2));
00205     return f(midt);
00206   }
00207 
00208   inline
00209   Point_2 f(FT t) const
00210   {
00211     if ( CGAL::is_negative(t) )  return rchain(-t);
00212     return lchain(t);
00213   }
00214 
00215   inline
00216   FT t(const Point_2 &p) const
00217   {
00218     FT tt = distance(p, c) - distance(c, o);
00219     if ( right(p) )  return -tt;
00220     return tt;
00221   }
00222 
00223   void compute_origin()
00224   {
00225     FT d = divide(l.a() * c.x() + l.b() * c.y() + l.c(),
00226                   FT(2) * ( CGAL::square(l.a()) + CGAL::square(l.b()) )  );
00227     o = Point_2(c.x() - l.a() * d, c.y() - l.b() * d);
00228   }
00229 
00230 public:
00231   Parabola_2() {}
00232 
00233   template<class ApolloniusSite>
00234   Parabola_2(const ApolloniusSite &p, const Line_2 &l1)
00235   {
00236     this->c = p.point();
00237 
00238     FT d_a = CGAL::to_double(l1.a());
00239     FT d_b = CGAL::to_double(l1.b());
00240     FT len = sqrt(CGAL::square(d_a) + CGAL::square(d_b));
00241 
00242     FT r = p.weight() * len;
00243 
00244     this->l = Line_2(-l1.a(), -l1.b(), -l1.c() + r);
00245     compute_origin();
00246   }
00247 
00248   Parabola_2(const Point_2 &p, const Line_2 &line)
00249   {
00250     this->c = p;
00251 
00252     if ( line.has_on_positive_side(p) ) {
00253       this->l = line;
00254     } else {
00255       this->l = line.opposite();
00256     }
00257     compute_origin();
00258   }
00259 
00260 
00261   Oriented_side
00262   side_of_parabola(const Point_2& p) const
00263   {
00264     Point_2 q(CGAL::to_double(p.x()), CGAL::to_double(p.y()));
00265 
00266     FT d = distance(q, c) - fabs(distance(q, l));
00267     if ( d < 0 )  return ON_NEGATIVE_SIDE;
00268     if ( d > 0 )  return ON_POSITIVE_SIDE;
00269     return ON_ORIENTED_BOUNDARY;
00270   }
00271 
00272 
00273   inline Line_2 line() const
00274   {
00275     return l;
00276   }
00277 
00278   inline Point_2 center() const
00279   {
00280     return c;
00281   }
00282 
00283   template< class Stream >
00284   void draw(Stream& W) const
00285   {
00286     std::vector< Point_2 > p;
00287     std::vector< Point_2 > pleft, pright;
00288 
00289     pleft.push_back(o);
00290     pright.push_back(o);
00291 
00292     for (int i = 1; i <= 100; i++) {
00293       p = compute_points(i * i * STEP());
00294 
00295       W << p[0];
00296       W << p[1];
00297 
00298       if ( p.size() > 0 ) {
00299         if ( right(p[0]) ) {
00300           pright.push_back(p[0]);
00301           pleft.push_back(p[1]);
00302         } else {
00303           pright.push_back(p[1]);
00304           pleft.push_back(p[0]);
00305         }
00306       }
00307     }
00308 
00309     for (unsigned int i = 0; i < pleft.size() - 1; i++) {
00310       W << Segment_2(pleft[i], pleft[i+1]);
00311     }
00312 
00313     for (unsigned int i = 0; i < pright.size() - 1; i++) {
00314       W << Segment_2(pright[i], pright[i+1]);
00315     }
00316 
00317     W << o;
00318   }
00319 };
00320 
00321 template< class Stream, class Gt >
00322 inline
00323 Stream& operator<<(Stream& s, const Parabola_2<Gt> &P)
00324 {
00325   P.draw(s);
00326   return s;
00327 }
00328 
00329 
00330 
00331 
00332 CGAL_END_NAMESPACE
00333 
00334 #endif // CGAL_PARABOLA_2_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines