Merge branch 'releases/CGAL-4.14-branch'

# Conflicts:
#	Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Apollonius_graph_2_impl.h
#	Convex_hull_3/include/CGAL/convex_hull_3.h
#	Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h
#	Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp
#	Stream_support/include/CGAL/IO/Color.h
This commit is contained in:
Laurent Rineau 2019-06-20 14:20:37 +02:00
commit 8535a3c03c
61 changed files with 1657 additions and 1484 deletions

View File

@ -32,8 +32,9 @@
#include <iostream> #include <iostream>
#include <vector>
#include <map> #include <map>
#include <vector>
#include <stack>
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>

View File

@ -817,69 +817,85 @@ check_edge_for_hidden_sites(const Face_handle& f, int i,
template<class Gt, class Agds, class LTag> template<class Gt, class Agds, class LTag>
void void
Apollonius_graph_2<Gt,Agds,LTag>:: Apollonius_graph_2<Gt,Agds,LTag>::
expand_conflict_region(const Face_handle& f, const Site_2& p, expand_conflict_region(const Face_handle& in_f,
List& l, Face_map& fm, Vertex_map& vm, const Site_2& p,
std::vector<Vh_triple*>* fe) List& l,
Face_map& fm,
Vertex_map& vm,
std::vector<Vh_triple*>* fe)
{ {
// setting fm[f] to true means that the face has been reached and std::stack<Face_handle> face_stack;
// that the face is available for recycling. If we do not want the face_stack.push(in_f);
// face to be available for recycling we must set this flag to
// false.
fm[f] = true;
// CGAL_assertion( fm.find(f) != fm.end() ); while(!face_stack.empty())
for (int i = 0; i < 3; i++) { {
bool hidden_found = const Face_handle curr_f = face_stack.top();
check_edge_for_hidden_sites(f, i, p, vm); face_stack.pop();
Face_handle n = f->neighbor(i); // setting fm[curr_f] to true means that the face has been reached and
// that the face is available for recycling. If we do not want the
// face to be available for recycling we must set this flag to false.
fm[curr_f] = true;
if ( !hidden_found ) { // CGAL_assertion( fm.find(curr_f) != fm.end() );
Sign s = incircle(n, p); for (int i = 0; i < 3; ++i)
if ( s != NEGATIVE ) { continue; } {
bool hidden_found = check_edge_for_hidden_sites(curr_f, i, p, vm);
bool interior_in_conflict = edge_interior(f, i, p, true); Face_handle n = curr_f->neighbor(i);
if ( !interior_in_conflict ) { continue; } if ( !hidden_found )
} {
Sign s = incircle(n, p);
if ( s != NEGATIVE )
continue;
if ( fm.find(n) != fm.end() ) { bool interior_in_conflict = edge_interior(curr_f, i, p, true);
Edge e = sym_edge(f, i); if ( !interior_in_conflict )
if ( l.is_in_list(e) || continue;
l.is_in_list(sym_edge(e)) ) {
l.remove(e);
l.remove(sym_edge(e));
} }
continue;
}
Edge e = sym_edge(f, i); if ( fm.find(n) != fm.end() )
{
Edge e = sym_edge(curr_f, i);
if ( l.is_in_list(e) )
l.remove(e);
CGAL_assertion( l.is_in_list(e) ); if( l.is_in_list(sym_edge(e)) )
int j = tds().mirror_index(f, i); l.remove(sym_edge(e));
Edge e_before = sym_edge(n, ccw(j));
Edge e_after = sym_edge(n, cw(j));
if ( !l.is_in_list(e_before) ) {
l.insert_before(e, e_before);
}
if ( !l.is_in_list(e_after) ) {
l.insert_after(e, e_after);
}
l.remove(e);
if ( fe != nullptr ) { continue;
Vh_triple* vhq = new Vh_triple[1]; }
(*vhq)[0] = Vertex_handle(); Edge e = sym_edge(curr_f, i);
(*vhq)[1] = n->vertex( j ); CGAL_assertion( l.is_in_list(e) );
(*vhq)[2] = n->vertex( ccw(j) );
fe->push_back(vhq); int j = tds().mirror_index(curr_f, i);
} Edge e_before = sym_edge(n, ccw(j));
Edge e_after = sym_edge(n, cw(j));
if ( !l.is_in_list(e_before) )
l.insert_before(e, e_before);
expand_conflict_region(n, p, l, fm, vm, fe); if ( !l.is_in_list(e_after) )
} // for-loop l.insert_after(e, e_after);
l.remove(e);
if ( fe != nullptr )
{
Vh_triple* vhq = new Vh_triple[1];
(*vhq)[0] = Vertex_handle();
(*vhq)[1] = n->vertex( j );
(*vhq)[2] = n->vertex( ccw(j) );
fe->push_back(vhq);
}
face_stack.push(n);
} // neighbor for-loop
}
} }

View File

@ -13,6 +13,13 @@ function when `R` is a kernel with exact predicates but inexact constructions
\cgalModels `IsStronglyConvexTraits_3` \cgalModels `IsStronglyConvexTraits_3`
\attention The user must include the header file of the polygon mesh type, even for the default type. \attention The user must include the header file of the polygon mesh type, even for the default type.
\cgalAdvancedBegin
This class has a fourth undocumented template argument. Passing `CGAL::Tag_false`
switches off a caching of a plane with coordinates with interval arithmetic.
Instead an orientation test of four points is performed.
\cgalAdvancedEnd
*/ */
template< typename R, typename PolygonMesh = Polyhedron_3<R> > template< typename R, typename PolygonMesh = Polyhedron_3<R> >
class Convex_hull_traits_3 { class Convex_hull_traits_3 {

View File

@ -4,7 +4,7 @@ namespace CGAL {
\ingroup PkgConvexHull3Functions \ingroup PkgConvexHull3Functions
\brief computes the convex hull of the set of points in the range \brief computes the convex hull of the set of points in the range
[`first`, `last`). The polyhedron `pm` is cleared, then [`first`, `last`). The polygon mesh `pm` is cleared, then
the convex hull is stored in `pm`. Note that the convex hull will be triangulated, the convex hull is stored in `pm`. Note that the convex hull will be triangulated,
that is `pm` will contain only triangular facets. that is `pm` will contain only triangular facets.
if the convex hull is a point or a segment, endpoints will be added in `pm` as isolated vertices. if the convex hull is a point or a segment, endpoints will be added in `pm` as isolated vertices.
@ -39,9 +39,9 @@ void convex_hull_3(InputIterator first, InputIterator last, PolygonMesh& pm, con
\brief computes the convex hull of the set of points in the range \brief computes the convex hull of the set of points in the range
[`first`, `last`). The result, which may be a point, a segment, [`first`, `last`). The result, which may be a point, a segment,
a triangle, or a polyhedron, is stored in `ch_object`. a triangle, or a polygon mesh, is stored in `ch_object`.
In the case the result is a polyhedron, the convex hull will be triangulated, In the case the result is a polygon mesh, the convex hull will be triangulated,
that is the polyhedron will contain only triangular facets. that is the polygon mesh will contain only triangular facets.
\tparam InputIterator must be an input iterator with a value type equivalent to `Traits::Point_3`. \tparam InputIterator must be an input iterator with a value type equivalent to `Traits::Point_3`.
\tparam Traits must be model of the concept `ConvexHullTraits_3`. \tparam Traits must be model of the concept `ConvexHullTraits_3`.

View File

@ -49,11 +49,19 @@ computing the hull.
The function `convex_hull_3()` is parameterized by a traits class, The function `convex_hull_3()` is parameterized by a traits class,
which specifies the types and geometric primitives to be used in the which specifies the types and geometric primitives to be used in the
computation. If input points from a kernel with exact predicates computation. As the function constructs 3D planes from three input
points, we cannot simply pass a kernel with inexact constructions as
optional argument for the traits class.
If input points from a kernel with exact predicates
and non-exact constructions are used, and a certified result is expected, and non-exact constructions are used, and a certified result is expected,
the traits `Convex_hull_traits_3<R>` should be used the class `Convex_hull_traits_3<R>` should be used
(`R` being the input kernel). Note that the default traits class takes this into (`R` being the input kernel).
account. If the constructions from a kernel are exact this kernel can be used
directly as a traits class.
Note that the default traits class takes this into account, that is the
above considerations are only important for custom traits classes.
\subsubsection Convex_hull_3Example Example \subsubsection Convex_hull_3Example Example

View File

@ -43,6 +43,7 @@
#include <iostream> #include <iostream>
#include <algorithm> #include <algorithm>
#include <utility> #include <utility>
#include <memory>
#include <list> #include <list>
#include <vector> #include <vector>
#include <boost/bind.hpp> #include <boost/bind.hpp>
@ -236,17 +237,23 @@ public:
//and in case of failure, exact arithmetic is used. //and in case of failure, exact arithmetic is used.
template <class Kernel, class P> template <class Kernel, class P>
class Is_on_positive_side_of_plane_3<Convex_hull_traits_3<Kernel, P, Tag_true>, boost::true_type >{ class Is_on_positive_side_of_plane_3<Convex_hull_traits_3<Kernel, P, Tag_true>, boost::true_type >{
typedef Simple_cartesian<CGAL::internal::Exact_field_selector<double>::Type> PK; typedef Simple_cartesian<CGAL::internal::Exact_field_selector<double>::Type> Exact_K;
typedef Simple_cartesian<Interval_nt_advanced > CK; typedef Simple_cartesian<Interval_nt_advanced > Approx_K;
typedef Convex_hull_traits_3<Kernel, P, Tag_true> Traits; typedef Convex_hull_traits_3<Kernel, P, Tag_true> Traits;
typedef typename Traits::Point_3 Point_3; typedef typename Traits::Point_3 Point_3;
Cartesian_converter<Kernel,CK> to_CK; Cartesian_converter<Kernel,Approx_K> to_AK;
Cartesian_converter<Kernel,PK> to_PK; Cartesian_converter<Kernel,Exact_K> to_EK;
template <typename K>
struct Vector_plus_point {
typename K::Vector_3 vector;
typename K::Point_3 point;
};
const Point_3& p,q,r; const Point_3& p,q,r;
mutable typename CK::Plane_3* ck_plane; mutable Vector_plus_point<Approx_K> ak_plane;
mutable typename PK::Plane_3* pk_plane; mutable Vector_plus_point<Exact_K>* ek_plane_ptr;
double m10,m20,m21,Maxx,Maxy,Maxz; double m10,m20,m21,Maxx,Maxy,Maxz;
@ -292,8 +299,13 @@ public:
typedef typename Interval_nt_advanced::Protector Protector; typedef typename Interval_nt_advanced::Protector Protector;
Is_on_positive_side_of_plane_3(const Traits&,const Point_3& p_,const Point_3& q_,const Point_3& r_) Is_on_positive_side_of_plane_3(const Traits&,const Point_3& p_,const Point_3& q_,const Point_3& r_)
:p(p_),q(q_),r(r_),ck_plane(nullptr),pk_plane(nullptr) : p(p_),q(q_),r(r_)
, ak_plane()
, ek_plane_ptr(nullptr)
{ {
ak_plane.vector =
typename Approx_K::Vector_3(Interval_nt_advanced(0., std::numeric_limits<double>::infinity()),
0., 0.);
double pqx = q.x() - p.x(); double pqx = q.x() - p.x();
double pqy = q.y() - p.y(); double pqy = q.y() - p.y();
double pqz = q.z() - p.z(); double pqz = q.z() - p.z();
@ -319,8 +331,7 @@ public:
} }
~Is_on_positive_side_of_plane_3(){ ~Is_on_positive_side_of_plane_3(){
if (ck_plane!=nullptr) delete ck_plane; if (ek_plane_ptr!=nullptr) delete ek_plane_ptr;
if (pk_plane!=nullptr) delete pk_plane;
} }
bool operator() (const Point_3& s) const bool operator() (const Point_3& s) const
@ -334,15 +345,29 @@ public:
return static_res == 1; return static_res == 1;
try{ try{
if (ck_plane==nullptr) // infinity() is the sentinel for uninitialized `ak_plane`
ck_plane=new typename CK::Plane_3(to_CK(p),to_CK(q),to_CK(r)); if (ak_plane.vector.x().sup() == std::numeric_limits<double>::infinity())
return ck_plane->has_on_positive_side(to_CK(s)); {
const typename Approx_K::Point_3 ap = to_AK(p);
ak_plane.vector = cross_product(to_AK(q)-ap, to_AK(r)-ap);
ak_plane.point = ap;
}
Uncertain<Sign> res =
sign(scalar_product(to_AK(s) - ak_plane.point,
ak_plane.vector));
if(is_certain(res)) {
return (get_certain(res) == POSITIVE);
}
} }
catch (Uncertain_conversion_exception&){ catch (Uncertain_conversion_exception&){}
if (pk_plane==nullptr) if (ek_plane_ptr==nullptr) {
pk_plane=new typename PK::Plane_3(to_PK(p),to_PK(q),to_PK(r)); const typename Exact_K::Point_3 ep = to_EK(p);
return pk_plane->has_on_positive_side(to_PK(s)); ek_plane_ptr = new Vector_plus_point<Exact_K>;
ek_plane_ptr->vector = cross_product(to_EK(q)-ep, to_EK(r)-ep);
ek_plane_ptr->point = ep;
} }
return sign(scalar_product(to_EK(s) - ek_plane_ptr->point,
ek_plane_ptr->vector)) == POSITIVE;
} }
}; };

View File

@ -14,7 +14,7 @@
#include <iostream> #include <iostream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Epick_without_intervals K;
typedef CGAL::Polyhedron_3<K> Polyhedron_3; typedef CGAL::Polyhedron_3<K> Polyhedron_3;
typedef K::Point_3 Point_3; typedef K::Point_3 Point_3;

View File

@ -81,4 +81,6 @@ int main()
test<Epec,CGAL::Polyhedron_3<Epec> >(); test<Epec,CGAL::Polyhedron_3<Epec> >();
test<Epic,CGAL::Surface_mesh<Epic::Point_3> >(); test<Epic,CGAL::Surface_mesh<Epic::Point_3> >();
test<Epec,CGAL::Surface_mesh<Epec::Point_3> >(); test<Epec,CGAL::Surface_mesh<Epec::Point_3> >();
test<CGAL::Epick_without_intervals,
CGAL::Surface_mesh<CGAL::Epick_without_intervals::Point_3> >();
} }

View File

@ -26,21 +26,46 @@
#include <CGAL/Bbox_2.h> #include <CGAL/Bbox_2.h>
#include <CGAL/Circle_2.h> #include <CGAL/Circle_2.h>
#include <CGAL/Intersections_2/internal/Bbox_2_Circle_2_do_intersect.h> #include <CGAL/Intersections_2/Circle_2_Iso_rectangle_2.h>
namespace CGAL { namespace CGAL {
namespace Intersections {
namespace internal {
template <class K>
bool do_intersect(const CGAL::Bbox_2& bbox,
const typename K::Circle_2& circle,
const K&)
{
return do_intersect_circle_iso_rectangle_2(circle, bbox, K());
}
template <class K>
bool do_intersect(const typename K::Circle_2& circle,
const CGAL::Bbox_2& bbox,
const K&)
{
return do_intersect_circle_iso_rectangle_2(circle, bbox, K());
}
} // namespace internal
} // namespace Intersections
template<typename K> template<typename K>
bool do_intersect(const CGAL::Bbox_2& a, bool do_intersect(const CGAL::Bbox_2& a,
const Circle_2<K>& b) { const Circle_2<K>& b)
{
return K().do_intersect_2_object()(a, b); return K().do_intersect_2_object()(a, b);
} }
template<typename K> template<typename K>
bool do_intersect(const Circle_2<K>& a, bool do_intersect(const Circle_2<K>& a,
const CGAL::Bbox_2& b) { const CGAL::Bbox_2& b)
{
return K().do_intersect_2_object()(a, b); return K().do_intersect_2_object()(a, b);
} }
} } // namespace CGAL
#endif // CGAL_INTERSECTIONS_2_BBOX_2_CIRCLE_2_H #endif // CGAL_INTERSECTIONS_2_BBOX_2_CIRCLE_2_H

View File

@ -23,80 +23,50 @@
// //
// Author(s) : Geert-Jan Giezeman // Author(s) : Geert-Jan Giezeman
#ifndef CGAL_INTERSECTIONS_2_BBOX_2_LINE_2_H #ifndef CGAL_INTERSECTIONS_2_BBOX_2_LINE_2_H
#define CGAL_INTERSECTIONS_2_BBOX_2_LINE_2_H #define CGAL_INTERSECTIONS_2_BBOX_2_LINE_2_H
#include <CGAL/Bbox_2.h> #include <CGAL/Bbox_2.h>
#include <CGAL/Line_2.h> #include <CGAL/Line_2.h>
#include <CGAL/kernel_assertions.h>
#include <CGAL/number_utils.h> #include <CGAL/Intersections_2/Iso_rectangle_2_Line_2.h>
namespace CGAL { namespace CGAL {
namespace Intersections {
namespace internal {
class Bbox_2_Line_2_pair_impl; template <class K>
bool do_intersect(const typename K::Line_2& line,
class CGAL_EXPORT Bbox_2_Line_2_pair { const CGAL::Bbox_2& bbox,
public: const K& k)
enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT};
Bbox_2_Line_2_pair() ;
Bbox_2_Line_2_pair(Bbox_2_Line_2_pair const &);
Bbox_2_Line_2_pair(Bbox_2 const &bbox,
double line_a, double line_b, double line_c);
~Bbox_2_Line_2_pair() ;
Bbox_2_Line_2_pair &operator=(Bbox_2_Line_2_pair const &o);
// set_bbox(Bbox_2 const &bbox);
// set_line(double line_a, double line_b, double line_c);
Intersection_results intersection_type() const;
bool intersection(double &x, double &y) const;
bool intersection(double &x1, double &y1, double &x2, double &y2) const;
protected:
Bbox_2_Line_2_pair_impl *pimpl;
};
template <class Line>
Bbox_2_Line_2_pair intersection_computer_line_2(
Bbox_2 const &bbox, Line const &line)
{ {
return Bbox_2_Line_2_pair(bbox, to_double(line->a()), typedef typename K::Iso_rectangle_2 Iso_rectangle_2;
to_double(line->b()), to_double(line->c())); return Intersections::internal::do_intersect(line, Iso_rectangle_2(bbox), k);
} }
inline bool do_intersect_line_2( template <class K>
const Bbox_2 &box, double line_a, double line_b, double line_c) bool do_intersect(const CGAL::Bbox_2& bbox,
const typename K::Line_2& line,
const K& k)
{ {
Bbox_2_Line_2_pair pair(box, line_a, line_b, line_c); return Intersections::internal::do_intersect(line, bbox, k);
return pair.intersection_type() != Bbox_2_Line_2_pair::NO_INTERSECTION;
} }
template <class Line> } // namespace internal
bool do_intersect_line_2( } // namespace Intersections
Bbox_2 const &bbox, Line const &line)
template<typename K>
bool do_intersect(const CGAL::Bbox_2& bbox, const Line_2<K>& line)
{ {
return do_intersect_line_2(bbox, to_double(line->a()), return K().do_intersect_2_object()(bbox, line);
to_double(line->b()), to_double(line->c()));
} }
template <class Line> template<typename K>
bool do_intersect_line_2( bool do_intersect(const Line_2<K>& line, const CGAL::Bbox_2& bbox)
Line const &line, Bbox_2 const &bbox)
{ {
return do_intersect_line_2(bbox, to_double(line->a()), return K().do_intersect_2_object()(line, bbox);
to_double(line->b()), to_double(line->c()));
} }
template <class R> } // namespace CGAL
inline bool do_intersect(
const Line_2<R> &line,
const Bbox_2 &box)
{
return do_intersect(box, line);
}
} //namespace CGAL #endif // CGAL_INTERSECTIONS_2_BBOX_2_LINE_2_H
#ifdef CGAL_HEADER_ONLY
#include <CGAL/Intersections_2/internal/Bbox_2_Line_2_intersection_impl.h>
#endif // CGAL_HEADER_ONLY
#endif

View File

@ -29,29 +29,29 @@
#include <CGAL/Intersections_2/Iso_rectangle_2_Point_2.h> #include <CGAL/Intersections_2/Iso_rectangle_2_Point_2.h>
namespace CGAL { namespace CGAL {
template<typename K>
bool do_intersect(const CGAL::Bbox_2& a,
const Point_2<K>& b)
{
Point_2<K> bl(a.xmin(), a.ymin()), tr(a.xmax(), a.ymax());
Iso_rectangle_2<K> ic(bl,tr);
return K().do_intersect_2_object()(ic, b);
}
template<typename K>
bool do_intersect(const Point_2<K>& a,
const CGAL::Bbox_2& b)
{
return do_intersect(b,a);
}
namespace Intersections { namespace Intersections {
namespace internal { namespace internal {
template <class K>
inline bool do_intersect(const Bbox_2 &bbox,
const Point_2<K> &pt,
const K& k)
{
Point_2<K> bl(bbox.xmin(), bbox.ymin()),
tr(bbox.xmax(), bbox.ymax());
Iso_rectangle_2<K> ic(bl,tr);
return k.do_intersect_2_object()(ic, pt);
}
template <class K>
inline bool do_intersect(const Point_2<K> &pt,
const Bbox_2& bbox,
const K& k)
{
return do_intersect(bbox, pt, k);
}
template<typename K> template<typename K>
typename CGAL::Intersection_traits<K, typename K::Point_2, CGAL::Bbox_2>::result_type typename CGAL::Intersection_traits<K, typename K::Point_2, CGAL::Bbox_2>::result_type
intersection(const Point_2<K>& a, intersection(const Point_2<K>& a,
@ -77,6 +77,20 @@ intersection(const CGAL::Bbox_2& b,
} // namespace internal } // namespace internal
} // namespace Intersections } // namespace Intersections
template<typename K>
bool do_intersect(const CGAL::Bbox_2& a,
const Point_2<K>& b)
{
return Intersections::internal::do_intersect(a,b,K());
}
template<typename K>
bool do_intersect(const Point_2<K>& a,
const CGAL::Bbox_2& b)
{
return Intersections::internal::do_intersect(b,a,K());
}
template<typename K> template<typename K>
typename CGAL::Intersection_traits<K, Bbox_2, Point_2<K> >::result_type typename CGAL::Intersection_traits<K, Bbox_2, Point_2<K> >::result_type
intersection(const Bbox_2& b, intersection(const Bbox_2& b,
@ -92,6 +106,7 @@ typename CGAL::Intersection_traits<K, Bbox_2, Point_2<K> >::result_type
{ {
return Intersections::internal::intersection(b,a,K()); return Intersections::internal::intersection(b,a,K());
} }
} // namespace CGAL } // namespace CGAL
#endif // CGAL_INTERSECTIONS_2_BBOX_2_POINT_2_H #endif // CGAL_INTERSECTIONS_2_BBOX_2_POINT_2_H

View File

@ -23,61 +23,50 @@
// //
// Author(s) : Geert-Jan Giezeman // Author(s) : Geert-Jan Giezeman
#ifndef CGAL_INTERSECTIONS_2_BBOX_2_RAY_2_H
#ifndef CGAL_INTERSECTIONS_BBOX_2_RAY_2_H #define CGAL_INTERSECTIONS_2_BBOX_2_RAY_2_H
#define CGAL_INTERSECTIONS_BBOX_2_RAY_2_H
#include <CGAL/Bbox_2.h> #include <CGAL/Bbox_2.h>
#include <CGAL/Ray_2.h> #include <CGAL/Ray_2.h>
#include <CGAL/kernel_assertions.h>
#include <CGAL/number_utils.h> #include <CGAL/Intersections_2/Iso_rectangle_2_Ray_2.h>
namespace CGAL { namespace CGAL {
namespace Intersections {
namespace internal {
class Bbox_2_Ray_2_pair_impl; template <class K>
bool do_intersect(const typename K::Ray_2& ray,
class CGAL_EXPORT Bbox_2_Ray_2_pair { const CGAL::Bbox_2& bbox,
public: const K& k)
enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT};
~Bbox_2_Ray_2_pair() ;
Bbox_2_Ray_2_pair() ;
Bbox_2_Ray_2_pair(Bbox_2_Ray_2_pair const &o) ;
Bbox_2_Ray_2_pair(Bbox_2 const &box,
double x, double y, double dx, double dy) ;
Bbox_2_Ray_2_pair& operator=(Bbox_2_Ray_2_pair const &o) ;
Intersection_results intersection_type() const;
bool intersection(double &x, double &y) const;
bool intersection(double &x1, double &y1, double &x2, double &y2) const;
protected:
Bbox_2_Ray_2_pair_impl *pimpl;
};
CGAL_EXPORT bool do_intersect_ray_2(
const Bbox_2 &box, double x, double y, double dx, double dy);
template <class Ray>
bool do_intersect_ray_2(
const Bbox_2 &box,
const Ray &ray)
{ {
double startx = to_double(ray->start().x()); typedef typename K::Iso_rectangle_2 Iso_rectangle_2;
double starty = to_double(ray->start().y()); return Intersections::internal::do_intersect(ray, Iso_rectangle_2(bbox), k);
double dx = to_double(ray->direction().to_vector().x());
double dy = to_double(ray->direction().to_vector().y());
return do_intersect_ray_2(box, startx, starty, dx, dy);
} }
template <class Ray> template <class K>
inline bool do_intersect_ray_2( bool do_intersect(const CGAL::Bbox_2& bbox,
const Ray &ray, const typename K::Ray_2& ray,
const Bbox_2 &box) const K& k)
{ {
return do_intersect_ray_2(box, ray); return Intersections::internal::do_intersect(ray, bbox, k);
} }
} //namespace CGAL
#ifdef CGAL_HEADER_ONLY } // namespace internal
#include <CGAL/Intersections_2/internal/Ray_2_Bbox_2_intersection_impl.h> } // namespace Intersections
#endif // CGAL_HEADER_ONLY
#endif template<typename K>
bool do_intersect(const CGAL::Bbox_2& bbox, const Ray_2<K>& ray)
{
return K().do_intersect_2_object()(bbox, ray);
}
template<typename K>
bool do_intersect(const Ray_2<K>& ray, const CGAL::Bbox_2& bbox)
{
return K().do_intersect_2_object()(ray, bbox);
}
} // namespace CGAL
#endif // CGAL_INTERSECTIONS_2_BBOX_2_RAY_2_H

View File

@ -23,47 +23,38 @@
// //
// Author(s) : Geert-Jan Giezeman // Author(s) : Geert-Jan Giezeman
#ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_CIRCLE_2_H #ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_CIRCLE_2_H
#define CGAL_INTERSECTIONS_2_CIRCLE_2_CIRCLE_2_H #define CGAL_INTERSECTIONS_2_CIRCLE_2_CIRCLE_2_H
#include <CGAL/Circle_2.h> #include <CGAL/Circle_2.h>
#include <CGAL/squared_distance_2_1.h> #include <CGAL/squared_distance_2_1.h>
#include <CGAL/Intersection_traits_2.h>
namespace CGAL { namespace CGAL {
namespace Intersections { namespace Intersections {
namespace internal { namespace internal {
template <class K> template <class K>
bool bool do_intersect(const typename K::Circle_2 & circ1,
do_intersect(const typename K::Circle_2 & circ1, const typename K::Circle_2& circ2,
const typename K::Circle_2& circ2, const K&)
const K&)
{ {
typedef typename K::FT FT; typedef typename K::FT FT;
FT sr1 = circ1.squared_radius();
FT sr2 = circ2.squared_radius(); FT sr1 = circ1.squared_radius();
FT squared_dist = squared_distance(circ1.center(), circ2.center()); FT sr2 = circ2.squared_radius();
FT temp = sr1+sr2-squared_dist; FT squared_dist = squared_distance(circ1.center(), circ2.center());
return !(FT(4)*sr1*sr2 < temp*temp); FT temp = sr1+sr2-squared_dist;
return !(FT(4)*sr1*sr2 < temp*temp);
} }
} // namespace internal } // namespace internal
} // namespace Intersections } // namespace Intersections
template <class K> CGAL_DO_INTERSECT_FUNCTION_SELF(Circle_2, 2)
inline
bool
do_intersect(const Circle_2<K> & circ1,
const Circle_2<K> & circ2)
{
typedef typename K::Do_intersect_2 Do_intersect;
return Do_intersect()(circ1, circ2);
}
} // namespace CGAL
} //namespace CGAL
#endif #endif

View File

@ -23,13 +23,105 @@
#ifndef CGAL_INTERSECTIONS_2_ISO_RECTANGLE_2_CIRCLE_2_H #ifndef CGAL_INTERSECTIONS_2_ISO_RECTANGLE_2_CIRCLE_2_H
#define CGAL_INTERSECTIONS_2_ISO_RECTANGLE_2_CIRCLE_2_H #define CGAL_INTERSECTIONS_2_ISO_RECTANGLE_2_CIRCLE_2_H
#include <CGAL/Iso_rectangle_2.h>
#include <CGAL/Circle_2.h> #include <CGAL/Circle_2.h>
#include <CGAL/Iso_rectangle_2.h>
#include <CGAL/Intersections_2/internal/Bbox_2_Circle_2_do_intersect.h> #include <CGAL/Intersection_traits_2.h>
namespace CGAL { namespace CGAL {
CGAL_DO_INTERSECT_FUNCTION(Iso_rectangle_2, Circle_2, 2) namespace Intersections {
namespace internal {
// Circle_2 is not a disk, thus if the box is contained within the circle, there is no intersection.
template <class K>
bool do_intersect_circle_iso_rectangle_2(const typename K::Circle_2& circle,
const typename K::Iso_rectangle_2& rec,
const K&)
{
typedef typename K::FT FT;
typedef typename K::Point_2 Point;
Point center = circle.center();
// Check that the minimum distance to the box is smaller than the radius, otherwise there is
// no intersection.
FT distance = FT(0);
if(center.x() < rec.xmin())
{
FT d = rec.xmin() - center.x();
distance += d * d;
}
else if(center.x() > rec.xmax())
{
FT d = center.x() - rec.xmax();
distance += d * d;
}
if(center.y() < rec.ymin())
{
FT d = rec.ymin() - center.y();
distance += d * d;
}
else if(center.y() > rec.ymax())
{
FT d = center.y() - rec.ymax();
distance += d * d;
}
// Note that with the way the distance above is computed, the distance is '0' if the box strictly
// contains the circle. But since we use '>', we don't exit
if(distance > circle.squared_radius())
return false;
// Check that the maximum distance between the center of the circle and the box is not (strictly)
// smaller than the radius of the center, otherwise the box is entirely contained.
distance = FT(0);
if(center.x() <= (rec.xmin() + rec.xmax()) / FT(2))
{
FT d = rec.xmax() - center.x();
distance += d * d;
}
else
{
FT d = center.x() - rec.xmin();
distance += d * d;
}
if(center.y() < (rec.ymin() + rec.ymax()) / FT(2))
{
FT d = rec.ymax() - center.y();
distance += d * d;
}
else
{
FT d = center.y() - rec.ymin();
distance += d * d;
}
return (distance >= circle.squared_radius());
}
template <class K>
bool do_intersect(const typename K::Iso_rectangle_2& rec,
const typename K::Circle_2& circle,
const K&)
{
return do_intersect_circle_iso_rectangle_2(circle, rec, K());
}
template <class K>
bool do_intersect(const typename K::Circle_2& circle,
const typename K::Iso_rectangle_2& rec,
const K&)
{
return do_intersect_circle_iso_rectangle_2(circle, rec, K());
}
} // namespace internal
} // namespace Intersections
CGAL_DO_INTERSECT_FUNCTION(Iso_rectangle_2, Circle_2, 2)
} }
#endif // CGAL_INTERSECTIONS_2_ISO_RECTANGLE_2_CIRCLE_2_H #endif // CGAL_INTERSECTIONS_2_ISO_RECTANGLE_2_CIRCLE_2_H

View File

@ -30,6 +30,7 @@
#include <CGAL/Circle_2.h> #include <CGAL/Circle_2.h>
#include <CGAL/Line_2.h> #include <CGAL/Line_2.h>
#include <CGAL/squared_distance_2_1.h> #include <CGAL/squared_distance_2_1.h>
#include <CGAL/Intersection_traits_2.h>
namespace CGAL { namespace CGAL {
namespace Intersections { namespace Intersections {
@ -38,45 +39,26 @@ namespace internal {
template <class K> template <class K>
bool bool
do_intersect(const typename K::Circle_2 & c, do_intersect(const typename K::Circle_2 & c,
const typename K::Line_2& l, const typename K::Line_2& l,
const K&) const K&)
{ {
return squared_distance(c.center(), l) <= c.squared_radius(); return squared_distance(c.center(), l) <= c.squared_radius();
} }
template <class K> template <class K>
bool bool
do_intersect(const typename K::Line_2& l, do_intersect(const typename K::Line_2& l,
const typename K::Circle_2 & c, const typename K::Circle_2 & c,
const K&) const K&)
{ {
return squared_distance(c.center(), l) <= c.squared_radius(); return squared_distance(c.center(), l) <= c.squared_radius();
} }
} // namespace internal } // namespace internal
} // namespace Intersections } // namespace Intersections
template <class K> CGAL_DO_INTERSECT_FUNCTION(Circle_2, Line_2, 2)
inline
bool
do_intersect(const Circle_2<K> & c,
const Line_2<K> & l)
{
typedef typename K::Do_intersect_2 Do_intersect;
return Do_intersect()(c, l);
}
template <class K> } // namespace CGAL
inline
bool
do_intersect(const Line_2<K> & l,
const Circle_2<K> & c)
{
typedef typename K::Do_intersect_2 Do_intersect;
return Do_intersect()(c, l);
}
} //namespace CGAL
#endif #endif

View File

@ -273,6 +273,9 @@ namespace internal {
typename std::vector<Point>::iterator last = std::unique(result.begin(),result.end()); typename std::vector<Point>::iterator last = std::unique(result.begin(),result.end());
result.erase(last,result.end()); result.erase(last,result.end());
while(result.size() > 1 && result.back() == result.front())
result.pop_back();
switch(result.size()){ switch(result.size()){
case 0: case 0:
return intersection_return<typename K::Intersect_2, Triangle, typename K::Iso_rectangle_2>(); return intersection_return<typename K::Intersect_2, Triangle, typename K::Iso_rectangle_2>();

View File

@ -157,7 +157,7 @@ intersection(const typename K::Ray_2 &ray,
default: default:
return intersection_return<typename K::Intersect_2, typename K::Ray_2, typename K::Triangle_2>(); return intersection_return<typename K::Intersect_2, typename K::Ray_2, typename K::Triangle_2>();
case is_t::POINT: case is_t::POINT:
return intersection_return<typename K::Intersect_2, typename K::Ray_2, typename K::Triangle_2>(ispair.intersection_segment()); return intersection_return<typename K::Intersect_2, typename K::Ray_2, typename K::Triangle_2>(ispair.intersection_point());
case is_t::SEGMENT: case is_t::SEGMENT:
return intersection_return<typename K::Intersect_2, typename K::Ray_2, typename K::Triangle_2>(ispair.intersection_segment()); return intersection_return<typename K::Intersect_2, typename K::Ray_2, typename K::Triangle_2>(ispair.intersection_segment());
} }

View File

@ -1,112 +0,0 @@
// Copyright (c) 2018 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
//
// Author(s) : Andreas Fabri
#ifndef CGAL_INTERNAL_INTERSECTIONS_2_BBOX_2_CIRCLE_2_DO_INTERSECT_H
#define CGAL_INTERNAL_INTERSECTIONS_2_BBOX_2_CIRCLE_2_DO_INTERSECT_H
#include <CGAL/Circle_2.h>
#include <CGAL/Bbox_2.h>
#include <CGAL/number_utils.h>
namespace CGAL {
namespace Intersections {
namespace internal {
template <class K, class Box3>
bool do_intersect_circle_box_2(const typename K::Circle_2& circle,
const Box3& bbox,
const K&)
{
typedef typename K::FT FT;
typedef typename K::Point_2 Point;
FT d = FT(0);
FT distance = FT(0);
Point center = circle.center();
if(center.x() < FT(bbox.xmin()))
{
d = FT(bbox.xmin()) - center.x();
distance += d * d;
}
else if(center.x() > FT(bbox.xmax()))
{
d = center.x() - FT(bbox.xmax());
distance += d * d;
}
if(center.y() < FT(bbox.ymin()))
{
d = FT(bbox.ymin()) - center.y();
distance += d * d;
}
else if(center.y() > FT(bbox.ymax()))
{
d = center.y() - FT(bbox.ymax());
distance += d * d;
}
return distance <= circle.squared_radius();
}
template <class K>
bool do_intersect(const CGAL::Bbox_2& bbox,
const typename K::Circle_2& circle,
const K&)
{
return do_intersect_circle_box_2(circle, bbox, K());
}
template <class K>
bool do_intersect(const typename K::Circle_2& circle,
const CGAL::Bbox_2& bbox,
const K&)
{
return do_intersect_circle_box_2(circle, bbox, K());
}
template <class K>
bool do_intersect(const typename K::Iso_rectangle_2& bbox,
const typename K::Circle_2& circle,
const K&)
{
return do_intersect_circle_box_2(circle, bbox, K());
}
template <class K>
bool do_intersect(const typename K::Circle_2& circle,
const typename K::Iso_rectangle_2& bbox,
const K&)
{
return do_intersect_circle_box_2(circle, bbox, K());
}
} // namespace internal
} // namespace Intersections
} //namespace CGAL
#endif // CGAL_INTERNAL_INTERSECTIONS_2_BBOX_2_CIRCLE_2_DO_INTERSECT_H

View File

@ -1,211 +0,0 @@
// Copyright (c) 2000
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
//
// Author(s) : Geert-Jan Giezeman
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> Lcart;
namespace CGAL {
class Bbox_2_Line_2_pair_impl
{
public:
Bbox_2_Line_2_pair_impl() {}
Bbox_2_Line_2_pair_impl(Bbox_2 const &bb, Lcart::Line_2 const &line)
: _bbox(bb), _line(line), _known(false) {}
Bbox_2 _bbox;
Lcart::Line_2 _line;
mutable bool _known;
mutable Bbox_2_Line_2_pair::Intersection_results _result;
mutable double _min, _max;
};
CGAL_INLINE_FUNCTION
Bbox_2_Line_2_pair::~Bbox_2_Line_2_pair()
{
delete pimpl;
}
CGAL_INLINE_FUNCTION
Bbox_2_Line_2_pair::Bbox_2_Line_2_pair()
{
pimpl = new Bbox_2_Line_2_pair_impl;
pimpl->_known = false;
}
CGAL_INLINE_FUNCTION
Bbox_2_Line_2_pair::Bbox_2_Line_2_pair(Bbox_2_Line_2_pair const &o)
{
pimpl = new Bbox_2_Line_2_pair_impl(*o.pimpl);
}
CGAL_INLINE_FUNCTION
Bbox_2_Line_2_pair::Bbox_2_Line_2_pair(
Bbox_2 const &bbox, double line_a, double line_b, double line_c)
{
pimpl = new Bbox_2_Line_2_pair_impl(bbox,
Lcart::Line_2(line_a, line_b, line_c));
}
CGAL_INLINE_FUNCTION
Bbox_2_Line_2_pair &
Bbox_2_Line_2_pair::operator=(Bbox_2_Line_2_pair const &o)
{
*pimpl = *o.pimpl;
return *this;
}
CGAL_INLINE_FUNCTION
Bbox_2_Line_2_pair::Intersection_results
Bbox_2_Line_2_pair::intersection_type() const
{
if (pimpl->_known)
return pimpl->_result;
// The non const this pointer is used to cast away const.
pimpl->_known = true;
const Lcart::Point_2 &ref_point = pimpl->_line.point();
const Lcart::Vector_2 &dir =
pimpl->_line.direction().to_vector();
bool to_infinity = true;
// first on x value
if (dir.x() == 0.0) {
if (ref_point.x() < pimpl->_bbox.xmin()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
if (ref_point.x() > pimpl->_bbox.xmax()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
} else {
double newmin, newmax;
if (dir.x() > 0.0) {
newmin = (pimpl->_bbox.xmin()-ref_point.x())/dir.x();
newmax = (pimpl->_bbox.xmax()-ref_point.x())/dir.x();
} else {
newmin = (pimpl->_bbox.xmax()-ref_point.x())/dir.x();
newmax = (pimpl->_bbox.xmin()-ref_point.x())/dir.x();
}
if (to_infinity) {
pimpl->_min = newmin;
pimpl->_max = newmax;
} else {
if (newmin > pimpl->_min)
pimpl->_min = newmin;
if (newmax < pimpl->_max)
pimpl->_max = newmax;
if (pimpl->_max < pimpl->_min) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
}
to_infinity = false;
}
// now on y value
if (dir.y() == 0.0) {
if (ref_point.y() < pimpl->_bbox.ymin()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
if (ref_point.y() > pimpl->_bbox.ymax()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
} else {
double newmin, newmax;
if (dir.y() > 0.0) {
newmin = (pimpl->_bbox.ymin()-ref_point.y())/dir.y();
newmax = (pimpl->_bbox.ymax()-ref_point.y())/dir.y();
} else {
newmin = (pimpl->_bbox.ymax()-ref_point.y())/dir.y();
newmax = (pimpl->_bbox.ymin()-ref_point.y())/dir.y();
}
if (to_infinity) {
pimpl->_min = newmin;
pimpl->_max = newmax;
} else {
if (newmin > pimpl->_min)
pimpl->_min = newmin;
if (newmax < pimpl->_max)
pimpl->_max = newmax;
if (pimpl->_max < pimpl->_min) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
}
to_infinity = false;
}
CGAL_kernel_assertion(!to_infinity);
if (pimpl->_max == pimpl->_min) {
pimpl->_result = POINT;
return pimpl->_result;
}
pimpl->_result = SEGMENT;
return pimpl->_result;
}
CGAL_INLINE_FUNCTION
bool
Bbox_2_Line_2_pair::intersection(
double &x1, double &y1, double &x2, double &y2) const
{
if (!pimpl->_known)
intersection_type();
if (pimpl->_result != SEGMENT)
return false;
Lcart::Point_2 p1(pimpl->_line.point()
+ pimpl->_min*pimpl->_line.direction().to_vector());
Lcart::Point_2 p2(pimpl->_line.point()
+ pimpl->_max*pimpl->_line.direction().to_vector());
x1 = p1.x();
y1 = p1.y();
x2 = p2.x();
y2 = p2.y();
return true;
}
CGAL_INLINE_FUNCTION
bool
Bbox_2_Line_2_pair::intersection(
double &x, double &y) const
{
if (!pimpl->_known)
intersection_type();
if (pimpl->_result != POINT)
return false;
Lcart::Point_2 pt(pimpl->_line.point()
+ pimpl->_min*pimpl->_line.direction().to_vector());
x = pt.x();
y = pt.y();
return true;
}
} //namespace CGAL

View File

@ -1,209 +0,0 @@
// Copyright (c) 2000
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
//
// Author(s) : Geert-Jan Giezeman
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> Rcart;
namespace CGAL {
class Bbox_2_Ray_2_pair_impl
{
public:
Bbox_2_Ray_2_pair_impl():_known(false) {}
Bbox_2_Ray_2_pair_impl(Bbox_2 const &bbox, Rcart::Point_2 const &pt,
Rcart::Vector_2 const &dir)
:_box(bbox), _known(false), _ref_point(pt), _dir(dir), _min(0.0) {}
Ray_2< Rcart > _ray;
Bbox_2 _box;
bool _known;
Bbox_2_Ray_2_pair::Intersection_results _result;
Rcart::Point_2 _ref_point;
Rcart::Vector_2 _dir;
double _min, _max;
};
CGAL_INLINE_FUNCTION
Bbox_2_Ray_2_pair::~Bbox_2_Ray_2_pair()
{
delete pimpl;
}
CGAL_INLINE_FUNCTION
Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair()
{
pimpl = new Bbox_2_Ray_2_pair_impl;
}
CGAL_INLINE_FUNCTION
Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair(Bbox_2_Ray_2_pair const &o)
{
pimpl = new Bbox_2_Ray_2_pair_impl(*o.pimpl);
}
CGAL_INLINE_FUNCTION
Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair(
Bbox_2 const &bbox, double x, double y, double dx, double dy)
{
pimpl = new Bbox_2_Ray_2_pair_impl(bbox,
Rcart::Point_2(x,y), Rcart::Vector_2(dx,dy));
}
CGAL_INLINE_FUNCTION
Bbox_2_Ray_2_pair &
Bbox_2_Ray_2_pair::operator=(Bbox_2_Ray_2_pair const &o)
{
*pimpl = *o.pimpl;
return *this;
}
CGAL_INLINE_FUNCTION
Bbox_2_Ray_2_pair::Intersection_results
Bbox_2_Ray_2_pair::intersection_type() const
{
if (pimpl->_known)
return pimpl->_result;
pimpl->_known = true;
bool to_infinity = true;
// first on x value
if (pimpl->_dir.x() == 0.0) {
if (pimpl->_ref_point.x() < pimpl->_box.xmin()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
if (pimpl->_ref_point.x() > pimpl->_box.xmax()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
} else {
double newmin, newmax;
if (pimpl->_dir.x() > 0.0) {
newmin =(pimpl->_box.xmin()-pimpl->_ref_point.x())/pimpl->_dir.x();
newmax =(pimpl->_box.xmax()-pimpl->_ref_point.x())/pimpl->_dir.x();
} else {
newmin =(pimpl->_box.xmax()-pimpl->_ref_point.x())/pimpl->_dir.x();
newmax =(pimpl->_box.xmin()-pimpl->_ref_point.x())/pimpl->_dir.x();
}
if (newmin > pimpl->_min)
pimpl->_min = newmin;
if (to_infinity) {
pimpl->_max = newmax;
} else {
if (newmax < pimpl->_max)
pimpl->_max = newmax;
}
if (pimpl->_max < pimpl->_min){
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
to_infinity = false;
}
// now on y value
if (pimpl->_dir.y() == 0.0) {
if (pimpl->_ref_point.y() < pimpl->_box.ymin()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
if (pimpl->_ref_point.y() > pimpl->_box.ymax()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
} else {
double newmin, newmax;
if (pimpl->_dir.y() > 0.0) {
newmin =(pimpl->_box.ymin()-pimpl->_ref_point.y())/pimpl->_dir.y();
newmax =(pimpl->_box.ymax()-pimpl->_ref_point.y())/pimpl->_dir.y();
} else {
newmin =(pimpl->_box.ymax()-pimpl->_ref_point.y())/pimpl->_dir.y();
newmax =(pimpl->_box.ymin()-pimpl->_ref_point.y())/pimpl->_dir.y();
}
if (newmin > pimpl->_min)
pimpl->_min = newmin;
if (to_infinity) {
pimpl->_max = newmax;
} else {
if (newmax < pimpl->_max)
pimpl->_max = newmax;
}
if (pimpl->_max < pimpl->_min) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
to_infinity = false;
}
CGAL_kernel_assertion(!to_infinity);
if (pimpl->_max == pimpl->_min) {
pimpl->_result = POINT;
return pimpl->_result;
}
pimpl->_result = SEGMENT;
return pimpl->_result;
}
CGAL_INLINE_FUNCTION
bool Bbox_2_Ray_2_pair::
intersection(double &x1, double &y1, double &x2, double &y2) const
{
if (!pimpl->_known)
intersection_type();
if (pimpl->_result != SEGMENT)
return false;
Rcart::Point_2 p1(pimpl->_ref_point + pimpl->_min*pimpl->_dir);
Rcart::Point_2 p2(pimpl->_ref_point + pimpl->_max*pimpl->_dir);
x1 = p1.x();
y1 = p1.y();
x2 = p2.x();
y2 = p2.y();
return true;
}
CGAL_INLINE_FUNCTION
bool Bbox_2_Ray_2_pair::intersection(double &x, double &y) const
{
if (!pimpl->_known)
intersection_type();
if (pimpl->_result != POINT)
return false;
Rcart::Point_2 pt = pimpl->_ref_point + pimpl->_min*pimpl->_dir;
x = pt.x();
y = pt.y();
return true;
}
CGAL_INLINE_FUNCTION
bool do_intersect_ray_2(
const Bbox_2 &box, double x, double y, double dx, double dy)
{
Bbox_2_Ray_2_pair pair(box, x, y, dx, dy);
return pair.intersection_type() != Bbox_2_Ray_2_pair::NO_INTERSECTION;
}
} //namespace CGAL

View File

@ -29,10 +29,12 @@
#define CGAL_INTERSECTION_2_H #define CGAL_INTERSECTION_2_H
#include <CGAL/Intersections_2/Bbox_2_Circle_2.h> #include <CGAL/Intersections_2/Bbox_2_Circle_2.h>
#include <CGAL/Intersections_2/Bbox_2_Line_2.h>
#include <CGAL/Intersections_2/Bbox_2_Point_2.h> #include <CGAL/Intersections_2/Bbox_2_Point_2.h>
#include <CGAL/Intersections_2/Bbox_2_Ray_2.h>
#include <CGAL/Intersections_2/Circle_2_Iso_rectangle_2.h>
#include <CGAL/Intersections_2/Circle_2_Circle_2.h> #include <CGAL/Intersections_2/Circle_2_Circle_2.h>
#include <CGAL/Intersections_2/Circle_2_Iso_rectangle_2.h>
#include <CGAL/Intersections_2/Circle_2_Line_2.h> #include <CGAL/Intersections_2/Circle_2_Line_2.h>
#include <CGAL/Intersections_2/Circle_2_Point_2.h> #include <CGAL/Intersections_2/Circle_2_Point_2.h>
@ -49,9 +51,9 @@
#include <CGAL/Intersections_2/Line_2_Segment_2.h> #include <CGAL/Intersections_2/Line_2_Segment_2.h>
#include <CGAL/Intersections_2/Line_2_Triangle_2.h> #include <CGAL/Intersections_2/Line_2_Triangle_2.h>
#include <CGAL/Intersections_2/Point_2_Point_2.h>
#include <CGAL/Intersections_2/Point_2_Ray_2.h> #include <CGAL/Intersections_2/Point_2_Ray_2.h>
#include <CGAL/Intersections_2/Point_2_Segment_2.h> #include <CGAL/Intersections_2/Point_2_Segment_2.h>
#include <CGAL/Intersections_2/Point_2_Point_2.h>
#include <CGAL/Intersections_2/Point_2_Triangle_2.h> #include <CGAL/Intersections_2/Point_2_Triangle_2.h>
#include <CGAL/Intersections_2/Ray_2_Ray_2.h> #include <CGAL/Intersections_2/Ray_2_Ray_2.h>
@ -63,5 +65,4 @@
#include <CGAL/Intersections_2/Triangle_2_Triangle_2.h> #include <CGAL/Intersections_2/Triangle_2_Triangle_2.h>
#endif // CGAL_INTERSECTION_2_H #endif // CGAL_INTERSECTION_2_H

View File

@ -1,34 +0,0 @@
// Copyright (c) 2000
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
//
// Author(s) : Geert-Jan Giezeman
#ifndef CGAL_HEADER_ONLY
#include <CGAL/Intersections_2/Bbox_2_Line_2.h>
#include <CGAL/Intersections_2/internal/Bbox_2_Line_2_intersection_impl.h>
#include <CGAL/Intersections_2/Bbox_2_Ray_2.h>
#include <CGAL/Intersections_2/internal/Ray_2_Bbox_2_intersection_impl.h>
#endif // CGAL_HEADER_ONLY

View File

@ -1,21 +1,14 @@
// 2D intersection tests. // 2D intersection tests.
#include <CGAL/Simple_cartesian.h> #include <CGAL/Simple_cartesian.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Homogeneous.h> #include <CGAL/Homogeneous.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Intersection_traits_2.h> #include <CGAL/FPU.h>
#include <CGAL/Intersections_2/Segment_2_Segment_2.h> #include <CGAL/internal/Exact_type_selector.h>
#include <CGAL/Intersections_2/Line_2_Line_2.h> #include <CGAL/intersection_2.h>
#include <CGAL/Intersections_2/Ray_2_Ray_2.h>
#include <CGAL/Intersections_2/Triangle_2_Triangle_2.h>
#include <CGAL/Intersections_2/Iso_rectangle_2_Line_2.h>
#include <CGAL/Intersections_2/Iso_rectangle_2_Ray_2.h>
#include <CGAL/Intersections_2/Bbox_2_Circle_2.h>
#include <CGAL/Intersections_2/Bbox_2_Point_2.h>
#include <CGAL/Intersections_2/Circle_2_Iso_rectangle_2.h>
#include <CGAL/Intersections_2/Circle_2_Point_2.h>
#include <CGAL/Intersections_2/Point_2_Point_2.h>
#include <vector> #include <vector>
#include <iostream> #include <iostream>
@ -23,7 +16,8 @@
const double epsilon = 0.001; const double epsilon = 0.001;
struct randomint { struct randomint
{
randomint() ; randomint() ;
int get() const { return sequence[cur]; } int get() const { return sequence[cur]; }
int next() { cur = (cur+1)%11; return get();} int next() { cur = (cur+1)%11; return get();}
@ -55,9 +49,9 @@ inline double to_nt(int d)
return double(d); return double(d);
} }
template < typename K > template <typename K >
struct Test { struct Test
{
typedef typename K::Point_2 P; typedef typename K::Point_2 P;
typedef typename K::Line_2 L; typedef typename K::Line_2 L;
typedef typename K::Segment_2 S; typedef typename K::Segment_2 S;
@ -65,86 +59,114 @@ struct Test {
typedef typename K::Triangle_2 T; typedef typename K::Triangle_2 T;
typedef typename K::Iso_rectangle_2 Rec; typedef typename K::Iso_rectangle_2 Rec;
typedef typename K::Circle_2 C; typedef typename K::Circle_2 C;
typedef std::vector<P> Pol;
typedef CGAL::Bbox_2 B;
typedef std::vector<P> Pol;
template < typename Type > Test(const K& k = K()) : kernel(k) { }
template <typename Type >
bool approx_equal_nt(const Type &t1, const Type &t2) bool approx_equal_nt(const Type &t1, const Type &t2)
{ {
if (t1 == t2) if (t1 == t2)
return true; return true;
if (CGAL::abs(t1 - t2) / (CGAL::max)(CGAL::abs(t1), CGAL::abs(t2)) < epsilon)
return true; if (CGAL::abs(t1 - t2) / (CGAL::max)(CGAL::abs(t1), CGAL::abs(t2)) < epsilon)
std::cout << " Approximate comparison failed between : " << t1 << " and " << t2 << "\n"; return true;
return false;
std::cout << " Approximate comparison failed between : " << t1 << " and " << t2 << "" << std::endl;
return false;
} }
template < typename Type > template <typename Type >
bool approx_equal(const Type&t1, const Type&t2) bool approx_equal(const Type&t1, const Type&t2)
{ {
return t1 == t2; return t1 == t2;
// we need approx equal to check approx kernels, but maybe we should only test with exact kernels // we need approx equal to check approx kernels, but maybe we should only test with exact kernels
// (approx kernels were useful before, when the text output was checked by diff ?) // (approx kernels were useful before, when the text output was checked by diff ?)
// idea : test containment with intervals ? or use some "epsilon double"? // idea : test containment with intervals ? or use some "epsilon double"?
// I need to convert the text output to exact rationals in the source... // I need to convert the text output to exact rationals in the source...
// Well, for now the current scheme works. // Well, for now the current scheme works.
} }
bool approx_equal(const P & p, const P & q) bool approx_equal(const P & p, const P & q)
{ {
return approx_equal_nt(p.x(), q.x()) && approx_equal_nt(p.y(), q.y()); return approx_equal_nt(p.x(), q.x()) && approx_equal_nt(p.y(), q.y());
} }
bool approx_equal(const Pol & p, const Pol & q) bool approx_equal(const Pol & p, const Pol & q)
{ {
if (p.size() != q.size()) if (p.size() != q.size())
return false; return false;
for(typename Pol::const_iterator itp = p.begin(), itq = q.begin(); itp != p.end(); ++itp, ++itq)
if (!approx_equal(*itp, *itq)) for(typename Pol::const_iterator itp = p.begin(), itq = q.begin(); itp != p.end(); ++itp, ++itq)
return false; if (!approx_equal(*itp, *itq))
return true; return false;
return true;
} }
template < typename O1, typename O2> template <typename O1, typename O2>
void check_no_do_intersect(const O1& o1, const O2& o2)
{
assert(!CGAL::do_intersect(o1, o2));
assert(!CGAL::do_intersect(o2, o1));
typename K::Do_intersect_2 do_2 = kernel.do_intersect_2_object();
assert(!do_2(o1, o2));
assert(!do_2(o2, o1));
}
template <typename O1, typename O2>
void check_no_intersection(const O1& o1, const O2& o2) void check_no_intersection(const O1& o1, const O2& o2)
{ {
assert(!CGAL::do_intersect(o1, o2)); check_no_do_intersect(o1, o2);
assert(!CGAL::do_intersect(o2, o1));
assert(!CGAL::intersection(o2, o1));
//check with the functors assert(!CGAL::intersection(o2, o1));
typename CGAL::Kernel_traits<O1>::Kernel::Do_intersect_2 do_2;
typename CGAL::Kernel_traits<O1>::Kernel::Intersect_2 i_2; typename K::Intersect_2 i_2 = kernel.intersect_2_object();
assert(!do_2(o1, o2)); assert(!i_2(o1, o2));
assert(!i_2(o1, o2)); assert(!i_2(o2, o1));
assert(!do_2(o2, o1));
assert(!i_2(o2, o1));
} }
template < typename Res, typename O1, typename O2 > template <typename O1, typename O2 >
void check_do_intersect(const O1& o1, const O2& o2)
{
assert(CGAL::do_intersect(o1, o2));
assert(CGAL::do_intersect(o2, o1));
}
template <typename Res, typename O1, typename O2 >
void check_intersection(const O1& o1, const O2& o2) void check_intersection(const O1& o1, const O2& o2)
{ {
Res tmp; check_do_intersect(o1, o2);
assert(CGAL::do_intersect(o1, o2));
assert(CGAL::assign(tmp, CGAL::intersection(o1, o2))); Res tmp;
assert(CGAL::do_intersect(o2, o1)); assert(CGAL::assign(tmp, CGAL::intersection(o1, o2)));
assert(CGAL::assign(tmp, CGAL::intersection(o2, o1))); assert(CGAL::assign(tmp, CGAL::intersection(o2, o1)));
} }
template < typename Res, typename O1, typename O2 > template <typename Res, typename O1, typename O2 >
void check_intersection(const O1& o1, const O2& o2, const Res& result, bool do_opposite=true) void check_intersection(const O1& o1, const O2& o2, const Res& result, bool do_opposite=true)
{ {
Res tmp; check_do_intersect(o1, o2);
assert(CGAL::do_intersect(o1, o2));
assert(CGAL::assign(tmp, CGAL::intersection(o1, o2))); Res tmp;
assert(approx_equal(tmp, result));
if (do_opposite) { assert(CGAL::assign(tmp, CGAL::intersection(o1, o2)));
assert(CGAL::do_intersect(o2, o1)); assert(approx_equal(tmp, result));
assert(CGAL::assign(tmp, CGAL::intersection(o2, o1))); if (do_opposite)
assert(approx_equal(tmp, result)); {
} assert(CGAL::assign(tmp, CGAL::intersection(o2, o1)));
assert(approx_equal(tmp, result));
}
} }
template <typename O >
void check_intersection(const O& o)
{
return check_intersection(o, o, o);
}
P p(int x, int y) P p(int x, int y)
{ {
@ -152,92 +174,323 @@ struct Test {
return P(to_nt(x*w), to_nt(y*w), to_nt(w)); return P(to_nt(x*w), to_nt(y*w), to_nt(w));
} }
void B_C()
{
std::cout << "Bbox - Circle" << std::endl;
// no intersection
check_no_do_intersect (p(0, 0).bbox() + p( 2, 3).bbox(), C(p( 8, 9), 3));
check_no_do_intersect (p(8, 9).bbox() + p( 9, 10).bbox(), C(p( 9, 9), 9)); // circle containing the bbox
// point intersection
check_do_intersect (p(0, 0).bbox() + p( 2, 3).bbox(), C(p(-1, 0), 1));
check_do_intersect (p(0, 0).bbox() + p( 2, 3).bbox(), C(p( 1, 1), 1));
// generic intersection
check_do_intersect (p(0, 0).bbox() + p( 2, 3).bbox(), C(p(-1, 0), 2));
check_do_intersect (p(0, 0).bbox() + p( 2, 0).bbox(), C(p( 1, 0), 1));
check_do_intersect (p(0, 0).bbox() + p(10, 10).bbox(), C(p( 3, 2), 3));
}
void B_L()
{
std::cout << "Bbox - Line" << std::endl;
// no intersection
check_no_do_intersect (p(0,0).bbox() , L(p( 1,1), p( 0,1)));
check_no_do_intersect (p(0,0).bbox() + p(4,5).bbox(), L(p(-1,1), p(-1,5)));
// point intersection
check_do_intersect (p( 0, 0).bbox() , L(p(-1,1), p( 1,-1)));
check_do_intersect (p(-1,-1).bbox() + p(4,2).bbox(), L(p( 1,5), p(-3,-1)));
// segment intersection
check_do_intersect (p(0,0).bbox() + p(4,5).bbox(), L(p(-1, 5), p(7,5)));
check_do_intersect (p(0,0).bbox() + p(4,5).bbox(), L(p(-1, 5), p(2,5)));
check_do_intersect (p(0,0).bbox() + p(4,5).bbox(), L(p( 4,-3), p(4,1)));
}
void B_P() void B_P()
{ {
CGAL::Bbox_2 bb(0,0,10,10); std::cout << "Bbox - Point" << std::endl;
P p(1,0), bl(0,0), tr(10,10);
C c(bl,1); // no intersection
Rec r(bl,tr); check_no_intersection (p(1,2).bbox() + p(4,6).bbox(), p(8,9)); // point is outside the bbox
check_intersection(bb,p,p,true);
check_intersection(c,p,p,true); // point intersection
assert(do_intersect(r,c)); check_intersection (p(1,2).bbox() , p(1,2), p(1,2)); // degenerate bbox (0d)
check_intersection (p(1,2).bbox() + p(4,2).bbox(), p(2,2), p(2,2)); // degenerate bbox (1d)
check_intersection (p(1,2).bbox() + p(4,6).bbox(), p(1,6), p(1,6)); // point is a bbox corner
check_intersection (p(1,2).bbox() + p(4,6).bbox(), p(3,6), p(3,6)); // point is on a bbox edge
check_intersection (p(1,2).bbox() + p(4,6).bbox(), p(3,3), p(3,3)); // point is within the bbox
}
void B_R()
{
std::cout << "Bbox - Ray" << std::endl;
// no intersection
check_no_do_intersect (p(0,0).bbox() , R(p( 1,1), p( 0,1)));
check_no_do_intersect (p(0,0).bbox() + p(4,5).bbox(), R(p(-1,1), p(-1,5)));
// point intersection
check_do_intersect (p( 0, 0).bbox() , R(p(-1,1), p( 1,-1)));
check_do_intersect (p(-1,-1).bbox() + p(4,2).bbox(), R(p( 1,5), p(-3,-1)));
// segment intersection
check_do_intersect (p(0,0).bbox() + p(4,5).bbox(), R(p(-1, 5), p(7,5)));
check_do_intersect (p(0,0).bbox() + p(4,5).bbox(), R(p(-1, 5), p(2,5)));
check_do_intersect (p(0,0).bbox() + p(4,5).bbox(), R(p( 4,-3), p(4,1)));
}
void C_C()
{
std::cout << "Circle - Circle" << std::endl;
// no intersection
check_no_do_intersect (C(p(13, 14), 5), C(p( 3, 2), 1));
check_no_do_intersect (C(p( 2, 3), 9), C(p( 3, 4), 1)); // one contains the other
// point intersection
check_do_intersect (C(p(-1, -4), 0), C(p(-1, -4), 0));
check_do_intersect (C(p( 3, 4), 25), C(p( 6, 8), 0));
check_do_intersect (C(p( 3, 4), 1), C(p( 3, 2), 1));
// more than point intersection
check_do_intersect (C(p( 2, 5), 9), C(p(-3, 2), 9));
check_do_intersect (C(p( 1, 2), 1), C(p( 1, 2), 1)); // same cicle twice
}
void C_Rec()
{
std::cout << "Circle - Iso_rectangle" << std::endl;
// no intersection
check_no_do_intersect (C(p( 2, 1), 0), Rec(p( 3, 2), p( 4, 6)));
check_no_do_intersect (C(p(13, 14), 5), Rec(p( 3, 2), p( 4, 6)));
check_no_do_intersect (C(p(13, 14), 9), Rec(p(12, 13), p(14, 15))); // circle contains the box
// point intersection
check_do_intersect (C(p(-3, -2), 0), Rec(p(-3, -2), p(14, 2))); // vertex of the rectangle
check_do_intersect (C(p( 0, 0), 4), Rec(p( 0, 2), p(12, 9))); // vertex of the rectangle
check_do_intersect (C(p(-4, 3), 0), Rec(p(-6, 2), p( 7, 3))); // point on an edge
check_do_intersect (C(p( 0, 0), 4), Rec(p(-2, 2), p(13, 4))); // point on an edge
// more than point intersection
check_do_intersect (C(p( 5, 5), 4), Rec(p( 3, 3), p( 7, 7)));
check_do_intersect (C(p(10, 10), 2), Rec(p( 0, 0), p(10, 10)));
check_do_intersect (C(p(13, 14), 3), Rec(p( 1, 1), p(30, 32))); // rectangle contains the circle
check_do_intersect (C(p( 0, 0), 25), Rec(p(-3, -4), p( 3, 4))); // inscribed circle of the box
// intersection with all vertices outside of the circle
check_do_intersect (C(p( 0, 0), 9), Rec(p(-10, 2), p(10, 13)));
}
void C_L()
{
std::cout << "Circle - Line" << std::endl;
// no intersection
check_no_do_intersect (C(p( 2, 8), 6), L(p(-3, -2), p( 2, 4)));
check_no_do_intersect (C(p( 2, 8), 6), L(p(-3, 22), p( 2, 14)));
// point intersection
check_do_intersect (C(p( 3, 4), 0), L(p(-3, 8), p( 6, 2)));
check_do_intersect (C(p( 4, 3), 4), L(p( 6, -7), p( 6, -2)));
check_do_intersect (C(p( 4, 3), 4), L(p( 6, -7), p( 6, -9)));
// two points intersection
check_do_intersect (C(p(-3, 1), 7), L(p(-1, -3), p(-6, 7)));
}
void C_P()
{
std::cout << "Circle - Point" << std::endl;
// no intersection
check_no_intersection (C(p(13, 14), 5) , p(13, 14));
check_no_intersection (C(p( 2, 9), 4) , p(11, 12));
// point intersection
check_intersection (C(p( 3, 4), 16) , p( 7, 4), p(7, 4));
check_intersection (C(p( 0, 5), p(5, 0), p(-5, 0)), p( 0, -5), p(0, -5));
// check_intersection (C(p( 3, 4), p(2, 6), p( 1, 5)), p( 1, 5), p(1, 5));
check_intersection<P> (C(p( 0, 0), 25) , p( 5, 0));
} }
void L_L() void L_L()
{ {
std::cout << "Line - Line\n"; std::cout << "Line - Line" << std::endl;
check_intersection (L(p(0, 0), p(10, 0)), L(p(1,7), p(1,-2)), P(1,0));
check_intersection (L(p(0,-1), p(10, 0)), L(p(2,1), p(8,-6)), P(3.42105,-0.657895));
check_intersection<L> (L(p(0, 0), p(10, 0)), L(p(1,0), p(8, 0)));
check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0))); // no intersection
check_intersection<L> (L(p(0, 0), p(10, 0)), L(p(8,0), p(1, 0))); check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0)));
// point intersection
check_intersection (L(p(0, 0), p(10, 0)), L(p( 1, 7), p( 1, -2)), P(1,0));
check_intersection (L(p(0,-1), p(10, 0)), L(p( 2, 1), p( 8, -6)), P(3.42105,-0.657895));
check_intersection<P> (L(p(0, 0), p( 0, 4)), L(p(-1,-3), p(-10, -10)));
// line intersection
check_intersection (L(p( 1, 1), p( 5, 5)));
check_intersection<L> (L(p( 1, 1), p( 5, 5)), L(p(3, 3), p( 7, 7))); // ps0 < ps1 < pt0 < pt1
check_intersection<L> (L(p( 5, 5), p( 1, 1)), L(p(3, 3), p( 7, 7))); // L0 & L1 have opposite directions
check_intersection<L> (L(p( 0, 0), p(10, 0)), L(p(0, 0), p(10, 0))); // ps0 == ps1 < pt0 == pt1
check_intersection<L> (L(p(10, 0), p( 0, 0)), L(p(0, 0), p(10, 0))); // ps1 == pt0 < ps0 == pt1
check_intersection<L> (L(p( 0, 0), p(10, 0)), L(p(1, 0), p( 8, 0))); // ps0 < ps1 < pt1 < pt0
check_intersection<L> (L(p( 0, 0), p(10, 0)), L(p(8, 0), p( 1, 0))); // L0 & L1 have opposite directions
}
void L_P()
{
std::cout << "Line - Point" << std::endl;
// no intersection
check_no_intersection (L(p(-3, 0), p( 7, 10)), p(9, 11));
// point intersection
check_intersection (L(p(-3, 0), p(-3, 10)), p(-3, 2), p(-3, 2));
check_intersection (L(p(-3, 10), p(-3, 7)), p(-3, 4), p(-3, 4));
check_intersection (L(p(-3, 4), p( 6, 4)), p( 7, 4), p( 7, 4));
check_intersection (L(p(-3, 4), p(-6, 4)), p( 9, 4), p( 9, 4));
check_intersection (L(p( 3, -1), p( 6, 1)), p(12, 5), p(12, 5));
} }
void S_S() void S_S()
{ {
std::cout << "Segment - Segment\n"; std::cout << "Segment - Segment" << std::endl;
// no intersection
check_no_intersection (S(p(29, 16), p( 28, 9)), S(p( 30, 12), p( 29, 6))); check_no_intersection (S(p(29, 16), p( 28, 9)), S(p( 30, 12), p( 29, 6)));
check_no_intersection (S(p( 0, 0), p(103567,9826)), S(p(10000,3782), p(76250,83736)));
// point intersection
check_intersection (S(p( 0, 0), p( 10, 0)), S(p( 1, 6), p( 1, -3)), P(1, 0));
check_intersection (S(p( 0, -1), p( 10, 0)), S(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895));
check_intersection (S(p( 0, 0), p( 10, 0)), S(p( 0, 0), p( 4, -7)), P(0, 0)); // meeting at an extremity
// segment intersection
check_intersection (S(p( 0, 0), p( 10, 0)));
check_intersection (S(p( 0, 0), p( 10, 0)), S(p( 1, 0), p( 8, 0)), S(P( 1, 0), P( 8, 0)));
check_intersection (S(p(68, 106), p(192, 106)), S(p(150, 106), p(255, 106)), S(P(150, 106), P(192, 106))); check_intersection (S(p(68, 106), p(192, 106)), S(p(150, 106), p(255, 106)), S(P(150, 106), P(192, 106)));
check_intersection (S(p( 1, 10), p( 1, 2)), S(p( 1, 7), p( 1, 3)), S(P( 1, 3), P( 1, 7))); check_intersection (S(p( 1, 10), p( 1, 2)), S(p( 1, 7), p( 1, 3)), S(P( 1, 3), P( 1, 7)));
check_no_intersection (S(p( 0, 0), p(103567,9826)), S(p(10000,3782), p(76250,83736)));
check_intersection (S(p( 0, -1), p( 10, 0)), S(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895));
check_intersection (S(p( 0, 0), p( 10, 0)), S(p( 1, 0), p( 8, 0)), S(P( 1, 0), P( 8, 0)));
check_intersection (S(p( 0, 0), p( 10, 0)), S(p( 1, 6), p( 1, -3)), P(1, 0));
} }
void R_R() void R_R()
{ {
std::cout << "Ray - Ray\n"; std::cout << "Ray - Ray" << std::endl;
// no intersection
check_no_intersection (R(p( 3, 4), p( 5, 7)), R(p( 2, 0), p( 2, 4)));
// point intersection
check_intersection (R(p( 2, -1), p( 2, 1)), R(p( 1, 3), p( 2, 3)), P(2, 3)); check_intersection (R(p( 2, -1), p( 2, 1)), R(p( 1, 3), p( 2, 3)), P(2, 3));
check_intersection (R(p( 0, -1), p( 10, 0)), R(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895)); check_intersection (R(p( 0, -1), p( 10, 0)), R(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895));
check_intersection (R(p( 0, 0), p( 10, 0)), R(p( 1, 6), p( 1, -3)), P(1, 0)); check_intersection (R(p( 0, 0), p( 10, 0)), R(p( 1, 6), p( 1, -3)), P(1, 0));
check_intersection (R(p( 0, 0), p( 10, 0)), R(p( 15, 0), p( 18, 30)), P(15, 0)); // R1's source on R0's path
check_intersection (R(p( 0, 0), p( 10, 0)), R(p( 0, 0), p( -3, 4)), P(0, 0)); // same source but different directions
// segment intersection (same supporting line, different directions)
check_intersection<S> (R(p( 2, 4), p( 6, 1)), R(p( 14, -5), p(10, -2)));
check_intersection<S> (R(p( 2, 4), p( 10, -2)), R(p( 6, 1), p(-2, 7)));
// ray intersection
check_intersection (R(p( 0, 0), p( 10, 0)));
check_intersection<R> (R(p( 0, 0), p( 10, 0)), R(p( -1, 0), p(0, 0))); // R0 'runs' into R1's source
} }
void S_R() void R_S()
{ {
std::cout << "Segment - Ray\n"; std::cout << "Ray - Segment" << std::endl;
// no intersection
check_no_intersection (S(p( 2, -1), p( 2, 1)), R(p( 1, 3), p( 2, 3))); check_no_intersection (S(p( 2, -1), p( 2, 1)), R(p( 1, 3), p( 2, 3)));
// point intersection
check_intersection (S(p( 0, -1), p( 10, 0)), R(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895)); check_intersection (S(p( 0, -1), p( 10, 0)), R(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895));
check_intersection (S(p( 0, 0), p( 10, 0)), R(p( 1, 6), p( 1, -3)), P(1, 0)); check_intersection (S(p( 0, 0), p( 10, 0)), R(p( 1, 6), p( 1, -3)), P(1, 0));
check_intersection (S(p( 0, 0), p( 10, 0)), R(p( 1, 6), p( 1, -3)), P(1, 0));
check_intersection (S(p( 0, 0), p( 10, 0)), R(p( 0, 0), p(-10, 4)), P(0, 0)); // start of ray is exactly on the segment
check_intersection (S(p( 0, 0), p( 10, 0)), R(p( 4, 0), p(-10, 4)), P(4, 0)); // start of ray is a segment extremity
// segment intersection
check_intersection (S(p( 0, 0), p( 1, 0)), R(p( 0, 0), p( 10, 0)), S(P(0, 0), P(1,0)));
check_intersection<S> (S(p( 3, 7), p( 2, 5)), R(p( 1, 3), p( 4, 9)));
} }
void L_R() void L_R()
{ {
std::cout << "Line - Ray\n"; std::cout << "Line - Ray" << std::endl;
// no intersection
check_no_intersection (L(p( 2, -1), p( 2, 1)), R(p( 1, -3), p( 1, 3)));
// point intersection
check_intersection (L(p( 2, -1), p( 2, 1)), R(p( 1, 3), p( 2, 3)), P(2, 3)); check_intersection (L(p( 2, -1), p( 2, 1)), R(p( 1, 3), p( 2, 3)), P(2, 3));
check_intersection (L(p( 0, -1), p( 10, 0)), R(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895)); check_intersection (L(p( 0, -1), p( 10, 0)), R(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895));
check_intersection (L(p( 0, 0), p( 10, 0)), R(p( 1, 6), p( 1, -3)), P(1, 0)); check_intersection (L(p( 0, 0), p( 10, 0)), R(p( 1, 6), p( 1, -3)), P(1, 0));
check_intersection (L(p( 0, 0), p( 4, 5)), R(p( 1, 8), p( 7, 2)), P(4, 5)); // ray starts on the line
// ray intersection
check_intersection<R> (L(p( 2, -1), p( 2, 1)), R(p( 2, -3), p( 2, 3)));
check_intersection<R> (L(p( 2, -1), p( 2, 1)), R(p( 2, 3), p( 2, -3))); // opposite direction
} }
void S_L() void L_S()
{ {
std::cout << "Segment - Line\n"; std::cout << "Line - Segment" << std::endl;
// no intersection
check_no_intersection (S(p( 2, -1), p( 2, 1)), L(p( 1, 3), p( 2, 3))); check_no_intersection (S(p( 2, -1), p( 2, 1)), L(p( 1, 3), p( 2, 3)));
// point intersection
check_intersection (S(p( 0, -1), p( 10, 0)), L(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895)); check_intersection (S(p( 0, -1), p( 10, 0)), L(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895));
check_intersection (S(p( 0, 0), p( 10, 0)), L(p( 1, 6), p( 1, -3)), P(1, 0)); check_intersection (S(p( 0, 0), p( 10, 0)), L(p( 1, 6), p( 1, -3)), P(1, 0));
check_intersection (S(p( 0, 0), p( 10, 0)), L(p( 1, 6), p( 2, 12)), P(0, 0));
// segment intersection
check_intersection<S> (S(p(-3, 5), p( 12, 1)), L(p( 12, 1), p( 27, -3)));
check_intersection<S> (S(p(-3, 5), p( 12, 1)), L(p(-18, 9), p( 27, -3)));
check_intersection<S> (S(p(-3, 5), p( 12, 1)), L(p( 27, -3), p(-18, 9)));
} }
void T_T() void T_T()
{ {
std::cout << "Triangle - Triangle\n"; std::cout << "Triangle - Triangle" << std::endl;
// no intersection
check_no_intersection (T(p( -10,-10), p( 0, 10), p( 20, -5)), T(p( 90, -10), p(100, 10), p(120, -5)));
// point intersection
check_intersection (T(p( -10, 0), p( 10, 0), p(0, 3)), T(p( -12, 3), p( 12, 3), p(1, 5)), P(0, 3)); // intersection on an edge
check_intersection (T(p( -25, -4), p( 13, -18), p(0, 3)), T(p( -12, 5), p( 12, 5), p(0, 3)), P(0, 3)); // intersection at a vertex
// segment intersection
check_intersection<S> (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( -8, 0), p( 12, 0), p(1, 5))); check_intersection<S> (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( -8, 0), p( 12, 0), p(1, 5)));
check_intersection<S> (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( -8, 0), p( 8, 0), p(1, 5))); check_intersection<S> (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( -8, 0), p( 8, 0), p(1, 5)));
check_intersection<S> (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( -10, 0), p( 10, 0), p(1, 5)));
check_intersection<S> (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( 10, 0), p(-10, 0), p(1, 5)));
check_intersection<S> (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( -10, 0), p( 10, 0), p(1, 5)));
check_intersection<S> (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( -12, 0), p( 12, 0), p(1, 5))); check_intersection<S> (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( -12, 0), p( 12, 0), p(1, 5)));
check_intersection (T(p( -10, 0), p( 10, 0), p(0, 3)), T(p( -12, 3), p( 12, 3), p(1, 5)), P(0, 3));
// triangle intersection
check_intersection<T> (T(p( 0, 10), p(-10, -10), p( 20, -5)), T(p( -10, -10), p( 0, 10), p( 20, -5)));
check_intersection<T> (T(p( -12, 1), p( 5, 3), p( -7, -15)), T(p( 29, -2), p( 0, -13), p(1, 21)));
// polygon intersection
Pol pol0; Pol pol0;
pol0.push_back(P(-6, -4)); pol0.push_back(P(-6, -4));
pol0.push_back(P( -5.11111, -0.222222 )); pol0.push_back(P( -5.11111, -0.222222 ));
pol0.push_back(P( 0, 10 )); pol0.push_back(P( 0, 10 ));
pol0.push_back(P( 8, 4 )); pol0.push_back(P( 8, 4 ));
check_intersection (T(p( 0, 10), p(-10, -10), p( 20, -5)), T(p( 2, 30), p( -6, -4), p(15, 8)), pol0, false); check_intersection (T(p( 0, 10), p(-10, -10), p( 20, -5)), T(p( 2, 30), p( -6, -4), p(15, 8)), pol0, false);
check_intersection<T> (T(p( -12, 1), p( 5, 3), p( -7, -15)), T(p( 29, -2), p( 0, -13), p(1, 21)));
Pol pol1; Pol pol1;
pol1.push_back(P( 8, 4)); pol1.push_back(P( 8, 4));
pol1.push_back(P( 0, 10 )); pol1.push_back(P( 0, 10 ));
pol1.push_back(P( -5.11111, -0.222222 )); pol1.push_back(P( -5.11111, -0.222222 ));
pol1.push_back(P(-6, -4)); pol1.push_back(P(-6, -4));
check_intersection (T(p( -10,-10), p( 0, 10), p( 20, -5)), T(p( 2, 30), p( -6, -4), p(15, 8)), pol1, false); check_intersection (T(p( -10,-10), p( 0, 10), p( 20, -5)), T(p( 2, 30), p( -6, -4), p(15, 8)), pol1, false);
Pol pol2; Pol pol2;
pol2.push_back(P( 10.2222, 2.33333 )); pol2.push_back(P( 10.2222, 2.33333 ));
pol2.push_back(P( 1.96923, 8.52308 )); pol2.push_back(P( 1.96923, 8.52308 ));
@ -246,17 +499,24 @@ check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0)));
pol2.push_back(P( -3.96178, -8.99363 )); pol2.push_back(P( -3.96178, -8.99363 ));
pol2.push_back(P( 3.5, -7.75 )); pol2.push_back(P( 3.5, -7.75 ));
check_intersection (T(p( -10,-10), p( 0, 10), p( 20, -5)), T(p( -9, 9), p( 14, 8), p(-2, -16)), pol2, false); check_intersection (T(p( -10,-10), p( 0, 10), p( 20, -5)), T(p( -9, 9), p( 14, 8), p(-2, -16)), pol2, false);
check_no_intersection (T(p( -10,-10), p( 0, 10), p( 20, -5)), T(p( 90, -10), p(100, 10), p(120, -5)));
} }
void L_T() void L_T()
{ {
std::cout << "Line - Triangle\n"; std::cout << "Line - Triangle" << std::endl;
// no intersection
check_no_intersection (L(p(-10, 0), p( 10, 0)), T(p( -12, 3), p( 12, 3), p(1, 5)));
// point intersection
check_intersection<P> (L(p( -8, 30), p( 8, 30)), T(p( 2, 30), p( 14, 2), p(-7, -2)));
check_intersection<P> (L(p( -8, 30), p( -7, 30)), T(p( 2, 30), p( 14, 2), p(-7, -2)));
// segment intersection
check_intersection<S> (L(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 10, 0), p(0, -4))); check_intersection<S> (L(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 10, 0), p(0, -4)));
check_intersection<S> (L(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 15, 2), p(0, -4))); check_intersection<S> (L(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 15, 2), p(0, -4)));
check_intersection<S> (L(p(-10, 0), p( 10, 0)), T(p( -8, 0), p( 8, 0), p(1, 5))); check_intersection<S> (L(p(-10, 0), p( 10, 0)), T(p( -8, 0), p( 8, 0), p(1, 5)));
check_intersection<S> (L(p(-10, 0), p( 10, 0)), T(p( -12, 0), p( 12, 0), p(1, 5))); check_intersection<S> (L(p(-10, 0), p( 10, 0)), T(p( -12, 0), p( 12, 0), p(1, 5)));
check_no_intersection (L(p(-10, 0), p( 10, 0)), T(p( -12, 3), p( 12, 3), p(1, 5)));
check_intersection<S> (L(p( 0, 10), p(-10, -10)), T(p( 2, 30), p( -6, -4), p(15, 8))); check_intersection<S> (L(p( 0, 10), p(-10, -10)), T(p( 2, 30), p( -6, -4), p(15, 8)));
check_intersection<S> (L(p(-12, 1), p( 5, 3)), T(p( 29, -2), p( 0, -13), p( 1, 21))); check_intersection<S> (L(p(-12, 1), p( 5, 3)), T(p( 29, -2), p( 0, -13), p( 1, 21)));
check_intersection<S> (L(p(-10, -10), p( 0, 10)), T(p( 2, 30), p( -6, -4), p(15, 8))); check_intersection<S> (L(p(-10, -10), p( 0, 10)), T(p( 2, 30), p( -6, -4), p(15, 8)));
@ -265,12 +525,22 @@ check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0)));
void R_T() void R_T()
{ {
std::cout << "Ray - Triangle\n"; std::cout << "Ray - Triangle" << std::endl;
// no intersection
check_no_intersection (R(p(-10, 0), p( 10, 0)), T(p( -12, 3), p( 12, 3), p(1, 5)));
// point intersection
check_intersection<P> (R(p(-2, -16), p( 4, -20)), T(p( -9, 9), p( 14, 8), p(-2, -16)));
check_intersection<P> (R(p(-8, -1), p( -8, -12)), T(p( -12, 2), p( 10, 3), p(-4, -4)));
check_intersection<P> (R(p(-8, 30), p( 4, 30)), T(p( 2, 30), p( 14, 2), p(-7, -2)));
check_intersection<P> (R(p(-8, 30), p( -7, 30)), T(p( 2, 30), p( 14, 2), p(-7, -2)));
// segment intersection
check_intersection<S> (R(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 10, 0), p(0, -4))); check_intersection<S> (R(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 10, 0), p(0, -4)));
check_intersection<S> (R(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 15, 2), p(0, -4))); check_intersection<S> (R(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 15, 2), p(0, -4)));
check_intersection<S> (R(p(-10, 0), p( 10, 0)), T(p( -8, 0), p( 8, 0), p(1, 5))); check_intersection<S> (R(p(-10, 0), p( 10, 0)), T(p( -8, 0), p( 8, 0), p(1, 5)));
check_intersection<S> (R(p(-10, 0), p( 10, 0)), T(p( -12, 0), p( 12, 0), p(1, 5))); check_intersection<S> (R(p(-10, 0), p( 10, 0)), T(p( -12, 0), p( 12, 0), p(1, 5)));
check_no_intersection (R(p(-10, 0), p( 10, 0)), T(p( -12, 3), p( 12, 3), p(1, 5)));
check_intersection<S> (R(p( 0, 10), p(-10, -10)), T(p( 2, 30), p( -6, -4), p(15, 8))); check_intersection<S> (R(p( 0, 10), p(-10, -10)), T(p( 2, 30), p( -6, -4), p(15, 8)));
check_intersection<S> (R(p(-12, 1), p( 5, 3)), T(p( 29, -2), p( 0, -13), p( 1, 21))); check_intersection<S> (R(p(-12, 1), p( 5, 3)), T(p( 29, -2), p( 0, -13), p( 1, 21)));
check_intersection<S> (R(p(-10, -10), p( 0, 10)), T(p( 2, 30), p( -6, -4), p(15, 8))); check_intersection<S> (R(p(-10, -10), p( 0, 10)), T(p( 2, 30), p( -6, -4), p(15, 8)));
@ -279,13 +549,23 @@ check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0)));
void S_T() void S_T()
{ {
std::cout << "Segment - Triangle\n"; std::cout << "Segment - Triangle" << std::endl;
check_intersection<S> (S(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 10, 0), p(0, -4)));
// no intersection
check_no_intersection (S(p(-10, -10), p( 0, 10)), T(p( 90, -10), p( 100, 10), p(120, -5))); check_no_intersection (S(p(-10, -10), p( 0, 10)), T(p( 90, -10), p( 100, 10), p(120, -5)));
check_no_intersection (S(p(-10, 0), p( 10, 0)), T(p( -12, 3), p( 12, 3), p(1, 5)));
// point intersection
check_intersection<P> (S(p(-2, -16), p( 4, -20)), T(p( -9, 9), p( 14, 8), p(-2, -16)));
check_intersection<P> (S(p(-8, -1), p( -8, -12)), T(p( -12, 2), p( 10, 3), p(-4, -4)));
check_intersection<P> (S(p(-8, -12), p( -8, -1)), T(p( -12, 2), p( 10, 3), p(-4, -4)));
check_intersection<P> (S(p(-8, 30), p( 1, 30)), T(p( -2, 30), p( 14, 2), p(-7, -2)));
// segment intersection
check_intersection<S> (S(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 10, 0), p(0, -4)));
check_intersection<S> (S(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 15, 2), p(0, -4))); check_intersection<S> (S(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 15, 2), p(0, -4)));
check_intersection<S> (S(p(-10, 0), p( 10, 0)), T(p( -8, 0), p( 8, 0), p(1, 5))); check_intersection<S> (S(p(-10, 0), p( 10, 0)), T(p( -8, 0), p( 8, 0), p(1, 5)));
check_intersection<S> (S(p(-10, 0), p( 10, 0)), T(p( -12, 0), p( 12, 0), p(1, 5))); check_intersection<S> (S(p(-10, 0), p( 10, 0)), T(p( -12, 0), p( 12, 0), p(1, 5)));
check_no_intersection (S(p(-10, 0), p( 10, 0)), T(p( -12, 3), p( 12, 3), p(1, 5)));
check_intersection<S> (S(p( 0, 10), p(-10, -10)), T(p( 2, 30), p( -6, -4), p(15, 8))); check_intersection<S> (S(p( 0, 10), p(-10, -10)), T(p( 2, 30), p( -6, -4), p(15, 8)));
check_intersection<S> (S(p(-12, 1), p( 5, 3)), T(p( 29, -2), p( 0, -13), p( 1, 21))); check_intersection<S> (S(p(-12, 1), p( 5, 3)), T(p( 29, -2), p( 0, -13), p( 1, 21)));
check_intersection<S> (S(p(-10, -10), p( 0, 10)), T(p( 2, 30), p( -6, -4), p(15, 8))); check_intersection<S> (S(p(-10, -10), p( 0, 10)), T(p( 2, 30), p( -6, -4), p(15, 8)));
@ -294,85 +574,233 @@ check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0)));
void P_P() void P_P()
{ {
std::cout << "Point - Point\n"; std::cout << "Point - Point" << std::endl;
check_no_intersection<P> (p( 8, 4), p(-4, 8));
check_intersection<P> (p( 8, 4), p( 8, 4)); check_no_intersection<P>(p(8, 4), p(-4, 8));
check_intersection<P> (p(8, 4), p( 8, 4));
}
void P_R()
{
std::cout << "Point - Ray" << std::endl;
// no intersection
check_no_intersection (R(p(-1, -1), p(0, 12)), p( 9, -1));
// point intersection
check_intersection (R(p(-3, 0), p(7, 10)), p(-3, 0), p(-3, 0)); // origin of the ray
check_intersection (R(p(-3, 0), p(7, 10)), p( 9, 12), p( 9, 12));
}
void P_S()
{
std::cout << "Point - Segment" << std::endl;
// no intersection
check_no_intersection (S(p(-1, -1), p( 0, 12)), p( 9, -1));
check_no_intersection (S(p(-2, -3), p( 0, 4)), p( 4, 18));
// point intersection
check_intersection (S(p(-2, -3), p( 4, 18)), p( 0, 4), p( 0, 4));
check_intersection (S(p(-3, 0), p( 7, 10)), p(-3, 0), p(-3, 0));
check_intersection (S(p( 3, 2), p(-2, 11)), p(-2, 11), p(-2, 11));
} }
void P_T() void P_T()
{ {
std::cout << "Point - Triangle\n"; std::cout << "Point - Triangle" << std::endl;
// no intersection
check_no_intersection (p( 8, 6), T(p( 4, 0), p( 12, 4), p(-4, 8)));
// point intersection
check_intersection<P> (p( 8, 4), T(p( 4, 0), p( 12, 4), p(-4, 8))); check_intersection<P> (p( 8, 4), T(p( 4, 0), p( 12, 4), p(-4, 8)));
check_intersection<P> (p( 8, 5), T(p( 4, 0), p( 12, 4), p(-4, 8))); check_intersection<P> (p( 8, 5), T(p( 4, 0), p( 12, 4), p(-4, 8)));
check_no_intersection (p( 8, 6), T(p( 4, 0), p( 12, 4), p(-4, 8))); check_intersection<P> (p( 4, 0), T(p( 4, 0), p( 12, 4), p(-4, 8)));
check_intersection<P> (p( 12, 4), T(p( 4, 0), p( 12, 4), p(-4, 8)));
check_intersection<P> (p( -4, 8), T(p( 4, 0), p( 12, 4), p(-4, 8)));
} }
void L_Rec() void Rec_L()
{ {
std::cout << "Line - Iso_rectangle\n"; std::cout << "Iso_rectangle - Line" << std::endl;
check_intersection<S> (L(p( 18, 6), p(0, 0)), Rec(p( 2, 0), p( 6, 3)));
// no intersection
check_no_intersection (L(p( 18, 6), p( 16, 4)), Rec(p( 2, 0), p(6, 3)));
// point intersection
check_intersection (L(p( -1, 0), p( 4, 5)), Rec(p( 0, 0), p(1, 1)), P(0, 1));
check_intersection<P> (L(p( -5, 10), p(-1, -12)), Rec(p(-3, -1), p(2, 14)));
// segment intersection
check_intersection<S> (L(p( 18, 6), p( 0, 0)), Rec(p( 2, 0), p(6, 3)));
check_intersection<S> (L(p( 18, 6), p( 0, 0)), Rec(p( 2, 0), p(6, 3)));
check_intersection<S> (L(p( 2, 14), p( 2, -14)), Rec(p( 2, 0), p(6, 3)));
check_intersection<S> (L(p( 6, 1), p( 6, 2)), Rec(p( 2, 0), p(6, 3)));
check_intersection<S> (L(p(-1, 3), p(-2, 3)), Rec(p( 2, 0), p(6, 3)));
} }
void R_Rec() void Rec_P()
{ {
std::cout << "Ray - Iso_rectangle\n"; std::cout << "Iso_rectangle - Point" << std::endl;
check_intersection<S> (R(p( 18, 6), p(0, 0)), Rec(p( 2, 0), p( 6, 3)));
// no intersection
check_no_intersection (Rec(p(-2, -6), p( 6, 3)), p( 7, 2));
check_no_intersection (Rec(p(-2, -6), p( 6, 3)), p(-2, -7));
// point intersection
check_intersection (Rec(p(-1, 4), p(-1, 4)), p(-1, 4), p(-1, 4)); // degenerate rectange (0d)
check_intersection (Rec(p(-2, 4), p(-2, 7)), p(-2, 6), p(-2, 6)); // degenerate rectange (1d)
check_intersection (Rec(p(-2, 4), p(-2, 7)), p(-2, 7), p(-2, 7)); // degenerate rectange (1d)
check_intersection (Rec(p(-3, 0), p( 4, 2)), p(-3, 2), p(-3, 2)); // on vertex
check_intersection (Rec(p( 7, 8), p( 9, 9)), p( 8, 9), p( 8, 9)); // on edge
check_intersection (Rec(p(-2, 0), p( 6, 7)), p( 1, 1), p( 1, 1)); // within
} }
void S_Rec() void Rec_R()
{ {
std::cout << "Segment - Iso_rectangle\n"; std::cout << "Iso_rectangle - Ray" << std::endl;
check_intersection<S> (S(p( 18, 6), p(0, 0)), Rec(p( 2, 0), p( 6, 3)));
// no intersection
check_no_intersection (R(p( 18, 6), p( 16, 4)), Rec(p( 2, 0), p(6, 3)));
// point intersection
check_intersection (R(p( -1, 0), p( 4, 5)), Rec(p( 0, 0), p(1, 1)), P(0, 1));
check_intersection (R(p( 0, 2), p(-4, 14)), Rec(p( 0, 0), p(5, 2)), P(0, 2));
check_intersection<P> (R(p( -5, 10), p(-1, -12)), Rec(p(-3, -1), p(2, 14)));
// segment intersection
check_intersection<S> (R(p( 18, 6), p( 0, 0)), Rec(p( 2, 0), p(6, 3)));
check_intersection<S> (R(p( 2, 14), p( 2, -14)), Rec(p( 2, 0), p(6, 3)));
check_intersection<S> (R(p( 2, 1), p( 2, 4)), Rec(p( 2, 0), p(6, 3)));
check_intersection<S> (R(p(-2, 3), p(-1, 3)), Rec(p( 2, 0), p(6, 3)));
}
void Rec_S()
{
std::cout << "Iso_rectangle - Segment" << std::endl;
// no intersection
check_no_intersection (S(p( 18, 6), p( 16, 4)), Rec(p( 2, 0), p(6, 3)));
// point intersection
check_intersection (S(p( -1, 0), p( 4, 5)), Rec(p( 0, 0), p(1, 1)), P(0, 1));
check_intersection (S(p( 0, 2), p(-4, 14)), Rec(p( 0, 0), p(5, 2)), P(0, 2));
check_intersection<P> (S(p( -5, 10), p(-1, -12)), Rec(p(-3, -1), p(2, 14)));
// segment intersection
check_intersection<S> (S(p( 18, 6), p( 0, 0)), Rec(p( 2, 0), p(6, 3)));
check_intersection<S> (S(p( 2, 14), p( 2, -14)), Rec(p( 2, 0), p(6, 3)));
check_intersection<S> (S(p( 6, 1), p( 6, 2)), Rec(p( 2, 0), p(6, 3)));
check_intersection<S> (S(p(-2, 3), p( 6, 3)), Rec(p( 2, 0), p(6, 3)));
} }
void Rec_Rec() void Rec_Rec()
{ {
std::cout << "Iso_rectangle - Iso_rectangle\n"; std::cout << "Iso_rectangle - Iso_rectangle" << std::endl;
// no intersection
check_no_intersection (Rec(p( -4, -12), p(12, 23)), Rec(p( -4, 24), p( 5, 26)));
check_no_intersection (Rec(p( -4, -12), p(12, 23)), Rec(p( 13, -24), p( 14, 15)));
// point intersection
check_intersection<Rec> (Rec(p( 10, 12), p(30, 40)), Rec(p( 30, 40), p( 31, 42))/*, p(30, 40)*/);
check_intersection<Rec> (Rec(p( 10, 12), p(30, 40)), Rec(p( 30, -13), p( 33, 12))/*, p(30, 12)*/);
// segment intersection
check_intersection<Rec> (Rec(p( 3, 5), p(4, 6)), Rec(p( 2, 4), p( 6, 5)));
check_intersection<Rec> (Rec(p( 3, 5), p(4, 6)), Rec(p( 1, 1), p( 3, 8)));
check_intersection<Rec> (Rec(p( 3, 5), p(9, 9)), Rec(p( 1, 4), p( 3, 8)));
// Iso rectangle intersection
check_intersection (Rec(p( 10, 12), p(30, 40)));
check_intersection (Rec(p( 10, 12), p(30, 40)), Rec(p( 25, 40), p( 26, 103)), Rec(P(25, 40), P(26, 40))); check_intersection (Rec(p( 10, 12), p(30, 40)), Rec(p( 25, 40), p( 26, 103)), Rec(P(25, 40), P(26, 40)));
} }
void T_Rec() void Rec_T()
{ {
std::cout << "Triangle Iso_rectangle\n"; std::cout << "Iso_rectangle - Triangle" << std::endl;
// no intersection
check_no_intersection (Rec(p( 10, 12), p(30, 40)), T(p( 4, 0), p( 12, 4), p(-4, 8))); check_no_intersection (Rec(p( 10, 12), p(30, 40)), T(p( 4, 0), p( 12, 4), p(-4, 8)));
check_intersection<T>(Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p( -1, 2), p(2, 2))); check_no_intersection (Rec(p( 2, 0), p( 3, 1)), T(p( 0, 3), p( 3, 3), p( 0, 0)));
check_intersection<T>(Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p(2, 2), p( -1, 2)));
check_intersection<Pol>(Rec(p( 0, 0), p(1, 1)), T(p( -1, -2), p( -1, 2), p(5, 2))); // point intersection
check_intersection<T>(Rec(p( 0, 0), p(2, 2)), T(p( 0, 0), p( 1, 0), p(0, 1))); check_intersection<P> (Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p( 0, 0), p( 0, -1))); // intersection at a vertex
check_intersection<T>(Rec(p( 0, 0), p(3, 3)), T(p( 1, 1), p( 2, 1), p(1, 2))); check_intersection<P> (Rec(p( 0, 0), p(1, 1)), T(p( 0, 0), p( -1, 0), p( 0, -1))); // inversed triangle
check_intersection<P>(Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p( 0, 0), p(0, -1))); check_intersection<P> (Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p( 2, 3), p(-4, 6))); // intersection on an edge of the triangle
check_intersection<P>(Rec(p( 0, 0), p(1, 1)), T(p( 0, 0), p( -1, 0), p(0, -1))); check_intersection (Rec(p( 0, 0), p(3, 3)), T(p( -10, 0), p( 0, 2), p(-1, 4)), p(0, 2)); // intersection on an edge of the iso rectangle
check_intersection<Pol>(Rec(p( 100, 100), p(200, 200)), T(p(150, 50), p(250, 170), p(50, 170)));
// segment intersection
check_intersection<S> (Rec(p( 0, 0), p(3, 3)), T(p( -10, 0), p( 0, 0), p( 0, 3)));
check_intersection<S> (Rec(p(-2, 2), p(3, 3)), T(p( -15, 12), p( -1, 3), p( 2, 3)));
check_intersection<S> (Rec(p(-2, 2), p(3, 3)), T(p( -15, 12), p( -4, 3), p( 2, 3)));
check_intersection<S> (Rec(p(-2, 2), p(3, 3)), T(p( -15, 12), p( -4, 3), p( 15, 3)));
// triangle intersection
check_intersection<T> (Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p( -1, 2), p( 2, 2)));
check_intersection<T> (Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p( 2, 2), p( -1, 2)));
check_intersection<T> (Rec(p( 0, 0), p(2, 2)), T(p( 0, 0), p( 1, 0), p( 0, 1)));
check_intersection<T> (Rec(p( 0, 0), p(3, 3)), T(p( 1, 1), p( 2, 1), p( 1, 2)));
// polygon intersection
check_intersection<Pol>(Rec(p( 0, 0), p( 1, 1)), T(p( -1, -2), p( -1, 2), p( 5, 2)));
check_intersection<Pol>(Rec(p( 100, 100), p(200, 200)), T(p(150, 50), p(250, 170), p(50, 170)));
} }
void run() void run()
{ {
std::cout << "2D Intersection tests\n"; std::cout << "2D Intersection tests with Kernel: " << typeid(K).name() << std::endl;
B_C();
B_L();
B_P(); B_P();
L_L(); B_R();
S_S();
R_R(); C_C();
S_R(); C_Rec();
L_R(); C_L();
S_L(); C_P();
T_T();
L_T();
R_T();
S_T();
P_T();
P_P();
L_Rec();
R_Rec();
S_Rec();
Rec_Rec(); Rec_Rec();
T_Rec(); Rec_L();
Rec_P();
Rec_R();
Rec_S();
Rec_T();
L_L();
L_P();
L_R();
L_S();
L_T();
P_P();
P_R();
P_S();
P_T();
R_R();
R_S();
R_T();
S_S();
S_T();
T_T();
} }
private:
K kernel;
}; };
int main() int main()
{ {
Test< CGAL::Simple_cartesian<double> >().run(); CGAL::Set_ieee_double_precision pfr;
Test< CGAL::Homogeneous<double> >().run();
// TODO : test more kernels. Test< CGAL::Simple_cartesian<typename CGAL::internal::Exact_field_selector<void*>::Type > >().run();
Test< CGAL::Cartesian<double> >().run();
Test< CGAL::Homogeneous<typename CGAL::internal::Exact_field_selector<void*>::Type > >().run();
Test< CGAL::Exact_predicates_inexact_constructions_kernel >().run();
Test< CGAL::Exact_predicates_exact_constructions_kernel >().run();
} }

View File

@ -45,6 +45,12 @@ class Epick
#endif #endif
{}; {};
class Epick_without_intervals
: public Static_filters_base<
Type_equality_wrapper< Simple_cartesian<double>::Base<Epick_without_intervals>::Type,
Epick_without_intervals > >
{};
typedef Epick Exact_predicates_inexact_constructions_kernel; typedef Epick Exact_predicates_inexact_constructions_kernel;
template <> template <>

View File

@ -27,6 +27,7 @@
#include <CGAL/MP_Float.h> #include <CGAL/MP_Float.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h> #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <cassert> #include <cassert>
@ -52,9 +53,12 @@
#include "CGAL/_test_mf_plane_3_to_2d.h" #include "CGAL/_test_mf_plane_3_to_2d.h"
template <typename Cls>
void test();
int int
main() main()
{ {
CGAL::force_ieee_double_precision();
typedef CGAL::Cartesian<double> Clsdb; typedef CGAL::Cartesian<double> Clsdb;
typedef CGAL::Filtered_kernel<Clsdb> Clsd; typedef CGAL::Filtered_kernel<Clsdb> Clsd;
@ -71,6 +75,17 @@ main()
std::cout << "Testing IO with F_k<Cartesian<double>>:" << std::endl; std::cout << "Testing IO with F_k<Cartesian<double>>:" << std::endl;
_test_io( Clsd() ); _test_io( Clsd() );
std::cout << "Testing with Epeck:\n";
test<Cls>();
std::cout << "Testing with Epick:\n";
test<CGAL::Epick>();
std::cout << "Testing with Epick_without_intervals:\n";
test<CGAL::Epick_without_intervals>();
return 0;
}
template <typename Cls>
void test() {
std::cout << "Testing 2d :"; std::cout << "Testing 2d :";
std::cout << std::endl; std::cout << std::endl;
_test_2( Cls() ); _test_2( Cls() );
@ -101,6 +116,4 @@ main()
std::cout << "Testing 3d-2d :"; std::cout << "Testing 3d-2d :";
std::cout << std::endl; std::cout << std::endl;
_test_mf_plane_3_to_2d( Cls() ); _test_mf_plane_3_to_2d( Cls() );
return 0;
} }

View File

@ -46,30 +46,26 @@
#include "CGAL/_test_mf_plane_3_to_2d.h" #include "CGAL/_test_mf_plane_3_to_2d.h"
int #include <string>
main()
{
typedef CGAL::Simple_cartesian<double> Clsd;
std::cout << "Testing IO with Simple_cartesian<double> :" << std::endl;
_test_io( Clsd() );
typedef CGAL::Simple_cartesian<CGAL::Quotient<Precise_integer> > Cls; template <typename Cls>
std::cout << "Testing 2d with Simple_cartesian<Quotient<Precise_integer>> :"; void test_kernel(std::string kernel_name, Cls) {
std::cout << "Testing 2d with "+kernel_name+" :";
std::cout << std::endl; std::cout << std::endl;
_test_2( Cls() ); _test_2( Cls() );
std::cout << "Testing 3d with Simple_cartesian<Quotient<Precise_integer>> :"; std::cout << "Testing 3d with "+kernel_name+" :";
std::cout << std::endl; std::cout << std::endl;
_test_3( Cls() ); _test_3( Cls() );
std::cout << "Testing new 2d with Simple_cartesian<Quotient<Precise_integer>>:"; std::cout << "Testing new 2d with "+kernel_name+" :";
std::cout << std::endl; std::cout << std::endl;
test_new_2( Cls() ); test_new_2( Cls() );
std::cout << "Testing new 3d with Simple_cartesian<Quotient<Precise_integer>>:"; std::cout << "Testing new 3d with "+kernel_name+" :";
std::cout << std::endl; std::cout << std::endl;
test_new_3( Cls() ); test_new_3( Cls() );
std::cout << "Testing new parts with Simple_cartesian<Quotient<Precise_integer>> :"; std::cout << "Testing new parts with "+kernel_name+" :";
std::cout << std::endl; std::cout << std::endl;
_test_orientation_and_bounded_side( Cls() ); _test_orientation_and_bounded_side( Cls() );
_test_fct_points_implicit_sphere( Cls() ); _test_fct_points_implicit_sphere( Cls() );
@ -80,9 +76,19 @@ main()
_test_cls_iso_cuboid_3( Cls() ); _test_cls_iso_cuboid_3( Cls() );
_test_angle( Cls() ); _test_angle( Cls() );
std::cout << "Testing 3d-2d with Simple_cartesian<Quotient<Precise_integer>>:"; std::cout << "Testing 3d-2d with "+kernel_name+" :";
std::cout << std::endl; std::cout << std::endl;
_test_mf_plane_3_to_2d( Cls() ); _test_mf_plane_3_to_2d( Cls() );
}
int
main()
{
typedef CGAL::Simple_cartesian<double> Clsd;
std::cout << "Testing IO with Simple_cartesian<double> :" << std::endl;
_test_io( Clsd() );
typedef CGAL::Simple_cartesian<CGAL::Quotient<Precise_integer> > Cls;
test_kernel("Simple_cartesian<Quotient<Precise_integer>>", Cls());
return 0; return 0;
} }

View File

@ -0,0 +1,44 @@
#ifndef CGAL_TESTSUITE_APPROX_EQUAL_H
#define CGAL_TESTSUITE_APPROX_EQUAL_H
#include <boost/math/special_functions/next.hpp>
namespace CGAL {
namespace testsuite {
template <typename FT>
bool approx_equal(FT a, FT b) { return a == b; }
bool approx_equal(double a, double b) {
return std::abs(boost::math::float_distance(a, b)) <= 1;
}
struct Xyz_tag {};
struct Xy_tag {};
template <typename Object>
bool approx_equal(Object a, Object b, CGAL::testsuite::Xyz_tag)
{
return approx_equal(a.x(), b.x()) &&
approx_equal(a.y(), b.y()) &&
approx_equal(a.z(), b.z());
}
template <typename Object>
bool approx_equal(Object a, Object b, CGAL::testsuite::Xy_tag)
{
return approx_equal(a.x(), b.x()) && approx_equal(a.y(), b.y());
}
struct Direction_2_tag {};
template <typename Object>
bool approx_equal(Object a, Object b, CGAL::testsuite::Direction_2_tag)
{
return CGAL_NTS sign(a.dx()) == CGAL_NTS sign(a.dx())
&& CGAL_NTS sign(a.dy()) == CGAL_NTS sign(b.dy())
&& approx_equal(a.dx() * b.dy(), a.dy() * b.dx());
}
} // end namespace testsuite
} // end namespace CGAL
#endif // CGAL_TESTSUITE_APPROX_EQUAL_H

View File

@ -24,6 +24,9 @@
#ifndef CGAL__TEST_CLS_AFF_TRANSFORMATION_2_H #ifndef CGAL__TEST_CLS_AFF_TRANSFORMATION_2_H
#define CGAL__TEST_CLS_AFF_TRANSFORMATION_2_H #define CGAL__TEST_CLS_AFF_TRANSFORMATION_2_H
#include <CGAL/use.h>
#include <boost/type_traits/is_same.hpp>
template <class R> template <class R>
bool bool
_test_cls_aff_transformation_2(const R& ) _test_cls_aff_transformation_2(const R& )
@ -33,6 +36,8 @@ _test_cls_aff_transformation_2(const R& )
typedef typename R::RT RT; typedef typename R::RT RT;
typedef typename R::FT FT; typedef typename R::FT FT;
const bool nonexact = boost::is_same<FT, double>::value;
typename R::Aff_transformation_2 ia; typename R::Aff_transformation_2 ia;
CGAL::Aff_transformation_2<R> a1(ia); CGAL::Aff_transformation_2<R> a1(ia);
@ -56,7 +61,7 @@ _test_cls_aff_transformation_2(const R& )
CGAL::Vector_2<R> tvec; CGAL::Vector_2<R> tvec;
CGAL::Point_2<R> pnt( n8, n1, n10 ); // ( 6,-5) CGAL::Point_2<R> pnt( n8, n1, n10 ); // ( 6,-5)
CGAL::Point_2<R> tpnt; CGAL::Point_2<R> tpnt;
CGAL::Point_2<R> pvec = CGAL::ORIGIN + vec; CGAL::Point_2<R> pvec = CGAL::ORIGIN + vec; CGAL_USE(pvec);
CGAL::Vector_2<R> vpnt = pnt - CGAL::ORIGIN; CGAL::Vector_2<R> vpnt = pnt - CGAL::ORIGIN;
CGAL::Point_2<R> p1(-n3, n7, n3 ); // (-1, 2) CGAL::Point_2<R> p1(-n3, n7, n3 ); // (-1, 2)
@ -168,7 +173,7 @@ _test_cls_aff_transformation_2(const R& )
tisor= isor.transform( a[i]); tisor= isor.transform( a[i]);
assert( tseg == CGAL::Segment_2<R>(tp1, tp2) ); assert( tseg == CGAL::Segment_2<R>(tp1, tp2) );
assert( tray == CGAL::Ray_2<R>(tp3, tp2) ); assert( tray == CGAL::Ray_2<R>(tp3, tp2) );
assert( tlin == CGAL::Line_2<R>(tp2, tp4) ); assert( tlin == CGAL::Line_2<R>(tp2, tp4) || nonexact);
assert( ttri == CGAL::Triangle_2<R>(tp2, tp3, tp4) ); assert( ttri == CGAL::Triangle_2<R>(tp2, tp3, tp4) );
assert( tisor== CGAL::Iso_rectangle_2<R>( tp3, tp4 ) ); assert( tisor== CGAL::Iso_rectangle_2<R>( tp3, tp4 ) );
@ -178,11 +183,11 @@ _test_cls_aff_transformation_2(const R& )
tray = tray.transform( inv ); tray = tray.transform( inv );
tlin = tlin.transform( inv ); tlin = tlin.transform( inv );
ttri = ttri.transform( inv ); ttri = ttri.transform( inv );
assert( tp4 == p4 ); assert( tp4 == p4 || nonexact );
assert( tseg == seg ); assert( tseg == seg || nonexact );
assert( tray == ray ); assert( tray == ray || nonexact );
assert( tlin == lin ); assert( tlin == lin || nonexact );
assert( ttri == tri ); assert( ttri == tri || nonexact );
}; };
std::cout << '.'; std::cout << '.';
@ -291,7 +296,7 @@ _test_cls_aff_transformation_2(const R& )
// rotation // rotation
assert( d0.transform( rot90 ) == d1 ); assert( d0.transform( rot90 ) == d1 );
assert( d1.transform( rot90.inverse() ) == d0 ); assert( d1.transform( rot90.inverse() ) == d0 );
assert( d0.transform( rot3 ) == CGAL::Direction_2<R>( RT(4), RT(3)) ); assert( d0.transform( rot3 ) == CGAL::Direction_2<R>( RT(4), RT(3)) || nonexact);
co1 = rot3 * rot90; co1 = rot3 * rot90;
assert( d1.transform( rot3) == d0.transform( co1 ) ); assert( d1.transform( rot3) == d0.transform( co1 ) );
co1 = rot2 * rot90; co1 = rot2 * rot90;
@ -324,7 +329,7 @@ _test_cls_aff_transformation_2(const R& )
tp3 = p3.transform( rot3 ); tp3 = p3.transform( rot3 );
tp4 = p4.transform( rot3 ); tp4 = p4.transform( rot3 );
tcirc = circ.orthogonal_transform( rot3 ); tcirc = circ.orthogonal_transform( rot3 );
assert( tcirc == CGAL::Circle_2<R>( tp2, tp3, tp4 ) ); assert( tcirc == CGAL::Circle_2<R>( tp2, tp3, tp4 ) || nonexact );
// copy // copy

View File

@ -24,6 +24,9 @@
#ifndef CGAL__TEST_CLS_AFF_TRANSFORMATION_3_H #ifndef CGAL__TEST_CLS_AFF_TRANSFORMATION_3_H
#define CGAL__TEST_CLS_AFF_TRANSFORMATION_3_H #define CGAL__TEST_CLS_AFF_TRANSFORMATION_3_H
#include <CGAL/use.h>
#include <boost/type_traits/is_same.hpp>
template <class R> template <class R>
bool bool
_test_cls_aff_transformation_3(const R& ) _test_cls_aff_transformation_3(const R& )
@ -32,6 +35,7 @@ _test_cls_aff_transformation_3(const R& )
typedef typename R::RT RT; typedef typename R::RT RT;
typedef typename R::FT FT; typedef typename R::FT FT;
const bool nonexact = boost::is_same<FT, double>::value;
typename R::Aff_transformation_3 ia; typename R::Aff_transformation_3 ia;
CGAL::Aff_transformation_3<R> a1(ia); CGAL::Aff_transformation_3<R> a1(ia);
@ -56,7 +60,7 @@ _test_cls_aff_transformation_3(const R& )
CGAL::Vector_3<R> tvec; CGAL::Vector_3<R> tvec;
CGAL::Point_3<R> pnt( n8, n1, n9, n10 ); // ( 6,-5, 3) CGAL::Point_3<R> pnt( n8, n1, n9, n10 ); // ( 6,-5, 3)
CGAL::Point_3<R> tpnt; CGAL::Point_3<R> tpnt;
CGAL::Point_3<R> pvec = CGAL::ORIGIN + vec; CGAL::Point_3<R> pvec = CGAL::ORIGIN + vec; CGAL_USE(pvec);
CGAL::Vector_3<R> vpnt = pnt - CGAL::ORIGIN; CGAL::Vector_3<R> vpnt = pnt - CGAL::ORIGIN;
CGAL::Point_3<R> p1(-n3, n7, n11, n3 ); // (-1, 2,-3) CGAL::Point_3<R> p1(-n3, n7, n11, n3 ); // (-1, 2,-3)
@ -182,7 +186,7 @@ _test_cls_aff_transformation_3(const R& )
tlin = lin.transform( a[i] ); tlin = lin.transform( a[i] );
ttri = tri.transform( a[i] ); ttri = tri.transform( a[i] );
ttet = tet.transform( a[i] ); ttet = tet.transform( a[i] );
assert( tpla == CGAL::Plane_3<R>( tp1, tp2, tp3) ); assert( tpla == CGAL::Plane_3<R>( tp1, tp2, tp3) || nonexact );
assert( tseg == CGAL::Segment_3<R>(tp1, tp2) ); assert( tseg == CGAL::Segment_3<R>(tp1, tp2) );
assert( tray == CGAL::Ray_3<R>(tp3, tp2) ); assert( tray == CGAL::Ray_3<R>(tp3, tp2) );
assert( tlin == CGAL::Line_3<R>(tp2, tp4) ); assert( tlin == CGAL::Line_3<R>(tp2, tp4) );
@ -196,13 +200,13 @@ _test_cls_aff_transformation_3(const R& )
tlin = tlin.transform( inv ); tlin = tlin.transform( inv );
ttri = ttri.transform( inv ); ttri = ttri.transform( inv );
ttet = ttet.transform( inv ); ttet = ttet.transform( inv );
assert( tp4 == p4 ); assert( tp4 == p4 || nonexact );
assert( tpla == pla ); assert( tpla == pla || nonexact );
assert( tseg == seg ); assert( tseg == seg || nonexact );
assert( tray == ray ); assert( tray == ray || nonexact );
assert( tlin == lin ); assert( tlin == lin || nonexact );
assert( ttri == tri ); assert( ttri == tri || nonexact );
assert( ttet == tet ); assert( ttet == tet || nonexact );
}; };
std::cout << '.'; std::cout << '.';
@ -211,7 +215,7 @@ _test_cls_aff_transformation_3(const R& )
assert( vec.transform(ident) == vec ); assert( vec.transform(ident) == vec );
assert( dir.transform(ident) == dir ); assert( dir.transform(ident) == dir );
assert( pnt.transform(ident) == pnt ); assert( pnt.transform(ident) == pnt );
assert( pla.transform(ident) == pla ); assert( pla.transform(ident) == pla || nonexact );
// scale11 and gscale // scale11 and gscale
tpnt = pnt.transform(scale11); tpnt = pnt.transform(scale11);
@ -234,7 +238,7 @@ _test_cls_aff_transformation_3(const R& )
assert( vec.transform(scale11) == vec.transform(gscale) ); assert( vec.transform(scale11) == vec.transform(gscale) );
assert( dir.transform(scale11) == dir.transform(gscale) ); assert( dir.transform(scale11) == dir.transform(gscale) );
assert( pnt.transform(scale11) == pnt.transform(gscale) ); assert( pnt.transform(scale11) == pnt.transform(gscale) );
assert( pla.transform(scale11) == pla.transform(gscale) ); assert( pla.transform(scale11) == pla.transform(gscale) || nonexact );
// translate and gtrans // translate and gtrans
tvec = vec.transform(translate); tvec = vec.transform(translate);
@ -272,7 +276,7 @@ _test_cls_aff_transformation_3(const R& )
assert( pnt.transform(xrefl).transform(xrefl) == pnt ); assert( pnt.transform(xrefl).transform(xrefl) == pnt );
assert( dir.transform(xrefl).transform(xrefl) == dir ); assert( dir.transform(xrefl).transform(xrefl) == dir );
assert( vec.transform(xrefl).transform(xrefl) == vec ); assert( vec.transform(xrefl).transform(xrefl) == vec );
assert( pla.transform(xrefl).transform(xrefl) == pla ); assert( pla.transform(xrefl).transform(xrefl) == pla || nonexact );
CGAL::Aff_transformation_3<R> co1 = xrefl * xrefl; CGAL::Aff_transformation_3<R> co1 = xrefl * xrefl;
assert( pnt.transform(xrefl).transform(xrefl) == pnt.transform(co1) ); assert( pnt.transform(xrefl).transform(xrefl) == pnt.transform(co1) );
assert( dir.transform(xrefl).transform(xrefl) == dir.transform(co1) ); assert( dir.transform(xrefl).transform(xrefl) == dir.transform(co1) );
@ -282,7 +286,7 @@ _test_cls_aff_transformation_3(const R& )
assert( pnt.transform(gat3).transform(gat2) == pnt.transform(co1) ); assert( pnt.transform(gat3).transform(gat2) == pnt.transform(co1) );
assert( dir.transform(gat3).transform(gat2) == dir.transform(co1) ); assert( dir.transform(gat3).transform(gat2) == dir.transform(co1) );
assert( vec.transform(gat3).transform(gat2) == vec.transform(co1) ); assert( vec.transform(gat3).transform(gat2) == vec.transform(co1) );
assert( pla.transform(gat3).transform(gat2) == pla.transform(co1) ); assert( pla.transform(gat3).transform(gat2) == pla.transform(co1) || nonexact );
co1 = ident * gat1; co1 = ident * gat1;
assert( vec.transform(gat1) == vec.transform(co1) ); assert( vec.transform(gat1) == vec.transform(co1) );
assert( dir.transform(gat1) == dir.transform(co1) ); assert( dir.transform(gat1) == dir.transform(co1) );
@ -294,10 +298,10 @@ _test_cls_aff_transformation_3(const R& )
assert( pnt.transform(gat1) == pnt.transform(co1) ); assert( pnt.transform(gat1) == pnt.transform(co1) );
assert( pla.transform(gat1) == pla.transform(co1) ); assert( pla.transform(gat1) == pla.transform(co1) );
co1 = gat1 * gat1.inverse() ; co1 = gat1 * gat1.inverse() ;
assert( vec == vec.transform(co1) ); assert( vec == vec.transform(co1) || nonexact );
assert( dir == dir.transform(co1) ); assert( dir == dir.transform(co1) || nonexact );
assert( pnt == pnt.transform(co1) ); assert( pnt == pnt.transform(co1) || nonexact );
assert( pla == pla.transform(co1) ); assert( pla == pla.transform(co1) || nonexact );
assert( vec.transform( gat5 ) == vec.transform( gat2 ) ); assert( vec.transform( gat5 ) == vec.transform( gat2 ) );
assert( dir.transform( gat5 ) == dir.transform( gat2 ) ); assert( dir.transform( gat5 ) == dir.transform( gat2 ) );

View File

@ -27,6 +27,8 @@
#include <CGAL/Bbox_2.h> #include <CGAL/Bbox_2.h>
#include <cassert> #include <cassert>
#include <boost/type_traits/is_same.hpp>
template <class K> template <class K>
void _test_construct_radical_line(const K &k) { void _test_construct_radical_line(const K &k) {
typedef typename K::FT FT; typedef typename K::FT FT;
@ -83,6 +85,8 @@ _test_cls_circle_2(const R& )
typename R::Circle_2 ic; typename R::Circle_2 ic;
CGAL::Circle_2<R> c0; CGAL::Circle_2<R> c0;
const bool nonexact = boost::is_same<FT, double>::value;
RT n0 = 0; RT n0 = 0;
RT n1 = 16; RT n1 = 16;
RT n2 = -4; RT n2 = -4;
@ -194,9 +198,9 @@ _test_cls_circle_2(const R& )
== CGAL::ON_POSITIVE_SIDE ); == CGAL::ON_POSITIVE_SIDE );
assert( c10.oriented_side(CGAL::ORIGIN + v1 + vx*n2 ) \ assert( c10.oriented_side(CGAL::ORIGIN + v1 + vx*n2 ) \
== CGAL::ON_NEGATIVE_SIDE ); == CGAL::ON_NEGATIVE_SIDE );
assert( c10.oriented_side(p9 ) == CGAL::ON_ORIENTED_BOUNDARY ); assert( c10.oriented_side(p9 ) == CGAL::ON_ORIENTED_BOUNDARY || nonexact);
assert( c10.has_on_boundary(p9) ); assert( c10.has_on_boundary(p9) || nonexact);
assert( c10.has_on_boundary(p4 + v1) ); assert( c10.has_on_boundary(p4 + v1) || nonexact );
CGAL::Point_2<R> p11( n4, n4, n3) ; // (2.5, 2.5) CGAL::Point_2<R> p11( n4, n4, n3) ; // (2.5, 2.5)
CGAL::Point_2<R> p12( n5, n5, n3) ; // ( 5 , 5 ) CGAL::Point_2<R> p12( n5, n5, n3) ; // ( 5 , 5 )
assert( c10.has_on_bounded_side( p11 ) ); assert( c10.has_on_bounded_side( p11 ) );
@ -206,8 +210,8 @@ _test_cls_circle_2(const R& )
assert( c10.has_on_negative_side( p12 ) ); assert( c10.has_on_negative_side( p12 ) );
assert( c10.opposite().has_on_negative_side( p11 ) ); assert( c10.opposite().has_on_negative_side( p11 ) );
assert( c10.opposite().has_on_positive_side( p12 ) ); assert( c10.opposite().has_on_positive_side( p12 ) );
assert( c10.has_on_boundary( p6 ) ); assert( c10.has_on_boundary( p6 ) || nonexact);
assert( c10.has_on_boundary( p8 ) ); assert( c10.has_on_boundary( p8 ) || nonexact);
std::cout << '.'; std::cout << '.';

View File

@ -24,6 +24,8 @@
#ifndef CGAL__TEST_CLS_DIRECTION_2_H #ifndef CGAL__TEST_CLS_DIRECTION_2_H
#define CGAL__TEST_CLS_DIRECTION_2_H #define CGAL__TEST_CLS_DIRECTION_2_H
#include <CGAL/use.h>
template <class R> template <class R>
bool bool
_test_cls_direction_2(const R& ) _test_cls_direction_2(const R& )
@ -34,7 +36,7 @@ _test_cls_direction_2(const R& )
typename R::Direction_2 id; typename R::Direction_2 id;
CGAL::Direction_2<R> d0; CGAL::Direction_2<R> d0;
CGAL::Direction_2<R> d1(id); CGAL::Direction_2<R> d1(id); CGAL_USE(d1);
std::cout << '.'; std::cout << '.';
RT n0 = 10; RT n0 = 10;

View File

@ -24,6 +24,8 @@
#ifndef CGAL__TEST_CLS_DIRECTION_3_H #ifndef CGAL__TEST_CLS_DIRECTION_3_H
#define CGAL__TEST_CLS_DIRECTION_3_H #define CGAL__TEST_CLS_DIRECTION_3_H
#include <CGAL/use.h>
template <class R> template <class R>
bool bool
_test_cls_direction_3(const R& ) _test_cls_direction_3(const R& )
@ -35,7 +37,7 @@ _test_cls_direction_3(const R& )
typename R::Direction_3 id; typename R::Direction_3 id;
CGAL::Direction_3<R> d0; CGAL::Direction_3<R> d0;
CGAL::Direction_3<R> d1(id); CGAL::Direction_3<R> d1(id); CGAL_USE(d1);
std::cout << '.'; std::cout << '.';
RT n0 = 10; RT n0 = 10;

View File

@ -26,6 +26,7 @@
#include <CGAL/Bbox_3.h> #include <CGAL/Bbox_3.h>
#include <cassert> #include <cassert>
#include <CGAL/use.h>
template <class R> template <class R>
bool bool
@ -36,9 +37,6 @@ _test_cls_iso_cuboid_3(const R& )
typedef typename R::RT RT; typedef typename R::RT RT;
typedef typename R::FT FT; typedef typename R::FT FT;
typename R::Iso_cuboid_3 ir;
CGAL::Iso_cuboid_3<R> r0(ir);
RT n1 = 1; RT n1 = 1;
RT n2 = 2; RT n2 = 2;
RT n3 = 3; RT n3 = 3;
@ -65,6 +63,10 @@ _test_cls_iso_cuboid_3(const R& )
CGAL::Point_3<R> p12(n1, n1, n3 ); // ( 1, 1, 3) CGAL::Point_3<R> p12(n1, n1, n3 ); // ( 1, 1, 3)
CGAL::Point_3<R> p13(n4, n1, n3 ); // ( 4, 1, 3) CGAL::Point_3<R> p13(n4, n1, n3 ); // ( 4, 1, 3)
typename R::Iso_cuboid_3 ir0; CGAL_USE(ir0); // test default-construction
typename R::Iso_cuboid_3 ir( p1, p3);
CGAL::Iso_cuboid_3<R> r0(ir);
const CGAL::Iso_cuboid_3<R> r1( p1, p3); const CGAL::Iso_cuboid_3<R> r1( p1, p3);
CGAL::Iso_cuboid_3<R> r1_( p1, p3, 0); CGAL::Iso_cuboid_3<R> r1_( p1, p3, 0);
CGAL::Iso_cuboid_3<R> r2( p3, p1); CGAL::Iso_cuboid_3<R> r2( p3, p1);

View File

@ -26,6 +26,7 @@
#include <CGAL/Bbox_2.h> #include <CGAL/Bbox_2.h>
#include <cassert> #include <cassert>
#include <CGAL/use.h>
template <class R> template <class R>
bool bool
@ -36,9 +37,6 @@ _test_cls_iso_rectangle_2(const R& )
typedef typename R::RT RT; typedef typename R::RT RT;
typedef typename R::FT FT; typedef typename R::FT FT;
typename R::Iso_rectangle_2 ir;
CGAL::Iso_rectangle_2<R> r0(ir);
RT n1 = 1; RT n1 = 1;
RT n2 = 2; RT n2 = 2;
RT n3 = 3; RT n3 = 3;
@ -59,6 +57,10 @@ _test_cls_iso_rectangle_2(const R& )
CGAL::Point_2<R> p8( n4, n6, n2); // ( 2, 3) CGAL::Point_2<R> p8( n4, n6, n2); // ( 2, 3)
CGAL::Point_2<R> p9(-n3, n7); // (-3, 7) CGAL::Point_2<R> p9(-n3, n7); // (-3, 7)
typename R::Iso_rectangle_2 ir0; CGAL_USE(ir0); // test default-construction
typename R::Iso_rectangle_2 ir(p1, p3);
CGAL::Iso_rectangle_2<R> r0(ir);
const CGAL::Iso_rectangle_2<R> r1( p1, p3); const CGAL::Iso_rectangle_2<R> r1( p1, p3);
CGAL::Iso_rectangle_2<R> r1_( p1, p3, 0); CGAL::Iso_rectangle_2<R> r1_( p1, p3, 0);
CGAL::Iso_rectangle_2<R> r2( p3, p1); CGAL::Iso_rectangle_2<R> r2( p3, p1);

View File

@ -24,6 +24,8 @@
#ifndef CGAL__TEST_CLS_LINE_2_H #ifndef CGAL__TEST_CLS_LINE_2_H
#define CGAL__TEST_CLS_LINE_2_H #define CGAL__TEST_CLS_LINE_2_H
#include <CGAL/use.h>
template <class R> template <class R>
bool bool
_test_cls_line_2(const R& ) _test_cls_line_2(const R& )
@ -47,7 +49,8 @@ _test_cls_line_2(const R& )
CGAL::Point_2<R> p3(-n6, n6, n3 ); // (-2, 2 ) CGAL::Point_2<R> p3(-n6, n6, n3 ); // (-2, 2 )
CGAL::Point_2<R> p4( n8, n4, n2 ); // ( 4, 2 ) CGAL::Point_2<R> p4( n8, n4, n2 ); // ( 4, 2 )
typename R::Line_2 il; typename R::Line_2 il0; CGAL_USE(il0); // test default-construction
typename R::Line_2 il(p1, p2);
CGAL::Line_2<R> l0(il); CGAL::Line_2<R> l0(il);
CGAL::Line_2<R> l12( p1, p2 ); CGAL::Line_2<R> l12( p1, p2 );
CGAL::Line_2<R> l21( p2, p1 ); CGAL::Line_2<R> l21( p2, p1 );

View File

@ -24,6 +24,9 @@
#ifndef CGAL__TEST_CLS_LINE_3_H #ifndef CGAL__TEST_CLS_LINE_3_H
#define CGAL__TEST_CLS_LINE_3_H #define CGAL__TEST_CLS_LINE_3_H
#include <CGAL/use.h>
#include <boost/type_traits/is_same.hpp>
template <class R> template <class R>
bool bool
_test_cls_line_3(const R& ) _test_cls_line_3(const R& )
@ -31,10 +34,11 @@ _test_cls_line_3(const R& )
std::cout << "Testing class Line_3" ; std::cout << "Testing class Line_3" ;
typedef typename R::RT RT; typedef typename R::RT RT;
const bool nonexact = boost::is_same<RT, double>::value;
typename R::Line_3 il; typename R::Line_3 il;
CGAL::Line_3<R> l0( il ); CGAL::Line_3<R> l0( il ); CGAL_USE(l0);
CGAL::Line_3<R> l1; CGAL::Line_3<R> l1; CGAL_USE(l1);
RT n1 = 3; RT n1 = 3;
RT n2 = 53; RT n2 = 53;
@ -99,20 +103,20 @@ _test_cls_line_3(const R& )
assert( l4.point(2) - l4.point(1) == l4.point(1) - l4.point(0) ); assert( l4.point(2) - l4.point(1) == l4.point(1) - l4.point(0) );
CGAL::Point_3<R> p1l4proj = l4.projection(p1); CGAL::Point_3<R> p1l4proj = l4.projection(p1);
assert( l4.has_on( p1l4proj ) ); assert( l4.has_on( p1l4proj ) || nonexact );
assert( l4.perpendicular_plane( p1l4proj ).has_on( p1l4proj ) ); assert( l4.perpendicular_plane( p1l4proj ).has_on( p1l4proj ) || nonexact );
assert( l4.perpendicular_plane( p1l4proj ).has_on( p1 ) ); assert( l4.perpendicular_plane( p1l4proj ).has_on( p1 ) || nonexact );
CGAL::Point_3<R> p4 = l4.projection(p2); CGAL::Point_3<R> p4 = l4.projection(p2);
CGAL::Point_3<R> p5 = l4.projection(p3); CGAL::Point_3<R> p5 = l4.projection(p3);
assert( ( l4.direction() == ( p5 - p4 ).direction() )\ assert( ( l4.direction() == ( p5 - p4 ).direction() )\
||( l4.direction() == ( p4 - p5 ).direction() ) ); ||( l4.direction() == ( p4 - p5 ).direction() ) || nonexact );
assert( l5.direction() == - l6.direction() ); assert( l5.direction() == - l6.direction() );
std::cout <<'.'; std::cout <<'.';
assert( l2.has_on(p1) ); assert( l2.has_on(p1) );
assert( l2.has_on(p2) ); assert( l2.has_on(p2) );
assert( l4.has_on(p4) ); assert( l4.has_on(p4) || nonexact );
assert( l4.has_on(p5) ); assert( l4.has_on(p5) );
assert( CGAL::Line_3<R>(p1,p1).is_degenerate() ); assert( CGAL::Line_3<R>(p1,p1).is_degenerate() );

View File

@ -24,6 +24,8 @@
#ifndef CGAL__TEST_CLS_PLANE_3_H #ifndef CGAL__TEST_CLS_PLANE_3_H
#define CGAL__TEST_CLS_PLANE_3_H #define CGAL__TEST_CLS_PLANE_3_H
#include <CGAL/use.h>
template <class R> template <class R>
bool bool
_test_cls_plane_3(const R& ) _test_cls_plane_3(const R& )
@ -34,7 +36,7 @@ _test_cls_plane_3(const R& )
typedef typename R::FT FT; typedef typename R::FT FT;
typename R::Plane_3 ip; typename R::Plane_3 ip;
CGAL::Plane_3<R> pl0(ip); CGAL::Plane_3<R> pl0(ip); CGAL_USE(pl0);
RT x1 = -1; RT x1 = -1;
RT x2 = 4; RT x2 = 4;
@ -45,7 +47,7 @@ _test_cls_plane_3(const R& )
py(RT(0),RT(1),RT(0)), py(RT(0),RT(1),RT(0)),
pz(RT(0),RT(0),RT(1)); pz(RT(0),RT(0),RT(1));
CGAL::Point_3<R> p3(p1); CGAL::Point_3<R> p3(p1); CGAL_USE(p3);
CGAL::Direction_3<R> d1( RT(5), RT(-5), RT(10) ); CGAL::Direction_3<R> d1( RT(5), RT(-5), RT(10) );
CGAL::Vector_3<R> v1 = d1.vector(); CGAL::Vector_3<R> v1 = d1.vector();
@ -121,8 +123,8 @@ _test_cls_plane_3(const R& )
assert( xy_pl.has_on( gnup ) ); assert( xy_pl.has_on( gnup ) );
CGAL::Vector_3<R> nov = pl1.orthogonal_vector(); CGAL::Vector_3<R> nov = pl1.orthogonal_vector();
CGAL::Vector_3<R> vb1 = pl1.base1(); CGAL::Vector_3<R> vb1 = pl1.base1(); CGAL_USE(vb1);
CGAL::Vector_3<R> vb2 = pl1.base2(); CGAL::Vector_3<R> vb2 = pl1.base2(); CGAL_USE(vb2);
assert( (nov*pl1.base1()) == FT(0)&&(nov*pl1.base2()) == FT(0) ); assert( (nov*pl1.base1()) == FT(0)&&(nov*pl1.base2()) == FT(0) );
assert( (pl1.base2()*pl1.base1()) == FT(0) ); assert( (pl1.base2()*pl1.base1()) == FT(0) );
assert( pl1.has_on(pl1.point() + pl1.base1()) ); assert( pl1.has_on(pl1.point() + pl1.base1()) );

View File

@ -30,6 +30,7 @@
#include <CGAL/Origin.h> #include <CGAL/Origin.h>
#include <CGAL/Vector_2.h> #include <CGAL/Vector_2.h>
#include <CGAL/Weighted_point_2.h> #include <CGAL/Weighted_point_2.h>
#include <CGAL/use.h>
#include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/is_convertible.hpp>
@ -49,7 +50,7 @@ _test_cls_point_2(const R& )
typedef typename R::Point_2::Cartesian_const_iterator CCI; typedef typename R::Point_2::Cartesian_const_iterator CCI;
CGAL::Point_2<R> p1; CGAL::Point_2<R> p1;
CGAL::Point_2<R> p2(ip); CGAL::Point_2<R> p2(ip); CGAL_USE(p2);
CGAL::Point_2<R> p0(CGAL::ORIGIN); CGAL::Point_2<R> p0(CGAL::ORIGIN);
RT n1(-35 ); RT n1(-35 );

View File

@ -29,6 +29,7 @@
#include <CGAL/Origin.h> #include <CGAL/Origin.h>
#include <CGAL/Vector_3.h> #include <CGAL/Vector_3.h>
#include <CGAL/Weighted_point_3.h> #include <CGAL/Weighted_point_3.h>
#include <CGAL/use.h>
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
@ -46,7 +47,7 @@ _test_cls_point_3(const R& )
typedef typename R::Point_3::Cartesian_const_iterator CCI; typedef typename R::Point_3::Cartesian_const_iterator CCI;
CGAL::Point_3<R> p1; CGAL::Point_3<R> p1;
CGAL::Point_3<R> p2(ip); CGAL::Point_3<R> p2(ip); CGAL_USE(p2);
CGAL::Point_3<R> p0(CGAL::ORIGIN); CGAL::Point_3<R> p0(CGAL::ORIGIN);
RT n1(-35 ); RT n1(-35 );

View File

@ -26,6 +26,7 @@
#include <CGAL/Bbox_3.h> #include <CGAL/Bbox_3.h>
#include <cassert> #include <cassert>
#include <boost/type_traits/is_same.hpp>
template <class R> template <class R>
bool bool
@ -38,6 +39,7 @@ _test_cls_sphere_3(const R& )
typename R::Sphere_3 ic; typename R::Sphere_3 ic;
CGAL::Sphere_3<R> c0; CGAL::Sphere_3<R> c0;
const bool nonexact = boost::is_same<FT, double>::value;
RT n0 = 0; RT n0 = 0;
RT n1 = 16; RT n1 = 16;
RT n2 = -4; RT n2 = -4;
@ -104,8 +106,8 @@ _test_cls_sphere_3(const R& )
assert( cn3 == cp3.opposite() ); assert( cn3 == cp3.opposite() );
assert( c7.opposite() == c8 ); assert( c7.opposite() == c8 );
assert( c8.opposite() == c7 ); assert( c8.opposite() == c7 );
assert( c1.opposite() == c3 ); assert( c1.opposite() == c3 || nonexact );
assert( c3.opposite() == c1 ); assert( c3.opposite() == c1 || nonexact );
assert( c7.orientation() == CGAL::POSITIVE ); assert( c7.orientation() == CGAL::POSITIVE );
assert( c8.orientation() == CGAL::NEGATIVE ); assert( c8.orientation() == CGAL::NEGATIVE );
assert( c5.orientation() == CGAL::POSITIVE ); assert( c5.orientation() == CGAL::POSITIVE );
@ -181,22 +183,22 @@ _test_cls_sphere_3(const R& )
CGAL::Point_3<R> ori = CGAL::Point_3<R>( RT(0), RT(0), RT(0)); CGAL::Point_3<R> ori = CGAL::Point_3<R>( RT(0), RT(0), RT(0));
CGAL::Point_3<R> p6 = p2.transform( rotate1 ); CGAL::Point_3<R> p6 = p2.transform( rotate1 );
assert( CGAL::compare_distance_to_point( ori, p2, p6) == CGAL::EQUAL ); assert( CGAL::compare_distance_to_point( ori, p2, p6) == CGAL::EQUAL || nonexact );
CGAL::Point_3<R> p7 = p2.transform( rotate2 ); CGAL::Point_3<R> p7 = p2.transform( rotate2 );
assert( CGAL::compare_distance_to_point( ori, p2, p7) == CGAL::EQUAL ); assert( CGAL::compare_distance_to_point( ori, p2, p7) == CGAL::EQUAL || nonexact );
CGAL::Point_3<R> p8 = p2.transform( rotate3 ); CGAL::Point_3<R> p8 = p2.transform( rotate3 );
assert( CGAL::compare_distance_to_point( ori, p2, p8) == CGAL::EQUAL ); assert( CGAL::compare_distance_to_point( ori, p2, p8) == CGAL::EQUAL || nonexact );
CGAL::Point_3<R> p9 = p2.transform( rotate4 ); CGAL::Point_3<R> p9 = p2.transform( rotate4 );
assert( CGAL::compare_distance_to_point( ori, p2, p9) == CGAL::EQUAL ); assert( CGAL::compare_distance_to_point( ori, p2, p9) == CGAL::EQUAL );
CGAL::Point_3<R> p10 = p2.transform( rotate5 ); CGAL::Point_3<R> p10 = p2.transform( rotate5 );
assert( CGAL::compare_distance_to_point( ori, p2, p10) == CGAL::EQUAL ); assert( CGAL::compare_distance_to_point( ori, p2, p10) == CGAL::EQUAL || nonexact );
p6 = p6 + v1; p6 = p6 + v1;
p7 = p7 + v1; p7 = p7 + v1;
p8 = p8 + v1; p8 = p8 + v1;
p9 = p9 + v1; p9 = p9 + v1;
p10 = p10 + v1; p10 = p10 + v1;
CGAL::Sphere_3<R> c10 (p6, p8, p7, p9); CGAL::Sphere_3<R> c10 (p6, p8, p7, p9);
assert( c10.center() == ori + v1 ); assert( c10.center() == ori + v1 || nonexact );
assert( c10.orientation() == CGAL::POSITIVE ); assert( c10.orientation() == CGAL::POSITIVE );
assert( c10.opposite().orientation() == CGAL::NEGATIVE ); assert( c10.opposite().orientation() == CGAL::NEGATIVE );
@ -205,9 +207,9 @@ _test_cls_sphere_3(const R& )
== CGAL::ON_POSITIVE_SIDE ); == CGAL::ON_POSITIVE_SIDE );
assert( c10.oriented_side(CGAL::ORIGIN + v1 + vx*n2 ) \ assert( c10.oriented_side(CGAL::ORIGIN + v1 + vx*n2 ) \
== CGAL::ON_NEGATIVE_SIDE ); == CGAL::ON_NEGATIVE_SIDE );
assert( c10.oriented_side(p9 ) == CGAL::ON_ORIENTED_BOUNDARY ); assert( c10.oriented_side(p9 ) == CGAL::ON_ORIENTED_BOUNDARY || nonexact );
assert( c10.has_on_boundary(p9) ); assert( c10.has_on_boundary(p9) || nonexact );
assert( c10.has_on_boundary(p4 + v1) ); assert( c10.has_on_boundary(p4 + v1) || nonexact );
CGAL::Point_3<R> p11( n4, n4, n4, n3) ; // (2.5, 2.5, 2.5) CGAL::Point_3<R> p11( n4, n4, n4, n3) ; // (2.5, 2.5, 2.5)
CGAL::Point_3<R> p12( n5, n5, n5, n3) ; // ( 5 , 5, 5 ) CGAL::Point_3<R> p12( n5, n5, n5, n3) ; // ( 5 , 5, 5 )
assert( c10.has_on_bounded_side( p11 ) ); assert( c10.has_on_bounded_side( p11 ) );
@ -217,8 +219,8 @@ _test_cls_sphere_3(const R& )
assert( c10.has_on_negative_side( p12 ) ); assert( c10.has_on_negative_side( p12 ) );
assert( c10.opposite().has_on_negative_side( p11 ) ); assert( c10.opposite().has_on_negative_side( p11 ) );
assert( c10.opposite().has_on_positive_side( p12 ) ); assert( c10.opposite().has_on_positive_side( p12 ) );
assert( c10.has_on_boundary( p6 ) ); assert( c10.has_on_boundary( p6 ) || nonexact );
assert( c10.has_on_boundary( p8 ) ); assert( c10.has_on_boundary( p8 ) || nonexact );
std::cout << '.'; std::cout << '.';

View File

@ -26,6 +26,7 @@
#include <CGAL/Bbox_2.h> #include <CGAL/Bbox_2.h>
#include <cassert> #include <cassert>
#include <CGAL/use.h>
template <class R> template <class R>
bool bool
@ -36,9 +37,6 @@ _test_cls_triangle_2(const R& )
typedef typename R::RT RT; typedef typename R::RT RT;
typedef typename R::FT FT; typedef typename R::FT FT;
typename R::Triangle_2 it;
CGAL::Triangle_2<R> t0(it);
RT n0 = 0; RT n0 = 0;
RT n1 = 1; RT n1 = 1;
RT n2 = 2; RT n2 = 2;
@ -62,6 +60,10 @@ _test_cls_triangle_2(const R& )
CGAL::Point_2<R> p8(-n12,-n8,-n2); // ( 6, 4) CGAL::Point_2<R> p8(-n12,-n8,-n2); // ( 6, 4)
CGAL::Point_2<R> p9( n9, n9, n3); // ( 3, 3) CGAL::Point_2<R> p9( n9, n9, n3); // ( 3, 3)
typename R::Triangle_2 it0; CGAL_USE(it0); // test default-construction
typename R::Triangle_2 it(p1, p2, p3);
CGAL::Triangle_2<R> t0(it);
CGAL::Triangle_2<R> t1( p1, p3, p5); CGAL::Triangle_2<R> t1( p1, p3, p5);
CGAL::Triangle_2<R> t2( p3, p1, p5); CGAL::Triangle_2<R> t2( p3, p1, p5);
CGAL::Triangle_2<R> t3( p7, p8, p9); CGAL::Triangle_2<R> t3( p7, p8, p9);

View File

@ -24,6 +24,8 @@
#ifndef CGAL__TEST_CLS_VECTOR_2_H #ifndef CGAL__TEST_CLS_VECTOR_2_H
#define CGAL__TEST_CLS_VECTOR_2_H #define CGAL__TEST_CLS_VECTOR_2_H
#include <CGAL/use.h>
template <class R> template <class R>
bool bool
_test_cls_vector_2(const R& ) _test_cls_vector_2(const R& )
@ -37,7 +39,7 @@ _test_cls_vector_2(const R& )
typedef typename R::Vector_2::Cartesian_const_iterator CCI; typedef typename R::Vector_2::Cartesian_const_iterator CCI;
CGAL::Vector_2<R> v1; CGAL::Vector_2<R> v1;
CGAL::Vector_2<R> v2(iv); CGAL::Vector_2<R> v2(iv); CGAL_USE(v2);
CGAL::Vector_2<R> v0(CGAL::NULL_VECTOR); CGAL::Vector_2<R> v0(CGAL::NULL_VECTOR);
RT n1( 12 ); RT n1( 12 );

View File

@ -24,6 +24,8 @@
#ifndef CGAL__TEST_CLS_VECTOR_3_H #ifndef CGAL__TEST_CLS_VECTOR_3_H
#define CGAL__TEST_CLS_VECTOR_3_H #define CGAL__TEST_CLS_VECTOR_3_H
#include <CGAL/use.h>
template <class R> template <class R>
bool bool
_test_cls_vector_3(const R& ) _test_cls_vector_3(const R& )
@ -37,7 +39,7 @@ _test_cls_vector_3(const R& )
typedef typename R::Vector_3::Cartesian_const_iterator CCI; typedef typename R::Vector_3::Cartesian_const_iterator CCI;
CGAL::Vector_3<R> v1; CGAL::Vector_3<R> v1;
CGAL::Vector_3<R> v2(iv); CGAL::Vector_3<R> v2(iv); CGAL_USE(v2);
CGAL::Vector_3<R> v0(CGAL::NULL_VECTOR); CGAL::Vector_3<R> v0(CGAL::NULL_VECTOR);
RT n1( 12 ); RT n1( 12 );

View File

@ -24,6 +24,8 @@
#ifndef CGAL__TEST_FCT_POINTS_IMPLICIT_SPHERE_H #ifndef CGAL__TEST_FCT_POINTS_IMPLICIT_SPHERE_H
#define CGAL__TEST_FCT_POINTS_IMPLICIT_SPHERE_H #define CGAL__TEST_FCT_POINTS_IMPLICIT_SPHERE_H
#include <boost/type_traits/is_same.hpp>
template <class R> template <class R>
bool bool
_test_fct_points_implicit_sphere(const R&) _test_fct_points_implicit_sphere(const R&)
@ -32,6 +34,8 @@ _test_fct_points_implicit_sphere(const R&)
typedef typename R::FT FT; typedef typename R::FT FT;
typedef CGAL::Tetrahedron_3<R> Tetrahedron; typedef CGAL::Tetrahedron_3<R> Tetrahedron;
const bool nonexact = boost::is_same<FT, double>::value;
const RT RT0(0); const RT RT0(0);
const RT RT4(4); const RT RT4(4);
const FT FT1(1); const FT FT1(1);
@ -70,7 +74,7 @@ _test_fct_points_implicit_sphere(const R&)
CGAL::Point_3<R> tpt = p.transform(rot_z); CGAL::Point_3<R> tpt = p.transform(rot_z);
assert( CGAL::squared_distance( tpt, org ) == FT1 ); assert( CGAL::squared_distance( tpt, org ) == FT1 );
p = tpt.transform(rot_z); p = tpt.transform(rot_z);
assert( CGAL::squared_distance( p, org ) == FT1 ); assert( CGAL::squared_distance( p, org ) == FT1 || nonexact );
CGAL::rational_rotation_approximation( RT(35), RT(-8), CGAL::rational_rotation_approximation( RT(35), RT(-8),
sin, cos, den, sin, cos, den,
@ -82,9 +86,9 @@ _test_fct_points_implicit_sphere(const R&)
assert( CGAL::squared_distance( q, org ) == FT1 ); assert( CGAL::squared_distance( q, org ) == FT1 );
tpt = q.transform(rot_x); tpt = q.transform(rot_x);
assert( CGAL::squared_distance( tpt, org ) == FT1 ); assert( CGAL::squared_distance( tpt, org ) == FT1 || nonexact );
q = tpt.transform(rot_y); q = tpt.transform(rot_y);
assert( CGAL::squared_distance( q, org ) == FT1 ); assert( CGAL::squared_distance( q, org ) == FT1 || nonexact );
CGAL::rational_rotation_approximation( RT(9), RT(-8), CGAL::rational_rotation_approximation( RT(9), RT(-8),
sin, cos, den, sin, cos, den,
@ -98,7 +102,7 @@ _test_fct_points_implicit_sphere(const R&)
tpt = r.transform(rot_z); tpt = r.transform(rot_z);
assert( CGAL::squared_distance( tpt, org ) == FT1 ); assert( CGAL::squared_distance( tpt, org ) == FT1 );
r = tpt.transform(rot_y); r = tpt.transform(rot_y);
assert( CGAL::squared_distance( r, org ) == FT1 ); assert( CGAL::squared_distance( r, org ) == FT1 || nonexact );
CGAL::rational_rotation_approximation( RT(-19), RT(-1), CGAL::rational_rotation_approximation( RT(-19), RT(-1),
sin, cos, den, sin, cos, den,
@ -137,11 +141,11 @@ _test_fct_points_implicit_sphere(const R&)
CGAL::Point_3<R> ez( RT0, RT0, RT1); CGAL::Point_3<R> ez( RT0, RT0, RT1);
CGAL::Point_3<R> oz( RT0, RT0, -RT1); CGAL::Point_3<R> oz( RT0, RT0, -RT1);
assert( CGAL::circumcenter(ex, ey, ez, oz) == org ); assert( CGAL::circumcenter(ex, ey, ez, oz) == org );
assert( CGAL::circumcenter(p,q,r,s) == org ); assert( CGAL::circumcenter(p,q,r,s) == org || nonexact );
assert( CGAL::circumcenter(p,r,q,s) == org ); assert( CGAL::circumcenter(p,r,q,s) == org || nonexact );
assert( CGAL::circumcenter(Tetrahedron(ex, ey, ez, oz)) == org ); assert( CGAL::circumcenter(Tetrahedron(ex, ey, ez, oz)) == org );
assert( CGAL::circumcenter(Tetrahedron(p,q,r,s)) == org ); assert( CGAL::circumcenter(Tetrahedron(p,q,r,s)) == org || nonexact );
assert( CGAL::circumcenter(Tetrahedron(p,r,q,s)) == org ); assert( CGAL::circumcenter(Tetrahedron(p,r,q,s)) == org || nonexact );
CGAL::Vector_3<R> v( RT(12), RT(4), RT(-4), RT(2) ); CGAL::Vector_3<R> v( RT(12), RT(4), RT(-4), RT(2) );
CGAL::Point_3<R> pt = p + v; CGAL::Point_3<R> pt = p + v;
@ -169,10 +173,10 @@ _test_fct_points_implicit_sphere(const R&)
assert( CGAL::side_of_bounded_sphere(pt,rt,qt,st,ot) \ assert( CGAL::side_of_bounded_sphere(pt,rt,qt,st,ot) \
== CGAL::ON_UNBOUNDED_SIDE); == CGAL::ON_UNBOUNDED_SIDE);
assert( CGAL::circumcenter(pt,qt,rt,st) == c ); assert( CGAL::circumcenter(pt,qt,rt,st) == c || nonexact );
assert( CGAL::circumcenter(pt,rt,qt,st) == c ); assert( CGAL::circumcenter(pt,rt,qt,st) == c || nonexact );
assert( CGAL::circumcenter(Tetrahedron(pt,qt,rt,st)) == c ); assert( CGAL::circumcenter(Tetrahedron(pt,qt,rt,st)) == c || nonexact );
assert( CGAL::circumcenter(Tetrahedron(pt,rt,qt,st)) == c ); assert( CGAL::circumcenter(Tetrahedron(pt,rt,qt,st)) == c || nonexact );
// Now test side_of_bounded_sphere(p, q, t). // Now test side_of_bounded_sphere(p, q, t).

View File

@ -31,6 +31,8 @@
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include "_approx_equal.h"
template <class R> template <class R>
bool bool
_test_fct_weighted_point_2(const R& ) _test_fct_weighted_point_2(const R& )
@ -158,8 +160,9 @@ _test_fct_weighted_point_2(const R& )
std::cout << CGAL::weighted_circumcenter(wp_00, wp_10, wp_01) << std::endl; std::cout << CGAL::weighted_circumcenter(wp_00, wp_10, wp_01) << std::endl;
assert( CGAL::squared_radius_smallest_orthogonal_circle(wp1, wp3, wp5) using CGAL::testsuite::approx_equal;
== CGAL::squared_radius(p1, p3, p5)); assert( approx_equal(CGAL::squared_radius_smallest_orthogonal_circle(wp1, wp3, wp5),
CGAL::squared_radius(p1, p3, p5)) );
assert( CGAL::squared_radius_smallest_orthogonal_circle(wp_00, wp_10, wp_01) == RT(0)); assert( CGAL::squared_radius_smallest_orthogonal_circle(wp_00, wp_10, wp_01) == RT(0));
std::cout << "done" << std::endl; std::cout << "done" << std::endl;

View File

@ -27,6 +27,7 @@
#include <CGAL/Point_3.h> #include <CGAL/Point_3.h>
#include <CGAL/Weighted_point_3.h> #include <CGAL/Weighted_point_3.h>
#include <boost/type_traits/is_same.hpp>
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
@ -37,6 +38,7 @@ _test_fct_weighted_point_3(const R& )
std::cout << "Testing functions Weighted_point_3" ; std::cout << "Testing functions Weighted_point_3" ;
typedef typename R::RT RT; typedef typename R::RT RT;
const bool nonexact = boost::is_same<RT, double>::value;
CGAL::Point_3<R> p1(RT(18), RT(15), RT(-21), RT(3) ); // 6, 5, -7 CGAL::Point_3<R> p1(RT(18), RT(15), RT(-21), RT(3) ); // 6, 5, -7
CGAL::Point_3<R> p2(RT(18), RT(15), RT( 12), RT(3) ); // 6, 5, 4 CGAL::Point_3<R> p2(RT(18), RT(15), RT( 12), RT(3) ); // 6, 5, 4
@ -138,7 +140,7 @@ _test_fct_weighted_point_3(const R& )
assert( CGAL::power_side_of_bounded_power_sphere(wp3_b, wp1_b, wp6b_b) == CGAL::ON_BOUNDED_SIDE ); assert( CGAL::power_side_of_bounded_power_sphere(wp3_b, wp1_b, wp6b_b) == CGAL::ON_BOUNDED_SIDE );
assert( CGAL::power_side_of_bounded_power_sphere(wp1_b, wp3_b, wp6b_b) == CGAL::ON_BOUNDED_SIDE ); assert( CGAL::power_side_of_bounded_power_sphere(wp1_b, wp3_b, wp6b_b) == CGAL::ON_BOUNDED_SIDE );
assert( CGAL::coplanar(p4, p5, p6, p7) ); assert( CGAL::coplanar(p4, p5, p6, p7) || nonexact );
assert( CGAL::power_side_of_bounded_power_sphere(wp4, wp5, wp6, wp7) assert( CGAL::power_side_of_bounded_power_sphere(wp4, wp5, wp6, wp7)
== CGAL::side_of_bounded_sphere(p4, p5, p6, p7) ); == CGAL::side_of_bounded_sphere(p4, p5, p6, p7) );
assert( CGAL::power_side_of_bounded_power_sphere(wp4, wp5, wp6, wp5) assert( CGAL::power_side_of_bounded_power_sphere(wp4, wp5, wp6, wp5)
@ -171,11 +173,11 @@ _test_fct_weighted_point_3(const R& )
assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp1_b, wp3_b) == RT(164)); assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp1_b, wp3_b) == RT(164));
assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp1, wp3, wp5) assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp1, wp3, wp5)
== CGAL::squared_radius(p1, p3, p5)); == CGAL::squared_radius(p1, p3, p5) || nonexact);
assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp000, wp100, wp010) == RT(0)); assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp000, wp100, wp010) == RT(0));
assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp1, wp3, wp4, wp5) assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp1, wp3, wp4, wp5)
== CGAL::squared_radius(p1, p3, p4, p5)); == CGAL::squared_radius(p1, p3, p4, p5) || nonexact);
assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp000, wp100, wp010, wp001) == RT(0)); assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp000, wp100, wp010, wp001) == RT(0));
std::cout << "."; std::cout << ".";

View File

@ -24,6 +24,9 @@
#ifndef CGAL__TEST_FURTHER_FCT_POINT_2_H #ifndef CGAL__TEST_FURTHER_FCT_POINT_2_H
#define CGAL__TEST_FURTHER_FCT_POINT_2_H #define CGAL__TEST_FURTHER_FCT_POINT_2_H
#include "_approx_equal.h"
#include <boost/type_traits/is_same.hpp>
template <class R> template <class R>
bool bool
_test_further_fct_point_2(const R& ) _test_further_fct_point_2(const R& )
@ -95,23 +98,27 @@ _test_further_fct_point_2(const R& )
p4 = p0.transform(rotate4); p4 = p0.transform(rotate4);
p5 = p0.transform(rotate5); p5 = p0.transform(rotate5);
using CGAL::testsuite::approx_equal;
using CGAL::testsuite::Direction_2_tag;
assert( (p5 - CGAL::ORIGIN).direction() == dir5 ); const bool nonexact = boost::is_same<FT, double>::value;
assert( approx_equal((p5 - CGAL::ORIGIN).direction(), dir5, Direction_2_tag()) );
assert( CGAL::side_of_bounded_circle(p1, p2, p3, CGAL::Point_2<R>(CGAL::ORIGIN))\ assert( CGAL::side_of_bounded_circle(p1, p2, p3, CGAL::Point_2<R>(CGAL::ORIGIN))\
== CGAL::ON_BOUNDED_SIDE ); == CGAL::ON_BOUNDED_SIDE );
assert( CGAL::side_of_bounded_circle(p1+v, p2+v, p3+v, CGAL::ORIGIN + v) \ assert( CGAL::side_of_bounded_circle(p1+v, p2+v, p3+v, CGAL::ORIGIN + v) \
== CGAL::ON_BOUNDED_SIDE ); == CGAL::ON_BOUNDED_SIDE );
assert( CGAL::side_of_bounded_circle(p1+v, p2+v, p3+v, CGAL::ORIGIN - v) \ assert( CGAL::side_of_bounded_circle(p1+v, p2+v, p3+v, CGAL::ORIGIN - v) \
== CGAL::ON_UNBOUNDED_SIDE ); == CGAL::ON_UNBOUNDED_SIDE || nonexact);
assert( CGAL::side_of_bounded_circle(p1, p2, p3, p4) \ assert( CGAL::side_of_bounded_circle(p1, p2, p3, p4) \
== CGAL::ON_BOUNDARY ); == CGAL::ON_BOUNDARY || nonexact);
assert( CGAL::side_of_bounded_circle(p1+v, p2+v, p3+v, p4+v) \ assert( CGAL::side_of_bounded_circle(p1+v, p2+v, p3+v, p4+v) \
== CGAL::ON_BOUNDARY ); == CGAL::ON_BOUNDARY || nonexact);
assert( CGAL::side_of_bounded_circle(p1+v, p3+v, p4+v, p2+v) \ assert( CGAL::side_of_bounded_circle(p1+v, p3+v, p4+v, p2+v) \
== CGAL::ON_BOUNDARY ); == CGAL::ON_BOUNDARY || nonexact);
assert( CGAL::side_of_bounded_circle(p2+v, p4+v, p1+v, p3+v) \ assert( CGAL::side_of_bounded_circle(p2+v, p4+v, p1+v, p3+v) \
== CGAL::ON_BOUNDARY ); == CGAL::ON_BOUNDARY || nonexact);
assert( CGAL::orientation( p1, p2, p3 ) == CGAL::POSITIVE ); assert( CGAL::orientation( p1, p2, p3 ) == CGAL::POSITIVE );
@ -126,11 +133,11 @@ _test_further_fct_point_2(const R& )
assert( CGAL::side_of_oriented_circle(p2+v, p1+v, p3+v, CGAL::ORIGIN - v) \ assert( CGAL::side_of_oriented_circle(p2+v, p1+v, p3+v, CGAL::ORIGIN - v) \
== CGAL::ON_POSITIVE_SIDE ); == CGAL::ON_POSITIVE_SIDE );
assert( CGAL::side_of_oriented_circle(p1, p2, p3, p4) \ assert( CGAL::side_of_oriented_circle(p1, p2, p3, p4) \
== CGAL::ON_ORIENTED_BOUNDARY ); == CGAL::ON_ORIENTED_BOUNDARY || nonexact);
assert( CGAL::side_of_oriented_circle(p1+v, p2+v, p3+v, p4+v) \ assert( CGAL::side_of_oriented_circle(p1+v, p2+v, p3+v, p4+v) \
== CGAL::ON_ORIENTED_BOUNDARY ); == CGAL::ON_ORIENTED_BOUNDARY || nonexact);
assert( CGAL::side_of_oriented_circle(p1+v, p3+v, p4+v, p2+v) \ assert( CGAL::side_of_oriented_circle(p1+v, p3+v, p4+v, p2+v) \
== CGAL::ON_ORIENTED_BOUNDARY ); == CGAL::ON_ORIENTED_BOUNDARY || nonexact);
CGAL::Point_2<R> p10( RT(100), RT(100), RT(10) ); CGAL::Point_2<R> p10( RT(100), RT(100), RT(10) );
CGAL::Point_2<R> p11( RT(-100), RT(-100), RT(10) ); CGAL::Point_2<R> p11( RT(-100), RT(-100), RT(10) );

View File

