Main Page   Modules   Namespace List   Compound List   File List   Namespace Members   Compound Members  

Segment_3_Triangle_3.C

00001 #include <CEP/intersection/Segment_3_Segment_3.h>
00002 #include <CEP/intersection/Segment_3_Triangle_3.h>
00003 #include <CEP/intersection/Triangle_3_Point_3.h>
00004 #include <CEP/intersection/Halfplane_3.h>
00005 
00006 #include <CGAL/Plane_3.h>
00007 #include <CGAL/predicates_on_points_3.h>
00008 #include <CGAL/intersection_3.h>
00009 
00010 
00011 namespace CEP {  
00012 namespace intersection {
00013 
00014     using CGAL::Segment_3;
00015     using CGAL::Triangle_3;
00016     using CGAL::Plane_3;
00017 
00018     using CGAL::assign;
00019     using CGAL::orientation;
00020 
00021 
00027     template <class R>
00028     bool
00029     coplanar_do_intersect( const Segment_3<R>& segment, 
00030                            const Triangle_3<R>& triangle )
00031     {
00032         CGAL_exactness_precondition( !triangle.is_degenerate() );
00033         CGAL_exactness_precondition( CGAL::coplanar( triangle[0],
00034                                                      triangle[1],
00035                                                      triangle[2],
00036                                                      segment.source() ) );
00037         CGAL_exactness_precondition( CGAL::coplanar( triangle[0],
00038                                                      triangle[1],
00039                                                      triangle[2],
00040                                                      segment.target() ) );
00041 
00042         // Check the segment against each triangle edge.
00043 
00044         return 
00045             coplanar_do_intersect( segment, Segment_3<R>(triangle[0],triangle[1]) )
00046          || coplanar_do_intersect( segment, Segment_3<R>(triangle[1],triangle[2]) )
00047          || coplanar_do_intersect( segment, Segment_3<R>(triangle[2],triangle[0]) )
00048          || triangle.has_on( segment.source() );
00049     }
00050 
00051 
00057     template <class R>
00058     CGAL::Object
00059     coplanar_intersection( const Segment_3<R>& segment, 
00060                            const Triangle_3<R>& T )
00061     {
00062         CGAL_exactness_precondition( !T.is_degenerate() );
00063         CGAL_exactness_precondition( CGAL::coplanar( T[0], T[1], T[2],
00064                                                      segment.source() ) );
00065         CGAL_exactness_precondition( CGAL::coplanar( T[0], T[1], T[2],
00066                                                      segment.target() ) );
00067         // Clip the segment with a halfplane through
00068         // each triangle edge.
00069         //using CEP::intersection::Halfplane_3_Segment_3::coplanar_intersection;
00070 
00071         CGAL::Object obj = CEP::intersection::Halfplane_3_Segment_3::coplanar_intersection( T[0], T[1], T[2], segment );
00072         if ( obj.is_empty() )    return obj;
00073         Segment_3<R> seg;
00074         bool intersection_is_segment = assign( seg, obj );
00075         CGAL_assertion( intersection_is_segment );
00076 
00077         obj = CEP::intersection::Halfplane_3_Segment_3::coplanar_intersection( T[1], T[2], T[0], seg );
00078         if ( obj.is_empty() )    return obj;
00079         intersection_is_segment = assign( seg, obj );
00080         CGAL_assertion( intersection_is_segment );
00081 
00082         return CEP::intersection::Halfplane_3_Segment_3::coplanar_intersection( T[2], T[0], T[1], seg );
00083     }
00084 
00085 
00087     template <class R>
00088     bool
00089     do_intersect( const Segment_3<R>& segment, 
00090                   const Triangle_3<R>& triangle )
00091     {
00092         // If the triangle is degenerate then we treat it as a
00093         // segment/segment intersection.  In a degenerate triangle any
00094         // edge will be contained in the union of the other two edges,
00095         // so it suffices to check only two edges of the triangle.
00096         if ( triangle.is_degenerate() )
00097         {
00098             return 
00099                 do_intersect( segment, Segment_3<R>(triangle[0],triangle[1]) )
00100              || do_intersect( segment, Segment_3<R>(triangle[1],triangle[2]) );
00101         }
00102 
00103         CGAL::Orientation or_source = orientation( triangle[0],
00104                                                    triangle[1],
00105                                                    triangle[2],
00106                                                    segment.source() );
00107 
00108         CGAL::Orientation or_target = orientation( triangle[0],
00109                                                    triangle[1],
00110                                                    triangle[2],
00111                                                    segment.target() );
00112 
00113         // For the case that the segment endpoints lie on opposite
00114         // sides of the triangle's supporting plane, we need to know
00115         // which is on the positive side and which on the negative side.
00116         Point_3<R> pos;
00117         Point_3<R> neg;
00118 
00119         switch( or_source ) {
00120         case CGAL::NEGATIVE:
00121             switch( or_target ) {
00122             case CGAL::NEGATIVE:
00123                 return false;
00124             case CGAL::COPLANAR:
00125                 return do_intersect( triangle, segment.target() );
00126             case CGAL::POSITIVE:
00127                 pos = segment.target();
00128                 neg = segment.source();
00129                 break;
00130             }
00131             break;
00132         case CGAL::COPLANAR:
00133             switch( or_target ) {
00134             case CGAL::NEGATIVE:
00135                 return do_intersect( triangle, segment.source() );
00136             case CGAL::COPLANAR:
00137                 return coplanar_do_intersect( segment, triangle );
00138             case CGAL::POSITIVE:
00139                 return do_intersect( triangle, segment.source() );
00140             }
00141         case CGAL::POSITIVE:
00142             switch( or_target ) {
00143             case CGAL::NEGATIVE:
00144                 pos = segment.source();
00145                 neg = segment.target();
00146                 break;
00147             case CGAL::COPLANAR:
00148                 return do_intersect( triangle, segment.target() );
00149             case CGAL::POSITIVE:
00150                 return false;
00151             }
00152             break;
00153         }
00154 
00155         // We are left with the case that point neg is strictly on
00156         // the negative side of the (plane supporting the) triangle,
00157         // while point pos is strictly on the positive side.
00158         // Consider the three-sided cone with apex at neg, and
00159         // passing through the three edges of the triangle.  The
00160         // intersection of the segment (neg,pos) with the triangle's
00161         // supporting plane is on the triangle if, and only if, point
00162         // pos is inside the cone (including the bounding planes).
00163 
00164         return 
00165             orientation( neg, triangle[0], triangle[1], pos ) != CGAL::NEGATIVE
00166          && orientation( neg, triangle[1], triangle[2], pos ) != CGAL::NEGATIVE
00167          && orientation( neg, triangle[2], triangle[0], pos ) != CGAL::NEGATIVE;
00168     }   
00169 
00170 
00172 
00174     template <class R>
00175     CGAL::Object
00176     intersection( const Segment_3<R>& segment, 
00177                   const Triangle_3<R>& T )
00178     {
00179         CGAL_exactness_precondition( !T.is_degenerate() );
00180 
00181         Plane_3<R> plane = T.supporting_plane();
00182         CGAL::Object obj = CGAL::intersection( plane, segment );
00183 
00184         if ( obj.is_empty() )    return obj;
00185 
00186         Segment_3<R> s;
00187         if ( assign(s, obj) ) {
00188             CGAL_assertion( s == segment );
00189             return coplanar_intersection( segment, T );
00190         }
00191 
00192         Point_3<R> p;
00193         bool intersection_is_point = assign( p, obj );
00194         CGAL_assertion( intersection_is_point );
00195         if ( T.has_on(p) )
00196             return CGAL::make_object(p);
00197         return CGAL::Object();
00198     }
00199 
00200 }
00201 }
00202 

Generated on Sun Jun 8 17:38:22 2003 for CEP::intersection by doxygen1.3-rc3