mirror of https://github.com/CGAL/cgal
modify the internal do_intersect Ray_3 vs Triangle_3 function
to be able to known whether the endpoint of the ray lies inside the plane of the triangle. The running time is the public do_intersect function should remain the same.
This commit is contained in:
parent
e9372eb7ae
commit
b058a2a4f3
|
|
@ -25,15 +25,45 @@ namespace CGAL {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template <class K>
|
struct r3t3_do_intersect_empty_visitor{
|
||||||
bool do_intersect_coplanar(const typename K::Triangle_3 &t,
|
typedef bool result_type;
|
||||||
const typename K::Ray_3 &r,
|
result_type result(bool b){return b;}
|
||||||
const K & k );
|
void update(Orientation){}
|
||||||
|
};
|
||||||
|
|
||||||
template <class K>
|
struct r3t3_do_intersect_endpoint_position_visitor{
|
||||||
bool do_intersect(const typename K::Triangle_3 &t,
|
bool m_endpoint_outside_triangle_plane;
|
||||||
const typename K::Ray_3 &r,
|
r3t3_do_intersect_endpoint_position_visitor():
|
||||||
const K & k)
|
m_endpoint_outside_triangle_plane(true){}
|
||||||
|
typedef std::pair<bool,bool> result_type;
|
||||||
|
result_type result(bool b){return std::make_pair(b,m_endpoint_outside_triangle_plane);}
|
||||||
|
void update(Orientation orient)
|
||||||
|
{
|
||||||
|
m_endpoint_outside_triangle_plane &= orient!=ZERO;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//the template parameter Visitor here is used to offer the posibility to use
|
||||||
|
//r3t3_do_intersect_endpoint_position_visitor to track whether the endpoint of
|
||||||
|
//the ray lies inside the plane of the triangle or not. It is used for example
|
||||||
|
//in the function that checks whether a point is inside a polyhedron; if the ray
|
||||||
|
//is on an edge of the triangle, we should try with another random ray as this case does
|
||||||
|
//happen often in practise.
|
||||||
|
//By default an empty visitor is used to avoid penalizing the running time.
|
||||||
|
|
||||||
|
template <class K,class Visitor>
|
||||||
|
typename Visitor::result_type
|
||||||
|
do_intersect_coplanar(const typename K::Triangle_3 &t,
|
||||||
|
const typename K::Ray_3 &r,
|
||||||
|
const K & k,
|
||||||
|
Visitor visitor);
|
||||||
|
|
||||||
|
template <class K,class Visitor>
|
||||||
|
typename Visitor::result_type
|
||||||
|
do_intersect(const typename K::Triangle_3 &t,
|
||||||
|
const typename K::Ray_3 &r,
|
||||||
|
const K & k,
|
||||||
|
Visitor visitor)
|
||||||
{
|
{
|
||||||
|
|
||||||
CGAL_kernel_precondition( ! k.is_degenerate_3_object()(t) ) ;
|
CGAL_kernel_precondition( ! k.is_degenerate_3_object()(t) ) ;
|
||||||
|
|
@ -70,8 +100,8 @@ bool do_intersect(const typename K::Triangle_3 &t,
|
||||||
|
|
||||||
if (ray_direction == COPLANAR ) {
|
if (ray_direction == COPLANAR ) {
|
||||||
if (orientation(a,b,c,p) == COPLANAR)
|
if (orientation(a,b,c,p) == COPLANAR)
|
||||||
return do_intersect_coplanar(t,r,k);
|
return do_intersect_coplanar(t,r,k,visitor);
|
||||||
else return false;
|
else return visitor.result(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Orientation abcp = orientation(a,b,c,p);
|
const Orientation abcp = orientation(a,b,c,p);
|
||||||
|
|
@ -82,73 +112,98 @@ bool do_intersect(const typename K::Triangle_3 &t,
|
||||||
case POSITIVE:
|
case POSITIVE:
|
||||||
// the ray lies in the positive open halfspaces defined by the
|
// the ray lies in the positive open halfspaces defined by the
|
||||||
// triangle's supporting plane
|
// triangle's supporting plane
|
||||||
return false;
|
return visitor.result(false);
|
||||||
|
|
||||||
case NEGATIVE:
|
case NEGATIVE:{
|
||||||
// The ray straddles the triangle's plane
|
// The ray straddles the triangle's plane
|
||||||
// p sees the triangle in counterclockwise order
|
// p sees the triangle in counterclockwise order
|
||||||
|
Orientation
|
||||||
return orientation(p,q,a,b) != POSITIVE
|
orient=orientation(p,q,a,b);
|
||||||
&& orientation(p,q,b,c) != POSITIVE
|
if (orient == POSITIVE ) return visitor.result(false);
|
||||||
&& orientation(p,q,c,a) != POSITIVE;
|
visitor.update(orient);
|
||||||
|
orient=orientation(p,q,b,c);
|
||||||
// case COPLANAR: should not happen
|
if (orient == POSITIVE ) return visitor.result(false);
|
||||||
|
visitor.update(orient);
|
||||||
|
orient=orientation(p,q,c,a);
|
||||||
|
if (orient == POSITIVE ) return visitor.result(false);
|
||||||
|
visitor.update(orient);
|
||||||
|
return visitor.result(true);
|
||||||
|
}
|
||||||
|
// case COPLANAR: should not happen
|
||||||
default: // should not happen.
|
default: // should not happen.
|
||||||
CGAL_kernel_assertion(false);
|
CGAL_kernel_assertion(false);
|
||||||
return false;
|
return visitor.result(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
case NEGATIVE:
|
case NEGATIVE:
|
||||||
switch ( ray_direction ) {
|
switch ( ray_direction ) {
|
||||||
case POSITIVE:
|
case POSITIVE:{
|
||||||
// The ray straddles the triangle's plane
|
// The ray straddles the triangle's plane
|
||||||
// q sees the triangle in counterclockwise order
|
// q sees the triangle in counterclockwise order
|
||||||
|
Orientation
|
||||||
|
orient=orientation(q,p,a,b);
|
||||||
|
if (orient == POSITIVE ) return visitor.result(false);
|
||||||
|
visitor.update(orient);
|
||||||
|
orient=orientation(q,p,b,c);
|
||||||
|
if (orient == POSITIVE ) return visitor.result(false);
|
||||||
|
visitor.update(orient);
|
||||||
|
orient=orientation(q,p,c,a);
|
||||||
|
if (orient == POSITIVE ) return visitor.result(false);
|
||||||
|
visitor.update(orient);
|
||||||
|
return visitor.result(true);
|
||||||
|
|
||||||
return orientation(q,p,a,b) != POSITIVE
|
}
|
||||||
&& orientation(q,p,b,c) != POSITIVE
|
|
||||||
&& orientation(q,p,c,a) != POSITIVE;
|
|
||||||
|
|
||||||
case NEGATIVE:
|
case NEGATIVE:
|
||||||
// the ray lies in the negative open halfspaces defined by the
|
// the ray lies in the negative open halfspaces defined by the
|
||||||
// triangle's supporting plane
|
// triangle's supporting plane
|
||||||
return false;
|
return visitor.result(false);
|
||||||
|
|
||||||
// case COPLANAR: should not happen
|
// case COPLANAR: should not happen
|
||||||
|
|
||||||
default: // should not happen.
|
default: // should not happen.
|
||||||
CGAL_kernel_assertion(false);
|
CGAL_kernel_assertion(false);
|
||||||
return false;
|
return visitor.result(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
case COPLANAR: // p belongs to the triangle's supporting plane
|
case COPLANAR: // p belongs to the triangle's supporting plane
|
||||||
|
visitor.update(ZERO);
|
||||||
switch ( ray_direction ) {
|
switch ( ray_direction ) {
|
||||||
case POSITIVE:
|
case POSITIVE:
|
||||||
// q sees the triangle in counterclockwise order
|
// q sees the triangle in counterclockwise order
|
||||||
return orientation(q,p,a,b) != POSITIVE
|
return visitor.result(
|
||||||
|
orientation(q,p,a,b) != POSITIVE
|
||||||
&& orientation(q,p,b,c) != POSITIVE
|
&& orientation(q,p,b,c) != POSITIVE
|
||||||
&& orientation(q,p,c,a) != POSITIVE;
|
&& orientation(q,p,c,a) != POSITIVE);
|
||||||
|
|
||||||
case NEGATIVE:
|
case NEGATIVE:
|
||||||
// q sees the triangle in clockwise order
|
// q sees the triangle in clockwise order
|
||||||
return orientation(p,q,a,b) != POSITIVE
|
return visitor.result(
|
||||||
|
orientation(p,q,a,b) != POSITIVE
|
||||||
&& orientation(p,q,b,c) != POSITIVE
|
&& orientation(p,q,b,c) != POSITIVE
|
||||||
&& orientation(p,q,c,a) != POSITIVE;
|
&& orientation(p,q,c,a) != POSITIVE);
|
||||||
|
|
||||||
// case COPLANAR: should not happen
|
// case COPLANAR: should not happen
|
||||||
|
|
||||||
default: // should not happen.
|
default: // should not happen.
|
||||||
CGAL_kernel_assertion(false);
|
CGAL_kernel_assertion(false);
|
||||||
return false;
|
return visitor.result(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
default: // should not happen.
|
default: // should not happen.
|
||||||
CGAL_kernel_assertion(false);
|
CGAL_kernel_assertion(false);
|
||||||
return false;
|
return visitor.result(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
bool do_intersect(const typename K::Triangle_3 &t,
|
||||||
|
const typename K::Ray_3 &r,
|
||||||
|
const K & k)
|
||||||
|
{
|
||||||
|
return do_intersect(t,r,k,r3t3_do_intersect_empty_visitor());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
inline
|
inline
|
||||||
|
|
@ -160,12 +215,14 @@ bool do_intersect(const typename K::Ray_3 &r,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class K>
|
template <class K,class Visitor>
|
||||||
bool do_intersect_coplanar(const typename K::Triangle_3 &t,
|
typename Visitor::result_type
|
||||||
const typename K::Ray_3 &r,
|
do_intersect_coplanar(const typename K::Triangle_3 &t,
|
||||||
const K & k )
|
const typename K::Ray_3 &r,
|
||||||
|
const K & k,
|
||||||
|
Visitor visitor)
|
||||||
{
|
{
|
||||||
|
visitor.update(ZERO);
|
||||||
CGAL_kernel_precondition( ! k.is_degenerate_3_object()(t) ) ;
|
CGAL_kernel_precondition( ! k.is_degenerate_3_object()(t) ) ;
|
||||||
CGAL_kernel_precondition( ! k.is_degenerate_3_object()(r) ) ;
|
CGAL_kernel_precondition( ! k.is_degenerate_3_object()(r) ) ;
|
||||||
|
|
||||||
|
|
@ -217,81 +274,81 @@ bool do_intersect_coplanar(const typename K::Triangle_3 &t,
|
||||||
if (pqc == POSITIVE)
|
if (pqc == POSITIVE)
|
||||||
// the triangle lies in the positive halfspace
|
// the triangle lies in the positive halfspace
|
||||||
// defined by the ray's supporting line.
|
// defined by the ray's supporting line.
|
||||||
return false;
|
return visitor.result(false);
|
||||||
// c is isolated on the negative side
|
// c is isolated on the negative side
|
||||||
return coplanar_orientation(*a,*c,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*a,*c,p) != POSITIVE );
|
||||||
|
|
||||||
case NEGATIVE:
|
case NEGATIVE:
|
||||||
if (pqc == POSITIVE) // b is isolated on the negative side
|
if (pqc == POSITIVE) // b is isolated on the negative side
|
||||||
return coplanar_orientation(*c,*b,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*c,*b,p) != POSITIVE );
|
||||||
// a is isolated on the positive side
|
// a is isolated on the positive side
|
||||||
return coplanar_orientation(*a,*c,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*a,*c,p) != POSITIVE );
|
||||||
|
|
||||||
case COLLINEAR:
|
case COLLINEAR:
|
||||||
if (pqc == POSITIVE) // b is isolated on the negative side
|
if (pqc == POSITIVE) // b is isolated on the negative side
|
||||||
return coplanar_orientation(*c,*b,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*c,*b,p) != POSITIVE );
|
||||||
// a is isolated on the positive side
|
// a is isolated on the positive side
|
||||||
return coplanar_orientation(*a,*c,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*a,*c,p) != POSITIVE );
|
||||||
|
|
||||||
default: // should not happen.
|
default: // should not happen.
|
||||||
CGAL_kernel_assertion(false);
|
CGAL_kernel_assertion(false);
|
||||||
return false;
|
return visitor.result(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
case NEGATIVE:
|
case NEGATIVE:
|
||||||
switch ( pqb ) {
|
switch ( pqb ) {
|
||||||
case POSITIVE:
|
case POSITIVE:
|
||||||
if (pqc == POSITIVE) // a is isolated on the negative side
|
if (pqc == POSITIVE) // a is isolated on the negative side
|
||||||
return coplanar_orientation(*b,*a,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*b,*a,p) != POSITIVE );
|
||||||
// b is isolated on the positive side
|
// b is isolated on the positive side
|
||||||
return coplanar_orientation(*b,*a,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*b,*a,p) != POSITIVE );
|
||||||
|
|
||||||
case NEGATIVE:
|
case NEGATIVE:
|
||||||
if (pqc == NEGATIVE)
|
if (pqc == NEGATIVE)
|
||||||
// the triangle lies in the negative halfspace
|
// the triangle lies in the negative halfspace
|
||||||
// defined by the ray's supporting line.
|
// defined by the ray's supporting line.
|
||||||
return false;
|
return visitor.result( false );
|
||||||
// c is isolated on the positive side
|
// c is isolated on the positive side
|
||||||
return coplanar_orientation(*c,*b,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*c,*b,p) != POSITIVE );
|
||||||
case COLLINEAR:
|
case COLLINEAR:
|
||||||
if (pqc == NEGATIVE) // b is isolated on the positive side
|
if (pqc == NEGATIVE) // b is isolated on the positive side
|
||||||
return coplanar_orientation(*b,*a,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*b,*a,p) != POSITIVE );
|
||||||
// a is isolated on the negative side
|
// a is isolated on the negative side
|
||||||
return coplanar_orientation(*b,*a,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*b,*a,p) != POSITIVE );
|
||||||
|
|
||||||
default: // should not happen.
|
default: // should not happen.
|
||||||
CGAL_kernel_assertion(false);
|
CGAL_kernel_assertion(false);
|
||||||
return false;
|
return visitor.result(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
case COLLINEAR:
|
case COLLINEAR:
|
||||||
switch ( pqb ) {
|
switch ( pqb ) {
|
||||||
case POSITIVE:
|
case POSITIVE:
|
||||||
if (pqc == POSITIVE) // a is isolated on the negative side
|
if (pqc == POSITIVE) // a is isolated on the negative side
|
||||||
return coplanar_orientation(*b,*a,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*b,*a,p) != POSITIVE );
|
||||||
// b is isolated on the positive side
|
// b is isolated on the positive side
|
||||||
return coplanar_orientation(*b,*a,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*b,*a,p) != POSITIVE );
|
||||||
case NEGATIVE:
|
case NEGATIVE:
|
||||||
if (pqc == NEGATIVE) // a is isolated on the positive side
|
if (pqc == NEGATIVE) // a is isolated on the positive side
|
||||||
return coplanar_orientation(*a,*c,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*a,*c,p) != POSITIVE );
|
||||||
// b is isolated on the negative side
|
// b is isolated on the negative side
|
||||||
return coplanar_orientation(*c,*b,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*c,*b,p) != POSITIVE );
|
||||||
|
|
||||||
case COLLINEAR:
|
case COLLINEAR:
|
||||||
if (pqc == POSITIVE) // c is isolated on the positive side
|
if (pqc == POSITIVE) // c is isolated on the positive side
|
||||||
return coplanar_orientation(*c,*b,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*c,*b,p) != POSITIVE );
|
||||||
// c is isolated on the negative side
|
// c is isolated on the negative side
|
||||||
return coplanar_orientation(*a,*c,p) != POSITIVE ;
|
return visitor.result( coplanar_orientation(*a,*c,p) != POSITIVE );
|
||||||
// case pqc == COLLINEAR is imposiible
|
// case pqc == COLLINEAR is imposiible
|
||||||
|
|
||||||
default: // should not happen.
|
default: // should not happen.
|
||||||
CGAL_kernel_assertion(false);
|
CGAL_kernel_assertion(false);
|
||||||
return false;
|
return visitor.result(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
default: // should not happen.
|
default: // should not happen.
|
||||||
CGAL_kernel_assertion(false);
|
CGAL_kernel_assertion(false);
|
||||||
return false;
|
return visitor.result(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue