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