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
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
00068
00069
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
00093
00094
00095
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
00114
00115
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
00156
00157
00158
00159
00160
00161
00162
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