mirror of https://github.com/CGAL/cgal
merge from the experimental_package branches/experimental-packages/Faster_static_convex_hull_3
This commit is contained in:
parent
471a073cc8
commit
56db074632
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 |
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
@ -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}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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) );
|
||||
|
|
|
|||
Loading…
Reference in New Issue