BWAPI
|
00001 // Copyright (c) 1999 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/PlaneH3.h $ 00019 // $Id: PlaneH3.h 49057 2009-04-30 14:03:52Z spion $ 00020 // 00021 // 00022 // Author(s) : Stefan Schirra 00023 00024 #ifndef CGAL_PLANEH3_H 00025 #define CGAL_PLANEH3_H 00026 00027 #include <CGAL/array.h> 00028 00029 CGAL_BEGIN_NAMESPACE 00030 00031 template < class R_ > 00032 class PlaneH3 00033 { 00034 typedef typename R_::RT RT; 00035 typedef typename R_::FT FT; 00036 typedef typename R_::Point_2 Point_2; 00037 typedef typename R_::Point_3 Point_3; 00038 typedef typename R_::Vector_3 Vector_3; 00039 typedef typename R_::Line_3 Line_3; 00040 typedef typename R_::Segment_3 Segment_3; 00041 typedef typename R_::Ray_3 Ray_3; 00042 typedef typename R_::Direction_3 Direction_3; 00043 typedef typename R_::Plane_3 Plane_3; 00044 typedef typename R_::Aff_transformation_3 Aff_transformation_3; 00045 00046 typedef cpp0x::array<RT, 4> Rep; 00047 typedef typename R_::template Handle<Rep>::type Base; 00048 00049 Base base; 00050 00051 public: 00052 00053 typedef R_ R; 00054 00055 PlaneH3() {} 00056 00057 PlaneH3(const Point_3&, const Point_3&, const Point_3& ); 00058 PlaneH3(const RT& a, const RT& b, 00059 const RT& c, const RT& d ); 00060 PlaneH3(const Point_3&, const Ray_3& ); 00061 PlaneH3(const Point_3&, const Line_3& ); 00062 PlaneH3(const Point_3&, const Segment_3& ); 00063 PlaneH3(const Line_3&, const Point_3& ); 00064 PlaneH3(const Segment_3&, const Point_3& ); 00065 PlaneH3(const Ray_3&, const Point_3& ); 00066 PlaneH3(const Point_3&, const Direction_3& ); 00067 PlaneH3(const Point_3&, const Vector_3& ); 00068 PlaneH3(const Point_3&, const Direction_3&, const Direction_3& ); 00069 00070 const RT & a() const; 00071 const RT & b() const; 00072 const RT & c() const; 00073 const RT & d() const; 00074 00075 bool operator==( const PlaneH3<R>& ) const; 00076 bool operator!=( const PlaneH3<R>& ) const; 00077 00078 Line_3 perpendicular_line(const Point_3& ) const; 00079 Plane_3 opposite() const; // plane with opposite orientation 00080 Point_3 projection(const Point_3& ) const; 00081 00082 Point_3 point() const; // same point on the plane 00083 Direction_3 orthogonal_direction() const; 00084 Vector_3 orthogonal_vector() const; 00085 00086 Oriented_side oriented_side(const Point_3 &p) const; 00087 bool has_on(const Point_3 &p) const; 00088 bool has_on(const Line_3 &p) const; 00089 bool has_on_positive_side(const Point_3&l) const; 00090 bool has_on_negative_side(const Point_3&l) const; 00091 00092 bool is_degenerate() const; 00093 00094 Aff_transformation_3 transform_to_2d() const; 00095 Point_2 to_2d(const Point_3& ) const; 00096 Point_3 to_3d(const Point_2& ) const; 00097 Vector_3 base1() const; 00098 Vector_3 base2() const; 00099 00100 protected: 00101 Point_3 point1() const; // same point different from point() 00102 Point_3 point2() const; // same point different from point() 00103 // and point1() 00104 00105 void new_rep(const Point_3 &p, 00106 const Point_3 &q, 00107 const Point_3 &r); 00108 00109 void new_rep(const RT &a, const RT &b, 00110 const RT &c, const RT &d); 00111 }; 00112 00113 // 00114 // a() * X + b() * Y + c() * Z() + d() * W() == 0 00115 // 00116 // | X Y Z W | 00117 // | p.hx() p.hy() p.hz() p.hw() | 00118 // | q.hx() q.hy() q.hz() q.hw() | 00119 // | r.hx() r.hy() r.hz() r.hw() | 00120 // 00121 // cpp0x::array<RT, 4> ( a(), b(), c(), d() ) 00122 00123 template < class R > 00124 inline 00125 void 00126 PlaneH3<R>::new_rep(const typename PlaneH3<R>::Point_3 &p, 00127 const typename PlaneH3<R>::Point_3 &q, 00128 const typename PlaneH3<R>::Point_3 &r) 00129 { 00130 RT phx = p.hx(); 00131 RT phy = p.hy(); 00132 RT phz = p.hz(); 00133 RT phw = p.hw(); 00134 00135 RT qhx = q.hx(); 00136 RT qhy = q.hy(); 00137 RT qhz = q.hz(); 00138 RT qhw = q.hw(); 00139 00140 RT rhx = r.hx(); 00141 RT rhy = r.hy(); 00142 RT rhz = r.hz(); 00143 RT rhw = r.hw(); 00144 00145 base = CGAL::make_array<RT>( 00146 phy*( qhz*rhw - qhw*rhz ) 00147 - qhy*( phz*rhw - phw*rhz ) // * X 00148 + rhy*( phz*qhw - phw*qhz ), 00149 00150 - phx*( qhz*rhw - qhw*rhz ) 00151 + qhx*( phz*rhw - phw*rhz ) // * Y 00152 - rhx*( phz*qhw - phw*qhz ), 00153 00154 phx*( qhy*rhw - qhw*rhy ) 00155 - qhx*( phy*rhw - phw*rhy ) // * Z 00156 + rhx*( phy*qhw - phw*qhy ), 00157 00158 - phx*( qhy*rhz - qhz*rhy ) 00159 + qhx*( phy*rhz - phz*rhy ) // * W 00160 - rhx*( phy*qhz - phz*qhy )); 00161 } 00162 00163 template < class R > 00164 inline 00165 void 00166 PlaneH3<R>::new_rep(const RT &a, const RT &b, const RT &c, const RT &d) 00167 { base = CGAL::make_array(a, b, c, d); } 00168 00169 template < class R > 00170 inline 00171 bool 00172 PlaneH3<R>::operator!=(const PlaneH3<R>& l) const 00173 { 00174 return !(*this == l); 00175 } 00176 00177 template < class R > 00178 CGAL_KERNEL_INLINE 00179 PlaneH3<R>::PlaneH3(const typename PlaneH3<R>::Point_3& p, 00180 const typename PlaneH3<R>::Point_3& q, 00181 const typename PlaneH3<R>::Point_3& r) 00182 { new_rep(p,q,r); } 00183 00184 template < class R > 00185 CGAL_KERNEL_INLINE 00186 PlaneH3<R>::PlaneH3(const RT& a, const RT& b, 00187 const RT& c, const RT& d) 00188 { new_rep(a,b,c,d); } 00189 00190 template < class R > 00191 CGAL_KERNEL_INLINE 00192 PlaneH3<R>::PlaneH3(const typename PlaneH3<R>::Point_3& p , 00193 const typename PlaneH3<R>::Line_3& l) 00194 { new_rep(p, l.point(0), l.point(1) ); } 00195 00196 template < class R > 00197 CGAL_KERNEL_INLINE 00198 PlaneH3<R>::PlaneH3(const typename PlaneH3<R>::Point_3& p, 00199 const typename PlaneH3<R>::Segment_3& s) 00200 { new_rep(p, s.source(), s.target() ); } 00201 00202 template < class R > 00203 CGAL_KERNEL_INLINE 00204 PlaneH3<R>::PlaneH3(const typename PlaneH3<R>::Point_3& p , 00205 const typename PlaneH3<R>::Ray_3& r) 00206 { new_rep(p, r.start(), r.start() + r.direction().to_vector() ); } 00207 00208 template < class R > 00209 CGAL_KERNEL_INLINE 00210 PlaneH3<R>::PlaneH3(const typename PlaneH3<R>::Line_3& l , 00211 const typename PlaneH3<R>::Point_3& p) 00212 { new_rep(l.point(0), p, l.point(1) ); } 00213 00214 template < class R > 00215 CGAL_KERNEL_INLINE 00216 PlaneH3<R>::PlaneH3(const typename PlaneH3<R>::Segment_3& s, 00217 const typename PlaneH3<R>::Point_3& p) 00218 { new_rep(s.source(), p, s.target() ); } 00219 00220 template < class R > 00221 CGAL_KERNEL_INLINE 00222 PlaneH3<R>::PlaneH3(const typename PlaneH3<R>::Ray_3& r, 00223 const typename PlaneH3<R>::Point_3& p) 00224 { new_rep(r.start(), p, r.start() + r.direction().to_vector() ); } 00225 00226 template < class R > 00227 CGAL_KERNEL_INLINE 00228 PlaneH3<R>::PlaneH3(const typename PlaneH3<R>::Point_3& p, 00229 const typename PlaneH3<R>::Direction_3& d) 00230 { 00231 Vector_3 ov = d.to_vector(); 00232 new_rep( ov.hx()*p.hw(), 00233 ov.hy()*p.hw(), 00234 ov.hz()*p.hw(), 00235 -(ov.hx()*p.hx() + ov.hy()*p.hy() + ov.hz()*p.hz() ) ); 00236 } 00237 00238 template < class R > 00239 CGAL_KERNEL_INLINE 00240 PlaneH3<R>::PlaneH3(const typename PlaneH3<R>::Point_3& p, 00241 const typename PlaneH3<R>::Vector_3& ov) 00242 { 00243 new_rep( ov.hx()*p.hw(), 00244 ov.hy()*p.hw(), 00245 ov.hz()*p.hw(), 00246 -(ov.hx()*p.hx() + ov.hy()*p.hy() + ov.hz()*p.hz() ) ); 00247 } 00248 00249 template < class R > 00250 CGAL_KERNEL_INLINE 00251 PlaneH3<R>::PlaneH3(const typename PlaneH3<R>::Point_3& p, 00252 const typename PlaneH3<R>::Direction_3& d1, 00253 const typename PlaneH3<R>::Direction_3& d2) 00254 { new_rep( p, p + d1.to_vector(), p + d2.to_vector() ); } 00255 00256 template < class R > 00257 inline 00258 const typename PlaneH3<R>::RT & 00259 PlaneH3<R>::a() const 00260 { return get(base)[0]; } 00261 00262 template < class R > 00263 inline 00264 const typename PlaneH3<R>::RT & 00265 PlaneH3<R>::b() const 00266 { return get(base)[1]; } 00267 00268 template < class R > 00269 inline 00270 const typename PlaneH3<R>::RT & 00271 PlaneH3<R>::c() const 00272 { return get(base)[2]; } 00273 00274 template < class R > 00275 inline 00276 const typename PlaneH3<R>::RT & 00277 PlaneH3<R>::d() const 00278 { return get(base)[3]; } 00279 00280 template < class R > 00281 CGAL_KERNEL_INLINE 00282 typename PlaneH3<R>::Line_3 00283 PlaneH3<R>::perpendicular_line(const typename PlaneH3<R>::Point_3& p) const 00284 { return Line_3( p, orthogonal_direction() ); } 00285 00286 template < class R > 00287 CGAL_KERNEL_INLINE 00288 typename PlaneH3<R>::Plane_3 00289 PlaneH3<R>::opposite() const 00290 { return PlaneH3<R>(-a(), -b(), -c(), -d() ); } 00291 00292 template < class R > 00293 CGAL_KERNEL_INLINE 00294 typename PlaneH3<R>::Point_3 00295 PlaneH3<R>::projection(const typename PlaneH3<R>::Point_3& p) const 00296 { return _projection( p, *this ); } 00297 00298 template < class R > 00299 CGAL_KERNEL_INLINE 00300 typename PlaneH3<R>::Point_3 00301 PlaneH3<R>::point() const 00302 { 00303 const RT RT0(0); 00304 if ( a() != RT0 ) 00305 { 00306 return Point_3( -d(), RT0, RT0, a() ); 00307 } 00308 if ( b() != RT0 ) 00309 { 00310 return Point_3( RT0, -d(), RT0, b() ); 00311 } 00312 CGAL_kernel_assertion ( c() != RT0); 00313 return Point_3( RT0, RT0, -d(), c() ); 00314 } 00315 00316 template < class R > 00317 CGAL_KERNEL_INLINE 00318 typename PlaneH3<R>::Vector_3 00319 PlaneH3<R>::base1() const 00320 { 00321 // point(): 00322 // a() != RT0 : Point_3( -d(), RT0, RT0, a() ); 00323 // b() != RT0 : Point_3( RT0, -d(), RT0, b() ); 00324 // : Point_3( RT0, RT0, -d(), c() ); 00325 // point1(): 00326 // a() != RT0 : Point_3( -b()-d(), a(), RT0, a() ); 00327 // b() != RT0 : Point_3( RT0, -c()-d(), b(), b() ); 00328 // : Point_3( c(), RT0, -a()-d(), c() ); 00329 00330 const RT RT0(0); 00331 if ( a() != RT0 ) 00332 { 00333 return Vector_3( -b(), a(), RT0, a() ); 00334 } 00335 if ( b() != RT0 ) 00336 { 00337 return Vector_3( RT0, -c(), b(), b() ); 00338 } 00339 CGAL_kernel_assertion ( c() != RT(0) ); 00340 return Vector_3( c(), RT0, -a(), c() ); 00341 } 00342 00343 template < class R > 00344 inline 00345 typename PlaneH3<R>::Vector_3 00346 PlaneH3<R>::base2() const 00347 { 00348 Vector_3 a = orthogonal_vector(); 00349 Vector_3 b = base1(); 00350 return Vector_3(a.hy()*b.hz() - a.hz()*b.hy(), 00351 a.hz()*b.hx() - a.hx()*b.hz(), 00352 a.hx()*b.hy() - a.hy()*b.hx(), 00353 a.hw()*b.hw() ); 00354 } 00355 // Actually, the following should work, but bcc doesn't like it: 00356 // { return cross_product( orthogonal_vector(), base1() ); } 00357 00358 00359 template < class R > 00360 inline 00361 typename PlaneH3<R>::Point_3 00362 PlaneH3<R>::point1() const 00363 { return point() + base1(); } 00364 00365 template < class R > 00366 inline 00367 typename PlaneH3<R>::Point_3 00368 PlaneH3<R>::point2() const 00369 { return point() + base2(); } 00370 00371 template < class R > 00372 inline 00373 typename PlaneH3<R>::Direction_3 00374 PlaneH3<R>::orthogonal_direction() const 00375 { return Direction_3(a(), b(), c() ); } 00376 00377 template < class R > 00378 inline 00379 typename PlaneH3<R>::Vector_3 00380 PlaneH3<R>::orthogonal_vector() const 00381 { return Vector_3(a(), b(), c() ); } 00382 00383 template < class R > 00384 bool 00385 PlaneH3<R>::is_degenerate() const 00386 { 00387 const RT RT0(0); 00388 return ( (a() == RT0 ) && (b() == RT0 ) && (c() == RT0 ) ); 00389 } 00390 00391 template < class R > 00392 bool 00393 PlaneH3<R>::has_on_positive_side( const typename PlaneH3<R>::Point_3& p) const 00394 { 00395 return (a()*p.hx() + b()*p.hy() + c()*p.hz() + d()*p.hw() > RT(0) ); 00396 } 00397 00398 template < class R > 00399 bool 00400 PlaneH3<R>::has_on_negative_side( const typename PlaneH3<R>::Point_3& p) const 00401 { 00402 return (a()*p.hx() + b()*p.hy() + c()*p.hz() + d()*p.hw() < RT(0) ); 00403 } 00404 00405 00406 template < class R > 00407 bool 00408 PlaneH3<R>::has_on( const typename PlaneH3<R>::Point_3& p) const 00409 { 00410 return (a()*p.hx() + b()*p.hy() + c()*p.hz() + d()*p.hw() == RT(0) ); 00411 } 00412 00413 template < class R > 00414 bool 00415 PlaneH3<R>::has_on( const typename PlaneH3<R>::Line_3& l) const 00416 { 00417 Point_3 p = l.point(); 00418 Vector_3 ld = l.direction().to_vector(); 00419 Vector_3 ov = orthogonal_vector(); 00420 00421 return ( ( a()*p.hx() + b()*p.hy() + c()*p.hz() + d()*p.hw() == RT(0) ) 00422 &&( ld.hx()*ov.hx() + ld.hy()*ov.hy() + ld.hz()*ov.hz() == RT(0) ) ); 00423 } 00424 00425 template < class R > 00426 Oriented_side 00427 PlaneH3<R>::oriented_side( const typename PlaneH3<R>::Point_3& p) const 00428 { 00429 return CGAL_NTS sign( a()*p.hx() + b()*p.hy() + c()*p.hz() + d()*p.hw() ); 00430 } 00431 00432 00433 template < class R > 00434 bool 00435 PlaneH3<R>::operator==(const PlaneH3<R>& l) const 00436 { 00437 if ( (a() * l.d() != l.a() * d() ) 00438 ||(b() * l.d() != l.b() * d() ) 00439 ||(c() * l.d() != l.c() * d() ) ) 00440 { 00441 return false; 00442 } 00443 int sd = static_cast<int>(CGAL_NTS sign(d())); 00444 int sld = static_cast<int>(CGAL_NTS sign(l.d())); 00445 if ( sd == sld ) 00446 { 00447 if (sd == 0) 00448 { 00449 return ( (a()*l.b() == b()*l.a() ) 00450 &&(a()*l.c() == c()*l.a() ) 00451 &&(b()*l.c() == c()*l.b() ) 00452 &&(CGAL_NTS sign(a() )== CGAL_NTS sign( l.a() )) 00453 &&(CGAL_NTS sign(b() )== CGAL_NTS sign( l.b() )) 00454 &&(CGAL_NTS sign(c() )== CGAL_NTS sign( l.c() )) ); 00455 } 00456 else 00457 { 00458 return true; 00459 } 00460 } 00461 else 00462 { 00463 return false; 00464 } 00465 } 00466 00467 template < class R > 00468 typename PlaneH3<R>::Aff_transformation_3 00469 PlaneH3<R>::transform_to_2d() const 00470 { 00471 const RT RT0(0); 00472 const RT RT1(1); 00473 Vector_3 nov = orthogonal_vector(); 00474 Vector_3 e1v = point1()-point() ; 00475 Vector_3 e2v = point2()-point() ; 00476 RT orthohx = nov.hx(); 00477 RT orthohy = nov.hy(); 00478 RT orthohz = nov.hz(); 00479 RT e1phx = e1v.hx(); 00480 RT e1phy = e1v.hy(); 00481 RT e1phz = e1v.hz(); 00482 RT e2phx = e2v.hx(); 00483 RT e2phy = e2v.hy(); 00484 RT e2phz = e2v.hz(); 00485 00486 RT t11 = -( orthohy*e2phz - orthohz*e2phy ); 00487 RT t12 = ( orthohx*e2phz - orthohz*e2phx ); 00488 RT t13 = -( orthohx*e2phy - orthohy*e2phx ); 00489 00490 RT t21 = ( orthohy*e1phz - orthohz*e1phy ); 00491 RT t22 = -( orthohx*e1phz - orthohz*e1phx ); 00492 RT t23 = ( orthohx*e1phy - orthohy*e1phx ); 00493 00494 RT t31 = ( e1phy*e2phz - e1phz*e2phy ); 00495 RT t32 = -( e1phx*e2phz - e1phz*e2phx ); 00496 RT t33 = ( e1phx*e2phy - e1phy*e2phx ); 00497 00498 RT scale = determinant( orthohx, orthohy, orthohz, 00499 e1phx, e1phy, e1phz, 00500 e2phx, e2phy, e2phz ); 00501 00502 Aff_transformation_3 00503 point_to_origin(TRANSLATION, - ( point() - ORIGIN ) ); 00504 Aff_transformation_3 00505 rotate_and_more( t11, t12, t13, RT0, 00506 t21, t22, t23, RT0, 00507 t31, t32, t33, RT0, 00508 scale); 00509 00510 Point_3 ortho( orthohx, orthohy, orthohz ); 00511 Point_3 e1p( e1phx, e1phy, e1phz ); 00512 Point_3 e2p( e2phx, e2phy, e2phz ); 00513 CGAL_kernel_assertion(( ortho.transform(rotate_and_more) 00514 == Point_3( RT(0), RT(0), RT(1)) )); 00515 CGAL_kernel_assertion(( e1p.transform(rotate_and_more) 00516 == Point_3( RT(1), RT(0), RT(0)) )); 00517 CGAL_kernel_assertion(( e2p.transform(rotate_and_more) 00518 == Point_3( RT(0), RT(1), RT(0)) )); 00519 00520 return rotate_and_more * point_to_origin; 00521 } 00522 00523 template < class R > 00524 CGAL_KERNEL_INLINE 00525 typename PlaneH3<R>::Point_2 00526 PlaneH3<R>::to_2d(const typename PlaneH3<R>::Point_3& p) const 00527 { 00528 Point_3 tp = p.transform( transform_to_2d() ); 00529 return Point_2( tp.hx(), tp.hy(), tp.hw()); 00530 } 00531 00532 00533 template < class R > 00534 CGAL_KERNEL_INLINE 00535 typename PlaneH3<R>::Point_3 00536 PlaneH3<R>::to_3d(const typename PlaneH3<R>::Point_2& p) const 00537 { 00538 Point_3 hp( p.hx(), p.hy(), RT(0.0), p.hw()); 00539 return hp.transform( transform_to_2d().inverse() ); 00540 } 00541 00542 CGAL_END_NAMESPACE 00543 00544 #endif // CGAL_PLANEH3_H