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;
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,13 @@ Predicate object type that provides
|
|||
*/
|
||||
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
|
||||
a constructor taking a single `Point_3` object and
|
||||
|
|
|
|||
|
|
@ -95,6 +95,23 @@ public:
|
|||
|
||||
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>
|
||||
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 */>
|
||||
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_negative_side_3<R_> Has_on_negative_side_3;
|
||||
|
||||
|
||||
typedef Point_triple_less_signed_distance_to_plane_3<R_>
|
||||
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>
|
||||
> 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<
|
||||
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 >,
|
||||
|
|
@ -230,6 +256,8 @@ class Convex_hull_traits_3 :
|
|||
|
||||
typedef typename Convex_hull_traits_base_3<R_, Has_filtered_predicates_tag>
|
||||
::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>
|
||||
::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
|
||||
{ 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_object() const
|
||||
{ return Oriented_side_3(); }
|
||||
|
|
|
|||
|
|
@ -358,8 +358,8 @@ find_visible_set(TDS_2& tds,
|
|||
typedef typename Traits::Plane_3 Plane_3;
|
||||
typedef typename TDS_2::Face_handle Face_handle;
|
||||
typedef typename TDS_2::Vertex_handle Vertex_handle;
|
||||
typename Traits::Has_on_positive_side_3 has_on_positive_side =
|
||||
traits.has_on_positive_side_3_object();
|
||||
typename Traits::Has_on_negative_side_3 has_on_negative_side =
|
||||
traits.has_on_negative_side_3_object();
|
||||
|
||||
std::vector<Vertex_handle> vertices;
|
||||
vertices.reserve(10);
|
||||
|
|
@ -387,7 +387,7 @@ find_visible_set(TDS_2& tds,
|
|||
f->info() = VISITED;
|
||||
Plane_3 plane(f->vertex(0)->point(),f->vertex(1)->point(),f->vertex(2)->point());
|
||||
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);
|
||||
Vertex_handle vh = f->vertex(ind);
|
||||
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
|
||||
|
||||
|
||||
|
|
@ -810,13 +860,7 @@ convex_hull_3(InputIterator first, InputIterator beyond,
|
|||
Polyhedron P;
|
||||
|
||||
P3_iterator minx, maxx, miny, it;
|
||||
minx = maxx = miny = it = points.begin();
|
||||
++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;
|
||||
}
|
||||
internal::Convex_hull_3::init_iterators(minx, maxx, miny, it, points);
|
||||
if(! collinear(*minx, *maxx, *miny) ){
|
||||
internal::Convex_hull_3::ch_quickhull_polyhedron_3(points, minx, maxx, miny, P, traits);
|
||||
} else {
|
||||
|
|
@ -893,8 +937,20 @@ void convex_hull_3(InputIterator first, InputIterator beyond,
|
|||
|
||||
clear(polyhedron);
|
||||
// result will be a polyhedron
|
||||
P3_iterator minx, maxx, miny, it;
|
||||
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_exact_constructions_kernel.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/convex_hull_3.h>
|
||||
#include <CGAL/Side_of_triangle_mesh.h>
|
||||
#include <CGAL/convexity_check_3.h>
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
|
||||
typedef CGAL::Epick K;
|
||||
typedef CGAL::Epeck EK;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
|
@ -18,8 +22,20 @@ int main()
|
|||
|
||||
CGAL::Polyhedron_3<K> r;
|
||||
CGAL::convex_hull_3(pointset.begin(), pointset.end(), r);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue