mirror of https://github.com/CGAL/cgal
Fix Convex_hull_3 so it becomes minimal.
This commit is contained in:
parent
156c9e7c47
commit
c945d27dc2
|
|
@ -98,6 +98,11 @@ unspecified_type Has_on_positive_side_3;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
*/
|
||||||
|
unspecified_type Has_on_negative_side_3;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
|
||||||
*/
|
*/
|
||||||
unspecified_type Less_signed_distance_to_plane_3;
|
unspecified_type Less_signed_distance_to_plane_3;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,13 @@ Predicate object type that provides
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Has_on_positive_side_3;
|
typedef unspecified_type Has_on_positive_side_3;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Predicate object type that provides
|
||||||
|
`bool operator()(Plane_3 h, Point_3 q)`, which determines if the point
|
||||||
|
`q` is on the negative side of the halfspace `h`.
|
||||||
|
*/
|
||||||
|
typedef unspecified_type Has_on_negative_side_3;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Predicate object type that provides
|
Predicate object type that provides
|
||||||
a constructor taking a single `Point_3` object and
|
a constructor taking a single `Point_3` object and
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,23 @@ public:
|
||||||
|
|
||||||
typedef bool result_type;
|
typedef bool result_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
class Point_triple_has_on_negative_side_3 {
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename K::Point_3 Point_3;
|
||||||
|
typedef Point_triple<K> Plane_3;
|
||||||
|
bool
|
||||||
|
operator()( const Plane_3& pl, const Point_3& p) const
|
||||||
|
{
|
||||||
|
typename K::Orientation_3 o;
|
||||||
|
return ( o(pl.p(), pl.q(), pl.r(), p) == CGAL::NEGATIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef bool result_type;
|
||||||
|
};
|
||||||
|
|
||||||
template <class K, class OldK>
|
template <class K, class OldK>
|
||||||
class Point_triple_construct_orthogonal_vector_3
|
class Point_triple_construct_orthogonal_vector_3
|
||||||
{
|
{
|
||||||
|
|
@ -167,6 +184,8 @@ struct GT3_for_CH3 {
|
||||||
template <class R_, class Has_filtered_predicates_tag /* = Tag_false */>
|
template <class R_, class Has_filtered_predicates_tag /* = Tag_false */>
|
||||||
struct Convex_hull_traits_base_3 {
|
struct Convex_hull_traits_base_3 {
|
||||||
typedef Point_triple_has_on_positive_side_3<R_> Has_on_positive_side_3;
|
typedef Point_triple_has_on_positive_side_3<R_> Has_on_positive_side_3;
|
||||||
|
typedef Point_triple_has_on_negative_side_3<R_> Has_on_negative_side_3;
|
||||||
|
|
||||||
|
|
||||||
typedef Point_triple_less_signed_distance_to_plane_3<R_>
|
typedef Point_triple_less_signed_distance_to_plane_3<R_>
|
||||||
Less_signed_distance_to_plane_3;
|
Less_signed_distance_to_plane_3;
|
||||||
|
|
@ -181,6 +200,13 @@ struct Convex_hull_traits_base_3<R_, Tag_true>{
|
||||||
Point_triple_converter<R_,typename R_::Approximate_kernel>
|
Point_triple_converter<R_,typename R_::Approximate_kernel>
|
||||||
> Has_on_positive_side_3;
|
> Has_on_positive_side_3;
|
||||||
|
|
||||||
|
typedef Filtered_predicate<
|
||||||
|
Point_triple_has_on_negative_side_3< typename R_::Exact_kernel_rt >,
|
||||||
|
Point_triple_has_on_negative_side_3< typename R_::Approximate_kernel >,
|
||||||
|
Point_triple_converter<R_,typename R_::Exact_kernel_rt>,
|
||||||
|
Point_triple_converter<R_,typename R_::Approximate_kernel>
|
||||||
|
> Has_on_negative_side_3;
|
||||||
|
|
||||||
typedef Filtered_predicate<
|
typedef Filtered_predicate<
|
||||||
Point_triple_less_signed_distance_to_plane_3< typename R_::Exact_kernel_rt >,
|
Point_triple_less_signed_distance_to_plane_3< typename R_::Exact_kernel_rt >,
|
||||||
Point_triple_less_signed_distance_to_plane_3< typename R_::Approximate_kernel >,
|
Point_triple_less_signed_distance_to_plane_3< typename R_::Approximate_kernel >,
|
||||||
|
|
@ -230,6 +256,8 @@ class Convex_hull_traits_3 :
|
||||||
|
|
||||||
typedef typename Convex_hull_traits_base_3<R_, Has_filtered_predicates_tag>
|
typedef typename Convex_hull_traits_base_3<R_, Has_filtered_predicates_tag>
|
||||||
::Has_on_positive_side_3 Has_on_positive_side_3;
|
::Has_on_positive_side_3 Has_on_positive_side_3;
|
||||||
|
typedef typename Convex_hull_traits_base_3<R_, Has_filtered_predicates_tag>
|
||||||
|
::Has_on_negative_side_3 Has_on_negative_side_3;
|
||||||
|
|
||||||
typedef typename Convex_hull_traits_base_3<R_, Has_filtered_predicates_tag>
|
typedef typename Convex_hull_traits_base_3<R_, Has_filtered_predicates_tag>
|
||||||
::Less_signed_distance_to_plane_3 Less_signed_distance_to_plane_3;
|
::Less_signed_distance_to_plane_3 Less_signed_distance_to_plane_3;
|
||||||
|
|
@ -290,6 +318,10 @@ class Convex_hull_traits_3 :
|
||||||
has_on_positive_side_3_object() const
|
has_on_positive_side_3_object() const
|
||||||
{ return Has_on_positive_side_3(); }
|
{ return Has_on_positive_side_3(); }
|
||||||
|
|
||||||
|
Has_on_negative_side_3
|
||||||
|
has_on_negative_side_3_object() const
|
||||||
|
{ return Has_on_negative_side_3(); }
|
||||||
|
|
||||||
Oriented_side_3
|
Oriented_side_3
|
||||||
oriented_side_3_object() const
|
oriented_side_3_object() const
|
||||||
{ return Oriented_side_3(); }
|
{ return Oriented_side_3(); }
|
||||||
|
|
|
||||||
|
|
@ -358,8 +358,8 @@ find_visible_set(TDS_2& tds,
|
||||||
typedef typename Traits::Plane_3 Plane_3;
|
typedef typename Traits::Plane_3 Plane_3;
|
||||||
typedef typename TDS_2::Face_handle Face_handle;
|
typedef typename TDS_2::Face_handle Face_handle;
|
||||||
typedef typename TDS_2::Vertex_handle Vertex_handle;
|
typedef typename TDS_2::Vertex_handle Vertex_handle;
|
||||||
typename Traits::Has_on_positive_side_3 has_on_positive_side =
|
typename Traits::Has_on_negative_side_3 has_on_negative_side =
|
||||||
traits.has_on_positive_side_3_object();
|
traits.has_on_negative_side_3_object();
|
||||||
|
|
||||||
std::vector<Vertex_handle> vertices;
|
std::vector<Vertex_handle> vertices;
|
||||||
vertices.reserve(10);
|
vertices.reserve(10);
|
||||||
|
|
@ -387,7 +387,7 @@ find_visible_set(TDS_2& tds,
|
||||||
f->info() = VISITED;
|
f->info() = VISITED;
|
||||||
Plane_3 plane(f->vertex(0)->point(),f->vertex(1)->point(),f->vertex(2)->point());
|
Plane_3 plane(f->vertex(0)->point(),f->vertex(1)->point(),f->vertex(2)->point());
|
||||||
int ind = f->index(*vis_it);
|
int ind = f->index(*vis_it);
|
||||||
if ( has_on_positive_side(plane, point) ){ // is visible
|
if ( !has_on_negative_side(plane, point) ){ // is visible
|
||||||
visible.push_back(f);
|
visible.push_back(f);
|
||||||
Vertex_handle vh = f->vertex(ind);
|
Vertex_handle vh = f->vertex(ind);
|
||||||
if(vh->info() == 0){ vertices.push_back(vh); vh->info() = VISITED;}
|
if(vh->info() == 0){ vertices.push_back(vh); vh->info() = VISITED;}
|
||||||
|
|
@ -717,6 +717,56 @@ ch_quickhull_polyhedron_3(std::list<typename Traits::Point_3>& points,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class P3_iterator,
|
||||||
|
class Point_3_list>
|
||||||
|
void init_iterators(P3_iterator& minx,
|
||||||
|
P3_iterator& maxx,
|
||||||
|
P3_iterator& miny,
|
||||||
|
const P3_iterator& start,
|
||||||
|
const Point_3_list& points)
|
||||||
|
{
|
||||||
|
P3_iterator it = start;
|
||||||
|
for(; it != points.end(); ++it){
|
||||||
|
if(it->x() < minx->x()) minx = it;
|
||||||
|
else if(it->x() == minx->x())
|
||||||
|
{
|
||||||
|
if(it->y() < minx->y()) minx = it;
|
||||||
|
else if(it->y() == minx->y())
|
||||||
|
{
|
||||||
|
if(it->z() < minx->z()) minx = it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it = start;
|
||||||
|
for(; it != points.end(); ++it){
|
||||||
|
if(it == minx )
|
||||||
|
continue;
|
||||||
|
if(it->x() > maxx->x()) maxx = it;
|
||||||
|
else if(it->x() == maxx->x())
|
||||||
|
{
|
||||||
|
if(it->y() > maxx->y()) maxx = it;
|
||||||
|
else if(it->y() == maxx->y())
|
||||||
|
{
|
||||||
|
if(it->z() > maxx->z()) maxx = it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it = start;
|
||||||
|
for(; it != points.end(); ++it){
|
||||||
|
if(it == minx || it == maxx)
|
||||||
|
continue;
|
||||||
|
if(it->y() < miny->y()) miny = it;
|
||||||
|
else if(it->y() == miny->y())
|
||||||
|
{
|
||||||
|
if(it->x() > miny->x()) miny = it;
|
||||||
|
else if(it->x() == miny->x())
|
||||||
|
{
|
||||||
|
if(it->z() < miny->z()) miny = it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} } //namespace internal::Convex_hull_3
|
} } //namespace internal::Convex_hull_3
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -810,13 +860,7 @@ convex_hull_3(InputIterator first, InputIterator beyond,
|
||||||
Polyhedron P;
|
Polyhedron P;
|
||||||
|
|
||||||
P3_iterator minx, maxx, miny, it;
|
P3_iterator minx, maxx, miny, it;
|
||||||
minx = maxx = miny = it = points.begin();
|
internal::Convex_hull_3::init_iterators(minx, maxx, miny, it, points);
|
||||||
++it;
|
|
||||||
for(; it != points.end(); ++it){
|
|
||||||
if(it->x() < minx->x()) minx = it;
|
|
||||||
if(it->x() > maxx->x()) maxx = it;
|
|
||||||
if(it->y() < miny->y()) miny = it;
|
|
||||||
}
|
|
||||||
if(! collinear(*minx, *maxx, *miny) ){
|
if(! collinear(*minx, *maxx, *miny) ){
|
||||||
internal::Convex_hull_3::ch_quickhull_polyhedron_3(points, minx, maxx, miny, P, traits);
|
internal::Convex_hull_3::ch_quickhull_polyhedron_3(points, minx, maxx, miny, P, traits);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -893,8 +937,20 @@ void convex_hull_3(InputIterator first, InputIterator beyond,
|
||||||
|
|
||||||
clear(polyhedron);
|
clear(polyhedron);
|
||||||
// result will be a polyhedron
|
// result will be a polyhedron
|
||||||
internal::Convex_hull_3::ch_quickhull_polyhedron_3(points, point1_it, point2_it, point3_it,
|
P3_iterator minx, maxx, miny, it;
|
||||||
polyhedron, traits);
|
minx = maxx = miny = it = points.begin();
|
||||||
|
++it;
|
||||||
|
|
||||||
|
|
||||||
|
//take extreme points to begin with.
|
||||||
|
internal::Convex_hull_::init_iterators(minx, maxx, miny, it, points);
|
||||||
|
if(! collinear(*minx, *maxx, *miny) ){
|
||||||
|
internal::Convex_hull_3::ch_quickhull_polyhedron_3(points, minx, maxx, miny,
|
||||||
|
polyhedron, traits);
|
||||||
|
} else {//to do : this case leads to bad init a risk of non minimal convex hull
|
||||||
|
internal::Convex_hull_3::ch_quickhull_polyhedron_3(points, point1_it, point2_it, point3_it,
|
||||||
|
polyhedron, traits);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
#include <CGAL/Polyhedron_3.h>
|
#include <CGAL/Polyhedron_3.h>
|
||||||
#include <CGAL/convex_hull_3.h>
|
#include <CGAL/convex_hull_3.h>
|
||||||
|
#include <CGAL/Side_of_triangle_mesh.h>
|
||||||
|
#include <CGAL/convexity_check_3.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
typedef CGAL::Epick K;
|
typedef CGAL::Epick K;
|
||||||
|
typedef CGAL::Epeck EK;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
|
@ -18,8 +22,20 @@ int main()
|
||||||
|
|
||||||
CGAL::Polyhedron_3<K> r;
|
CGAL::Polyhedron_3<K> r;
|
||||||
CGAL::convex_hull_3(pointset.begin(), pointset.end(), r);
|
CGAL::convex_hull_3(pointset.begin(), pointset.end(), r);
|
||||||
|
|
||||||
assert(r.size_of_vertices()==82);
|
assert(r.size_of_vertices()==82);
|
||||||
|
|
||||||
|
CGAL::Polyhedron_3<EK> s;
|
||||||
|
CGAL::copy_face_graph(r,s);
|
||||||
|
assert(CGAL::is_strongly_convex_3(s));
|
||||||
|
|
||||||
|
CGAL::Cartesian_converter<K, EK> to_EK;
|
||||||
|
CGAL::Side_of_triangle_mesh<CGAL::Polyhedron_3<EK>, EK> sotm(s);
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_FOREACH(K::Point_3 p, pointset)
|
||||||
|
{
|
||||||
|
assert(sotm(to_EK(p)) != CGAL::ON_UNBOUNDED_SIDE);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue