BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Nef_3/SNC_intersection.h
Go to the documentation of this file.
00001 // Copyright (c) 1997-2002  Max-Planck-Institute Saarbruecken (Germany).
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/Nef_3/include/CGAL/Nef_3/SNC_intersection.h $
00015 // $Id: SNC_intersection.h 43273 2008-05-22 15:04:50Z hachenb $
00016 // 
00017 //
00018 // Author(s)     : Michael Seel       <seel@mpi-sb.mpg.de>
00019 //                 Peter Hachenberger <hachenberger@mpi-sb.mpg.de> 
00020 #ifndef CGAL_SNC_INTERSECTION_H
00021 #define CGAL_SNC_INTERSECTION_H
00022 
00023 #include <CGAL/basic.h>
00024 
00025 #undef CGAL_NEF_DEBUG
00026 #define CGAL_NEF_DEBUG 37
00027 #include <CGAL/Nef_2/debug.h>
00028 
00029 CGAL_BEGIN_NAMESPACE
00030 
00031 template < class Node, class Object>
00032 struct Project_shalfedge_point {
00033   typedef Node         argument_type;
00034   typedef Object       result_type;
00035   Object& operator()( Node& x) const   { 
00036     return x.source()->source()->point();
00037     /* a Point_3& reference must be returned by D.point() */
00038   }
00039   const Object& operator()( const Node& x) const   { 
00040     return x.source()->source()->point(); 
00041     /* a Point_3& reference must be returned by D.point() */
00042   }
00043 };
00044 
00045 template<typename SNC_structure_>
00046 class SNC_intersection : public SNC_const_decorator<SNC_structure_> {
00047   // TODO: granados: is it really necessary to inherit from the decorator?
00048 
00049   typedef SNC_structure_                     SNC_structure;
00050   typedef SNC_intersection<SNC_structure>    Self;
00051   typedef SNC_const_decorator<SNC_structure> Base;
00052   //  typedef SNC_const_decorator<SNC_structure> SNC_const_decorator;
00053 
00054   typedef typename SNC_structure::SHalfedge               SHalfedge;
00055   typedef typename SNC_structure::Halfedge_handle         Halfedge_handle;
00056   typedef typename SNC_structure::Halffacet_const_handle  
00057                                   Halffacet_const_handle;
00058   typedef typename SNC_structure::SHalfedge_const_handle  SHalfedge_const_handle;
00059   typedef typename SNC_structure::SHalfloop_const_handle  SHalfloop_const_handle;
00060   typedef typename SNC_structure::SHalfedge_around_facet_const_circulator 
00061                                   SHalfedge_around_facet_const_circulator;
00062   typedef typename SNC_structure::Halffacet_cycle_const_iterator
00063                                   Halffacet_cycle_const_iterator;
00064 
00065 #ifdef CGAL_NEF3_FACET_WITH_BOX
00066   typedef typename SNC_structure::Partial_facet Partial_facet;
00067 #endif
00068 
00069   typedef typename SNC_structure::Point_3        Point_3;
00070   typedef typename SNC_structure::Vector_3       Vector_3;
00071   typedef typename SNC_structure::Segment_3      Segment_3;
00072   typedef typename SNC_structure::Line_3         Line_3;
00073   typedef typename SNC_structure::Ray_3          Ray_3;
00074   typedef typename SNC_structure::Plane_3        Plane_3;
00075   typedef typename SNC_structure::Triangle_3     Triangle_3;
00076 
00077  public:
00078 
00079   SNC_intersection() : Base() {}
00080   SNC_intersection(const SNC_structure& W) : Base(W) {}
00081 
00082   bool does_contain_internally(const Segment_3& s, const Point_3& p) const {
00083     if(!are_strictly_ordered_along_line (s.source(), p, s.target()))
00084       return false;
00085     if(!s.supporting_line().has_on(p))
00086       return false;
00087     return true;
00088   }
00089 
00090   bool does_contain_internally( Halffacet_const_handle f, 
00091                                 const Point_3& p,
00092                                 bool check_has_on = true) const {
00093     if(check_has_on && !f->plane().has_on(p))
00094       return false;
00095     return (locate_point_in_halffacet( p, f) == CGAL::ON_BOUNDED_SIDE); 
00096   }
00097 
00098 #ifdef CGAL_NEF3_FACET_WITH_BOX
00099   bool does_contain_internally( Partial_facet& pf, 
00100                                 const Point_3& p) const {
00101     CGAL_NEF_TRACEN("does point lie in partial facet" << p);
00102     //    pf.debug();
00103     if( !pf.f->plane().has_on(p))
00104       return false;
00105     return (locate_point_in_halffacet( p, pf) == CGAL::ON_BOUNDED_SIDE); 
00106   }
00107 #endif
00108 
00109   bool does_contain_on_boundary( Halffacet_const_handle f, const Point_3& p) const {
00110     typedef Project_shalfedge_point
00111       < SHalfedge, const Point_3> Project;
00112     typedef Circulator_project
00113       < SHalfedge_around_facet_const_circulator, Project, 
00114       const Point_3&, const Point_3*> Circulator;
00115     Halffacet_cycle_const_iterator fc = f->facet_cycles_begin();
00116     CGAL_assertion(fc.is_shalfedge());
00117     if (fc.is_shalfedge() ) {
00118       SHalfedge_const_handle se(fc);
00119       SHalfedge_around_facet_const_circulator hfc(se);
00120       Circulator c(hfc), cp(c), cend(c);
00121       do {
00122         c++;
00123         CGAL_NEF_TRACEN("contained on edge "<<Segment_3( *c, *cp)<<"? "<<
00124                Segment_3( *c, *cp).has_on(p));
00125         if( Segment_3( *c, *cp).has_on(p))
00126           return true;
00127         cp++;
00128       }
00129       while( c != cend); 
00130     } 
00131     Halffacet_cycle_const_iterator fe = f->facet_cycles_end();
00132     ++fc;
00133     CGAL_For_all(fc, fe) {
00134       if (fc.is_shalfloop() ) { 
00135         SHalfloop_const_handle l(fc);
00136         CGAL_NEF_TRACEN("isolated point on "<<l->incident_sface()->center_vertex()->point()<<"? ");
00137         if( l->incident_sface()->center_vertex()->point() == p)
00138           return true;
00139       } 
00140       else if (fc.is_shalfedge() ) {
00141         SHalfedge_const_handle se(fc);
00142         SHalfedge_around_facet_const_circulator hfc(se);
00143         Circulator c(hfc), cp(c), cend(c);
00144         do {
00145           c++;
00146           CGAL_NEF_TRACEN("contained on edge "<<Segment_3( *c, *cp)<<"? "<<
00147                  Segment_3( *c, *cp).has_on(p));
00148           if( Segment_3( *c, *cp).has_on(p))
00149             return true;
00150           cp++;
00151         } 
00152         while( c != cend);
00153       }
00154       else 
00155         CGAL_error_msg( "Damn wrong handle.");
00156     }
00157     return false;
00158   }
00159   
00160 #ifdef LINE3_LINE3_INTERSECTION
00161   
00162   bool does_intersect_internally( const Segment_3& s1, 
00163                                   const Segment_3& s2, 
00164                                   Point_3& p) const  {
00165     CGAL_NEF_TRACEN("does intersect internally with  LINE3_LINE3_INTERSECTION");
00166     if ( s1.is_degenerate() || s2.is_degenerate())
00167       /* the segment is degenerate so there is not internal intersection */
00168       return false;
00169     if ( s1.has_on(s2.source()) || s1.has_on(s2.target()) ||
00170          s2.has_on(s1.source()) || s2.has_on(s1.target()))
00171       /* the segments does intersect at one endpoint */
00172       return false;
00173     Object o = intersection(Line_3(ray), Line_3(s)); 
00174     if ( !CGAL::assign(p, o))
00175       return false;
00176     return( does_contain_internally( s, p));
00177   }
00178 
00179 #else // LINE3_LINE3_INTERSECTION
00180 
00181   bool does_intersect_internally( const Segment_3& s1, 
00182                                   const Segment_3& s2, 
00183                                   Point_3& p) const {
00184     if(s2.has_on(s1.target()))
00185       return false;
00186     Ray_3 r(s1.source(), s1.target());
00187     if(!does_intersect_internally(r, s2, p))
00188       return false;
00189     Plane_3 pl(s1.target(), r.to_vector());
00190     return (pl.oriented_side(p) == CGAL::NEGATIVE);
00191   }
00192 
00193   bool does_intersect_internally( const Ray_3& s1, 
00194                                   const Segment_3& s2, 
00195                                   Point_3& p) const {
00196     CGAL_NEF_TRACEN("does intersect internally without  LINE3_LINE3_INTERSECTION");    
00197     CGAL_assertion(!s1.is_degenerate());
00198     CGAL_assertion(!s2.is_degenerate());
00199     if ( orientation( s1.source(), s1.point(1), s2.source(), s2.target()) 
00200          != COPLANAR)
00201       // the segments doesn't define a plane
00202       return false;
00203     if ( s1.has_on(s2.source()) || s1.has_on(s2.target()) ||
00204          s2.has_on(s1.source()))
00205       // the segments does intersect at one endpoint 
00206       return false;
00207     Line_3 ls1(s1), ls2(s2);
00208     if ( ls1.direction() ==  ls2.direction() ||
00209          ls1.direction() == -ls2.direction() )
00210       // the segments are parallel 
00211       return false;
00212     Vector_3 vs1(s1.to_vector()), vs2(s2.to_vector()), 
00213       vt(cross_product( vs1, vs2)), 
00214       ws1(cross_product( vt, vs1)); // , ws2(cross_product( vt, vs2));
00215     Plane_3 hs1( s1.source(), ws1);
00216     Object o = intersection(hs1, ls2);
00217     CGAL_assertion(CGAL::assign( p, o));
00218     // since line(s1) and line(s2) are not parallel they intersects in only
00219     //   one point 
00220     CGAL::assign( p ,o);
00221     Plane_3 pl(s1.source(), vs1);
00222     if(pl.oriented_side(p) != CGAL::POSITIVE)
00223       return false;
00224     pl = Plane_3(s2.source(), vs2);
00225     if(pl.oriented_side(p) != CGAL::POSITIVE)
00226       return false;
00227     pl = Plane_3(s2.target(), vs2);
00228     return (pl.oriented_side(p) == CGAL::NEGATIVE);
00229   }
00230     
00231 #endif // LINE3_LINE3_INTERSECTION
00232 
00233   bool does_intersect( const Ray_3& r, const Triangle_3& tr,
00234                        Point_3& ip) const {
00235     // Intersection between an open ray and
00236     // a closed 2d-triangular region in the space
00237     CGAL_NEF_TRACEN("-> Intersection triangle - ray");
00238     CGAL_NEF_TRACEN(" -> Ray: "<<r);
00239     CGAL_NEF_TRACEN(" -> Triangle: "<<tr);
00240     CGAL_assertion( !r.is_degenerate());
00241     Plane_3 h( tr.supporting_plane());
00242     CGAL_assertion( !h.is_degenerate());
00243     if( h.has_on( r.source()))
00244       return false;
00245     Object o = intersection( h, r);
00246     if( !CGAL::assign( ip, o))
00247       return false;
00248     CGAL_NEF_TRACEN(" -> intersection point: "<<ip);
00249     return tr.has_on(ip);
00250   }
00251 
00252   bool does_intersect( const Segment_3& s, const Triangle_3& tr,
00253                        Point_3& ip) const {
00254     // Intersection between a open segment and
00255     // a closed 2d-triangular region in the space
00256     CGAL_NEF_TRACEN("-> Intersection triangle - segment");
00257     CGAL_NEF_TRACEN(" -> Segment: "<<s);
00258     CGAL_NEF_TRACEN(" -> Triangle: "<<tr);
00259     CGAL_assertion( !s.is_degenerate());
00260     Plane_3 h( tr.supporting_plane());
00261     CGAL_assertion( !h.is_degenerate());
00262     if( h.has_on( s.source()) || h.has_on( s.target()))
00263       return false;
00264     Object o = intersection( h, s);
00265     if( !CGAL::assign( ip, o))
00266       return false;
00267     CGAL_NEF_TRACEN(" -> intersection point: "<<ip);
00268     return tr.has_on(ip);
00269   }
00270 
00271   bool does_intersect_internally( const Ray_3& ray,
00272                                   Halffacet_const_handle f,
00273                                   Point_3& p,
00274                                   bool checkHasOn = true) const { 
00275     CGAL_NEF_TRACEN("-> Intersection facet - ray");
00276     Plane_3 h( f->plane());
00277     CGAL_NEF_TRACEN("-> facet's plane: " << h);
00278     CGAL_NEF_TRACEN("-> a point on the plane: " << h.point());
00279     CGAL_NEF_TRACEN("-> ray: " << ray);
00280     CGAL_assertion(!ray.is_degenerate());
00281     if(checkHasOn) {
00282       if(h.has_on(ray.source()))
00283         return false;
00284     } else
00285       CGAL_assertion(!h.has_on(ray.source()));
00286     Object o = intersection( h, ray);
00287     if( !CGAL::assign( p, o))
00288       return false;
00289     CGAL_NEF_TRACEN( "-> intersection point: " << p );
00290     CGAL_NEF_TRACEN( "-> point in facet interior? "<<does_contain_internally( f, p));
00291     return does_contain_internally( f, p, false);
00292   }
00293 
00294 #ifdef CGAL_NEF3_FACET_WITH_BOX
00295   bool does_intersect_internally( const Ray_3& ray,
00296                                   Partial_facet pf,
00297                                   Point_3& p) const { 
00298     CGAL_NEF_TRACEN("-> Intersection facet - ray");
00299     Plane_3 h( pf.f->plane());
00300     CGAL_NEF_TRACEN("-> facet's plane: " << h);
00301     CGAL_NEF_TRACEN("-> a point on the plane: " << h.point());
00302     CGAL_NEF_TRACEN("-> ray: " << ray);
00303     CGAL_assertion(!ray.is_degenerate());
00304     if( h.has_on( ray.source()))
00305       /* no possible internal intersection */
00306         return false;
00307     Object o = intersection( h, ray);
00308     if( !CGAL::assign( p, o))
00309       return false;
00310     CGAL_NEF_TRACEN( "-> intersection point: " << p );
00311     //    CGAL_NEF_TRACEN( "-> point in facet interior? "<<does_contain_internally( f, p));
00312     return does_contain_internally( pf, p, false);
00313   }
00314 #endif
00315 
00316   bool does_intersect_internally( const Segment_3& seg,
00317                                   Halffacet_const_handle f,
00318                                   Point_3& p) const { 
00319     CGAL_NEF_TRACEN("-> Intersection facet - segment");
00320     Plane_3 h( f->plane());
00321     CGAL_NEF_TRACEN("-> facet's plane: " << h);
00322     CGAL_NEF_TRACEN("-> a point on the plane: " << h.point());
00323     CGAL_NEF_TRACEN("-> segment: " << seg);
00324     CGAL_assertion(!seg.is_degenerate());
00325     if( h.has_on( seg.source()) || h.has_on(seg.target()))
00326       /* no possible internal intersection */
00327       return false;
00328     return does_intersect(seg, f, p);
00329   }
00330 
00331   bool does_intersect(const Segment_3& seg,
00332                       Halffacet_const_handle f,
00333                       Point_3& p) const {
00334     Plane_3 h( f->plane());
00335     Object o = intersection( h, seg);
00336     if( !CGAL::assign( p, o))
00337       return false;
00338     CGAL_NEF_TRACEN( "-> intersection point: " << p );
00339     CGAL_NEF_TRACEN( "-> point in facet interior? "<<does_contain_internally( f, p));
00340     return( does_contain_internally( f, p, false));
00341   }
00342 
00343 #ifdef CGAL_NEF3_FACET_WITH_BOX
00344   bool does_intersect_internally( const Segment_3& seg,
00345                                   Partial_facet pf,
00346                                   Point_3& p) const { 
00347     CGAL_NEF_TRACEN("-> Intersection partial facet - segment");
00348     Plane_3 h( pf.f->plane());
00349     CGAL_NEF_TRACEN("-> facet's plane: " << h);
00350     CGAL_NEF_TRACEN("-> a point on the plane: " << h.point());
00351     CGAL_NEF_TRACEN("-> segment: " << seg);
00352     CGAL_assertion(!seg.is_degenerate());
00353     if( h.has_on( seg.source()) || h.has_on(seg.target()))
00354       /* no possible internal intersection */
00355       return false;
00356     Object o = intersection( h, seg);
00357     if( !CGAL::assign( p, o))
00358       return false;
00359     CGAL_NEF_TRACEN( "-> intersection point: " << p );
00360     //    CGAL_NEF_TRACEN( "-> point in facet interior? "<<does_contain_internally( f, p));
00361     return( does_contain_internally( pf, p, false));
00362   }
00363 #endif
00364 
00365   Bounded_side locate_point_in_halffacet( const Point_3& p, 
00366                                           Halffacet_const_handle f) const {
00367     CGAL_NEF_TRACEN("locate point in halffacet " << p << ", " << f->plane());
00368     typedef Project_shalfedge_point
00369       < SHalfedge, const Point_3> Project;
00370     typedef Circulator_project
00371       < SHalfedge_around_facet_const_circulator, Project, 
00372       const Point_3&, const Point_3*> Circulator;
00373     typedef Container_from_circulator<Circulator> Container;
00374 
00375     Plane_3 h(f->plane());
00376     CGAL_assertion(h.has_on(p));
00377     Halffacet_cycle_const_iterator fc = f->facet_cycles_begin();
00378     Bounded_side outer_bound_pos(CGAL::ON_BOUNDARY);
00379     if (fc.is_shalfedge() ) {
00380       SHalfedge_const_handle se(fc);
00381       SHalfedge_around_facet_const_circulator hfc(se);
00382       Circulator c(hfc);
00383       Container ct(c);
00384       CGAL_assertion( !is_empty_range(ct.begin(), ct.end()));
00385       outer_bound_pos = bounded_side_3(ct.begin(), ct.end(), p, h);
00386     } 
00387     else 
00388       CGAL_error_msg( "is facet first cycle a SHalfloop?");
00389     if( outer_bound_pos != CGAL::ON_BOUNDED_SIDE )
00390       return outer_bound_pos;
00391     /* The point p is not in the relative interior of the outer face cycle
00392        so it is not necesary to know the possition of p with respect to the 
00393        inner face cycles */
00394     Halffacet_cycle_const_iterator fe = f->facet_cycles_end();
00395     ++fc;
00396     if( fc == fe )
00397       return outer_bound_pos;
00398     Bounded_side inner_bound_pos(CGAL::ON_BOUNDARY);
00399     CGAL_For_all(fc, fe) {
00400       if (fc.is_shalfloop() ) {
00401         SHalfloop_const_handle l(fc);
00402         if(l->incident_sface()->center_vertex()->point() == p )
00403           inner_bound_pos = CGAL::ON_BOUNDARY;
00404         else
00405           inner_bound_pos = CGAL::ON_UNBOUNDED_SIDE;
00406       } 
00407       else if (fc.is_shalfedge() ) {
00408         SHalfedge_const_handle se(fc);
00409         SHalfedge_around_facet_const_circulator hfc(se);
00410         Circulator c(hfc);
00411         Container ct(c);
00412         CGAL_assertion( !is_empty_range(ct.begin(), ct.end()));
00413         inner_bound_pos = bounded_side_3( ct.begin(), ct.end(), 
00414                                           p, h.opposite());
00415       } 
00416       else 
00417         CGAL_error_msg( "Damn wrong handle.");
00418       if( inner_bound_pos != CGAL::ON_UNBOUNDED_SIDE )
00419         return opposite(inner_bound_pos);
00420       /* At this point the point p belongs to relative interior of the facet's
00421          outer cycle, and its possition is completely known when it belongs
00422          to the clousure of any inner cycle */
00423     }
00424     return CGAL::ON_BOUNDED_SIDE;
00425   }
00426 
00427 #ifdef CGAL_NEF3_FACET_WITH_BOX
00428   Bounded_side locate_point_in_halffacet( const Point_3& p, 
00429                                          Partial_facet pf) const {
00430 
00431     if(p.x() < pf.f->b.min_coord(0) || p.x() > pf.f->b.max_coord(0) ||
00432        p.y() < pf.f->b.min_coord(1) || p.y() > pf.f->b.max_coord(1) ||
00433        p.z() < pf.f->b.min_coord(2) || p.z() > pf.f->b.max_coord(2))
00434       return CGAL::ON_UNBOUNDED_SIDE;
00435     
00436     typedef Project_shalfedge_point
00437       < SHalfedge, Point_3> Project;
00438     typedef Circulator_project
00439       < SHalfedge_around_facet_const_circulator, Project, 
00440       const Point_3&, const Point_3*> Circulator;
00441     typedef Container_from_circulator<Circulator> Container;
00442 
00443     typedef typename Partial_facet::Outer_cycle_iterator  Outer_cycle_iterator;
00444     typedef typename Partial_facet::Inner_cycle_iterator  Inner_cycle_iterator;
00445     typedef typename Partial_facet::Isolated_vertex_iterator Isolated_vertex_iterator;
00446 
00447     Plane_3 h(pf.f->plane());
00448     CGAL_assertion(h.has_on(p));
00449     
00450     Bounded_side outer_bound_pos(CGAL::ON_BOUNDED_SIDE);
00451 
00452     Outer_cycle_iterator oc = pf.outer_cycles_begin();
00453     while(oc != pf.outer_cycles_end() && 
00454           outer_bound_pos == CGAL::ON_BOUNDED_SIDE) {
00455       if(oc->first == oc->second) {
00456         SHalfedge_around_facet_const_circulator hfc(oc->first);
00457         Circulator c(hfc);
00458         Container ct(c);
00459         CGAL_assertion( !is_empty_range(ct.begin(), ct.end()));
00460         outer_bound_pos = bounded_side_3(ct.begin(), ct.end(), p, h);   
00461       } else {
00462         outer_bound_pos = bounded_side_3(Circulator(SHalfedge_around_facet_const_circulator(oc->first)), 
00463                                          Circulator(SHalfedge_around_facet_const_circulator(oc->second)), p, h);
00464       }
00465       ++oc;
00466     }
00467     if(outer_bound_pos != CGAL::ON_BOUNDED_SIDE )
00468       return outer_bound_pos;    
00469 
00470     Bounded_side inner_bound_pos(CGAL::ON_UNBOUNDED_SIDE);
00471 
00472     Inner_cycle_iterator ic = pf.inner_cycles_begin();
00473     while(ic != pf.inner_cycles_end() && 
00474           inner_bound_pos == CGAL::ON_UNBOUNDED_SIDE) {
00475       if(ic->first == ic->second) {
00476         SHalfedge_around_facet_const_circulator hfc(ic->first);
00477         Circulator c(hfc);
00478         Container ct(c);
00479         CGAL_assertion( !is_empty_range(ct.begin(), ct.end()));
00480         inner_bound_pos = bounded_side_3(ct.begin(), ct.end(), p, h);   
00481       } else {
00482         inner_bound_pos = bounded_side_3(Circulator(SHalfedge_around_facet_const_circulator(ic->first)), 
00483                                          Circulator(SHalfedge_around_facet_const_circulator(ic->second)), p, h);
00484       }
00485       ++ic;
00486     }
00487     if(inner_bound_pos != CGAL::ON_UNBOUNDED_SIDE )
00488       return opposite(inner_bound_pos);
00489     
00490     Isolated_vertex_iterator iv = pf.isolated_vertices_begin();
00491     while(iv != pf.isolated_vertices_end()) {
00492       if(*iv == p)
00493         return CGAL::ON_BOUNDARY;
00494       ++iv;
00495     }
00496    
00497     return CGAL::ON_BOUNDED_SIDE;
00498   }
00499 #endif
00500 }; // SNC_intersection
00501 
00502 CGAL_END_NAMESPACE
00503 
00504 #endif //CGAL_SNC_INTERSECTION_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines