mirror of https://github.com/CGAL/cgal
Merge pull request #5244 from afabri/Triangulation_2-Intersect_use_variant-GF
Nef_3, Triangulation_2: Change the result type of the Intersect_2 functor
This commit is contained in:
commit
3bd7181ff3
|
|
@ -77,7 +77,7 @@ typedef Line_3<K> Line_2;
|
|||
A construction object.
|
||||
Provides the operator :
|
||||
|
||||
`Object_2 operator()(Segment_2 s1, Segment_2 s2);`
|
||||
`boost::optional< boost::variant<Point_2,Segment_2> > operator()(Segment_2 s1, Segment_2 s2);`
|
||||
which returns a 3D object whose projection on the xy-plane
|
||||
is the intersection of the projections of `s1` and `s2`.
|
||||
If non empty, the returned object is either a segment or a point.
|
||||
|
|
|
|||
|
|
@ -308,8 +308,13 @@ public:
|
|||
return (CGAL::abs(dx)>CGAL::abs(dy)) ? ( p.x()-source.x() ) / dx : (p.y()-source.y() ) / dy;
|
||||
}
|
||||
|
||||
Object operator()(const Segment_3& s1, const Segment_3& s2) const
|
||||
|
||||
|
||||
boost::optional< boost::variant<Point_3,Segment_3> >
|
||||
operator()(const Segment_3& s1, const Segment_3& s2) const
|
||||
{
|
||||
typedef boost::variant<Point_3, Segment_3> variant_type;
|
||||
|
||||
Point_2 s1_source = project(s1.source());
|
||||
Point_2 s1_target = project(s1.target());
|
||||
Point_2 s2_source = project(s2.source());
|
||||
|
|
@ -321,11 +326,14 @@ public:
|
|||
|
||||
//compute intersection points in projected plane
|
||||
//We know that none of the segment is degenerate
|
||||
Object o = intersection(s1_2,s2_2);
|
||||
const Point_2* pi=CGAL::object_cast<Point_2>(&o);
|
||||
if (pi==nullptr) { //case of segment or empty
|
||||
const Segment_2* si=CGAL::object_cast<Segment_2>(&o);
|
||||
if (si==nullptr) return Object();
|
||||
|
||||
typename CGAL::cpp11::result_of<typename R::Intersect_2(Segment_2, Segment_2)>::type
|
||||
o = intersection(s1_2,s2_2);
|
||||
if(! o){
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
if(const Segment_2* si = boost::get<Segment_2>(&*o)){
|
||||
FT src[3],tgt[3];
|
||||
//the third coordinate is the midpoint between the points on s1 and s2
|
||||
FT z1 = s1.source()[dim] + ( alpha(si->source(), s1_source, s1_target) * ( s1.target()[dim] - s1.source()[dim] ));
|
||||
|
|
@ -343,8 +351,11 @@ public:
|
|||
src[Projector<R,dim>::y_index] = si->source().y();
|
||||
tgt[Projector<R,dim>::x_index] = si->target().x();
|
||||
tgt[Projector<R,dim>::y_index] = si->target().y();
|
||||
return make_object( Segment_3( Point_3(src[0],src[1],src[2]),Point_3(tgt[0],tgt[1],tgt[2]) ) );
|
||||
return boost::make_optional(variant_type(Segment_3( Point_3(src[0],src[1],src[2]),Point_3(tgt[0],tgt[1],tgt[2]) ) ) );
|
||||
}
|
||||
|
||||
|
||||
const Point_2* pi = boost::get<Point_2>(&*o);
|
||||
FT coords[3];
|
||||
//compute the third coordinate of the projected intersection point onto 3D segments
|
||||
FT z1 = s1.source()[dim] + ( alpha(*pi, s1_source, s1_target) * ( s1.target()[dim] - s1.source()[dim] ));
|
||||
|
|
@ -356,7 +367,7 @@ public:
|
|||
|
||||
Point_3 res(coords[0],coords[1],coords[2]);
|
||||
CGAL_assertion(x(res)==pi->x() && y(res)==pi->y());
|
||||
return make_object(res);
|
||||
return boost::make_optional(variant_type(res));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -28,13 +28,16 @@ template<class R, class Tag> struct Exact_intersect_xy_2;
|
|||
template <class R>
|
||||
struct Exact_intersect_xy_2 <R,Cartesian_tag>
|
||||
{
|
||||
typedef typename R::Point_2 Point_2;
|
||||
typedef typename R::Segment_2 Segment_2;
|
||||
typedef typename R::Point_2 Point_2;
|
||||
typedef typename R::Segment_2 Segment_2;
|
||||
|
||||
typedef typename R::Point_3 Point_3;
|
||||
typedef typename R::Segment_3 Segment_3;
|
||||
typedef typename R::Point_3 Point_3;
|
||||
typedef typename R::Segment_3 Segment_3;
|
||||
|
||||
CGAL::Object operator() (Segment_3 s3, Segment_3 t3)
|
||||
typedef boost::variant<Point_3, Segment_3> variant_type;
|
||||
|
||||
boost::optional<variant_type>
|
||||
operator() (const Segment_3& s3, const Segment_3& t3)
|
||||
{ Point_2 p2, q2;
|
||||
Point_3 p3, q3;
|
||||
|
||||
|
|
@ -50,17 +53,21 @@ struct Exact_intersect_xy_2 <R,Cartesian_tag>
|
|||
// convert intersection from Object_2 to Object_3
|
||||
// Note: there is not necessarily a spartial intersection,
|
||||
// so all third components are faked!
|
||||
CGAL::Object obj = intersection (s2,t2);
|
||||
if ( CGAL::assign(p2, obj) )
|
||||
{ obj = make_object (Point_3 (p2.x(),p2.y(),0));
|
||||
auto obj = intersection (s2,t2);
|
||||
if(! obj){
|
||||
return boost::none;
|
||||
}
|
||||
else if ( CGAL::assign(s2, obj) )
|
||||
{ p2 = s2.source();
|
||||
q2 = s2.target();
|
||||
obj = make_object( Segment_3(
|
||||
Point_3(p2.x(),p2.y(),0), Point_3(q2.x(),q2.y(),0) ) );
|
||||
if (const Point_2* pi = boost::get<Point_2>(&*obj))
|
||||
{
|
||||
return boost::make_optional(variant_type(Point_3(p2.x(),p2.y(),0)));
|
||||
}
|
||||
return obj;
|
||||
|
||||
const Segment_2* si = boost::get<Segment_2>(&*obj);
|
||||
p2 = si->source();
|
||||
q2 = si->target();
|
||||
|
||||
return boost::make_optional(variant_type(Segment_3(Point_3(p2.x(),p2.y(),0),
|
||||
Point_3(q2.x(),q2.y(),0) ) ));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -73,7 +80,9 @@ struct Exact_intersect_xy_2 <R,Homogeneous_tag>
|
|||
typedef typename R::Point_3 Point_3;
|
||||
typedef typename R::Segment_3 Segment_3;
|
||||
|
||||
CGAL::Object operator() (Segment_3 s3, Segment_3 t3)
|
||||
typedef boost::variant<Point_3, Segment_3> variant_type;
|
||||
|
||||
boost::optional<variant_type> operator() (Segment_3 s3, Segment_3 t3)
|
||||
{ Point_2 p2, q2;
|
||||
Point_3 p3, q3;
|
||||
|
||||
|
|
@ -91,18 +100,21 @@ struct Exact_intersect_xy_2 <R,Homogeneous_tag>
|
|||
// convert intersection from Object_2 to Object_3
|
||||
// Note: there is not necessarily a spartial intersection,
|
||||
// so all third components are faked!
|
||||
CGAL::Object obj = intersection (s2,t2);
|
||||
if ( CGAL::assign(p2, obj) )
|
||||
{ obj = make_object (Point_3 (p2.hx(),p2.hy(),0,p2.hw()));
|
||||
auto obj = intersection (s2,t2);
|
||||
if(! obj){
|
||||
return boost::none;
|
||||
}
|
||||
else if ( CGAL::assign(s2, obj) )
|
||||
{ p2 = s2.source();
|
||||
q2 = s2.target();
|
||||
obj = make_object( Segment_3(
|
||||
Point_3 (p2.hx(),p2.hy(),0,p2.hw()),
|
||||
Point_3 (q2.hx(),q2.hy(),0,q2.hw()) ) );
|
||||
if (const Point_2* pi = boost::get<Point_2>(&*obj))
|
||||
{
|
||||
return boost::make_optional(variant_type(Point_3(p2.hx(),p2.hy(),0,p2.hw())));
|
||||
}
|
||||
return obj;
|
||||
|
||||
const Segment_2* si = boost::get<Segment_2>(&*obj);
|
||||
p2 = si->source();
|
||||
q2 = si->target();
|
||||
|
||||
return boost::make_optional(variant_type(Segment_3(Point_3 (p2.hx(),p2.hy(),0,p2.hw()),
|
||||
Point_3 (q2.hx(),q2.hy(),0,q2.hw())) ));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,10 @@ struct Exact_intersect_xz_2 <R,Cartesian_tag>
|
|||
typedef typename R::Point_3 Point_3;
|
||||
typedef typename R::Segment_3 Segment_3;
|
||||
|
||||
CGAL::Object operator() (Segment_3 s3, Segment_3 t3)
|
||||
typedef boost::variant<Point_3, Segment_3> variant_type;
|
||||
|
||||
boost::optional<variant_type>
|
||||
operator() (const Segment_3& s3, const Segment_3& t3)
|
||||
{ Point_2 p2, q2;
|
||||
Point_3 p3, q3;
|
||||
|
||||
|
|
@ -48,18 +51,22 @@ struct Exact_intersect_xz_2 <R,Cartesian_tag>
|
|||
|
||||
// convert intersection from Object_2 to Object_3
|
||||
// Note: there is not necessarily a spartial intersection,
|
||||
// so all second components are faked!
|
||||
CGAL::Object obj = intersection (s2,t2);
|
||||
if ( CGAL::assign(p2, obj) )
|
||||
{ obj = make_object (Point_3 (p2.x(),0,p2.y()));
|
||||
// so all third components are faked!
|
||||
auto obj = intersection (s2,t2);
|
||||
if(! obj){
|
||||
return boost::none;
|
||||
}
|
||||
else if ( CGAL::assign(s2, obj) )
|
||||
{ p2 = s2.source();
|
||||
q2 = s2.target();
|
||||
obj = make_object( Segment_3(
|
||||
Point_3(p2.x(),0,p2.y()), Point_3(q2.x(),0,q2.y()) ) );
|
||||
if (const Point_2* pi = boost::get<Point_2>(&*obj))
|
||||
{
|
||||
return boost::make_optional(variant_type(Point_3(p2.x(),0,p2.y())));
|
||||
}
|
||||
return obj;
|
||||
|
||||
const Segment_2* si = boost::get<Segment_2>(&*obj);
|
||||
p2 = si->source();
|
||||
q2 = si->target();
|
||||
|
||||
return boost::make_optional(variant_type(Segment_3(Point_3(p2.x(),0,p2.y()),
|
||||
Point_3(q2.x(),0,q2.y()) ) ));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -72,7 +79,9 @@ struct Exact_intersect_xz_2 <R,Homogeneous_tag>
|
|||
typedef typename R::Point_3 Point_3;
|
||||
typedef typename R::Segment_3 Segment_3;
|
||||
|
||||
CGAL::Object operator() (Segment_3 s3, Segment_3 t3)
|
||||
typedef boost::variant<Point_3, Segment_3> variant_type;
|
||||
|
||||
boost::optional<variant_type> operator() (Segment_3 s3, Segment_3 t3)
|
||||
{ Point_2 p2, q2;
|
||||
Point_3 p3, q3;
|
||||
|
||||
|
|
@ -89,20 +98,24 @@ struct Exact_intersect_xz_2 <R,Homogeneous_tag>
|
|||
|
||||
// convert intersection from Object_2 to Object_3
|
||||
// Note: there is not necessarily a spartial intersection,
|
||||
// so all second components are faked!
|
||||
CGAL::Object obj = intersection (s2,t2);
|
||||
if ( CGAL::assign(p2, obj) )
|
||||
{ obj = make_object (Point_3 (p2.hx(),0,p2.hy(),p2.hw()));
|
||||
// so all third components are faked!
|
||||
auto obj = intersection (s2,t2);
|
||||
if(! obj){
|
||||
return boost::none;
|
||||
}
|
||||
else if ( CGAL::assign(s2, obj) )
|
||||
{ p2 = s2.source();
|
||||
q2 = s2.target();
|
||||
obj = make_object( Segment_3(
|
||||
Point_3 (p2.hx(),0,p2.hy(),p2.hw()),
|
||||
Point_3 (q2.hx(),0,q2.hy(),q2.hw()) ) );
|
||||
if (const Point_2* pi = boost::get<Point_2>(&*obj))
|
||||
{
|
||||
return boost::make_optional(variant_type(Point_3(p2.hx(),0,p2.hy(),p2.hw())));
|
||||
}
|
||||
return obj;
|
||||
|
||||
const Segment_2* si = boost::get<Segment_2>(&*obj);
|
||||
p2 = si->source();
|
||||
q2 = si->target();
|
||||
|
||||
return boost::make_optional(variant_type(Segment_3(Point_3 (p2.hx(),0,p2.hy(),p2.hw()),
|
||||
Point_3 (q2.hx(),0,q2.hy(),q2.hw())) ));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class R>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,10 @@ struct Exact_intersect_yz_2 <R,Cartesian_tag>
|
|||
typedef typename R::Point_3 Point_3;
|
||||
typedef typename R::Segment_3 Segment_3;
|
||||
|
||||
CGAL::Object operator() (Segment_3 s3, Segment_3 t3)
|
||||
typedef boost::variant<Point_3, Segment_3> variant_type;
|
||||
|
||||
boost::optional<variant_type>
|
||||
operator() (const Segment_3& s3, const Segment_3& t3)
|
||||
{ Point_2 p2, q2;
|
||||
Point_3 p3, q3;
|
||||
|
||||
|
|
@ -49,18 +52,22 @@ struct Exact_intersect_yz_2 <R,Cartesian_tag>
|
|||
|
||||
// convert intersection from Object_2 to Object_3
|
||||
// Note: there is not necessarily a spartial intersection,
|
||||
// so all first components are faked!
|
||||
CGAL::Object obj = intersection (s2,t2);
|
||||
if ( CGAL::assign(p2, obj) )
|
||||
{ obj = make_object (Point_3 (0,p2.x(),p2.y()));
|
||||
// so all third components are faked!
|
||||
auto obj = intersection (s2,t2);
|
||||
if(! obj){
|
||||
return boost::none;
|
||||
}
|
||||
else if ( CGAL::assign(s2, obj) )
|
||||
{ p2 = s2.source();
|
||||
q2 = s2.target();
|
||||
obj = make_object( Segment_3(
|
||||
Point_3(0,p2.x(),p2.y()), Point_3(0,q2.x(),q2.y()) ) );
|
||||
if (const Point_2* pi = boost::get<Point_2>(&*obj))
|
||||
{
|
||||
return boost::make_optional(variant_type(Point_3(0,p2.x(),p2.y())));
|
||||
}
|
||||
return obj;
|
||||
|
||||
const Segment_2* si = boost::get<Segment_2>(&*obj);
|
||||
p2 = si->source();
|
||||
q2 = si->target();
|
||||
|
||||
return boost::make_optional(variant_type(Segment_3(Point_3(0,p2.x(),p2.y()),
|
||||
Point_3(0,q2.x(),q2.y()) ) ));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -73,7 +80,9 @@ struct Exact_intersect_yz_2 <R,Homogeneous_tag>
|
|||
typedef typename R::Point_3 Point_3;
|
||||
typedef typename R::Segment_3 Segment_3;
|
||||
|
||||
CGAL::Object operator() (Segment_3 s3, Segment_3 t3)
|
||||
typedef boost::variant<Point_3, Segment_3> variant_type;
|
||||
|
||||
boost::optional<variant_type> operator() (Segment_3 s3, Segment_3 t3)
|
||||
{ Point_2 p2, q2;
|
||||
Point_3 p3, q3;
|
||||
|
||||
|
|
@ -90,19 +99,22 @@ struct Exact_intersect_yz_2 <R,Homogeneous_tag>
|
|||
|
||||
// convert intersection from Object_2 to Object_3
|
||||
// Note: there is not necessarily a spartial intersection,
|
||||
// so all first components are faked!
|
||||
CGAL::Object obj = intersection (s2,t2);
|
||||
if ( CGAL::assign(p2, obj) )
|
||||
{ obj = make_object (Point_3 (0,p2.hx(),p2.hy(),p2.hw()));
|
||||
// so all third components are faked!
|
||||
auto obj = intersection (s2,t2);
|
||||
if(! obj){
|
||||
return boost::none;
|
||||
}
|
||||
else if ( CGAL::assign(s2, obj) )
|
||||
{ p2 = s2.source();
|
||||
q2 = s2.target();
|
||||
obj = make_object( Segment_3(
|
||||
Point_3 (0,p2.hx(),p2.hy(),p2.hw()),
|
||||
Point_3 (0,q2.hx(),q2.hy(),q2.hw()) ) );
|
||||
if (const Point_2* pi = boost::get<Point_2>(&*obj))
|
||||
{
|
||||
return boost::make_optional(variant_type(Point_3(0,p2.hx(),p2.hy(),p2.hw())));
|
||||
}
|
||||
return obj;
|
||||
|
||||
const Segment_2* si = boost::get<Segment_2>(&*obj);
|
||||
p2 = si->source();
|
||||
q2 = si->target();
|
||||
|
||||
return boost::make_optional(variant_type(Segment_3(Point_3 (0,p2.hx(),p2.hy(),p2.hw()),
|
||||
Point_3 (0,q2.hx(),q2.hy(),q2.hw())) ));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public:
|
|||
/*!
|
||||
A function object whose `operator()` computes the intersection of two segments.
|
||||
|
||||
`Object_2 operator()(Segment_2 s1, Segment_2 s2);`
|
||||
`boost:optional<boost::variant<Point_2,Segment_2> > operator()(Segment_2 s1, Segment_2 s2);`
|
||||
Returns the intersection of `s1` and `s2`.
|
||||
*/
|
||||
typedef unspecified_type Intersect_2;
|
||||
|
|
@ -113,4 +113,3 @@ compute_squared_distance_2_object();
|
|||
/// @}
|
||||
|
||||
}; /* end ConstrainedTriangulationTraits_2 */
|
||||
|
||||
|
|
|
|||
|
|
@ -1710,23 +1710,34 @@ compute_intersection(const Gt& gt,
|
|||
const typename Gt::Point_2& pd,
|
||||
typename Gt::Point_2& pi)
|
||||
{
|
||||
typename Gt::Intersect_2 compute_intersec=gt.intersect_2_object();
|
||||
typename Gt::Construct_segment_2
|
||||
construct_segment=gt.construct_segment_2_object();
|
||||
Object result = compute_intersec(construct_segment(pa,pb),
|
||||
construct_segment(pc,pd));
|
||||
typedef typename Gt::Point_2 Point_2;
|
||||
|
||||
typename Gt::Intersect_2 compute_intersec = gt.intersect_2_object();
|
||||
typename Gt::Construct_segment_2 construct_segment = gt.construct_segment_2_object();
|
||||
|
||||
auto // CGAL::cpp11::result_of<typename Gt::Intersect_2(Segment_2, Segment_2)>::type
|
||||
result = compute_intersec(construct_segment(pa,pb),
|
||||
construct_segment(pc,pd));
|
||||
|
||||
|
||||
#ifdef CGAL_CDT_2_DEBUG_INTERSECTIONS
|
||||
typename Gt::Segment_2 s;
|
||||
if(assign(s, result)) {
|
||||
std::cerr << CGAL::internal::cdt_2_indent_level
|
||||
<< "compute_intersection: " << s << '\n';
|
||||
}
|
||||
if(assign(pi, result)) {
|
||||
std::cerr << CGAL::internal::cdt_2_indent_level
|
||||
<< "compute_intersection: " << pi << '\n';
|
||||
typedef typename Gt::Segment_2 Segment_2;
|
||||
if(result){
|
||||
if (const Segment_2* s = boost::get<Segment_2>(&*result)){
|
||||
std::cerr << CGAL::internal::cdt_2_indent_level
|
||||
<< "compute_intersection: " << *s << '\n';
|
||||
}else if(const Point_2* p = boost::get<Point_2 >(&*result))
|
||||
std::cerr << CGAL::internal::cdt_2_indent_level
|
||||
<< "compute_intersection: " << *p << '\n';
|
||||
}
|
||||
#endif // CGAL_CDT_2_DEBUG_INTERSECTIONS
|
||||
return assign(pi, result);
|
||||
if(result){
|
||||
if(const Point_2* p = boost::get<Point_2 >(&*result)){
|
||||
pi = *p;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -185,7 +185,8 @@ public:
|
|||
CGAL_TIME_PROFILER("Construct Projected_intersect_3")
|
||||
}
|
||||
|
||||
Object operator()(const Segment& s1, const Segment& s2)
|
||||
boost::optional<boost::variant<Point,Segment> >
|
||||
operator()(const Segment& s1, const Segment& s2)
|
||||
{
|
||||
CGAL_PROFILER("Projected_intersect_3::operator()")
|
||||
CGAL_TIME_PROFILER("Projected_intersect_3::operator()")
|
||||
|
|
@ -200,12 +201,12 @@ public:
|
|||
const Plane_3 plane_1(s1.source(), u1);
|
||||
const Plane_3 plane_2(s2.source(), u2);
|
||||
|
||||
Object planes_intersection = intersection(plane_1, plane_2);
|
||||
if(planes_intersection.empty()) {
|
||||
auto planes_intersection = intersection(plane_1, plane_2);
|
||||
if(! planes_intersection) {
|
||||
std::cerr << "planes_intersection is empty\n";
|
||||
return planes_intersection;
|
||||
return boost::none;
|
||||
}
|
||||
if(const Line* line = object_cast<Line>(&planes_intersection))
|
||||
if(const Line* line = boost::get<Line>(&*planes_intersection))
|
||||
{
|
||||
const Point& pi = line->point(0);
|
||||
if(cross_product(normal, pi - s1.source())
|
||||
|
|
@ -216,25 +217,32 @@ public:
|
|||
{
|
||||
// the intersection of the lines is not inside the segments
|
||||
std::cerr << "intersection not inside\n";
|
||||
return Object();
|
||||
return boost::none;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let the plane passing through s1.source() and with normal
|
||||
// the cross product of s1.to_vector() and s2.to_vector(). That
|
||||
// plane should intersect *l, now.
|
||||
return intersection(*line, Plane_3(s1.source(),
|
||||
cross_product(s1.to_vector(),
|
||||
s2.to_vector())));
|
||||
auto inter = intersection(*line, Plane_3(s1.source(),
|
||||
cross_product(s1.to_vector(),
|
||||
s2.to_vector())));
|
||||
if(! inter){
|
||||
return boost::none;
|
||||
}
|
||||
if(const Point* point = boost::get<Point>(&*inter)){
|
||||
typedef boost::variant<Point, Segment> variant_type;
|
||||
return boost::make_optional(variant_type(*point));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(object_cast<Plane_3>(&planes_intersection))
|
||||
if(boost::get<Plane_3>(&*planes_intersection))
|
||||
{
|
||||
std::cerr << "coplanar lines\n";
|
||||
CGAL_error();
|
||||
return Object();
|
||||
return boost::none;
|
||||
}
|
||||
return Object();
|
||||
return boost::none;
|
||||
}
|
||||
}; // end class Projected_intersect_3
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue