47     namespace Intersection
    52             bool does_plane_intersect_plane;
    53             Geometry::Line3D inter;
    54             std::tie( does_plane_intersect_plane, inter ) =
    56             if( !does_plane_intersect_plane )
    58                 return std::make_tuple( 
false, std::vector< vec3 >() );
    70             double a1{ dot( diff, inter.direction ) };
    71             double a0{ diff.length2() - circle.
radius * circle.
radius };
    73             double discr{ a1 * a1 - a0 };
    76                 return std::make_tuple( 
false, std::vector< vec3 >() );
    79             std::vector< vec3 > result;
    80             if( discr < global_epsilon )
    82                 result.emplace_back( inter.origin - a1 * inter.direction );
    86                 double root{ std::sqrt( discr ) };
    88                     inter.origin - ( a1 + root ) * inter.direction );
    90                     inter.origin - ( a1 - root ) * inter.direction );
    92             return std::make_tuple( 
true, result );
   120             if( std::fabs( std::fabs( norm_d ) - 1 ) < global_epsilon )
   122                 return std::make_tuple( 
false, Geometry::Line3D{} );
   125             double invDet{ 1.0 / ( 1.0 - norm_d * norm_d ) };
   128             double c0{ ( const_P0 - norm_d * const_P1 ) * invDet };
   129             double c1{ ( const_P1 - norm_d * const_P0 ) * invDet };
   132             return std::make_tuple(
   133                 true, Geometry::Line3D{ D_inter, O_inter } );
   137             const Geometry::Line2D& line0, 
const Geometry::Line2D& line1 )
   150             vec2 diff{ line1.origin - line0.origin };
   151             double D0DotPerpD1{ 
dot_perp( line0.direction, line1.direction ) };
   152             if( std::fabs( D0DotPerpD1 ) < global_epsilon )
   155                 return std::make_tuple( 
false, 
vec2() );
   158             double invD0DotPerpD1{ 1.0 / D0DotPerpD1 };
   159             double diffDotPerpD1{ 
dot_perp( diff, line1.direction ) };
   160             double s0{ diffDotPerpD1 * invD0DotPerpD1 };
   161             vec2 result{ line0.origin + s0 * line0.direction };
   162             return std::make_tuple( 
true, result );
   166             const Geometry::Segment2D& segment0,
   167             const Geometry::Segment2D& segment1 )
   169             bool does_segment_intersect_segment;
   170             vec2 line_intersection_result;
   172                 does_segment_intersect_segment, line_intersection_result ) =
   174                     Geometry::Line2D{ segment1 } );
   175             if( does_segment_intersect_segment )
   179                     segment0.p0, segment1 ) };
   181                     segment0.p1, segment1 ) };
   182                 if( s0_seg0 != 
ZERO && ( s0_seg0 == s1_seg0 ) )
   184                     return std::make_tuple( 
false, 
vec2() );
   187                     segment1.p0, segment0 ) };
   189                     segment1.p1, segment0 ) };
   190                 if( s0_seg1 != 
ZERO && ( s0_seg1 == s1_seg1 ) )
   192                     return std::make_tuple( 
false, 
vec2() );
   195                 if( s0_seg0 == 
ZERO || s1_seg0 == 
ZERO   196                     || ( s0_seg0 != s1_seg0 ) )
   198                     if( s0_seg1 == 
ZERO || s1_seg1 == 
ZERO   199                         || ( s0_seg1 != s1_seg1 ) )
   201                         return std::make_tuple(
   202                             true, line_intersection_result );
   206             return std::make_tuple( 
false, 
vec2() );
   210             const Geometry::Segment2D& segment, 
const Geometry::Line2D& line )
   212             bool does_segment_intersect_line;
   213             vec2 line_intersection_result;
   214             std::tie( does_segment_intersect_line, line_intersection_result ) =
   215                 line_line( Geometry::Line2D{ segment }, line );
   216             if( does_segment_intersect_line )
   219                 Geometry::Segment2D line_segment{ { line_intersection_result
   221                     { line_intersection_result + line.direction } };
   223                     segment.p0, line_segment ) };
   225                     segment.p1, line_segment ) };
   226                 if( s0 == 
ZERO || s1 == 
ZERO || ( s0 != s1 ) )
   228                     return std::make_tuple( 
true, line_intersection_result );
   231             return std::make_tuple( 
false, 
vec2() );
   237             double dot_directions{ dot( line.direction, plane.
normal ) };
   238             if( std::fabs( dot_directions ) > global_epsilon )
   240                 double signed_distance{ dot( plane.
normal, line.origin )
   242                 vec3 result{ line.origin
   243                              - signed_distance * line.direction
   245                 return std::make_tuple( 
true, result );
   248             return std::make_tuple( 
false, 
vec3() );
   254             bool does_line_intersect_plane;
   255             vec3 line_plane_result;
   256             std::tie( does_line_intersect_plane, line_plane_result ) =
   257                 line_plane( Geometry::Line3D{ segment }, plane );
   258             if( does_line_intersect_plane )
   261                         line_plane_result, segment ) )
   264                     return std::make_tuple( 
true, line_plane_result );
   266                 return std::make_tuple( 
false, 
vec3() );
   268             return std::make_tuple( 
false, 
vec3() );
   274             bool does_segment_intersect_plane{ 
false };
   275             vec3 segment_plane_result;
   276             std::tie( does_segment_intersect_plane, segment_plane_result ) =
   278             if( does_segment_intersect_plane )
   280                 if( ( segment_plane_result - disk.
plane.
origin ).length()
   283                     return std::make_tuple( 
true, segment_plane_result );
   286             return std::make_tuple( 
false, 
vec3() );
   290             const Geometry::Triangle3D& triangle,
   293             bool does_circle_intersect_plane{ 
false };
   294             std::vector< vec3 > inter_circle_plane;
   295             std::tie( does_circle_intersect_plane, inter_circle_plane ) =
   297             std::vector< vec3 > result;
   298             if( does_circle_intersect_plane )
   300                 for( 
const vec3& p : inter_circle_plane )
   304                         result.push_back( p );
   308             return std::make_tuple( !result.empty(), result );
   312             const Geometry::Segment3D& segment,
   313             const Geometry::Triangle3D& triangle )
   317             vec3 seg_center{ segment.barycenter() };
   318             vec3 diff{ seg_center - triangle.p0 };
   319             vec3 edge1{ triangle.p1 - triangle.p0 };
   320             vec3 edge2{ triangle.p2 - triangle.p0 };
   321             vec3 normal{ cross( edge1, edge2 ) };
   328             vec3 D{ segment.direction() };
   329             double DdN{ dot( D, normal ) };
   331             if( DdN > global_epsilon )
   335             else if( DdN < -global_epsilon )
   345                 return std::make_tuple( 
false, 
vec3() );
   348             double DdQxE2{ sign * dot( D, cross( diff, edge2 ) ) };
   351                 double DdE1xQ{ sign * dot( D, cross( edge1, diff ) ) };
   354                     if( DdQxE2 + DdE1xQ <= DdN )
   357                         double QdN{ -sign * dot( diff, normal ) };
   358                         double extDdN{ segment.length() * DdN / 2. };
   359                         if( -extDdN <= QdN && QdN <= extDdN )
   362                             double inv{ 1. / DdN };
   363                             double seg_parameter{ QdN * inv };
   365                             vec3 result{ seg_center + seg_parameter * D };
   366                             return std::make_tuple( 
true, result );
   375             return std::make_tuple( 
false, 
vec3() );
   387             double a0{ dot( diff, diff ) - sphere.
radius * sphere.
radius };
   388             double a1{ dot( line.direction, diff ) };
   391             double discr{ a1 * a1 - a0 };
   392             std::vector< vec3 > results;
   393             if( discr > global_epsilon )
   395                 double root{ std::sqrt( discr ) };
   396                 results.reserve( 2 );
   397                 results.emplace_back(
   398                     line.origin + ( -a1 - root ) * line.direction );
   399                 results.emplace_back(
   400                     line.origin + ( -a1 + root ) * line.direction );
   402             else if( discr > -global_epsilon )
   404                 results.reserve( 1 );
   405                 results.emplace_back( line.origin + -a1 * line.direction );
   407             return std::make_tuple( !results.empty(), results );
   414             std::vector< vec3 > line_intersections;
   415             std::tie( line_intersect, line_intersections ) =
   416                 line_sphere( Geometry::Line3D{ segment }, sphere );
   418             std::vector< vec3 > segment_intersections;
   421                 segment_intersections.reserve( line_intersections.size() );
   422                 for( 
auto& point : line_intersections )
   426                         segment_intersections.emplace_back( point );
   430             return std::make_tuple(
   431                 !segment_intersections.empty(), segment_intersections );
 
double RINGMESH_API dot_perp(const vec2 &v0, const vec2 &v1)
 
bool RINGMESH_API point_inside_segment(const Geometry::Point3D &point, const Geometry::Segment3D &segment)
Tests if a point is on a segment. 
 
std::tuple< bool, vec3 > RINGMESH_API segment_disk(const Geometry::Segment3D &segment, const Geometry::Disk &disk)
 
std::tuple< bool, vec2 > RINGMESH_API segment_line(const Geometry::Segment2D &segment, const Geometry::Line2D &line)
 
std::tuple< bool, Geometry::Line3D > RINGMESH_API plane_plane(const Geometry::Plane &plane0, const Geometry::Plane &plane1)
 
std::tuple< bool, std::vector< vec3 > > RINGMESH_API line_sphere(const Geometry::Line3D &line, const Geometry::Sphere &sphere)
 
Sign RINGMESH_API point_side_to_segment(const Geometry::Point2D &point, const Geometry::Segment2D &segment)
 
std::tuple< bool, std::vector< vec3 > > RINGMESH_API triangle_circle(const Geometry::Triangle3D &triangle, const Geometry::Circle &circle)
 
std::tuple< bool, vec3 > RINGMESH_API segment_plane(const Geometry::Segment3D &segment, const Geometry::Plane &plane)
 
std::tuple< bool, std::vector< vec3 > > RINGMESH_API segment_sphere(const Geometry::Segment3D &segment, const Geometry::Sphere &sphere)
 
std::tuple< bool, vec3 > RINGMESH_API segment_triangle(const Geometry::Segment3D &segment, const Geometry::Triangle3D &triangle)
 
double plane_constant() const
 
bool point_inside_triangle(const Geometry::Point< DIMENSION > &point, const Geometry::Triangle< DIMENSION > &triangle)
Tests if a point is inside a triangle. 
 
std::tuple< bool, vec2 > RINGMESH_API line_line(const Geometry::Line2D &line0, const Geometry::Line2D &line1)
 
std::tuple< bool, vec2 > RINGMESH_API segment_segment(const Geometry::Segment2D &segment0, const Geometry::Segment2D &segment1)
 
Classes to build GeoModel from various inputs. 
 
std::tuple< bool, vec3 > RINGMESH_API line_plane(const Geometry::Line3D &line, const Geometry::Plane &plane)
 
std::tuple< bool, std::vector< vec3 > > RINGMESH_API circle_plane(const Geometry::Circle &circle, const Geometry::Plane &plane)