|
BWAPI
|
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
1.7.6.1