merge from the experimental_package branches/experimental-packages/Faster_static_convex_hull_3

This commit is contained in:
Sébastien Loriot 2011-06-16 14:19:49 +00:00
parent 471a073cc8
commit 56db074632
22 changed files with 1274 additions and 376 deletions

7
.gitattributes vendored
View File

@ -1417,9 +1417,16 @@ Convex_decomposition_3/test/Convex_decomposition_3/star.nef3 -text
Convex_hull_2/demo/Convex_hull_2/help/index.html svneol=native#text/html
Convex_hull_2/doc_tex/Convex_hull_2/convex_hull.png -text
Convex_hull_2/doc_tex/Convex_hull_2/saarhull.png -text svneol=unset#image/png
Convex_hull_3/benchmark/Convex_hull_3/compare_different_approach.cpp -text
Convex_hull_3/benchmark/Convex_hull_3/is_on_positive_side.cpp -text
Convex_hull_3/demo/Convex_hull_3/CMakeLists.txt -text
Convex_hull_3/doc_tex/Convex_hull_3/bunny.png -text
Convex_hull_3/doc_tex/Convex_hull_3/bunny.wrl.gz -text
Convex_hull_3/doc_tex/Convex_hull_3/chull_bimba.png -text
Convex_hull_3/doc_tex/Convex_hull_3_ref/convex_hull_3_to_polyhedron_3.tex -text
Convex_hull_3/examples/Convex_hull_3/incremental_hull_class_3.cpp -text
Convex_hull_3/include/CGAL/convex_hull_3_to_polyhedron_3.h -text
Convex_hull_3/test/Convex_hull_3/quick_hull_default_traits.cpp -text
Developers_manual/doc_tex/Developers_manual/fig/Cartesian_ipoint.gif -text svneol=unset#image/gif
Developers_manual/doc_tex/Developers_manual/fig/Cartesian_orientation.png -text svneol=unset#image/png
Developers_manual/doc_tex/Developers_manual/fig/Object.gif -text svneol=unset#image/gif

View File

@ -0,0 +1,95 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/algorithm.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/convex_hull_3.h>
#include <CGAL/convex_hull_3_to_polyhedron_3.h>
#include <CGAL/Delaunay_triangulation_3.h>
#include <CGAL/convex_hull_incremental_3.h>
#include <CGAL/Timer.h>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Exact_predicates_exact_constructions_kernel EK;
typedef CGAL::Polyhedron_3<K> Polyhedron_3;
typedef CGAL::Polyhedron_3<EK> EK_Polyhedron_3;
typedef K::Segment_3 Segment_3;
typedef CGAL::Delaunay_triangulation_3<K> Delaunay;
// define point creator
typedef K::Point_3 Point_3;
typedef CGAL::Creator_uniform_3<double, Point_3> PointCreator;
void load_from_file(const char* path,std::vector<Point_3>& points)
{
std::ifstream infile (path);
std::size_t nbpt;
infile >> nbpt;
points.reserve(nbpt);
Point_3 p;
while (--nbpt>0)
{
infile >> p;
points.push_back(p);
}
}
int main(int argc,char** argv)
{
std::vector<Point_3> points;
if (argc==1){
CGAL::Random_points_in_sphere_3<Point_3, PointCreator> gen(1.0);
int nbpt=1000000;
CGAL::copy_n( gen, nbpt, std::back_inserter(points) );
std::cout << "Using " << 1000000 << " random points in the unit ball\n";
}
else{
load_from_file(argv[1],points);
std::cout << "Using a model with " << points.size() << " points.\n";
}
Polyhedron_3 poly;
// compute convex hull
CGAL::Timer time;
time.start();
CGAL::convex_hull_3(points.begin(), points.end(), poly);
time.stop();
std::cout << "Static " << time.time() <<" "<< poly.size_of_vertices() << std::endl;
poly.clear();
time.reset();
time.start();
Delaunay T(points.begin(), points.end());
time.stop();
std::cout << "Delaunay " << time.time() << std::endl;
time.start();
CGAL::convex_hull_3_to_polyhedron_3(T,poly);
time.stop();
std::cout << "Delaunay+to_poly " << time.time() <<" "<< poly.size_of_vertices() << std::endl;
poly.clear();
time.reset();
time.start();
CGAL::convex_hull_incremental_3( points.begin(), points.end(), poly, false);
time.stop();
std::cout << "incremental EPIC " << time.time() <<" "<< poly.size_of_vertices() << std::endl;
EK_Polyhedron_3 poly2;
std::vector<EK::Point_3> ek_points;
ek_points.reserve(points.size());
CGAL::Cartesian_converter<K,EK> convert;
for (std::vector<K::Point_3>::iterator it=points.begin();it!=points.end();++it){
ek_points.push_back(convert(*it));
}
time.reset();
time.start();
CGAL::convex_hull_incremental_3( ek_points.begin(), ek_points.end(), poly2, false);
time.stop();
std::cout << "incremental EPEC " << time.time() <<" "<< poly2.size_of_vertices() << std::endl;
return 0;
}

View File

@ -0,0 +1,182 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Timer.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/random_selection.h>
#include <iostream>
namespace CGAL{
template <class Kernel,int alternatives>
struct Is_on_positive_side_of_plane_3;
template <class Kernel>
struct Is_on_positive_side_of_plane_3<Kernel,0>{
typedef typename Kernel::Point_3 Point_3;
Point_3 p,q,r;
typename Kernel::Orientation_3 orientation;
public:
Is_on_positive_side_of_plane_3(const Kernel& kernel,const Point_3& p_,const Point_3& q_,const Point_3& r_)
:p(p_),q(q_),r(r_),orientation(kernel.orientation_3_object()) {}
bool operator() (const Point_3& s) const
{
return orientation(p,q,r,s) == CGAL::POSITIVE;
}
};
template <class Kernel>
struct Is_on_positive_side_of_plane_3<Kernel,1>{
typedef typename Kernel::Point_3 Point_3;
double m10,m20,m21,Maxx,Maxy,Maxz;
const Point_3& p_;
int static_filtered(double psx,double psy, double psz) const{
using std::fabs;
// Then semi-static filter.
double maxx = Maxx;
if (maxx < fabs(psx)) maxx = fabs(psx);
double maxy = Maxy;
if (maxy < fabs(psy)) maxy = fabs(psy);
double maxz = Maxz;
if (maxz < fabs(psz)) maxz = fabs(psz);
double det = psx*m10 - m20*psy + m21*psz;
// Sort maxx < maxy < maxz.
if (maxx > maxz)
std::swap(maxx, maxz);
if (maxy > maxz)
std::swap(maxy, maxz);
else if (maxy < maxx)
std::swap(maxx, maxy);
// Protect against underflow in the computation of eps.
if (maxx < 1e-97) /* cbrt(min_double/eps) */ {
if (maxx == 0)
return 0;
}
// Protect against overflow in the computation of det.
else if (maxz < 1e102) /* cbrt(max_double [hadamard]/4) */ {
double eps = 5.1107127829973299e-15 * maxx * maxy * maxz;
if (det > eps) return 1;
if (det < -eps) return -1;
}
return 555;
}
public:
Is_on_positive_side_of_plane_3(const Kernel&,const Point_3& p,const Point_3& q,const Point_3& r):p_(p)
{
double pqx = q.x() - p.x();
double pqy = q.y() - p.y();
double pqz = q.z() - p.z();
double prx = r.x() - p.x();
double pry = r.y() - p.y();
double prz = r.z() - p.z();
m10 = pqy*prz - pry*pqz;
m20 = pqx*prz - prx*pqz;
m21 = pqx*pry - prx*pqy;
Maxx = fabs(pqx);
if (Maxx < fabs(prx)) Maxx = fabs(prx);
Maxy = fabs(pqy);
if (Maxy < fabs(pry)) Maxy = fabs(pry);
Maxz = fabs(pqz);
if (Maxz < fabs(prz)) Maxz = fabs(prz);
}
bool operator() (const Point_3& s) const
{
double psx = s.x() - p_.x();
double psy = s.y() - p_.y();
double psz = s.z() - p_.z();
int static_res = static_filtered(psx,psy,psz);
if (static_res != 555)
return static_res == 1;
std::cerr << "ERROR static predicate failure!!!\n";
exit(EXIT_FAILURE);
}
};
template <class Kernel>
struct Is_on_positive_side_of_plane_3<Kernel,2>{
typedef Simple_cartesian<Interval_nt_advanced > CK;
typedef typename Kernel::Point_3 Point_3;
Cartesian_converter<Kernel,CK> to_CK;
typename CK::Plane_3 ck_plane;
Is_on_positive_side_of_plane_3(const Kernel&,const Point_3& p,const Point_3& q,const Point_3& r):
ck_plane(to_CK(p),to_CK(q),to_CK(r))
{}
bool operator() (const Point_3& s) const
{
try{
return ck_plane.has_on_positive_side(to_CK(s));
}
catch (Uncertain_conversion_exception){
std::cerr << "ERROR Interval filtering failure\n";
exit(EXIT_FAILURE);
}
}
};
}//namespace CGAL
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Is_on_positive_side_of_plane_3<K,0> Pred_using_kernel;
typedef CGAL::Is_on_positive_side_of_plane_3<K,1> Pred_using_optimized_static;
typedef CGAL::Is_on_positive_side_of_plane_3<K,2> Pred_using_intervals;
template <class Predicate,class Outputiterator>
void run(const K::Point_3& p,const K::Point_3& q,const K::Point_3& r,const std::vector<K::Point_3>& queries,Outputiterator out){
CGAL::Timer time; time.start();
Predicate predicate(K(),p,q,r);
for (std::vector<K::Point_3>::const_iterator it=queries.begin();it!=queries.end();++it)
*out++=predicate(*it);
time.stop();
std::cout << time.time() << std::endl;
}
int main()
{
std::size_t nb_pts=20000000;
typedef CGAL::Creator_uniform_3<double,K::Point_3> Creator;
CGAL::Random_points_in_sphere_3<K::Point_3,Creator> gen(1);
std::vector<K::Point_3> points;
points.reserve(nb_pts);
K::Point_3 p=*gen++,q=*gen++,r=*gen++;
CGAL::copy_n(gen,nb_pts,std::back_inserter(points));
std::vector<bool> res0; res0.reserve(nb_pts);
std::vector<bool> res1; res1.reserve(nb_pts);
std::vector<bool> res2; res2.reserve(nb_pts);
std::cout << "Running kernel predicates: ";
run<Pred_using_kernel>(p,q,r,points,std::back_inserter(res0));
std::cout << "Running static optimized predicates: ";
run<Pred_using_optimized_static>(p,q,r,points,std::back_inserter(res1));
std::cout << "Running predicates with intervals: ";
run<Pred_using_intervals>(p,q,r,points,std::back_inserter(res2));
for (std::size_t k=0;k<nb_pts;++k)
if(res0[k]!=res1[k] || res1[k]!=res2[k]){
std::cerr << "ERROR results different\n";
exit(EXIT_FAILURE);
}
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

View File

@ -20,8 +20,11 @@ computing the hull.
The function \ccc{convex_hull_3} is parameterized by a traits class,
which specifies the types and geometric primitives to be used in the
computation. The default for this traits class is
\ccc{Convex_hull_traits_3}\ccIndexMainItem[C]{Convex_hull_traits_3}.
computation. If input points from a kernel with exact predicates
and non-exact constructions are used, and a certified result is expected,
the traits \ccc{Convex_hull_traits_3<R>} should be used
(\ccc{R} being the input kernel). Note that the default traits class takes this into
account.
\subsection{Convexity Checking}
@ -45,7 +48,7 @@ resulting hull is a segment or a polyhedron.
The function \ccc{convex_hull_incremental_3} %
\ccIndexMainItem[C]{convex_hull_incremental_3} provides an
interface similar to \ccc{convex_hull_3} for the $d$-dimensional
incremental construction algorithm \cite{cms-frric-93}.
incremental construction algorithm \cite{cms-frric-93}
implemented by the class \ccc{CGAL::Convex_hull_d<R>} that is specialized
to three dimensions. This function accepts an iterator range over a set of
input points and returns a polyhedron, but it does not have a traits class
@ -53,9 +56,13 @@ in its interface. It uses the kernel
class \ccc{Kernel} used in the polyhedron type to define an instance of the
adapter traits class \ccc{CGAL::Convex_hull_d_traits_3<Kernel>}.
In most cases, the function \ccc{convex_hull_3} will be faster than
\ccc{convex_hull_incremental_3}. The latter is provided mainly
for comparison purposes.
In almost all cases, the static and the dynamic version will
be faster than the incremental convex hull algorithm (mainly
because of the lack of efficient filtering and the overhead
of the general d-dimension). The incremental version is provided for
completeness and educational purposes. You should use the dynamic
version when you need an efficient incremental convex hull algorithm.
To use the full functionality available with the $d$-dimensional class
\ccc{CGAL::Convex_hull_d<R>} in three dimensions (\textit{e.g.}, the ability
@ -66,7 +73,7 @@ example.
\subsection{Example}
\ccIncludeExampleCode{Convex_hull_3/incremental_hull_3_demo.cpp}
\ccIncludeExampleCode{Convex_hull_3/incremental_hull_class_3.cpp}
\section{Dynamic Convex Hull Construction}
\ccIndexSubitem{convex hull, 3D}{dynamic}
@ -87,4 +94,33 @@ not all of them are vertices of the hull.
\subsection{Example}
\ccIncludeExampleCode{Convex_hull_3/dynamic_hull_3.cpp}
\section{Performance}
\begin{figure}
\begin{ccTexOnly}
\begin{center}
\includegraphics[width=12cm]{Convex_hull_3/chull_bimba.png}
\end{center}
\end{ccTexOnly}
\begin{ccHtmlOnly}
<CENTER>
<img border=0 src="./chull_bimba.png" alt="the convex hull of the bimba model">
</CENTER>
\end{ccHtmlOnly}
\caption{The convex hull of a model made of 192135 points.
\label{fig-ch-bimba}}
\end{figure}
In the following, we compare the running times of the three approaches to compute 3D convex hulls.
For the static version (using \ccc{CGAL::convex_hull_3}) and the dynamic version
(using \ccc{CGAL::Delaunay_triangulation_3} and \ccc{CGAL::convex_hull_3_to_polyhedron_3}), the kernel
used was \ccc{CGAL::Exact_predicates_inexact_constructions_kernel}. For the incremental version
(using \ccc{CGAL::convex_hull_incremental_3}), the kernel used was \ccc{CGAL::Exact_predicates_exact_constructions_kernel}.
To compute the convex hull of a million of random points in a unit ball the static approach needed 1.63s, while
the dynamic and incremental approaches needed 9.50s and 11.54s respectively.
To compute the convex hull of the model of Figure \ref{fig-ch-bimba} featuring 192135 points,
the static approach needed 0.18s, while the dynamic and incremental approaches needed 1.90s and 6.80s respectively.
The measurements have been performed using \cgal\ 3.9, using the \gnu\ \CC\ compiler version 4.3.5, under Linux (Debian distribution),
with the compilation options \texttt{-O3 -DCGAL\_NDEBUG}. The computer used was equipped with a 64bit Intel Xeon 2.27GHz processor and 12GB of RAM.

View File

@ -63,26 +63,26 @@ provides \ccc{bool operator()(Plane_3 p, Point_3 q, Point_3 r)}, which
returns true iff the signed distance from \ccc{q} to \ccc{p} is smaller
than the signed distance from \ccc{r} to \ccc{p}}
To handle the degenerate case when all points are coplanar, the following
three types that are default-constructable are necessary:
%To handle the degenerate case when all points are coplanar, the following
%three types that are default-constructable are necessary:
%
%\ccNestedType{Traits_xy}{A model of \ccc{ConvexHullTraits_2} for points projected
% into the $xy$-plane}
%\ccNestedType{Traits_xz}{A model of \ccc{ConvexHullTraits_2} for points projected
% into the $xz$-plane}
%\ccNestedType{Traits_yz}{A model of \ccc{ConvexHullTraits_2} for points projected
% into the $yz$-plane}
\ccNestedType{Traits_xy}{A model of \ccc{ConvexHullTraits_2} for points projected
into the $xy$-plane}
\ccNestedType{Traits_xz}{A model of \ccc{ConvexHullTraits_2} for points projected
into the $xz$-plane}
\ccNestedType{Traits_yz}{A model of \ccc{ConvexHullTraits_2} for points projected
into the $yz$-plane}
%One also needs the following function object to help choose which of the above
%traits classes to use:
%
%\ccNestedType{Max_coordinate_3}{Function object type that provides
%\ccc{int operator()(Vector_3 v)}, which returns the index (0, 1, or 2 for
%$x$, $y$, or $z$, respectively) of the coordinate of $v$ with maximum absolute
%value.}
One also needs the following function object to help choose which of the above
traits classes to use:
\ccNestedType{Max_coordinate_3}{Function object type that provides
\ccc{int operator()(Vector_3 v)}, which returns the index (0, 1, or 2 for
$x$, $y$, or $z$, respectively) of the coordinate of $v$ with maximum absolute
value.}
These types need not be provided when it is known that the points are
not all coplanar.
%These types need not be provided when it is known that the points are
%not all coplanar.
\ccCreation
\ccCreationVariable{traits}
@ -103,7 +103,8 @@ predicate object type. For example:
\ccAutoIndexingOn
\ccHasModels
\ccRefIdfierPage{CGAL::Convex_hull_traits_3<R>}
\ccRefIdfierPage{CGAL::Convex_hull_traits_3<R>}\\
All kernels of CGAL
%\ccSeeAlso

View File

@ -16,7 +16,8 @@
The class \ccRefName\ serves as a traits class for the function
\ccc{convex_hull_3}. This is the default traits class for this
function.
function when \ccc{R} is a kernel with exact predicates but inexact constructions
(note below that the type \ccc{Plane_3} is a triple of \ccc{Point_3} and not \ccc{R::Plane_3}).
\ccInclude{CGAL/Convex_hull_traits_3.h}
@ -101,7 +102,7 @@ function.
\ccCreation
\ccCreationVariable{traits} %% choose variable name
\ccConstructor{Convex_hull_traits_3(Convex_hull_traits_2& t);}%
\ccConstructor{Convex_hull_traits_3(Convex_hull_traits_3& t);}%
{copy constructor.}
\ccOperations

View File

@ -62,6 +62,7 @@ predicate object type. For example:
\ccHasModels
\ccRefIdfierPage{CGAL::Convex_hull_traits_3<R>} \\
All kernels of CGAL
%\ccc{CGAL::Kernel_traits_3}
\ccSeeAlso

View File

@ -47,9 +47,10 @@ Both functions require the following:
\begin{enumerate}
\item \ccc{InputIterator::value_type} is equivalent to \ccc{Traits::Point_3}.
\item \ccc{Traits} is a model of the concept \ccc{ConvexHullTraits_3}
\ccIndexMainItem[c]{ConvexHullTraits_3}. When it is known that
the input points are not all coplanar, the types \ccc{Traits_xy},
\ccc{Traits_yx}, and \ccc{Traits_yz} need not be provided.
\ccIndexMainItem[c]{ConvexHullTraits_3}.
%When it is known that
%the input points are not all coplanar, the types \ccc{Traits_xy},
%\ccc{Traits_yx}, and \ccc{Traits_yz} need not be provided.
For the purposes of checking the postcondition that the convex hull
is valid, \ccc{Traits} should also be a model of the concept
\ccc{IsStronglyConvexTraits_3}.
@ -67,9 +68,11 @@ and for the second, it is required that
\ccc{ConvexHullPolyhedron_3}.
\end{itemize}
The default traits class for both versions of \ccc{convex_hull_3} is
\ccc{Convex_hull_traits_3<R>},%
with the representation \ccc{R} determined by \ccc{InputIterator::value_type}.
For both versions, if the kernel \ccc{R} of the points determined by \ccc{InputIterator::value_type}
is a kernel with exact predicates but inexact constructions
(in practice we check \ccc{R::Has_filtered_predicates_tag} is \ccc{Tag_true} and \ccc{R::FT} is a floating point type),
then the default traits class of \ccc{convex_hull_3} is \ccc{Convex_hull_traits_3<R>}, and \ccc{R} otherwise.
\ccSeeAlso

View File

@ -0,0 +1,34 @@
\begin{ccRefFunction}{convex_hull_3_to_polyhedron_3}
\ccDefinition
The function \ccRefName\ fills a polyhedron with the convex hull
of a set of 3D points contained into a 3D triangulation of \cgal.
\ccInclude{CGAL/convex_hull_3_to_polyhedron_3.h}
\ccFunction{
template <class Triangulation_3, class Polyhedron_3>
void convex_hull_3_to_polyhedron_3(const Triangulation_3& T,Polyhedron_3& P);
}
{
The polyhedron \ccc{P} is cleared and the convex hull of the set of 3D points is stored in \ccc{P}.
The plane equations of each face are not computed.
\ccPrecond{\ccc{T.dimension()}==3}.
}
\ccHeading{Requirements}
This function requires the following:
\begin{enumerate}
\item \ccc{Triangulation_3} is a CGAL 3D triangulation.
\item \ccc{Polyhedron_3} is an instantiation of \ccc{CGAL::Polyhedron_3<Traits>}.
\end{enumerate}
\ccSeeAlso
\ccRefIdfierPage{CGAL::convex_hull_3}
\end{ccRefFunction}

View File

@ -14,8 +14,12 @@
\ccDefinition
The function \ccRefName\ computes the convex hull polyhedron from a set
of given three-dimensional points.
of given three-dimensional points.
This function is provided for completeness and educational
purposes. When an efficient incremental implementation is needed,
using \ccc{CGAL::Delaunay_triangulation_3} together with
\ccc{CGAL::convex_hull_3_to_polyhedron_3} is highly recommended.
\ccInclude{CGAL/convex_hull_incremental_3.h}

View File

@ -58,7 +58,8 @@ defining \ccc{CGAL_CH_CHECK_EXPENSIVE}%
\ccHeading{Convex Hull Functions}
\ccRefIdfierPage{CGAL::convex_hull_3} \\
\ccRefIdfierPage{CGAL::convex_hull_incremental_3}
\ccRefIdfierPage{CGAL::convex_hull_incremental_3}\\
\ccRefIdfierPage{CGAL::convex_hull_3_to_polyhedron_3}
\ccHeading{Convexity Checking Function}

View File

@ -15,6 +15,7 @@
\input{Convex_hull_3_ref/ConvexHullPolyhedron_3.tex}
\input{Convex_hull_3_ref/ConvexHullTraits_3.tex}
\input{Convex_hull_3_ref/Convex_hull_traits_3.tex}
\input{Convex_hull_3_ref/convex_hull_3_to_polyhedron_3.tex}
\input{Convex_hull_3_ref/is_strongly_convex_3.tex}
\input{Convex_hull_3_ref/IsStronglyConvexTraits_3.tex}

View File

@ -1,14 +1,17 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/Delaunay_triangulation_3.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/convex_hull_3_to_polyhedron_3.h>
#include <CGAL/algorithm.h>
#include <list>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_3 Point_3;
typedef CGAL::Delaunay_triangulation_3<K> Delaunay;
typedef Delaunay::Vertex_handle Vertex_handle;
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_3 Point_3;
typedef CGAL::Delaunay_triangulation_3<K> Delaunay;
typedef Delaunay::Vertex_handle Vertex_handle;
typedef CGAL::Polyhedron_3<K> Polyhedron_3;
int main()
{
@ -34,9 +37,15 @@ int main()
v_set_it++;
}
vertices.clear();
T.incident_vertices(T.infinite_vertex(), std::back_inserter(vertices));
//copy the convex hull of points into a polyhedron and use it
//to get the number of points on the convex hull
Polyhedron_3 chull;
CGAL::convex_hull_3_to_polyhedron_3(T,chull);
std::cout << "After removal of 25 points, there are "
<< vertices.size() << " points on the convex hull." << std::endl;
<< chull.size_of_vertices() << " points on the convex hull." << std::endl;
return 0;
}

View File

@ -0,0 +1,68 @@
// Copyright (c) 2002-2011 Max Planck Institut fuer Informatik (Germany).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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: svn+ssh://sloriot@scm.gforge.inria.fr/svn/cgal/branches/experimental-packages/Faster_static_convex_hull_3/demo/Convex_hull_3/incremental_hull_3_demo.cpp $
// $Id: incremental_hull_3_demo.cpp 44910 2008-08-12 12:58:18Z spion $
//
//
// Author(s) : Susan Hert
//
#include <CGAL/Homogeneous.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/Convex_hull_d.h>
#include <CGAL/Convex_hull_d_traits_3.h>
#include <CGAL/Convex_hull_d_to_polyhedron_3.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/algorithm.h>
#include <vector>
#include <cassert>
#ifdef CGAL_USE_GMP
#include <CGAL/Gmpz.h>
typedef CGAL::Gmpz RT;
#else
#include <CGAL/MP_Float.h>
typedef CGAL::MP_Float RT;
#endif
typedef CGAL::Homogeneous<RT> K;
typedef K::Point_3 Point_3;
typedef CGAL::Polyhedron_3< K> Polyhedron_3;
typedef CGAL::Convex_hull_d_traits_3<K> Hull_traits_3;
typedef CGAL::Convex_hull_d< Hull_traits_3 > Convex_hull_3;
typedef CGAL::Creator_uniform_3<double, Point_3> Creator;
int main ()
{
Convex_hull_3 CH(3); // create instance of the class with dimension == 3
// generate 250 points randomly on a sphere of radius 100
// and insert them into the convex hull
CGAL::Random_points_in_sphere_3<Point_3, Creator> gen(100);
for (int i = 0; i < 250 ; i++, ++gen)
CH.insert(*gen);
assert(CH.is_valid());
// define polyhedron to hold convex hull and create it
Polyhedron_3 P;
CGAL::convex_hull_d_to_polyhedron_3(CH,P);
std::cout << "The convex hull has " << P.size_of_vertices()
<< " vertices" << std::endl;
return 0;
}

View File

@ -1,14 +1,13 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/algorithm.h>
#include <CGAL/Convex_hull_traits_3.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/convex_hull_3.h>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Convex_hull_traits_3<K> Traits;
typedef Traits::Polyhedron_3 Polyhedron_3;
typedef CGAL::Polyhedron_3<K> Polyhedron_3;
typedef K::Segment_3 Segment_3;
// define point creator
@ -32,10 +31,12 @@ int main()
CGAL::convex_hull_3(points.begin(), points.end(), ch_object);
// determine what kind of object it is
if (CGAL::object_cast<Segment_3>(&ch_object) )
std::cout << "convex hull is a segment " << std::endl;
else if (CGAL::object_cast<Polyhedron_3>(&ch_object) )
std::cout << "convex hull is a polyhedron " << std::endl;
if ( const Segment_3* segment=CGAL::object_cast<Segment_3>(&ch_object) ){
std::cout << "convex hull is the segment " << *segment << std::endl;
}
else if (const Polyhedron_3* poly = CGAL::object_cast<Polyhedron_3>(&ch_object) )
std::cout << "convex hull is a polyhedron with "
<< poly->size_of_vertices() << " vertices" << std::endl;
else
std::cout << "convex hull error!" << std::endl;

View File

@ -0,0 +1,70 @@
// Copyright (c) 2003 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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$
//
//
// Author(s) : Mariette Yvinec,Sylvain Pion
// face of a triangulation of any dimension <=3
#ifndef CGAL_CONVEX_HULL_FACE_BASE_2_H
#define CGAL_CONVEX_HULL_FACE_BASE_2_H
#include <CGAL/Triangulation_face_base_2.h>
namespace CGAL {
template < typename Info_, typename GT,
typename Fb = Triangulation_face_base_2<GT> >
class Convex_hull_face_base_2
: public Fb
{
Info_ _info;
public:
typedef typename Fb::Vertex_handle Vertex_handle;
typedef typename Fb::Face_handle Face_handle;
typedef Info_ Info;
typename std::list<Face_handle>::iterator it;
std::list<typename GT::Point_3> points;
template < typename TDS2 >
struct Rebind_TDS {
typedef typename Fb::template Rebind_TDS<TDS2>::Other Fb2;
typedef Convex_hull_face_base_2<Info, GT, Fb2> Other;
};
Convex_hull_face_base_2()
: Fb(), _info(0) {}
Convex_hull_face_base_2(Vertex_handle v0,
Vertex_handle v1,
Vertex_handle v2)
: Fb(v0, v1, v2), _info(0) {}
Convex_hull_face_base_2(Vertex_handle v0,
Vertex_handle v1,
Vertex_handle v2,
Face_handle n0,
Face_handle n1,
Face_handle n2 )
: Fb(v0, v1, v2, n0, n1, n2), _info(0) {}
const Info& info() const { return _info; }
Info& info() { return _info; }
};
} //namespace CGAL
#endif // CGAL_CONVEX_HULL_FACE_BASE_2_H

View File

@ -21,9 +21,11 @@
#define CGAL_CONVEX_HULL_TRAITS_3_H
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Convex_hull_face_base_2.h>
#include <CGAL/Projection_traits_xy_3.h>
#include <CGAL/Projection_traits_xz_3.h>
#include <CGAL/Projection_traits_yz_3.h>
#include <list>
namespace CGAL {
template < class R_ >
@ -34,7 +36,7 @@ protected:
typedef typename R_::Point_3 Point_3;
typedef typename R_::Vector_3 Vector_3;
Point_3 p_, q_, r_;
Point_3 p_, q_, r_;
public:
typedef R_ R;
@ -115,9 +117,15 @@ public:
const Point_3& hp = h.p();
const Point_3& hq = h.q();
const Point_3& hr = h.r();
typename OldK::Less_signed_distance_to_plane_3
less_signed_distance_to_plane_3;
return less_signed_distance_to_plane_3(hp, hq, hr, p, q);
//typename OldK::Less_signed_distance_to_plane_3
// less_signed_distance_to_plane_3;
// return less_signed_distance_to_plane_3(hp, hq, hr, p, q);
return has_smaller_signed_dist_to_planeC3(hp.x(), hp.y(), hp.z(),
hq.x(), hq.y(), hq.z(),
hr.x(), hr.y(), hr.z(),
p.x(), p.y(), p.z(),
q.x(), q.y(), q.z());
}
};
@ -143,6 +151,14 @@ public:
}
};
template <typename GT>
struct GT3 {
typedef typename GT::Point_3 Point_2;
};
template <class R_>
class Convex_hull_traits_3
{
@ -157,7 +173,6 @@ class Convex_hull_traits_3
typedef CGAL::Polyhedron_3<R> Polyhedron_3;
typedef typename R::Construct_segment_3 Construct_segment_3;
typedef typename R::Construct_ray_3 Construct_ray_3;
@ -186,9 +201,6 @@ class Convex_hull_traits_3
Less_signed_distance_to_plane_3;
// required for degenerate case of all points coplanar
typedef Projection_traits_xy_3<R> Traits_xy;
typedef Projection_traits_xz_3<R> Traits_xz;
typedef Projection_traits_yz_3<R> Traits_yz;
typedef CGAL::Max_coordinate_3<Vector_3> Max_coordinate_3;
// for postcondition checking

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,93 @@
// Copyright (c) 2011 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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$
//
//
// Author(s) : Sebastien Loriot
//
#include <CGAL/Polyhedron_incremental_builder_3.h>
#ifndef CGAL_CONVEX_HULL_3_TO_POLYHEDRON_3_H
#define CGAL_CONVEX_HULL_3_TO_POLYHEDRON_3_H
namespace CGAL {
template <class HDS,class Triangulation>
class Convex_hull_modifier_from_triangulation_3 : public CGAL::Modifier_base<HDS> {
typedef std::map<typename Triangulation::Vertex_handle,unsigned> Vertex_map;
const Triangulation& t;
template <class Builder>
static unsigned get_vertex_index( Vertex_map& vertex_map,
typename Triangulation::Vertex_handle vh,
Builder& builder,
unsigned& vindex)
{
std::pair<typename Vertex_map::iterator,bool>
res=vertex_map.insert(std::make_pair(vh,vindex));
if (res.second){
builder.add_vertex(vh->point());
++vindex;
}
return res.first->second;
}
public:
Convex_hull_modifier_from_triangulation_3(const Triangulation& t_):t(t_)
{
CGAL_assertion(t.dimension()==3);
}
void operator()( HDS& hds) {
// Postcondition: `hds' is a valid polyhedral surface.
typedef typename HDS::Vertex Vertex;
typedef typename Vertex::Point Point;
CGAL::Polyhedron_incremental_builder_3<HDS> B( hds, true);
std::vector<typename Triangulation::Cell_handle> ch_facets;
Vertex_map vertex_map;
t.incident_cells(t.infinite_vertex(),std::back_inserter(ch_facets));
std::size_t nb_facets=ch_facets.size();
//start the surface
B.begin_surface( nb_facets, nb_facets);
unsigned vindex=0;
for (typename std::vector<typename Triangulation::Cell_handle>::const_iterator it=
ch_facets.begin();it!=ch_facets.end();++it)
{
unsigned ifv_index= (*it)->index(t.infinite_vertex());
bool is_odd=ifv_index%2==0;
unsigned i0=get_vertex_index(vertex_map,(*it)->vertex((ifv_index + (is_odd?3:1) )%4),B,vindex);
unsigned i1=get_vertex_index(vertex_map,(*it)->vertex((ifv_index + 2 )%4),B,vindex);
unsigned i2=get_vertex_index(vertex_map,(*it)->vertex((ifv_index + (is_odd?1:3) )%4),B,vindex);
B.begin_facet();
B.add_vertex_to_facet( i0 );
B.add_vertex_to_facet( i1 );
B.add_vertex_to_facet( i2 );
B.end_facet();
}
B.end_surface();
}
};
template<class Triangulation_3,class Polyhedron_3>
void convex_hull_3_to_polyhedron_3(const Triangulation_3& T,Polyhedron_3& P){
P.clear();
Convex_hull_modifier_from_triangulation_3<typename Polyhedron_3::HalfedgeDS,Triangulation_3> modifier(T);
P.delegate(modifier);
}
} //namespace CGAL
#endif //CGAL_CONVEX_HULL_3_TO_POLYHEDRON_3_H

View File

@ -0,0 +1,39 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Convex_hull_traits_3.h>
#include <CGAL/convex_hull_3.h>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#ifdef CGAL_USE_LEDA
# include <CGAL/leda_rational.h>
typedef leda_rational Precise_rational;
#elif defined CGAL_USE_GMP
# include <CGAL/Gmpz.h>
# include <CGAL/Quotient.h>
typedef CGAL::Quotient<CGAL::Gmpz> Precise_rational;
#else
# include <CGAL/MP_Float.h>
# include <CGAL/Quotient.h>
typedef CGAL::Quotient<CGAL::MP_Float> Precise_rational;
#endif
typedef CGAL::Exact_predicates_exact_constructions_kernel EPEC;
typedef CGAL::Exact_predicates_inexact_constructions_kernel EPIC;
typedef CGAL::Simple_cartesian<double> SCD;
typedef CGAL::Simple_cartesian<Precise_rational> SCR;
using namespace CGAL::internal::Convex_hull_3;
int main()
{
BOOST_STATIC_ASSERT( (boost::is_same<EPEC,Default_traits_for_Chull_3<EPEC::Point_3>::type>::value) );
BOOST_STATIC_ASSERT( (boost::is_same<SCD,Default_traits_for_Chull_3<SCD::Point_3>::type>::value) );
BOOST_STATIC_ASSERT( (boost::is_same<SCR,Default_traits_for_Chull_3<SCR::Point_3>::type>::value) );
BOOST_STATIC_ASSERT( (boost::is_same<EPEC,Default_traits_for_Chull_3<EPEC::Point_3>::type>::value) );
BOOST_STATIC_ASSERT( (boost::is_same<CGAL::Convex_hull_traits_3<EPIC>,Default_traits_for_Chull_3<EPIC::Point_3>::type>::value) );
BOOST_STATIC_ASSERT( (boost::is_same<Is_on_positive_side_of_plane_3<CGAL::Convex_hull_traits_3<EPIC> >::Protector,CGAL::Protect_FPU_rounding<true> >::value) );
return 0;
}

View File

@ -33,6 +33,33 @@ typedef CGAL::Random_points_in_sphere_3<Point_3,Creator> Generator;
const unsigned int num = 40;
template <class Facet_handle>
void compute_plane_equation(Facet_handle f)
{
typedef typename Facet_handle::value_type Facet;
typedef typename Facet::Halfedge_handle Halfedge_handle;
typedef typename Facet::Plane_3 Plane_3;
Halfedge_handle h = (*f).halfedge();
(*f).plane() = Plane_3(h->opposite()->vertex()->point(),
h->vertex()->point(),
h->next()->vertex()->point());
}
template <class Plane, class Facet_handle>
void get_plane(Plane& plane, Facet_handle f)
{
typedef typename Facet_handle::value_type Facet;
typedef typename Facet::Halfedge_handle Halfedge_handle;
Halfedge_handle h = (*f).halfedge();
plane = Plane(h->opposite()->vertex()->point(),
h->vertex()->point(),
h->next()->vertex()->point());
}
void test_tetrahedron_convexity()
{
Polyhedron_3 P;
@ -45,7 +72,7 @@ void test_tetrahedron_convexity()
for( Polyhedron_3::Facet_iterator f = P.facets_begin();
f != P.facets_end(); ++f )
{
CGAL::compute_plane_equation(f);
compute_plane_equation(f);
}
assert( CGAL::is_strongly_convex_3(P) );
@ -62,7 +89,7 @@ void test_triangle_convexity()
for( Polyhedron_3::Facet_iterator f = P.facets_begin();
f != P.facets_end(); ++f )
{
CGAL::compute_plane_equation(f);
compute_plane_equation(f);
}
assert( CGAL::is_strongly_convex_3(P) );