@ -24,6 +24,8 @@
#ifndef CGAL__TEST_MF_PLANE_3_TO_2D_H #ifndef CGAL__TEST_MF_PLANE_3_TO_2D_H
#define CGAL__TEST_MF_PLANE_3_TO_2D_H #define CGAL__TEST_MF_PLANE_3_TO_2D_H
#include <boost/type_traits/is_same.hpp>
template <class R> template <class R>
bool bool
_test_mf_plane_3_to_2d(const R& ) _test_mf_plane_3_to_2d(const R& )
@ -35,6 +37,8 @@ _test_mf_plane_3_to_2d(const R& )
typedef CGAL::Point_3< R> Point_3; typedef CGAL::Point_3< R> Point_3;
typedef CGAL::Point_2< R> Point_2; typedef CGAL::Point_2< R> Point_2;
const bool nonexact = boost::is_same<RT, double>::value;
RT n0 = 0; RT n0 = 0;
RT n1 = 7; RT n1 = 7;
RT n2 = 21; RT n2 = 21;
@ -51,33 +55,33 @@ _test_mf_plane_3_to_2d(const R& )
Point_3 p4 = p3 + (p2 - p1); Point_3 p4 = p3 + (p2 - p1);
Plane_3 pl1( p1, p2, p3); Plane_3 pl1( p1, p2, p3);
assert( pl1.has_on( pl1.to_3d( pl1.to_2d( pl1.point() ))) ); assert( pl1.has_on( pl1.to_3d( pl1.to_2d( pl1.point() ))) || nonexact );
assert( pl1.has_on( pl1.to_3d( pl1.to_2d( p4 ))) ); assert( pl1.has_on( pl1.to_3d( pl1.to_2d( p4 ))) || nonexact );
assert( p1 == pl1.to_3d( pl1.to_2d( p1)) ); assert( p1 == pl1.to_3d( pl1.to_2d( p1)) || nonexact );
assert( p2 == pl1.to_3d( pl1.to_2d( p2)) ); assert( p2 == pl1.to_3d( pl1.to_2d( p2)) || nonexact );
assert( p3 == pl1.to_3d( pl1.to_2d( p3)) ); assert( p3 == pl1.to_3d( pl1.to_2d( p3)) || nonexact );
assert( p4 == pl1.to_3d( pl1.to_2d( p4)) ); assert( p4 == pl1.to_3d( pl1.to_2d( p4)) || nonexact );
std::cout << '.'; std::cout << '.';
Plane_3 pl2( p2, p1, p3); Plane_3 pl2( p2, p1, p3);
assert( pl2.has_on( pl2.to_3d( pl2.to_2d( pl2.point() ))) ); assert( pl2.has_on( pl2.to_3d( pl2.to_2d( pl2.point() ))) || nonexact );
assert( pl2.has_on( pl2.to_3d( pl2.to_2d( p4 ))) ); assert( pl2.has_on( pl2.to_3d( pl2.to_2d( p4 ))) || nonexact );
assert( p1 == pl2.to_3d( pl2.to_2d( p1)) ); assert( p1 == pl2.to_3d( pl2.to_2d( p1)) || nonexact );
assert( p2 == pl2.to_3d( pl2.to_2d( p2)) ); assert( p2 == pl2.to_3d( pl2.to_2d( p2)) || nonexact );
assert( p3 == pl2.to_3d( pl2.to_2d( p3)) ); assert( p3 == pl2.to_3d( pl2.to_2d( p3)) || nonexact );
assert( p4 == pl2.to_3d( pl2.to_2d( p4)) ); assert( p4 == pl2.to_3d( pl2.to_2d( p4)) || nonexact );
Point_3 p5( n2, n8, n0, n7); Point_3 p5( n2, n8, n0, n7);
Point_3 p6( n4, n5, n0, n8); Point_3 p6( n4, n5, n0, n8);
Plane_3 pl3( p4, p5, p6); Plane_3 pl3( p4, p5, p6);
assert( p4 == pl3.to_3d( pl3.to_2d( p4)) ); assert( p4 == pl3.to_3d( pl3.to_2d( p4)) || nonexact );
assert( p5 == pl3.to_3d( pl3.to_2d( p5)) ); assert( p5 == pl3.to_3d( pl3.to_2d( p5)) );
assert( p6 == pl3.to_3d( pl3.to_2d( p6)) ); assert( p6 == pl3.to_3d( pl3.to_2d( p6)) || nonexact );
Plane_3 pl4( p4, p6, p5); Plane_3 pl4( p4, p6, p5);
assert( p4 == pl4.to_3d( pl4.to_2d( p4)) ); assert( p4 == pl4.to_3d( pl4.to_2d( p4)) || nonexact );
assert( p5 == pl4.to_3d( pl4.to_2d( p5)) ); assert( p5 == pl4.to_3d( pl4.to_2d( p5)) );
assert( p6 == pl4.to_3d( pl4.to_2d( p6)) ); assert( p6 == pl4.to_3d( pl4.to_2d( p6)) || nonexact );
Point_3 p7 = CGAL::midpoint( p1, p2); Point_3 p7 = CGAL::midpoint( p1, p2);
Point_3 p8 = CGAL::midpoint( p3, p3 + (p2-p1) ); Point_3 p8 = CGAL::midpoint( p3, p3 + (p2-p1) );
@ -98,14 +102,14 @@ _test_mf_plane_3_to_2d(const R& )
CGAL::Segment_2<R> sp2( pp9, pp10); CGAL::Segment_2<R> sp2( pp9, pp10);
Point_2 pp; Point_2 pp;
assert( CGAL::assign( pp, CGAL::intersection( sp1, sp2)) ); assert( CGAL::assign( pp, CGAL::intersection( sp1, sp2)) );
assert( sp1.has_on( pp) ); assert( sp1.has_on( pp) || nonexact );
assert( sp2.has_on( pp) ); assert( sp2.has_on( pp) || nonexact );
Point_3 p = pl1.to_3d( pp); Point_3 p = pl1.to_3d( pp);
assert( pl1.has_on( p )); assert( pl1.has_on( p ) || nonexact );
CGAL::Segment_3<R> s1( p7, p8); CGAL::Segment_3<R> s1( p7, p8);
CGAL::Segment_3<R> s2( p9, p10); CGAL::Segment_3<R> s2( p9, p10);
assert( s1.has_on( p) ); assert( s1.has_on( p) || nonexact );
assert( s2.has_on( p) ); assert( s2.has_on( p) || nonexact );
std::cout << '.' << std::endl; std::cout << '.' << std::endl;
return true; return true;

View File

@ -35,7 +35,7 @@
#include "_test_cls_iso_rectangle_new_2.h" #include "_test_cls_iso_rectangle_new_2.h"
#include "_test_cls_circle_new_2.h" #include "_test_cls_circle_new_2.h"
#include <CGAL/Testsuite/use.h> #include <CGAL/use.h>
using CGAL::internal::use; using CGAL::internal::use;
@ -175,8 +175,8 @@ test_new_2(const R& rep)
typename R::Construct_triangle_2 construct_triangle typename R::Construct_triangle_2 construct_triangle
= rep.construct_triangle_2_object(); = rep.construct_triangle_2_object();
Triangle_2 t1; Triangle_2 t0; CGAL_USE(t0); // test default-construction
Triangle_2 t2 = construct_triangle(p2,p3,p4); Triangle_2 t2 = construct_triangle(p2,p3,p4), t1 = t2;
typename R::Construct_iso_rectangle_2 construct_iso_rectangle typename R::Construct_iso_rectangle_2 construct_iso_rectangle
= rep.construct_iso_rectangle_2_object(); = rep.construct_iso_rectangle_2_object();
@ -379,6 +379,7 @@ test_new_2(const R& rep)
typename R::Compute_power_product_2 compute_power_product typename R::Compute_power_product_2 compute_power_product
= rep.compute_power_product_2_object(); = rep.compute_power_product_2_object();
tmp22d = compute_power_product(wp6, wp7); tmp22d = compute_power_product(wp6, wp7);
CGAL_USE(tmp22d);
typename R::Compute_squared_length_2 Compute_squared_length typename R::Compute_squared_length_2 Compute_squared_length
= rep.compute_squared_length_2_object(); = rep.compute_squared_length_2_object();
@ -672,7 +673,7 @@ test_new_2(const R& rep)
use(tmp9); use(tmp10); use(tmp11); use(tmp12); use(tmp12a); use(tmp9); use(tmp10); use(tmp11); use(tmp12); use(tmp12a);
use(tmp14); use(tmp14a); use(tmp15); use(tmp16); use(tmp14); use(tmp14a); use(tmp15); use(tmp16);
use(tmp16); use(tmp17); use(tmp19); use(tmp19a); use(tmp22a); use(tmp16); use(tmp17); use(tmp19); use(tmp19a); use(tmp22a);
use(tmp22b); use(tmp22c); use(tmp23); use(tmp22b); use(tmp22c); use(tmp22d); use(tmp23);
use(tmp58); use(tmp58);
use(tmp57); use(tmp56); use(tmp55); use(tmp54); use(tmp53b); use(tmp53a); use(tmp57); use(tmp56); use(tmp55); use(tmp54); use(tmp53b); use(tmp53a);

View File

@ -29,7 +29,7 @@
#include <CGAL/squared_distance_3.h> #include <CGAL/squared_distance_3.h>
#include <CGAL/_test_compare_dihedral_angle_3.h> #include <CGAL/_test_compare_dihedral_angle_3.h>
#include <CGAL/Testsuite/use.h> #include <CGAL/use.h>
using CGAL::internal::use; using CGAL::internal::use;
@ -157,8 +157,8 @@ test_new_3(const R& rep)
typename R::Construct_segment_3 construct_segment typename R::Construct_segment_3 construct_segment
= rep.construct_segment_3_object(); = rep.construct_segment_3_object();
Segment_3 s1; Segment_3 s0; CGAL_USE(s0); // test default-construction
Segment_3 s2 = construct_segment(p2,p3); Segment_3 s2 = construct_segment(p2,p3), s1 = s2;
typename R::Construct_ray_3 construct_ray = typename R::Construct_ray_3 construct_ray =
rep.construct_ray_3_object(); rep.construct_ray_3_object();
@ -214,11 +214,10 @@ test_new_3(const R& rep)
Sphere_3 sp8 = construct_sphere(p3); Sphere_3 sp8 = construct_sphere(p3);
Sphere_3 sp9 = construct_sphere(p3,CLOCKWISE); Sphere_3 sp9 = construct_sphere(p3,CLOCKWISE);
Triangle_3 t0; CGAL_USE(t0); // test the default-construction
typename R::Construct_triangle_3 construct_triangle typename R::Construct_triangle_3 construct_triangle
= rep.construct_triangle_3_object(); = rep.construct_triangle_3_object();
Triangle_3 t1; Triangle_3 t1 = construct_triangle(p2,p3,p4), t2 = t1;
Triangle_3 t2 = construct_triangle(p2,p3,p4);
typename R::Construct_tetrahedron_3 construct_tetrahedron typename R::Construct_tetrahedron_3 construct_tetrahedron
= rep.construct_tetrahedron_3_object(); = rep.construct_tetrahedron_3_object();

View File

@ -216,7 +216,7 @@ public:
stored_polyhedra.push_back(bounding_polyhedron); stored_polyhedra.push_back(bounding_polyhedron);
get(face_patch_id_t<Patch_id>(), stored_polyhedra.back()); get(face_patch_id_t<Patch_id>(), stored_polyhedra.back());
this->add_primitives(stored_polyhedra.back()); this->add_primitives(stored_polyhedra.back());
if(bounding_polyhedron.empty()) { if(CGAL::is_empty(bounding_polyhedron)) {
this->set_surface_only(); this->set_surface_only();
} else { } else {
this->add_primitives_to_bounding_tree(stored_polyhedra.back()); this->add_primitives_to_bounding_tree(stored_polyhedra.back());

View File

@ -1615,6 +1615,7 @@ void remove_unused_polylines(
} }
} }
std::vector<vertex_descriptor> vertices_kept;
for(vertex_descriptor v : vertices_to_remove) for(vertex_descriptor v : vertices_to_remove)
{ {
bool to_remove=true; bool to_remove=true;
@ -1629,7 +1630,31 @@ void remove_unused_polylines(
} }
if (to_remove) if (to_remove)
remove_vertex(v,tm); remove_vertex(v,tm);
else
vertices_kept.push_back(v);
} }
// update next/prev pointers around vertices in vertices_kept
for(vertex_descriptor v: vertices_kept)
{
halfedge_descriptor h = halfedge(v, tm), start=GT::null_halfedge();
do{
while ( !is_border(h, tm) || is_border(opposite(h, tm), tm) )
h = opposite(next(h, tm), tm);
halfedge_descriptor in = h;
if (start==GT::null_halfedge())
start=in;
else
if (start==in)
break;
while ( is_border(h, tm) )
h = opposite(next(h, tm), tm);
set_next(in, opposite(h, tm), tm);
}
while(true);//this loop handles non-manifold vertices
}
for(edge_descriptor e : edges_to_remove) for(edge_descriptor e : edges_to_remove)
remove_edge(e,tm); remove_edge(e,tm);
} }

View File

@ -89,33 +89,27 @@ public:
bool applicable(QAction* a) const { bool applicable(QAction* a) const {
if(a == actionSplitPolylines) { if(a == actionSplitPolylines) {
return qobject_cast<Scene_polylines_item*> return qobject_cast<Scene_polylines_item*>
(scene->item(scene->mainSelectionIndex())) != 0; (scene->item(scene->mainSelectionIndex())) != nullptr;
} }
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS
if(qobject_cast<Scene_implicit_function_item*>(scene->item(scene->mainSelectionIndex())) != NULL if(qobject_cast<Scene_implicit_function_item*>
&& a == actionMesh_3) (scene->item(scene->mainSelectionIndex())) != nullptr) {
return true; return true;
}
#endif #endif
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES
Q_FOREACH(int ind, scene->selectionIndices()){ if( qobject_cast<Scene_image_item*>
if( qobject_cast<Scene_image_item*>(scene->item(ind))) (scene->item(scene->mainSelectionIndex())) != nullptr ) {
return true; return true;
} }
#endif #endif
Q_FOREACH(int ind, scene->selectionIndices()){ for(int ind: scene->selectionIndices()){
Scene_surface_mesh_item* sm_item Scene_surface_mesh_item* sm_item
= qobject_cast<Scene_surface_mesh_item*>(scene->item(ind)); = qobject_cast<Scene_surface_mesh_item*>(scene->item(ind));
if(NULL == sm_item) if(nullptr == sm_item)
continue; return false;
if (a == actionMesh_3)
{
if(sm_item)
return is_closed(*sm_item->polyhedron());
}
else
return true;
} }
return false; return true;
} }
public Q_SLOTS: public Q_SLOTS:
@ -138,6 +132,7 @@ private:
Messages_interface* msg; Messages_interface* msg;
QMessageBox* message_box_; QMessageBox* message_box_;
Scene_item* source_item_; Scene_item* source_item_;
QString source_item_name_;
CGAL::Three::Scene_interface* scene; CGAL::Three::Scene_interface* scene;
QMainWindow* mw; QMainWindow* mw;
bool as_facegraph; bool as_facegraph;
@ -182,66 +177,76 @@ void Mesh_3_plugin::mesh_3_volume()
void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
{ {
Scene_surface_mesh_item* sm_item = NULL; QList<Scene_surface_mesh_item*> sm_items;
Scene_surface_mesh_item* bounding_sm_item = NULL; Scene_surface_mesh_item* bounding_sm_item = nullptr;
Scene_implicit_function_item* function_item = NULL; Scene_implicit_function_item* function_item = nullptr;
Scene_image_item* image_item = NULL; Scene_image_item* image_item = nullptr;
Scene_polylines_item* polylines_item = NULL; Scene_polylines_item* polylines_item = nullptr;
Q_FOREACH(int ind, scene->selectionIndices()) { for(int ind: scene->selectionIndices()) {
if(sm_item == NULL) Scene_surface_mesh_item* sm_item =
{ qobject_cast<Scene_surface_mesh_item*>(scene->item(ind));
sm_item = qobject_cast<Scene_surface_mesh_item*>(scene->item(ind)); if(sm_item) {
if (sm_item != NULL sm_items.push_back(sm_item);
&& scene->selectionIndices().size() == 2 if(is_closed(*sm_item->polyhedron())) {
&& bounding_sm_item == NULL) bounding_sm_item = sm_item;
{
bounding_sm_item = qobject_cast<Scene_surface_mesh_item*>(
scene->item(scene->selectionIndices().back()));
if (bounding_sm_item != NULL)
{
if (is_closed(*sm_item->polyhedron())
&& !is_closed(*bounding_sm_item->polyhedron()))
{
//todo : check sm_item is inside bounding_sm_item
std::swap(sm_item, bounding_sm_item);
//now bounding_sm_item is the bounding one
}
}
} }
} }
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS
if(function_item == NULL){ else if(function_item == nullptr &&
function_item = qobject_cast<Scene_implicit_function_item*>(scene->item(ind)); nullptr !=
} (function_item = qobject_cast<Scene_implicit_function_item*>(scene->item(ind))))
{}
#endif #endif
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES
if(image_item == NULL){ else if(image_item == nullptr &&
image_item = qobject_cast<Scene_image_item*>(scene->item(ind)); nullptr != (image_item = qobject_cast<Scene_image_item*>(scene->item(ind))))
} {}
#endif #endif
if(polylines_item == NULL){ else if(polylines_item == nullptr &&
polylines_item = qobject_cast<Scene_polylines_item*>(scene->item(ind)); nullptr != (polylines_item = qobject_cast<Scene_polylines_item*>(scene->item(ind))))
} {}
} else {
Scene_item* item = NULL; QMessageBox::warning(mw, tr("Mesh_3 plugin"),
bool features_protection_available = false; tr("Wrong selection of items"));
if(NULL != sm_item)
{
if (!is_triangle_mesh(*sm_item->polyhedron()))
{
QMessageBox::warning(mw, tr(""),
tr("Selected Scene_surface_mesh__item is not triangulated."));
return; return;
} }
item = sm_item; }
Scene_item* item = nullptr;
const bool more_than_one_item = sm_items.size() > 1;
bool features_protection_available = false;
if(!sm_items.empty())
{
for(auto sm_item : sm_items) {
if(nullptr == sm_item->polyhedron()) {
QApplication::restoreOverrideCursor();
QMessageBox::critical(mw, tr("Mesh_3 plugin"),
tr("ERROR: no data in selected item %1").arg(sm_item->name()));
return;
}
if (!is_triangle_mesh(*sm_item->polyhedron()))
{
QApplication::restoreOverrideCursor();
QMessageBox::warning(mw, tr("Mesh_3 plugin"),
tr("Selected Scene_surface_mesh_item %1 is not triangulated.")
.arg(sm_item->name()));
return;
}
if(sm_item->getNbIsolatedvertices() != 0)
{
QApplication::restoreOverrideCursor();
QMessageBox::critical(mw, tr(""), tr("ERROR: there are isolated vertices in this mesh."));
return;
}
}
item = sm_items.front();
features_protection_available = true; features_protection_available = true;
} }
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS
else if (NULL != function_item) { item = function_item; } else if (nullptr != function_item) { item = function_item; }
#endif #endif
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES
else if (NULL != image_item) else if (nullptr != image_item)
{ {
item = image_item; item = image_item;
features_protection_available = true; features_protection_available = true;
@ -275,7 +280,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
} }
#endif #endif
if (NULL == item) if (nullptr == item)
{ {
QMessageBox::warning(mw, tr(""), QMessageBox::warning(mw, tr(""),
tr("Selected object can't be meshed")); tr("Selected object can't be meshed"));
@ -336,9 +341,18 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
connect(ui.protect, SIGNAL(toggled(bool)), connect(ui.protect, SIGNAL(toggled(bool)),
ui.protectEdges, SLOT(setEnabled(bool))); ui.protectEdges, SLOT(setEnabled(bool)));
QString item_name = more_than_one_item ?
QString("%1...").arg(item->name()) :
item->name();
// Set default parameters // Set default parameters
CGAL::Three::Scene_interface::Bbox bbox = item->bbox(); CGAL::Three::Scene_interface::Bbox bbox = item->bbox();
ui.objectName->setText(item->name()); if(more_than_one_item) {
for(auto it: sm_items) {
bbox = bbox + it->bbox();
}
}
ui.objectName->setText(item_name);
ui.objectNameSize->setText(tr("Object bbox size (w,h,d): <b>%1</b>, <b>%2</b>, <b>%3</b>") ui.objectNameSize->setText(tr("Object bbox size (w,h,d): <b>%1</b>, <b>%2</b>, <b>%3</b>")
.arg(bbox.xmax() - bbox.xmin(),0,'g',3) .arg(bbox.xmax() - bbox.xmin(),0,'g',3)
.arg(bbox.ymax() - bbox.ymin(),0,'g',3) .arg(bbox.ymax() - bbox.ymin(),0,'g',3)
@ -372,13 +386,13 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
ui.protectEdges->setEnabled(features_protection_available); ui.protectEdges->setEnabled(features_protection_available);
ui.facegraphCheckBox->setVisible(surface_only); ui.facegraphCheckBox->setVisible(surface_only);
ui.initializationGroup->setVisible(image_item != NULL && !image_item->isGray()); ui.initializationGroup->setVisible(image_item != nullptr && !image_item->isGray());
ui.grayImgGroup->setVisible(image_item != NULL && image_item->isGray()); ui.grayImgGroup->setVisible(image_item != nullptr && image_item->isGray());
if (sm_item != NULL) if (!sm_items.empty())
ui.volumeGroup->setVisible(!surface_only && is_closed(*sm_item->polyhedron())); ui.volumeGroup->setVisible(!surface_only && nullptr != bounding_sm_item);
else else
ui.volumeGroup->setVisible(!surface_only); ui.volumeGroup->setVisible(!surface_only);
if ((sm_item == NULL)|| polylines_item != NULL) { if ((!sm_items.empty())|| polylines_item != nullptr) {
ui.sharpEdgesAngleLabel->setVisible(false); ui.sharpEdgesAngleLabel->setVisible(false);
ui.sharpEdgesAngle->setVisible(false); ui.sharpEdgesAngle->setVisible(false);
@ -394,7 +408,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
if (features_protection_available) if (features_protection_available)
{ {
if (NULL != sm_item) if (!sm_items.empty())
{ {
if (surface_only) if (surface_only)
{ {
@ -404,9 +418,9 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
else else
ui.protectEdges->addItem(QString("Sharp edges")); ui.protectEdges->addItem(QString("Sharp edges"));
} }
else if(NULL != image_item) else if(nullptr != image_item)
{ {
if(polylines_item != NULL) if(polylines_item != nullptr)
ui.protectEdges->addItem(QString("Input polylines")); ui.protectEdges->addItem(QString("Input polylines"));
else else
{ {
@ -444,30 +458,24 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
const float inside_is_less = float(ui.inside_is_less_checkBox->isChecked()); const float inside_is_less = float(ui.inside_is_less_checkBox->isChecked());
as_facegraph = surface_only ? ui.facegraphCheckBox->isChecked() : false; as_facegraph = surface_only ? ui.facegraphCheckBox->isChecked() : false;
Meshing_thread* thread = NULL; Meshing_thread* thread = nullptr;
if ( NULL != sm_item ) if (!sm_items.empty())
{ {
SMesh* pMesh = sm_item->polyhedron(); QList<const SMesh*> polyhedrons;
if (NULL == pMesh) sm_items.removeAll(bounding_sm_item);
{ std::transform(sm_items.begin(), sm_items.end(),
QApplication::restoreOverrideCursor(); std::back_inserter(polyhedrons),
QMessageBox::critical(mw, tr(""), tr("ERROR: no data in selected item")); [](Scene_surface_mesh_item* item) {
return; return item->polyhedron();
} });
if(sm_item->getNbIsolatedvertices() != 0)
{
QApplication::restoreOverrideCursor();
QMessageBox::critical(mw, tr(""), tr("ERROR: there are isolated vertices in this mesh."));
return;
}
Scene_polylines_item::Polylines_container plc; Scene_polylines_item::Polylines_container plc;
SMesh *pBMesh = (bounding_sm_item == NULL) ? NULL SMesh *bounding_polyhedron =
: bounding_sm_item->polyhedron(); (bounding_sm_item == nullptr) ? nullptr : bounding_sm_item->polyhedron();
thread = cgal_code_mesh_3(pMesh, thread = cgal_code_mesh_3(polyhedrons,
(polylines_item == NULL)?plc:polylines_item->polylines, (polylines_item == nullptr)?plc:polylines_item->polylines,
pBMesh, bounding_polyhedron,
item->name(), item_name,
angle, angle,
facet_sizing, facet_sizing,
approx, approx,
@ -482,10 +490,10 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
} }
// Image // Image
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS
else if (NULL != function_item) else if (nullptr != function_item)
{ {
const Implicit_function_interface* pFunction = function_item->function(); const Implicit_function_interface* pFunction = function_item->function();
if (NULL == pFunction) if (nullptr == pFunction)
{ {
QMessageBox::critical(mw, tr(""), tr("ERROR: no data in selected item")); QMessageBox::critical(mw, tr(""), tr("ERROR: no data in selected item"));
return; return;
@ -503,10 +511,10 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
} }
#endif #endif
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES
else if (NULL != image_item) else if (nullptr != image_item)
{ {
const Image* pImage = image_item->image(); const Image* pImage = image_item->image();
if (NULL == pImage) if (nullptr == pImage)
{ {
QMessageBox::critical(mw, tr(""), tr("ERROR: no data in selected item")); QMessageBox::critical(mw, tr(""), tr("ERROR: no data in selected item"));
return; return;
@ -515,7 +523,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
Scene_polylines_item::Polylines_container plc; Scene_polylines_item::Polylines_container plc;
thread = cgal_code_mesh_3(pImage, thread = cgal_code_mesh_3(pImage,
(polylines_item == NULL)?plc:polylines_item->polylines, (polylines_item == nullptr)?plc:polylines_item->polylines,
angle, angle,
facet_sizing, facet_sizing,
approx, approx,
@ -533,7 +541,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
} }
#endif #endif
if ( NULL == thread ) if ( nullptr == thread )
{ {
QMessageBox::critical(mw,tr(""),tr("ERROR: no thread created")); QMessageBox::critical(mw,tr(""),tr("ERROR: no thread created"));
return; return;
@ -541,6 +549,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
// Launch thread // Launch thread
source_item_ = item; source_item_ = item;
source_item_name_ = item_name;
launch_thread(thread); launch_thread(thread);
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();
@ -592,7 +601,7 @@ void
Mesh_3_plugin:: Mesh_3_plugin::
status_report(QString str) status_report(QString str)
{ {
if ( NULL == message_box_ ) { return; } if ( nullptr == message_box_ ) { return; }
message_box_->setInformativeText(str); message_box_->setInformativeText(str);
} }
@ -604,7 +613,7 @@ meshing_done(Meshing_thread* thread)
{ {
// Print message in console // Print message in console
QString str = QString("Meshing of \"%1\" done in %2s<br>") QString str = QString("Meshing of \"%1\" done in %2s<br>")
.arg(source_item_->name()) .arg(source_item_name_)
.arg(thread->time()); .arg(thread->time());
Q_FOREACH( QString param, thread->parameters_log() ) Q_FOREACH( QString param, thread->parameters_log() )
@ -629,7 +638,7 @@ meshing_done(Meshing_thread* thread)
// close message box // close message box
message_box_->done(0); message_box_->done(0);
message_box_ = NULL; message_box_ = nullptr;
// free memory // free memory
// TODO: maybe there is another way to do that // TODO: maybe there is another way to do that
@ -644,7 +653,7 @@ treat_result(Scene_item& source_item,
{ {
if(!as_facegraph) if(!as_facegraph)
{ {
result_item->setName(tr("%1 [3D Mesh]").arg(source_item.name())); result_item->setName(tr("%1 [3D Mesh]").arg(source_item_name_));
result_item->c3t3_changed(); result_item->c3t3_changed();
@ -670,7 +679,7 @@ treat_result(Scene_item& source_item,
{ {
Scene_surface_mesh_item* new_item = new Scene_surface_mesh_item; Scene_surface_mesh_item* new_item = new Scene_surface_mesh_item;
CGAL::facets_in_complex_3_to_triangle_mesh(result_item->c3t3(), *new_item->face_graph()); CGAL::facets_in_complex_3_to_triangle_mesh(result_item->c3t3(), *new_item->face_graph());
new_item->setName(tr("%1 [Remeshed]").arg(source_item.name())); new_item->setName(tr("%1 [Remeshed]").arg(source_item_name_));
Q_FOREACH(int ind, scene->selectionIndices()) { Q_FOREACH(int ind, scene->selectionIndices()) {
scene->item(ind)->setVisible(false); scene->item(ind)->setVisible(false);
} }

View File

@ -31,15 +31,9 @@ struct Compare_to_isovalue {
} }
}; };
template<typename Mesh> Meshing_thread* cgal_code_mesh_3(QList<const SMesh*> pMeshes,
struct Polyhedral_mesh_domain_selector
{
typedef Polyhedral_mesh_domain type;
};
template<class Mesh>
Meshing_thread* cgal_code_mesh_3_templated(const Mesh* pMesh,
const Polylines_container& polylines, const Polylines_container& polylines,
const Mesh* pBoundingMesh, const SMesh* pBoundingMesh,
QString filename, QString filename,
const double facet_angle, const double facet_angle,
const double facet_sizing, const double facet_sizing,
@ -53,43 +47,39 @@ Meshing_thread* cgal_code_mesh_3_templated(const Mesh* pMesh,
const int manifold, const int manifold,
const bool surface_only) const bool surface_only)
{ {
if(!pMesh) return 0; if(pMeshes.empty() && nullptr == pBoundingMesh) return 0;
std::cerr << "Meshing file \"" << qPrintable(filename) << "\"\n"; std::cerr << "Meshing file \"" << qPrintable(filename) << "\"\n";
std::cerr << " angle: " << facet_angle << std::endl std::cerr << " angle: " << facet_angle << std::endl
<< " edge size bound: " << edge_size << std::endl << " edge size bound: " << edge_size << std::endl
<< " facets size bound: " << facet_sizing << std::endl << " facets size bound: " << facet_sizing << std::endl
<< " approximation bound: " << facet_approx << std::endl; << " approximation bound: " << facet_approx << std::endl;
if (is_closed(*pMesh)) if (!surface_only)
std::cerr << " tetrahedra size bound: " << tet_sizing << std::endl; std::cerr << " tetrahedra size bound: " << tet_sizing << std::endl;
std::cerr << "Build AABB tree..."; std::cerr << "Build AABB tree...";
CGAL::Real_timer timer; CGAL::Real_timer timer;
timer.start(); timer.start();
typedef typename Polyhedral_mesh_domain_selector<Mesh>::type Polyhedral_mesh_domain;
// Create domain // Create domain
Polyhedral_mesh_domain* p_domain = NULL; Polyhedral_mesh_domain* p_domain = nullptr;
if (!surface_only && is_closed(*pMesh)) if (surface_only || nullptr == pBoundingMesh)
p_domain = new Polyhedral_mesh_domain(*pMesh); p_domain = new Polyhedral_mesh_domain(pMeshes.begin(), pMeshes.end());
else if (!surface_only && pBoundingMesh != NULL && is_closed(*pBoundingMesh)) else if(pMeshes.empty())
p_domain = new Polyhedral_mesh_domain(*pMesh, *pBoundingMesh); p_domain = new Polyhedral_mesh_domain(*pBoundingMesh);
else else
{ p_domain = new Polyhedral_mesh_domain(pMeshes.begin(), pMeshes.end(),
std::vector<const Mesh*> poly_ptrs_vector(1, pMesh); *pBoundingMesh);
p_domain = new Polyhedral_mesh_domain(poly_ptrs_vector.begin(), poly_ptrs_vector.end());
}
// Features // Features
if(polylines.empty() && protect_features) { if(polylines.empty()) {
if(protect_features) {
//includes detection of borders in the surface case //includes detection of borders in the surface case
p_domain->detect_features(sharp_edges_angle); p_domain->detect_features(sharp_edges_angle);
} }
else if (polylines.empty() && protect_borders) else if (protect_borders) {
{ p_domain->detect_borders();
p_domain->detect_borders(); }
} } else {
if(! polylines.empty()){
p_domain->add_features(polylines.begin(), polylines.end()); p_domain->add_features(polylines.begin(), polylines.end());
protect_features = true; // so that it will be passed in make_mesh_3 protect_features = true; // so that it will be passed in make_mesh_3
} }
@ -109,7 +99,7 @@ Meshing_thread* cgal_code_mesh_3_templated(const Mesh* pMesh,
.arg(edge_size) .arg(edge_size)
.arg(facet_sizing) .arg(facet_sizing)
.arg(facet_approx); .arg(facet_approx);
if (is_closed(*pMesh)) if (!surface_only)
tooltip += QString("<li>Tetrahedra size bound: %1</li>" ) tooltip += QString("<li>Tetrahedra size bound: %1</li>" )
.arg(tet_sizing); .arg(tet_sizing);
tooltip += "</ul></div>"; tooltip += "</ul></div>";
@ -133,40 +123,6 @@ Meshing_thread* cgal_code_mesh_3_templated(const Mesh* pMesh,
return new Meshing_thread(p_mesh_function, p_new_item); return new Meshing_thread(p_mesh_function, p_new_item);
} }
Meshing_thread* cgal_code_mesh_3(const SMesh* pMesh,
const Polylines_container& polylines,
const SMesh* pBoundingMesh,
QString filename,
const double facet_angle,
const double facet_sizing,
const double facet_approx,
const double tet_sizing,
const double edge_size,
const double tet_shape,
bool protect_features,
bool protect_borders,
const double sharp_edges_angle,
const int manifold,
const bool surface_only)
{
return cgal_code_mesh_3_templated(pMesh,
polylines,
pBoundingMesh,
filename,
facet_angle,
facet_sizing,
facet_approx,
tet_sizing,
edge_size,
tet_shape,
protect_features,
protect_borders,
sharp_edges_angle,
manifold,
surface_only);
}
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS
Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction, Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction,
@ -179,7 +135,7 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction,
const int manifold, const int manifold,
const bool surface_only) const bool surface_only)
{ {
if (pfunction == NULL) { return NULL; } if (pfunction == nullptr) { return nullptr; }
CGAL::Bbox_3 domain_bbox(pfunction->bbox().xmin(), CGAL::Bbox_3 domain_bbox(pfunction->bbox().xmin(),
pfunction->bbox().ymin(), pfunction->bbox().ymin(),
@ -238,7 +194,7 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage,
float value_outside, float value_outside,
bool inside_is_less) bool inside_is_less)
{ {
if (NULL == pImage) { return NULL; } if (nullptr == pImage) { return nullptr; }
if(! polylines.empty()){ if(! polylines.empty()){
protect_features = true; // so that it will be passed in make_mesh_3 protect_features = true; // so that it will be passed in make_mesh_3

View File

@ -8,6 +8,7 @@
#include "Meshing_thread.h" #include "Meshing_thread.h"
#include "Scene_surface_mesh_item.h" #include "Scene_surface_mesh_item.h"
#include <CGAL/IO/facets_in_complex_3_to_triangle_mesh.h> #include <CGAL/IO/facets_in_complex_3_to_triangle_mesh.h>
#include <QList>
class Scene_surface_mesh_item; class Scene_surface_mesh_item;
@ -19,7 +20,7 @@ namespace CGAL { namespace Three {
typedef std::list<std::vector<CGAL::Exact_predicates_inexact_constructions_kernel::Point_3> > Polylines_container; typedef std::list<std::vector<CGAL::Exact_predicates_inexact_constructions_kernel::Point_3> > Polylines_container;
Meshing_thread* cgal_code_mesh_3(const SMesh* pMesh, Meshing_thread* cgal_code_mesh_3(QList<const SMesh*> pMeshes,
const Polylines_container& polylines, const Polylines_container& polylines,
const SMesh* pBoundingMesh, const SMesh* pBoundingMesh,
QString filename, QString filename,

View File

@ -306,9 +306,9 @@ public:
if(!static_cast<CGAL::Three::Viewer_interface*>(CGAL::QGLViewer::QGLViewerPool().first())->isClipping()) if(!static_cast<CGAL::Three::Viewer_interface*>(CGAL::QGLViewer::QGLViewerPool().first())->isClipping())
return true; return true;
double x = p.x(), y = p.y(), z = p.z(); double x = p.x()+offset.x, y = p.y()+offset.y, z = p.z()+offset.z;
return !(clipbox[0][0]*x+clipbox[0][1]*y+clipbox[0][2]*z+clipbox[0][3]>0 || return !(clipbox[0][0]*x+clipbox[0][1]*y+clipbox[0][2]*z+clipbox[0][3] >0 ||
clipbox[1][0]*x+clipbox[1][1]*y+clipbox[1][2]*z+clipbox[1][3]>0 || clipbox[1][0]*x+clipbox[1][1]*y+clipbox[1][2]*z+clipbox[1][3]>0 ||
clipbox[2][0]*x+clipbox[2][1]*y+clipbox[2][2]*z+clipbox[2][3]>0 || clipbox[2][0]*x+clipbox[2][1]*y+clipbox[2][2]*z+clipbox[2][3]>0 ||
clipbox[3][0]*x+clipbox[3][1]*y+clipbox[3][2]*z+clipbox[3][3]>0 || clipbox[3][0]*x+clipbox[3][1]*y+clipbox[3][2]*z+clipbox[3][3]>0 ||

View File

@ -32,6 +32,7 @@
#include <vector> #include <vector>
#include <list> #include <list>
#include <set> #include <set>
#include <stack>
#include <map> #include <map>
#include <algorithm> #include <algorithm>
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
@ -968,11 +969,11 @@ protected:
std::map<Vertex_handle,Vertex_handle>& vmap, std::map<Vertex_handle,Vertex_handle>& vmap,
List& l) const; List& l) const;
void expand_conflict_region_remove(const Face_handle& f, void expand_conflict_region_remove(const Face_handle& in_f,
const Site_2& t, const Site_2& t,
const Storage_site_2& ss, List& l,
List& l, Face_map& fm, Face_map& fm,
Sign_map& sign_map); Sign_map& sign_map);
void find_conflict_region_remove(const Vertex_handle& v, void find_conflict_region_remove(const Vertex_handle& v,
const Vertex_handle& vnearest, const Vertex_handle& vnearest,
@ -1448,16 +1449,22 @@ protected:
std::pair<Face_handle,Face_handle> std::pair<Face_handle,Face_handle>
find_faces_to_split(const Vertex_handle& v, const Site_2& t) const; find_faces_to_split(const Vertex_handle& v, const Site_2& t) const;
void expand_conflict_region(const Face_handle& f, const Site_2& t, bool check_unregistered_face(const Face_handle& n,
const Storage_site_2& ss, const Site_2& t,
#ifdef CGAL_SDG_NO_FACE_MAP List& l,
List& l, #ifndef CGAL_SDG_NO_FACE_MAP
#else Face_map& fm,
List& l, Face_map& fm,
std::map<Face_handle,Sign>& sign_map,
#endif #endif
Triple<bool, Vertex_handle, Triple<bool, Vertex_handle, Arrangement_type>& vcross);
Arrangement_type>& vcross);
void expand_conflict_region(const Face_handle& in_f,
const Site_2& t,
List& l,
#ifndef CGAL_SDG_NO_FACE_MAP
Face_map& fm,
std::map<Face_handle, Sign>& sign_map,
#endif
Triple<bool, Vertex_handle, Arrangement_type>& vcross);
Vertex_handle add_bogus_vertex(Edge e, List& l); Vertex_handle add_bogus_vertex(Edge e, List& l);
Vertex_list add_bogus_vertices(List& l); Vertex_list add_bogus_vertices(List& l);

View File

@ -465,9 +465,9 @@ insert_point2(const Storage_site_2& ss, const Site_2& t,
// REGION AND EXPANDS THE CONFLICT REGION. // REGION AND EXPANDS THE CONFLICT REGION.
initialize_conflict_region(start_f, l); initialize_conflict_region(start_f, l);
#ifdef CGAL_SDG_NO_FACE_MAP #ifdef CGAL_SDG_NO_FACE_MAP
expand_conflict_region(start_f, t, ss, l, vcross); expand_conflict_region(start_f, t, l, vcross);
#else #else
expand_conflict_region(start_f, t, ss, l, fm, sign_map, vcross); expand_conflict_region(start_f, t, l, fm, sign_map, vcross);
#endif #endif
CGAL_assertion( !vcross.first ); CGAL_assertion( !vcross.first );
@ -846,9 +846,9 @@ insert_segment_interior(const Site_2& t, const Storage_site_2& ss,
// REGION AND EXPANDS THE CONFLICT REGION. // REGION AND EXPANDS THE CONFLICT REGION.
initialize_conflict_region(start_f, l); initialize_conflict_region(start_f, l);
#ifdef CGAL_SDG_NO_FACE_MAP #ifdef CGAL_SDG_NO_FACE_MAP
expand_conflict_region(start_f, t, ss, l, vcross); expand_conflict_region(start_f, t, l, vcross);
#else #else
expand_conflict_region(start_f, t, ss, l, fm, sign_map, vcross); expand_conflict_region(start_f, t, l, fm, sign_map, vcross);
#endif #endif
CGAL_assertion( vcross.third == AT2::DISJOINT || CGAL_assertion( vcross.third == AT2::DISJOINT ||
@ -958,152 +958,190 @@ initialize_conflict_region(const Face_handle& f, List& l)
template<class Gt, class ST, class D_S, class LTag> template<class Gt, class ST, class D_S, class LTag>
void bool
Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
expand_conflict_region(const Face_handle& f, const Site_2& t, check_unregistered_face(const Face_handle& n,
const Storage_site_2& ss, const Site_2& t,
#ifdef CGAL_SDG_NO_FACE_MAP List& l,
List& l, #ifndef CGAL_SDG_NO_FACE_MAP
#else Face_map& fm,
List& l, Face_map& fm,
std::map<Face_handle,Sign>& sign_map,
#endif #endif
Triple<bool,Vertex_handle,Arrangement_type>& vcross) Triple<bool, Vertex_handle, Arrangement_type>& vcross)
{ {
for (int j = 0; j < 3; ++j)
{
Vertex_handle vf = n->vertex(j);
if ( is_infinite(vf) )
continue;
Arrangement_type at_res = arrangement_type(t, vf);
CGAL_assertion( vcross.third == AT2::DISJOINT ||
vcross.third == AT2::CROSSING ||
vcross.third == AT2::INTERIOR );
if ( vf->is_segment() )
{
CGAL_assertion( at_res != AT2::IDENTICAL );
CGAL_assertion( at_res != AT2::TOUCH_11_INTERIOR_1 );
CGAL_assertion( at_res != AT2::TOUCH_12_INTERIOR_1 );
if ( at_res == AT2::CROSSING )
{
vcross.first = true;
vcross.second = vf;
vcross.third = AT2::CROSSING;
l.clear();
#ifdef CGAL_SDG_NO_FACE_MAP #ifdef CGAL_SDG_NO_FACE_MAP
if ( f->tds_data().is_in_conflict() ) { return; } fhc_.clear();
#else #else
if ( fm.find(f) != fm.end() ) { return; } fm.clear();
#endif #endif
return true;
// this is done to stop the recursion when intersecting segments }
// are found else // at_res != AT2::CROSSING
if ( vcross.first ) { return; } {
CGAL_assertion ( at_res == AT2::DISJOINT ||
// setting fm[f] to true means that the face has been reached and at_res == AT2::TOUCH_1 ||
// that the face is available for recycling. If we do not want the at_res == AT2::TOUCH_2 ||
// face to be available for recycling we must set this flag to at_res == AT2::TOUCH_11 ||
// false. at_res == AT2::TOUCH_12 ||
#ifdef CGAL_SDG_NO_FACE_MAP at_res == AT2::TOUCH_21 ||
f->tds_data().mark_in_conflict(); at_res == AT2::TOUCH_22 );
fhc_.push_back(f); // we do nothing in these cases
#else
fm[f] = true;
#endif
// CGAL_assertion( fm.find(f) != fm.end() );
for (int i = 0; i < 3; i++) {
Face_handle n = f->neighbor(i);
#ifdef CGAL_SDG_NO_FACE_MAP
bool face_registered = n->tds_data().is_in_conflict();
#else
bool face_registered = (fm.find(n) != fm.end());
#endif
if ( !face_registered ) {
for (int j = 0; j < 3; j++) {
Vertex_handle vf = n->vertex(j);
if ( is_infinite(vf) ) { continue; }
Arrangement_type at_res = arrangement_type(t, vf);
CGAL_assertion( vcross.third == AT2::DISJOINT ||
vcross.third == AT2::CROSSING ||
vcross.third == AT2::INTERIOR );
if ( vf->is_segment() ) {
CGAL_assertion( at_res != AT2::IDENTICAL );
CGAL_assertion( at_res != AT2::TOUCH_11_INTERIOR_1 );
CGAL_assertion( at_res != AT2::TOUCH_12_INTERIOR_1 );
if ( at_res == AT2::CROSSING ) {
vcross.first = true;
vcross.second = vf;
vcross.third = AT2::CROSSING;
l.clear();
#ifdef CGAL_SDG_NO_FACE_MAP
fhc_.clear();
#else
fm.clear();
#endif
return;
} else {
CGAL_assertion ( at_res == AT2::DISJOINT ||
at_res == AT2::TOUCH_1 ||
at_res == AT2::TOUCH_2 ||
at_res == AT2::TOUCH_11 ||
at_res == AT2::TOUCH_12 ||
at_res == AT2::TOUCH_21 ||
at_res == AT2::TOUCH_22 );
// we do nothing in these cases
}
} else {
CGAL_assertion( vf->is_point() );
if ( at_res == AT2::INTERIOR ) {
vcross.first = true;
vcross.second = vf;
vcross.third = AT2::INTERIOR;
l.clear();
#ifdef CGAL_SDG_NO_FACE_MAP
fhc_.clear();
#else
fm.clear();
#endif
return;
}
}
} }
} }
else // ! vf->is_segment()
{
CGAL_assertion( vf->is_point() );
if ( at_res == AT2::INTERIOR )
{
vcross.first = true;
vcross.second = vf;
vcross.third = AT2::INTERIOR;
l.clear();
#ifdef CGAL_SDG_NO_FACE_MAP
fhc_.clear();
#else
fm.clear();
#endif
return true;
}
}
}
Sign s = incircle(n, t); return false;
}
template<class Gt, class ST, class D_S, class LTag>
void
Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
expand_conflict_region(const Face_handle& in_f,
const Site_2& t,
List& l,
#ifndef CGAL_SDG_NO_FACE_MAP
Face_map& fm,
std::map<Face_handle, Sign>& sign_map,
#endif
Triple<bool, Vertex_handle, Arrangement_type>& vcross)
{
std::stack<Face_handle> face_stack;
face_stack.push(in_f);
while(!face_stack.empty())
{
// Stop as soon as intersecting segments are found
if ( vcross.first )
break;
const Face_handle curr_f = face_stack.top();
face_stack.pop();
#ifdef CGAL_SDG_NO_FACE_MAP #ifdef CGAL_SDG_NO_FACE_MAP
n->tds_data().set_incircle_sign(s); if ( curr_f->tds_data().is_in_conflict() )
continue;
Sign s_f = f->tds_data().incircle_sign();
#else #else
sign_map[n] = s; if ( fm.find(curr_f) != fm.end() )
continue;
Sign s_f = sign_map[f];
#endif #endif
if ( s == POSITIVE ) { continue; } // setting fm[f] to true means that the face has been reached and
if ( s != s_f ) { continue; } // that the face is available for recycling. If we do not want the
// face to be available for recycling we must set this flag to false.
#ifdef CGAL_SDG_NO_FACE_MAP
curr_f->tds_data().mark_in_conflict();
fhc_.push_back(curr_f);
#else
fm[curr_f] = true;
#endif
bool interior_in_conflict = edge_interior(f, i, t, s); // CGAL_assertion( fm.find(curr_f) != fm.end() );
if ( !interior_in_conflict ) { continue; } for (int i = 0; i < 3; ++i)
{
if ( face_registered ) { continue; } Face_handle n = curr_f->neighbor(i);
Edge e = sym_edge(f, i);
CGAL_assertion( l.is_in_list(e) );
int j = this->_tds.mirror_index(f, i);
Edge e_before = sym_edge(n, ccw(j));
Edge e_after = sym_edge(n, cw(j));
if ( !l.is_in_list(e_before) ) {
l.insert_before(e, e_before);
}
if ( !l.is_in_list(e_after) ) {
l.insert_after(e, e_after);
}
l.remove(e);
#ifdef CGAL_SDG_NO_FACE_MAP #ifdef CGAL_SDG_NO_FACE_MAP
expand_conflict_region(n, t, ss, l, vcross); bool face_registered = n->tds_data().is_in_conflict();
#else #else
expand_conflict_region(n, t, ss, l, fm, sign_map, vcross); bool face_registered = (fm.find(n) != fm.end());
#endif #endif
// this is done to stop the recursion when intersecting segments if ( !face_registered )
// are found {
// if ( fm.size() == 0 && l.size() == 0 ) { return; } #ifdef CGAL_SDG_NO_FACE_MAP
if ( vcross.first ) { return; } if(check_unregistered_face(n, t, l, vcross))
} // for-loop #else
if(check_unregistered_face(n, t, l, fm, vcross))
#endif
{
CGAL_assertion(vcross.first);
break; // intersecting segments were found
}
}
Sign s = incircle(n, t);
#ifdef CGAL_SDG_NO_FACE_MAP
n->tds_data().set_incircle_sign(s);
Sign s_f = curr_f->tds_data().incircle_sign();
#else
sign_map[n] = s;
Sign s_f = sign_map[curr_f];
#endif
if ( s == POSITIVE )
continue;
if ( s != s_f )
continue;
if ( face_registered )
continue;
bool interior_in_conflict = edge_interior(curr_f, i, t, s);
if ( !interior_in_conflict )
continue;
Edge e = sym_edge(curr_f, i);
CGAL_assertion( l.is_in_list(e) );
int j = this->_tds.mirror_index(curr_f, i);
Edge e_before = sym_edge(n, ccw(j));
Edge e_after = sym_edge(n, cw(j));
if ( !l.is_in_list(e_before) )
l.insert_before(e, e_before);
if ( !l.is_in_list(e_after) )
l.insert_after(e, e_after);
l.remove(e);
face_stack.push(n);
} // neighbor for-loop
}
} }
@ -1563,56 +1601,72 @@ equalize_degrees(const Vertex_handle& v, Self& small_d,
template<class Gt, class ST, class D_S, class LTag> template<class Gt, class ST, class D_S, class LTag>
void void
Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
expand_conflict_region_remove(const Face_handle& f, const Site_2& t, expand_conflict_region_remove(const Face_handle& in_f,
const Storage_site_2& ss, const Site_2& t,
List& l, Face_map& fm, Sign_map& sign_map) List& l,
Face_map& fm,
Sign_map& sign_map)
{ {
if ( fm.find(f) != fm.end() ) { return; } std::stack<Face_handle> face_stack;
face_stack.push(in_f);
// setting fm[f] to true means that the face has been reached and while(!face_stack.empty())
// that the face is available for recycling. If we do not want the {
// face to be available for recycling we must set this flag to const Face_handle curr_f = face_stack.top();
// false. face_stack.pop();
fm[f] = true;
// CGAL_assertion( fm.find(f) != fm.end() ); if ( fm.find(curr_f) != fm.end() )
continue;
for (int i = 0; i < 3; i++) { // setting fm[curr_f] to true means that the face has been reached and
Face_handle n = f->neighbor(i); // that the face is available for recycling. If we do not want the
// face to be available for recycling we must set this flag to
// false.
fm[curr_f] = true;
bool face_registered = (fm.find(n) != fm.end()); // CGAL_assertion( fm.find(f) != fm.end() );
Sign s = incircle(n, t); for (int i = 0; i < 3; ++i)
{
Face_handle n = curr_f->neighbor(i);
sign_map[n] = s; bool face_registered = (fm.find(n) != fm.end());
Sign s_f = sign_map[f]; Sign s = incircle(n, t);
if ( s == POSITIVE ) { continue; } sign_map[n] = s;
if ( s != s_f ) { continue; }
bool interior_in_conflict = edge_interior(f, i, t, s); Sign s_f = sign_map[curr_f];
if ( !interior_in_conflict ) { continue; } if ( s == POSITIVE )
continue;
if ( s != s_f )
continue;
if ( face_registered )
continue;
if ( face_registered ) { continue; } bool interior_in_conflict = edge_interior(curr_f, i, t, s);
if ( !interior_in_conflict )
continue;
Edge e = sym_edge(f, i); Edge e = sym_edge(curr_f, i);
CGAL_assertion( l.is_in_list(e) );
CGAL_assertion( l.is_in_list(e) ); int j = this->_tds.mirror_index(curr_f, i);
int j = this->_tds.mirror_index(f, i); Edge e_before = sym_edge(n, ccw(j));
Edge e_before = sym_edge(n, ccw(j)); Edge e_after = sym_edge(n, cw(j));
Edge e_after = sym_edge(n, cw(j));
if ( !l.is_in_list(e_before) ) {
l.insert_before(e, e_before);
}
if ( !l.is_in_list(e_after) ) {
l.insert_after(e, e_after);
}
l.remove(e);
expand_conflict_region_remove(n, t, ss, l, fm, sign_map); if ( !l.is_in_list(e_before) )
} // for-loop l.insert_before(e, e_before);
if ( !l.is_in_list(e_after) )
l.insert_after(e, e_after);
l.remove(e);
face_stack.push(n);
} // neighbor for-loop
}
} }
@ -1690,7 +1744,7 @@ find_conflict_region_remove(const Vertex_handle& v,
} }
initialize_conflict_region(start_f, l); initialize_conflict_region(start_f, l);
expand_conflict_region_remove(start_f, t, ss, l, fm, sign_map); expand_conflict_region_remove(start_f, t, l, fm, sign_map);
} }

View File

@ -478,8 +478,7 @@ insert_segment_interior(const Site_2& t, const Storage_site_2& ss,
vcross(false, Vertex_handle(), AT2::DISJOINT); vcross(false, Vertex_handle(), AT2::DISJOINT);
hierarchy[0]->initialize_conflict_region(start_f, l); hierarchy[0]->initialize_conflict_region(start_f, l);
hierarchy[0]->expand_conflict_region(start_f, t, ss, l, fm, hierarchy[0]->expand_conflict_region(start_f, t, l, fm, sign_map, vcross);
sign_map, vcross);
CGAL_assertion( vcross.third == AT2::DISJOINT || CGAL_assertion( vcross.third == AT2::DISJOINT ||
vcross.third == AT2::CROSSING || vcross.third == AT2::CROSSING ||

View File

@ -520,8 +520,7 @@ insert_segment_interior(const Site_2& t, const Storage_site_2& ss,
vcross(false, Vertex_handle(), AT2::DISJOINT); vcross(false, Vertex_handle(), AT2::DISJOINT);
hierarchy[0]->initialize_conflict_region(start_f, l); hierarchy[0]->initialize_conflict_region(start_f, l);
hierarchy[0]->expand_conflict_region(start_f, t, ss, l, fm, hierarchy[0]->expand_conflict_region(start_f, t, l, fm, sign_map, vcross);
sign_map, vcross);
CGAL_assertion( vcross.third == AT2::DISJOINT || CGAL_assertion( vcross.third == AT2::DISJOINT ||
vcross.third == AT2::CROSSING || vcross.third == AT2::CROSSING ||

View File

@ -28,6 +28,11 @@
#include <CGAL/config.h> #include <CGAL/config.h>
#include <CGAL/array.h> #include <CGAL/array.h>
#include <algorithm>
#include <cstdlib>
#include <cmath>
namespace CGAL { namespace CGAL {