1 // Copyright (c) 1997-2000  Max-Planck-Institute Saarbruecken (Germany).
2 // All rights reserved.
3 //
4 // This file is part of CGAL (www.cgal.org).
5 //
6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Convex_hull_d/include/CGAL/Convex_hull_d.h $
7 // $Id: Convex_hull_d.h 0d66e19 2020-07-24T17:05:10+02:00 Mael Rouxel-Labbé
8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
9 //
10 //
11 // Author(s)     : Michael Seel <seel@mpi-sb.mpg.de>
12 //---------------------------------------------------------------------
13 // file generated by notangle from Convex_hull_d.lw
14 // please debug or modify web file
15 // mails and bugs: Michael.Seel@mpi-sb.mpg.de
16 // based on LEDA architecture by S. Naeher, C. Uhrig
17 // coding: K. Mehlhorn, M. Seel
18 // debugging and templatization: M. Seel
19 //---------------------------------------------------------------------
20 
21 #ifndef CGAL_CONVEX_HULL_D_H
22 #define CGAL_CONVEX_HULL_D_H
23 
24 #include <CGAL/license/Convex_hull_d.h>
25 
26 #define CGAL_DEPRECATED_HEADER "<CGAL/Convex_hull_d.h>"
27 #define CGAL_DEPRECATED_MESSAGE_DETAILS \
28   "The Triangulation package (see https://doc.cgal.org/latest/Triangulation) should be used instead."
29 #include <CGAL/internal/deprecation_warning.h>
30 
31 /*{\Manpage {Convex_hull_d}{R}{Convex Hulls}{C}}*/
32 
33 /*{\Mdefinition An instance |\Mvar| of type |\Mname| is the convex
34 hull of a multi-set |S| of points in $d$-dimensional space. We call
35 |S| the underlying point set and $d$ or |dim| the dimension of the
36 underlying space. We use |dcur| to denote the affine dimension of |S|.
37 The data type supports incremental construction of hulls.
38 
39 The closure of the hull is maintained as a simplicial complex, i.e.,
40 as a collection of simplices. The intersection of any two is a face of
41 both\cgalFootnote{The empty set if a facet of every simplex.}. In the
42 sequel we reserve the word simplex for the simplices of dimension
43 |dcur|. For each simplex there is a handle of type |Simplex_handlex|
44 and for each vertex there is a handle of type |Vertex_handle|.  Each
45 simplex has $1 + |dcur|$ vertices indexed from $0$ to |dcur|; for a
46 simplex $s$ and an index $i$, |C.vertex(s,i)| returns the $i$-th
47 vertex of $s$. For any simplex $s$ and any index $i$ of $s$ there may
48 or may not be a simplex $t$ opposite to the $i$-th vertex of $s$.  The
49 function |C.opposite_simplex(s,i)| returns $t$ if it exists and
50 returns |Simplex_handle()| (the undefined handle) otherwise. If $t$
51 exists then $s$ and $t$ share |dcur| vertices, namely all but the
52 vertex with index $i$ of $s$ and the vertex with index
53 |C.index_of_vertex_in_opposite_simplex(s,i)| of $t$. Assume that $t$
54 exists and let |j = C.index_of_vertex_in_opposite_simplex(s,i)|.  Then
55 $s =$ |C.opposite_simplex(t,j)| and $i =$
56 |C.index_of_vertex_in_opposite_simplex(t,j)|.
57 
58 The boundary of the hull is also a simplicial complex. All simplices
59 in this complex have dimension $|dcur| - 1$.  For each boundary simplex
60 there is a handle of type |Facet_handle|.  Each facet has |dcur| vertices
61 indexed from $0$ to $|dcur| - 1$. If |dcur > 1| then for each facet $f$
62 and each index $i$, $0 \le i < |dcur|$, there is a facet $g$ opposite
63 to the $i$-th vertex of $f$.  The function |C.opposite_facet(f,i)|
64 returns $g$.  Two neighboring facets $f$ and $g$ share |dcur - 1|
65 vertices, namely all but the vertex with index $i$ of $f$ and the
66 vertex with index |C.index_of_vertex_in_opposite_facet(f,i)| of $g$.
67 Let |j = C.index_of_vertex_in_opposite_facet(f,i)|. Then
68 |f = C.opposite_facet(g,j)| and
69 |i = C.index_of_vertex_in_opposite_facet(g,j)|.}*/
70 
71 #include <CGAL/basic.h>
72 #include <CGAL/Origin.h>
73 #include <CGAL/Unique_hash_map.h>
74 #include <CGAL/Regular_complex_d.h>
75 #include <CGAL/Handle_for.h>
76 #include <list>
77 #include <vector>
78 
79 #include <CGAL/Kernel_d/debug.h>
80 
81 namespace CGAL {
82 
83 template <typename HP, typename H> class Facet_iterator_rep_;
84 template <typename HP, typename H> class Facet_iterator_;
85 
86 template <typename Hull_pointer, typename Handle>
87 class Facet_iterator_rep_
88 {
89   CGAL::Unique_hash_map<Handle,bool>* pvisited_;
90   std::list<Handle>* pcandidates_;
91   Hull_pointer hull_;
92   Handle current_;
93   friend class Facet_iterator_<Hull_pointer,Handle>;
94 
add_candidates()95   void add_candidates()
96   { CGAL_assertion(pvisited_ && pcandidates_ && hull_);
97     for(int i = 1; i <= hull_->current_dimension(); ++i) {
98       Handle f = hull_->opposite_simplex(current_,i);
99       if ( !(*pvisited_)[f] ) {
100         pcandidates_->push_front(f);
101         (*pvisited_)[f] = true;
102       }
103     }
104   }
105 public:
Facet_iterator_rep_()106   Facet_iterator_rep_() :
107     pvisited_(0), pcandidates_(0), hull_(0), current_() {}
Facet_iterator_rep_(Hull_pointer p,Handle h)108   Facet_iterator_rep_(Hull_pointer p, Handle h) :
109     pvisited_(0), pcandidates_(0), hull_(p), current_(h) {}
~Facet_iterator_rep_()110   ~Facet_iterator_rep_()
111   { if (pvisited_) delete pvisited_;
112     if (pcandidates_) delete pcandidates_; }
113 };
114 
115 template <typename Hull_pointer, typename Handle>
116 class Facet_iterator_ : private
117   Handle_for<Facet_iterator_rep_<Hull_pointer,Handle> >
118 { typedef Facet_iterator_<Hull_pointer,Handle> Self;
119   typedef Facet_iterator_rep_<Hull_pointer,Handle> Rep;
120   typedef Handle_for< Facet_iterator_rep_<Hull_pointer,Handle> > Base;
121 
122   using Base::ptr;
123 
124 public:
125   typedef typename Handle::value_type value_type;
126   typedef typename Handle::pointer    pointer;
127   typedef typename Handle::reference  reference;
128   typedef typename Handle::difference_type difference_type;
129   typedef std::forward_iterator_tag   iterator_category;
130 
Facet_iterator_()131   Facet_iterator_() : Base( Rep() ) {}
Facet_iterator_(Hull_pointer p,Handle h)132   Facet_iterator_(Hull_pointer p, Handle h) : Base( Rep(p,h) )
133   { ptr()->pvisited_ = new Unique_hash_map<Handle,bool>(false);
134     ptr()->pcandidates_ = new std::list<Handle>;
135     (*(ptr()->pvisited_))[ptr()->current_]=true;
136     ptr()->add_candidates();
137   }
138 
139   reference operator*() const
140   { return ptr()->current_.operator*(); }
141   pointer operator->() const
142   { return ptr()->current_.operator->(); }
143 
144   Self& operator++()
145   { if ( ptr()->current_ == Handle() ) return *this;
146     if ( ptr()->pcandidates_->empty() ) ptr()->current_ = Handle();
147     else {
148       ptr()->current_ = ptr()->pcandidates_->back();
149       ptr()->pcandidates_->pop_back();
150       ptr()->add_candidates();
151     }
152     return *this;
153   }
154   Self  operator++(int)
155   { Self tmp = *this; ++*this; return tmp; }
156   bool operator==(const Self& x) const
157   { return ptr()->current_ == x.ptr()->current_; }
158   bool operator!=(const Self& x) const
159   { return !operator==(x); }
160 
Handle()161   operator Handle() { return ptr()->current_; }
162 
163 };
164 
165 
166 template <typename HP, typename VH, typename FH>
167 class Hull_vertex_iterator_rep_;
168 template <typename HP, typename VH, typename FH>
169 class Hull_vertex_iterator_;
170 
171 template <typename Hull_pointer, typename VHandle, typename FHandle>
172 class Hull_vertex_iterator_rep_
173 {
174   CGAL::Unique_hash_map<VHandle,bool>* pvisited_;
175   Hull_pointer hull_;
176   VHandle v_; FHandle f_; int i_;
177   friend class Hull_vertex_iterator_<Hull_pointer,VHandle,FHandle>;
178 
advance()179   void advance()
180   { CGAL_assertion(pvisited_ &&  hull_);
181     if ( f_ == FHandle() ) return;
182     bool search_next = true; ++i_;
183     while ( search_next ) {
184       while(i_ < hull_->current_dimension()) {
185         v_ = hull_->vertex_of_facet(f_,i_);
186         if ( !(*pvisited_)[v_] ) { search_next=false; break; }
187         ++i_;
188       }
189       if ( search_next ) { i_=0; ++f_; }
190       if ( f_ == FHandle() )
191       { search_next=false; v_ = VHandle(); }
192     }
193     (*pvisited_)[v_] = true;
194   }
195 public:
Hull_vertex_iterator_rep_()196   Hull_vertex_iterator_rep_() :
197     pvisited_(0), hull_(0), i_(0) {}
Hull_vertex_iterator_rep_(Hull_pointer p,FHandle f)198   Hull_vertex_iterator_rep_(Hull_pointer p, FHandle f) :
199     pvisited_(0), hull_(p), f_(f), i_(-1) {}
~Hull_vertex_iterator_rep_()200   ~Hull_vertex_iterator_rep_()
201   { if (pvisited_) delete pvisited_; }
202 };
203 
204 template <typename Hull_pointer, typename VHandle, typename FHandle>
205 class Hull_vertex_iterator_ : private
206   Handle_for< Hull_vertex_iterator_rep_<Hull_pointer,VHandle,FHandle> >
207 { typedef Hull_vertex_iterator_<Hull_pointer,VHandle,FHandle> Self;
208   typedef Hull_vertex_iterator_rep_<Hull_pointer,VHandle,FHandle> Rep;
209   typedef Handle_for< Rep > Base;
210 
211   using Base::ptr;
212 
213 public:
214   typedef typename VHandle::value_type value_type;
215   typedef typename VHandle::pointer    pointer;
216   typedef typename VHandle::reference  reference;
217   typedef typename VHandle::difference_type difference_type;
218   typedef std::forward_iterator_tag   iterator_category;
219 
Hull_vertex_iterator_()220   Hull_vertex_iterator_() : Base( Rep() ) {}
Hull_vertex_iterator_(Hull_pointer p,FHandle f)221   Hull_vertex_iterator_(Hull_pointer p, FHandle f) : Base( Rep(p,f) )
222   { ptr()->pvisited_ = new Unique_hash_map<VHandle,bool>(false);
223     ptr()->advance();
224   }
225 
226   reference operator*() const
227   { return ptr()->v_.operator*(); }
228   pointer operator->() const
229   { return ptr()->v_.operator->(); }
230 
231   Self& operator++()
232   { if ( ptr()->v_ == VHandle() ) return *this;
233     ptr()->advance();
234     return *this;
235   }
236   Self  operator++(int)
237   { Self tmp = *this; ++*this; return tmp; }
238   bool operator==(const Self& x) const
239   { return ptr()->v_ == x.ptr()->v_; }
240   bool operator!=(const Self& x) const
241   { return !operator==(x); }
242 
VHandle()243   operator VHandle() { return ptr()->v_; }
244 
245 };
246 
247 template <class Vertex, class Point>
248 struct Point_from_Vertex {
249   typedef Vertex argument_type;
250   typedef Point  result_type;
operatorPoint_from_Vertex251   result_type& operator()(argument_type& x) const
252   { return x.point(); }
operatorPoint_from_Vertex253   const result_type& operator()(const argument_type& x) const
254   { return x.point(); }
255 };
256 
257 
258 template <typename H1, typename H2>
259 struct list_collector {
260   std::list<H1>& L_;
list_collectorlist_collector261   list_collector(std::list<H1>& L) : L_(L) {}
operatorlist_collector262   void operator()(H2 f) const
263   { L_.push_back(static_cast<H1>(f)); }
264 };
265 
266 
267 template <class R_>
268 class Convex_hull_d : public Regular_complex_d<R_>
269 {
270 typedef Regular_complex_d<R_> Base;
271 typedef Convex_hull_d<R_>     Self;
272 
273 public:
274 
275   using Base::new_simplex;
276   using Base::new_vertex;
277   using Base::associate_vertex_with_simplex;
278   using Base::associate_point_with_vertex;
279   using Base::set_neighbor;
280 
281   using Base::kernel;
282   using Base::dcur;
283 
284 /*{\Xgeneralization Regular_complex_d<R>}*/
285 /*{\Mtypes 6.5}*/
286 typedef R_ R;
287 /*{\Mtypemember the representation class.}*/
288 typedef typename R::Point_d Point_d;
289 /*{\Mtypemember the point type.}*/
290 typedef typename R::Hyperplane_d Hyperplane_d;
291 /*{\Mtypemember the hyperplane type.}*/
292 
293 typedef typename R::Vector_d Vector_d;
294 typedef typename R::Ray_d Ray_d;
295 typedef typename R::RT RT;
296 typedef std::list<Point_d> Point_list;
297 // make traits types locally available
298 
299 typedef typename Base::Simplex_handle Simplex_handle;
300 /*{\Mtypemember handle for simplices.}*/
301 
302 typedef typename Base::Simplex_handle Facet_handle;
303 /*{\Mtypemember handle for facets.}*/
304 
305 typedef typename Base::Vertex_handle Vertex_handle;
306 /*{\Mtypemember handle for vertices.}*/
307 
308 typedef typename Base::Simplex_iterator Simplex_iterator;
309 /*{\Mtypemember iterator for simplices.}*/
310 
311 typedef typename Base::Vertex_iterator Vertex_iterator;
312 /*{\Mtypemember iterator for vertices.}*/
313 
314 typedef Facet_iterator_<Self*,Facet_handle> Facet_iterator;
315 /*{\Mtypemember iterator for facets.}*/
316 
317 typedef Hull_vertex_iterator_<Self*,Vertex_handle,Facet_iterator>
318   Hull_vertex_iterator;
319 /*{\Mtypemember iterator for vertices that are part of the convex hull.}*/
320 
321 /*{\Mtext Note that each iterator fits the handle concept, i.e. iterators
322 can be used as handles. Note also that all iterator and handle types
323 come also in a const flavor, e.g., |Vertex_const_iterator| is the
324 constant version of |Vertex_iterator|. Thus use the const version
325 whenever the convex hull object is referenced as constant.}*/
326 
327 #define CGAL_USING(t) typedef typename Base::t t
328 CGAL_USING(Simplex_const_iterator);CGAL_USING(Vertex_const_iterator);
329 CGAL_USING(Simplex_const_handle);CGAL_USING(Vertex_const_handle);
330 #undef CGAL_USING
331 typedef Simplex_const_handle Facet_const_handle;
332 typedef Facet_iterator_<const Self*,Facet_const_handle> Facet_const_iterator;
333 typedef Hull_vertex_iterator_<const Self*,Vertex_const_handle,
334   Facet_const_iterator> Hull_vertex_const_iterator;
335 
336 typedef typename Point_list::const_iterator Point_const_iterator;
337 /*{\Mtypemember const iterator for all inserted points.}*/
338 
339 typedef typename Vertex_handle::value_type Vertex;
340 
341 typedef CGAL::Iterator_project<
342   Hull_vertex_const_iterator, Point_from_Vertex<Vertex,Point_d>,
343   const Point_d&, const Point_d*> Hull_point_const_iterator;
344 /*{\Mtypemember const iterator for all points of the hull.}*/
345 
346 protected:
347   Point_list         all_pnts_;
348   Vector_d           quasi_center_;   // sum of the vertices of origin simplex
349   Simplex_handle     origin_simplex_; // pointer to the origin simplex
350   Facet_handle       start_facet_;    // pointer to some facet on the surface
351   Vertex_handle      anti_origin_;
352 
353 public: // until there are template friend functions possible
center()354   Point_d center() const // compute center from quasi center
355   { typename R::Vector_to_point_d to_point =
356       kernel().vector_to_point_d_object();
357     return to_point(quasi_center_/RT(dcur + 1)); }
quasi_center()358   const Vector_d& quasi_center() const
359   { return quasi_center_; }
origin_simplex()360   Simplex_const_handle origin_simplex() const
361   { return origin_simplex_; }
base_facet_plane(Simplex_handle s)362   Hyperplane_d base_facet_plane(Simplex_handle s) const
363   { return s -> hyperplane_of_base_facet(); }
base_facet_plane(Simplex_const_handle s)364   Hyperplane_d base_facet_plane(Simplex_const_handle s) const
365   { return s -> hyperplane_of_base_facet(); }
visited_mark(Simplex_handle s)366   bool& visited_mark(Simplex_handle s) const
367   { return s->visited(); }
368 
369 protected:
370   std::size_t num_of_bounded_simplices;
371   std::size_t num_of_unbounded_simplices;
372   std::size_t num_of_visibility_tests;
373   std::size_t num_of_vertices;
374 
375   void compute_equation_of_base_facet(Simplex_handle s);
376   /*{\Xop computes the equation of the base facet of $s$ and sets the
377   |base_facet| member of $s$. The equation is normalized such
378   that the origin simplex lies in the negative halfspace.}*/
379 
is_base_facet_visible(Simplex_handle s,const Point_d & x)380   bool is_base_facet_visible(Simplex_handle s, const Point_d& x) const
381   { typename R::Has_on_positive_side_d has_on_positive_side =
382       kernel().has_on_positive_side_d_object();
383     return has_on_positive_side(s->hyperplane_of_base_facet(),x); }
384   /*{\Xop returns true if $x$ sees the base facet of $s$, i.e., lies in
385   its positive halfspace.}*/
386 
387   bool contains_in_base_facet(Simplex_handle s, const Point_d& x) const;
388   /*{\Xop returns true if $x$ lies in the closure of the base facet of
389   $s$.}*/
390 
391 
392   void visibility_search(Simplex_handle S, const Point_d& x,
393                          std::list<Simplex_handle>& visible_simplices,
394                          std::size_t& num_of_visited_simplices,
395                          int& location, Facet_handle& f) const;
396   /*{\Xop adds all unmarked unbounded simplices with $x$-visible base
397           facet to |visible_simplices| and marks them. In |location| the
398           procedure returns the position of |x| with respect to the
399           current hull: $-1$ for inside, $0$ for on the boundary,
400           and $+1$ for outside; the initial value of |location| for the
401           outermost call must be $-1$. If $x$ is contained in the
402           boundary of |\Mvar| then a facet incident to $x$ is returned
403           in $f$.}*/
404 
405   void clear_visited_marks(Simplex_handle s) const;
406  /*{\Xop removes the mark bits from all marked simplices reachable from $s$.}*/
407 
408   void dimension_jump(Simplex_handle S, Vertex_handle x);
409   /*{\Xop Adds a new vertex $x$ to the triangulation. The point associated
410   with $x$ lies outside the affine hull of the current point set.  }*/
411 
412   void visible_facets_search(Simplex_handle S, const Point_d& x,
413                              std::list< Facet_handle >& VisibleFacets,
414                              std::size_t& num_of_visited_facets) const;
415 
416 public:
417 
418   /*{\Mcreation 3}*/
419 
420   Convex_hull_d(int d, const R& Kernel = R());
421   /*{\Mcreate creates an instance |\Mvar| of type |\Mtype|. The
422   dimension of the underlying space is $d$ and |S| is initialized to the
423   empty point set. The traits class |R| specifies the models of
424   all types and the implementations of all geometric primitives used by
425   the convex hull class. The default model is one of the $d$-dimensional
426   representation classes (e.g., |Homogeneous_d|).}*/
427 
428   protected:
429   /*{\Mtext The data type |\Mtype| offers neither copy constructor nor
430   assignment operator.}*/
431     Convex_hull_d(const Self&);
432     Convex_hull_d& operator=(const Self&);
433   public:
434 
435 
436   /*{\Moperations 3}*/
437   /*{\Mtext All operations below that take a point |x| as argument have
438   the common precondition that |x| is a point of ambient space.}*/
439 
dimension()440   int dimension() const { return Base::dimension(); }
441   /*{\Mop returns the dimension of ambient space}*/
current_dimension()442   int current_dimension() const { return Base::current_dimension(); }
443   /*{\Mop returns the affine dimension |dcur| of $S$.}*/
444 
associated_point(Vertex_handle v)445   Point_d  associated_point(Vertex_handle v) const
446   { return Base::associated_point(v); }
447   /*{\Mop returns the point associated with vertex $v$.}*/
associated_point(Vertex_const_handle v)448   Point_d  associated_point(Vertex_const_handle v) const
449   { return Base::associated_point(v); }
450 
vertex_of_simplex(Simplex_handle s,int i)451   Vertex_handle  vertex_of_simplex(Simplex_handle s, int i) const
452   { return Base::vertex(s,i); }
453   /*{\Mop returns the vertex corresponding to the $i$-th vertex of $s$.\\
454   \precond $0 \leq i \leq |dcur|$. }*/
vertex_of_simplex(Simplex_const_handle s,int i)455   Vertex_const_handle  vertex_of_simplex(Simplex_const_handle s, int i) const
456   { return Base::vertex(s,i); }
457 
point_of_simplex(Simplex_handle s,int i)458   Point_d  point_of_simplex(Simplex_handle s,int i) const
459   { return associated_point(vertex_of_simplex(s,i)); }
460   /*{\Mop same as |C.associated_point(C.vertex_of_simplex(s,i))|. }*/
point_of_simplex(Simplex_const_handle s,int i)461   Point_d  point_of_simplex(Simplex_const_handle s,int i) const
462   { return associated_point(vertex_of_simplex(s,i)); }
463 
464 
opposite_simplex(Simplex_handle s,int i)465   Simplex_handle opposite_simplex(Simplex_handle s,int i) const
466   { return Base::opposite_simplex(s,i); }
467   /*{\Mop returns the simplex opposite to the $i$-th vertex of $s$
468   (|Simplex_handle()| if there is no such simplex).
469   \precond $0 \leq i \leq |dcur|$. }*/
opposite_simplex(Simplex_const_handle s,int i)470   Simplex_const_handle opposite_simplex(Simplex_const_handle s,int i) const
471   { return Base::opposite_simplex(s,i); }
472 
473 
index_of_vertex_in_opposite_simplex(Simplex_handle s,int i)474   int  index_of_vertex_in_opposite_simplex(Simplex_handle s,int i) const
475   { return Base::index_of_opposite_vertex(s,i); }
476   /*{\Mop returns the index of the vertex opposite to the $i$-th vertex
477   of $s$. \precond $0 \leq i \leq |dcur|$ and there is a
478   simplex opposite to the $i$-th vertex of $s$. }*/
index_of_vertex_in_opposite_simplex(Simplex_const_handle s,int i)479   int  index_of_vertex_in_opposite_simplex(Simplex_const_handle s,int i) const
480   { return Base::index_of_opposite_vertex(s,i); }
481 
simplex(Vertex_handle v)482   Simplex_handle  simplex(Vertex_handle v) const
483   { return Base::simplex(v); }
484   /*{\Mop returns a simplex of which $v$ is a node. Note that this
485   simplex is not unique. }*/
simplex(Vertex_const_handle v)486   Simplex_const_handle  simplex(Vertex_const_handle v) const
487   { return Base::simplex(v); }
488 
index(Vertex_handle v)489   int index(Vertex_handle v) const { return Base::index(v); }
490   /*{\Mop returns the index of $v$ in |simplex(v)|.}*/
index(Vertex_const_handle v)491   int index(Vertex_const_handle v) const { return Base::index(v); }
492 
vertex_of_facet(Facet_handle f,int i)493   Vertex_handle  vertex_of_facet(Facet_handle f, int i) const
494   { return vertex_of_simplex(f,i+1); }
495   /*{\Mop returns the vertex corresponding to the $i$-th vertex of $f$.
496   \precond $0 \leq i < |dcur|$. }*/
vertex_of_facet(Facet_const_handle f,int i)497   Vertex_const_handle  vertex_of_facet(Facet_const_handle f, int i) const
498   { return vertex_of_simplex(f,i+1); }
499 
point_of_facet(Facet_handle f,int i)500   Point_d point_of_facet(Facet_handle f, int i) const
501   { return point_of_simplex(f,i+1); }
502   /*{\Mop same as |C.associated_point(C.vertex_of_facet(f,i))|.}*/
point_of_facet(Facet_const_handle f,int i)503   Point_d point_of_facet(Facet_const_handle f, int i) const
504   { return point_of_simplex(f,i+1); }
505 
opposite_facet(Facet_handle f,int i)506   Facet_handle opposite_facet(Facet_handle f, int i) const
507   { return opposite_simplex(f,i+1); }
508   /*{\Mop returns the facet opposite to the $i$-th vertex of $f$
509   (|Facet_handle()| if there is no such facet). \precond $0 \leq i <
510   |dcur|$ and |dcur > 1|. }*/
opposite_facet(Facet_const_handle f,int i)511   Facet_const_handle opposite_facet(Facet_const_handle f, int i) const
512   { return opposite_simplex(f,i+1); }
513 
index_of_vertex_in_opposite_facet(Facet_handle f,int i)514   int index_of_vertex_in_opposite_facet(Facet_handle f, int i) const
515   { return index_of_vertex_in_opposite_simplex(f,i+1) - 1; }
516   /*{\Mop returns the index of the vertex opposite to the $i$-th vertex of
517   $f$. \precond $0 \leq i < |dcur|$ and |dcur > 1|.}*/
index_of_vertex_in_opposite_facet(Facet_const_handle f,int i)518   int index_of_vertex_in_opposite_facet(Facet_const_handle f, int i) const
519   { return index_of_vertex_in_opposite_simplex(f,i+1) - 1; }
520 
hyperplane_supporting(Facet_handle f)521   Hyperplane_d hyperplane_supporting(Facet_handle f) const
522   { return f -> hyperplane_of_base_facet(); }
523   /*{\Mop returns a hyperplane supporting facet |f|. The hyperplane is
524   oriented such that the interior of |\Mvar| is on the negative
525   side of it. \precond |f| is a facet of |\Mvar| and |dcur > 1|.}*/
hyperplane_supporting(Facet_const_handle f)526   Hyperplane_d hyperplane_supporting(Facet_const_handle f) const
527   { return f -> hyperplane_of_base_facet(); }
528 
529 
530   Vertex_handle insert(const Point_d& x);
531   /*{\Mop adds point |x| to the underlying set of points.  If $x$ is
532   equal to (the point associated with) a vertex of the current hull this
533   vertex is returned and its associated point is changed to $x$. If $x$
534   lies outside the current hull, a new vertex |v| with associated point
535   $x$ is added to the hull and returned. In all other cases, i.e., if
536   $x$ lies in the interior of the hull or on the boundary but not on a
537   vertex, the current hull is not changed and |Vertex_handle()| is
538   returned. If |CGAL_CHECK_EXPENSIVE| is defined then the validity
539   check |is_valid(true)| is executed as a post condition.}*/
540 
541   template <typename Forward_iterator>
insert(Forward_iterator first,Forward_iterator last)542   void insert(Forward_iterator first, Forward_iterator last)
543   { while (first != last) insert(*first++); }
544   /*{\Mop adds |S = set [first,last)| to the underlying set of
545   points. If any point |S[i]| is equal to (the point associated with) a
546   vertex of the current hull its associated point is changed to |S[i]|.}*/
547 
548 
is_dimension_jump(const Point_d & x)549   bool is_dimension_jump(const Point_d& x) const
550   /*{\Mop returns true if $x$ is not contained in the affine hull of |S|.}*/
551   {
552     if (current_dimension() == dimension()) return false;
553     typename R::Contained_in_affine_hull_d contained_in_affine_hull =
554       kernel().contained_in_affine_hull_d_object();
555     return ( !contained_in_affine_hull(origin_simplex_->points_begin(),
556       origin_simplex_->points_begin()+current_dimension()+1,x) );
557   }
558 
559 
560   std::list<Facet_handle>  facets_visible_from(const Point_d& x);
561   /*{\Mop returns the list of all facets that are visible from |x|.\\
562   \precond |x| is contained in the affine hull of |S|.}*/
563 
564   Bounded_side bounded_side(const Point_d& x);
565   /*{\Mop returns |ON_BOUNDED_SIDE| (|ON_BOUNDARY|,|ON_UNBOUNDED_SIDE|)
566   if |x| is contained in the interior (lies on the boundary, is contained
567   in the exterior) of |\Mvar|. \precond |x| is contained in the affine
568   hull of |S|.}*/
569 
570 
is_unbounded_simplex(Simplex_handle S)571   bool is_unbounded_simplex(Simplex_handle S) const
572   { return vertex_of_simplex(S,0) == anti_origin_; }
is_unbounded_simplex(Simplex_const_handle S)573   bool is_unbounded_simplex(Simplex_const_handle S) const
574   { return vertex_of_simplex(S,0) == anti_origin_; }
is_bounded_simplex(Simplex_handle S)575   bool is_bounded_simplex(Simplex_handle S) const
576   { return vertex_of_simplex(S,0) != anti_origin_; }
is_bounded_simplex(Simplex_const_handle S)577   bool is_bounded_simplex(Simplex_const_handle S) const
578   { return vertex_of_simplex(S,0) != anti_origin_; }
579 
clear(int d)580   void clear(int d)
581   /*{\Mop reinitializes |\Mvar| to an empty hull in $d$-dimensional space.}*/
582   {
583     typename R::Construct_vector_d create =
584       kernel().construct_vector_d_object();
585     quasi_center_ = create(d,NULL_VECTOR);
586     anti_origin_ = Vertex_handle();
587     origin_simplex_ = Simplex_handle();
588     all_pnts_.clear();
589     Base::clear(d);
590     num_of_vertices = 0;
591     num_of_unbounded_simplices = num_of_bounded_simplices = 0;
592     num_of_visibility_tests = 0;
593   }
594 
number_of_vertices()595   std::size_t number_of_vertices() const
596   /*{\Mop returns the number of vertices of |\Mvar|.}*/
597   { return num_of_vertices; }
598 
number_of_facets()599   std::size_t number_of_facets() const
600   /*{\Mop returns the number of facets of |\Mvar|.}*/
601   { return num_of_unbounded_simplices; }
602 
number_of_simplices()603   std::size_t number_of_simplices() const
604   /*{\Mop returns the number of bounded simplices of |\Mvar|.}*/
605   { return num_of_bounded_simplices; }
606 
print_statistics()607   void print_statistics()
608   /*{\Mop gives information about the size of the current hull and the
609   number of visibility tests performed.}*/
610   {
611     std::cout << "Convex_hull_d ("
612               << current_dimension() << "/" << dimension()
613               << ") - statistic" << std::endl;
614     std::cout<<" # points = " << all_pnts_.size() << std::endl;
615     std::cout<<" # vertices = " << num_of_vertices << std::endl;
616     std::cout<<" # unbounded simplices = " << num_of_unbounded_simplices
617       << std::endl;
618     std::cout<<" # bounded simplices = " << num_of_bounded_simplices
619       << std::endl;
620     std::cout<<" # visibility tests = " << num_of_visibility_tests
621       << std::endl;
622   }
623 
624   class chull_has_double_coverage {};
625   class chull_has_local_non_convexity {};
626   class chull_has_center_on_wrong_side_of_hull_facet {};
627 
628   bool is_valid(bool throw_exceptions = false) const;
629   /*{\Mop checks the validity of the data structure.
630   If |throw_exceptions == thrue| then the program throws
631   the following exceptions to inform about the problem.\\
632   [[chull_has_center_on_wrong_side_of_hull_facet]] the hyperplane
633   supporting a facet has the wrong orientation.\\
634   [[chull_has_local_non_convexity]] a ridge is locally non convex.\\
635   [[chull_has_double_coverage]] the hull has a winding number larger
636   than 1.
637   }*/
638 
639   template <typename Forward_iterator>
initialize(Forward_iterator first,Forward_iterator last)640   void initialize(Forward_iterator first, Forward_iterator last)
641   /*{\Xop initializes the complex with the set |S = set [first,last)|.
642   The initialization uses the quickhull approach.}*/
643   { CGAL_assertion(current_dimension()==-1);
644     Vertex_handle z;
645     Forward_iterator it(first);
646     std::list< Point_d > OtherPoints;
647     typename std::list< Point_d >::iterator pit, pred;
648     while ( it != last ) {
649       Point_d x = *it++;
650       if ( current_dimension() == -1 ) {
651 
652         Simplex_handle outer_simplex; // a pointer to the outer simplex
653         dcur = 0;  // we jump from dimension - 1 to dimension 0
654         origin_simplex_ = new_simplex();  num_of_bounded_simplices ++;
655         outer_simplex  = new_simplex();   num_of_unbounded_simplices ++;
656         start_facet_ = origin_simplex_;
657         z = new_vertex(x);                num_of_vertices ++;
658         associate_vertex_with_simplex(origin_simplex_,0,z);
659           // z is the only point and the peak
660         associate_vertex_with_simplex(outer_simplex,0,anti_origin_);
661         set_neighbor(origin_simplex_,0,outer_simplex,0);
662         typename R::Point_to_vector_d to_vector =
663           kernel().point_to_vector_d_object();
664         quasi_center_ = to_vector(x);
665 
666 
667       }
668       else if ( is_dimension_jump(x) ) {
669         dcur++;
670         z = new_vertex(x); num_of_vertices++;
671         typename R::Point_to_vector_d to_vector =
672           kernel().point_to_vector_d_object();
673         quasi_center_ = quasi_center_ + to_vector(x);
674         dimension_jump(origin_simplex_, z);
675         clear_visited_marks(origin_simplex_);
676         Simplex_iterator S;
677         forall_rc_simplices(S,*this) compute_equation_of_base_facet(S);
678         num_of_unbounded_simplices += num_of_bounded_simplices;
679         if (dcur > 1) {
680           start_facet_ = opposite_simplex(origin_simplex_,dcur);
681           CGAL_assertion(vertex_of_simplex(start_facet_,0)==Vertex_handle());
682         }
683 
684 
685       } else {
686         OtherPoints.push_back(x);
687       }
688     }
689     all_pnts_.insert(all_pnts_.end(),first,last);
690 
691     // what is the point of this line? ...
692     //int dcur = current_dimension();
693     Unique_hash_map<Facet_handle, std::list<Point_d> > PointsOf;
694     std::list<Facet_handle> FacetCandidates;
695     typename R::Oriented_side_d side_of =
696       kernel().oriented_side_d_object();
697     for (int i=0; i<=dcur; ++i) {
698       Simplex_handle f = opposite_simplex(origin_simplex_,i);
699       Hyperplane_d h = f->hyperplane_of_base_facet();
700       std::list<Point_d>& L = PointsOf[f];
701       pit = OtherPoints.begin();
702       while ( pit != OtherPoints.end() ) {
703         if ( side_of(h,*pit) == ON_POSITIVE_SIDE ) {
704           L.push_back(*pit); pred=pit; ++pit; OtherPoints.erase(pred);
705         } else ++pit; // not above h
706       }
707       if ( !L.empty() ) FacetCandidates.push_back(f);
708     }
709     OtherPoints.clear();
710 
711     while ( !FacetCandidates.empty() ) {
712       Facet_handle f = *FacetCandidates.begin();
713       FacetCandidates.pop_front();
714       Hyperplane_d h = f->hyperplane_of_base_facet();
715       std::list<Point_d>& L = PointsOf[f];
716       if (L.empty()) { CGAL_assertion( is_bounded_simplex(f) ); continue; }
717       Point_d p = *L.begin();
718       typename R::Value_at_d value_at = kernel().value_at_d_object();
719       RT maxdist = value_at(h,p), dist;
720       for (pit = ++L.begin(); pit != L.end(); ++pit) {
721         dist = value_at(h,*pit);
722         if ( dist > maxdist ) { maxdist = dist; p = *pit; }
723       }
724       num_of_visibility_tests += L.size();
725 
726       std::size_t num_of_visited_facets = 0;
727       std::list<Facet_handle> VisibleFacets;
728       VisibleFacets.push_back(f);
729       visible_facets_search(f, p, VisibleFacets, num_of_visited_facets);
730       num_of_visibility_tests += num_of_visited_facets;
731       num_of_bounded_simplices += VisibleFacets.size();
732       clear_visited_marks(f);
733 
734       ++num_of_vertices;
735       Vertex_handle z = new_vertex(p);
736       std::list<Simplex_handle> NewSimplices;
737       typename std::list<Facet_handle>::iterator it;
738       CGAL_assertion(OtherPoints.empty());
739       for (it = VisibleFacets.begin(); it != VisibleFacets.end(); ++it) {
740         OtherPoints.splice(OtherPoints.end(),PointsOf[*it]);
741         Facet_handle S = *it;
742         associate_vertex_with_simplex(S,0,z);
743         for (int k = 1; k <= dcur; ++k) {
744           if (!is_base_facet_visible(opposite_simplex(S,k),p)) {
745             Simplex_handle T = new_simplex();
746             NewSimplices.push_back(T);
747 
748             /* set the vertices of T as described above */
749             for (int i = 1; i < dcur; i++) {
750               if ( i != k )
751                 associate_vertex_with_simplex(T,i,vertex_of_simplex(S,i));
752             }
753             if (k != dcur)
754               associate_vertex_with_simplex(T,k,vertex_of_simplex(S,dcur));
755             associate_vertex_with_simplex(T,dcur,z);
756             associate_vertex_with_simplex(T,0,anti_origin_);
757             /* in the above, it is tempting to drop the tests ( i != k ) and
758                ( k != dcur ) since the subsequent lines after will correct the
759                erroneous assignment.  This reasoning is fallacious as the
760                procedure assoc_vertex_with_simplex also the internal data of
761                the third argument. */
762 
763             /* compute the equation of its base facet */
764             compute_equation_of_base_facet(T);
765 
766             /* record adjacency information for the two known neighbors */
767             set_neighbor(T,dcur,opposite_simplex(S,k),
768                          index_of_vertex_in_opposite_simplex(S,k));
769             set_neighbor(T,0,S,k);
770 
771 
772           }
773         }
774       }
775       num_of_unbounded_simplices -= VisibleFacets.size();
776       if ( vertex_of_simplex(start_facet_,0) != Vertex_handle() )
777         start_facet_ = *(--NewSimplices.end());
778       CGAL_assertion( vertex_of_simplex(start_facet_,0)==Vertex_handle() );
779       for (it = NewSimplices.begin(); it != NewSimplices.end(); ++it) {
780         Simplex_handle Af = *it;
781         for (int k = 1; k < dcur ; k++) {
782           // neighbors 0 and dcur are already known
783           if (opposite_simplex(Af,k) == Simplex_handle()) {
784             // we have not performed the walk in the opposite direction yet
785             Simplex_handle T = opposite_simplex(Af,0);
786             int y1 = 0;
787             while ( vertex_of_simplex(T,y1) != vertex_of_simplex(Af,k) )
788               y1++;
789             // exercise: show that we can also start with y1 = 1
790             int y2 = index_of_vertex_in_opposite_simplex(Af,0);
791 
792             while ( vertex_of_simplex(T,0) == z ) {
793               // while T has peak x do find new y_1 */
794               int new_y1 = 0;
795               while (vertex_of_simplex(opposite_simplex(T,y1),new_y1) !=
796                      vertex_of_simplex(T,y2))
797                 new_y1++;
798                 // exercise: show that we can also start with new_y1 = 1
799               y2 = index_of_vertex_in_opposite_simplex(T,y1);
800               T =  opposite_simplex(T,y1);
801               y1 = new_y1;
802             }
803             set_neighbor(Af,k,T,y1); // update adjacency information
804           }
805         }
806       }
807 
808 
809 
810       for (it = NewSimplices.begin(); it != NewSimplices.end(); ++it) {
811         Facet_handle f = *it;
812         CGAL_assertion( is_unbounded_simplex(f) );
813         Hyperplane_d h = f->hyperplane_of_base_facet();
814         std::list<Point_d>& L = PointsOf[f];
815         pit = OtherPoints.begin();
816         while ( pit != OtherPoints.end() ) {
817           if ( side_of(h,*pit) == ON_POSITIVE_SIDE ) {
818             L.push_back(*pit); pred=pit; ++pit; OtherPoints.erase(pred);
819           } else ++pit; // not above h
820         }
821         if ( !L.empty() ) FacetCandidates.push_back(f);
822       }
823       OtherPoints.clear();
824 
825     }
826 
827   #ifdef CGAL_CHECK_EXPENSIVE
828     CGAL_assertion(is_valid(true));
829   #endif
830   }
831 
832 
833   /*{\Mtext \headerline{Lists and Iterators}
834   \setopdims{3.5cm}{3.5cm}}*/
835 
vertices_begin()836   Vertex_iterator vertices_begin() { return Base::vertices_begin(); }
837   /*{\Mop returns an iterator to start iteration over all vertices
838   of |\Mvar|.}*/
vertices_end()839   Vertex_iterator vertices_end()   { return Base::vertices_end(); }
840   /*{\Mop the past the end iterator for vertices.}*/
simplices_begin()841   Simplex_iterator simplices_begin() { return Base::simplices_begin(); }
842   /*{\Mop returns an iterator to start iteration over all simplices
843   of |\Mvar|.}*/
simplices_end()844   Simplex_iterator simplices_end()   { return Base::simplices_end(); }
845   /*{\Mop the past the end iterator for simplices.}*/
facets_begin()846   Facet_iterator facets_begin() { return Facet_iterator(this,start_facet_); }
847   /*{\Mop returns an iterator to start iteration over all facets of |\Mvar|.}*/
facets_end()848   Facet_iterator facets_end() { return Facet_iterator(); }
849   /*{\Mop the past the end iterator for facets.}*/
hull_vertices_begin()850   Hull_vertex_iterator hull_vertices_begin()
851   { return Hull_vertex_iterator(this,facets_begin()); }
852   /*{\Mop returns an iterator to start iteration over all hull vertex
853   of |\Mvar|. Remember that the hull is a simplicial complex.}*/
hull_vertices_end()854   Hull_vertex_iterator hull_vertices_end()
855   { return Hull_vertex_iterator(); }
856   /*{\Mop the past the end iterator for hull vertices.}*/
857 
points_begin()858   Point_const_iterator points_begin() const { return all_pnts_.begin(); }
859   /*{\Mop returns the start iterator for all points that have been
860   inserted to construct |\Mvar|.}*/
points_end()861   Point_const_iterator points_end() const { return all_pnts_.end(); }
862   /*{\Mop returns the past the end iterator for all points.}*/
863 
hull_points_begin()864   Hull_point_const_iterator hull_points_begin() const
865   { return Hull_point_const_iterator(hull_vertices_begin()); }
866   /*{\Mop returns an iterator to start iteration over all inserted
867   points that are part of the convex hull |\Mvar|. Remember that the
868   hull is a simplicial complex.}*/
hull_points_end()869   Hull_point_const_iterator hull_points_end() const
870   { return Hull_point_const_iterator(hull_vertices_end()); }
871   /*{\Mop returns the past the end iterator for points of the hull.}*/
872 
vertices_begin()873   Vertex_const_iterator vertices_begin() const
874   { return Base::vertices_begin(); }
vertices_end()875   Vertex_const_iterator vertices_end()   const
876   { return Base::vertices_end(); }
simplices_begin()877   Simplex_const_iterator simplices_begin() const
878   { return Base::simplices_begin(); }
simplices_end()879   Simplex_const_iterator simplices_end()   const
880   { return Base::simplices_end(); }
facets_begin()881   Facet_const_iterator facets_begin() const
882   { return Facet_const_iterator(this,start_facet_); }
facets_end()883   Facet_const_iterator facets_end() const
884   { return Facet_const_iterator(); }
hull_vertices_begin()885   Hull_vertex_const_iterator hull_vertices_begin() const
886   { return Hull_vertex_const_iterator(this,facets_begin()); }
hull_vertices_end()887   Hull_vertex_const_iterator hull_vertices_end() const
888   { return Hull_vertex_const_iterator(); }
889 
890   /* We distinguish cases according to the current dimension.  If the
891      dimension is less than one then the hull has no facets, if the
892      dimension is one then the hull has two facets which we extract by a
893      scan through the set of all simplices, and if the hull has
894      dimension at least two the boundary is a connected set and we
895      construct the list of facets by depth first search starting at
896      |start_facet_|.*/
897 
898   /*{\Mtext\setopdims{5.5cm}{3.5cm}}*/
899   template <typename Visitor>
visit_all_facets(const Visitor & V)900   void visit_all_facets(const Visitor& V) const
901   /*{\Mop each facet of |\Mvar| is visited by the visitor object |V|.
902   |V| has to have a function call operator:\\
903   |void operator()(Facet_handle) const|}*/
904   {
905     if (current_dimension() > 1) {
906       Unique_hash_map<Facet_handle,bool> visited(false);
907       std::list<Facet_handle> candidates;
908       candidates.push_back(start_facet_);
909       visited[start_facet_] = true;
910       Facet_handle current;
911       while ( !candidates.empty() ) {
912         current = *(candidates.begin()); candidates.pop_front();
913         CGAL_assertion(vertex_of_simplex(current,0)==Vertex_handle());
914         V(current);
915         for(int i = 1; i <= dcur; ++i) {
916           Facet_handle f = opposite_simplex(current,i);
917           if ( !visited[f] ) {
918             candidates.push_back(f);
919             visited[f] = true;
920           }
921         }
922       }
923     }
924     else if ( current_dimension() == 1 ) { V(start_facet_); }
925   }
926 
all_points()927   const std::list<Point_d>& all_points() const
928   /*{\Mop returns a list of all points in |\Mvar|.}*/
929   { return all_pnts_; }
930 
all_vertices()931   std::list<Vertex_handle> all_vertices()
932   /*{\Mop returns a list of all vertices of |\Mvar|
933   (also interior ones).}*/
934   { return Base::all_vertices(); }
all_vertices()935   std::list<Vertex_const_handle> all_vertices() const
936   { return Base::all_vertices(); }
937 
all_simplices()938   std::list<Simplex_handle> all_simplices()
939   /*{\Mop returns a list of all simplices in |\Mvar|.}*/
940   { return Base::all_simplices(); }
all_simplices()941   std::list<Simplex_const_handle> all_simplices() const
942   { return Base::all_simplices(); }
943 
944 
945 
all_facets()946   std::list<Facet_handle>  all_facets()
947   /*{\Mop returns a list of all facets of |\Mvar|.}*/
948   { std::list<Facet_handle> L;
949     list_collector<Facet_handle,Facet_handle> visitor(L);
950     visit_all_facets(visitor);
951     return L;
952   }
953 
all_facets()954   std::list<Facet_const_handle>  all_facets() const
955   { std::list<Facet_const_handle> L;
956     list_collector<Facet_const_handle,Facet_handle> visitor(L);
957     visit_all_facets(visitor);
958     return L;
959   }
960 
961   #define forall_ch_vertices(x,CH)\
962   for(x = (CH).vertices_begin(); x != (CH).vertices_end(); ++x)
963   #define forall_ch_simplices(x,CH)\
964   for(x = (CH).simplices_begin(); x != (CH).simplices_end(); ++x)
965   #define forall_ch_facets(x,CH)\
966   for(x = (CH).facets_begin(); x != (CH).facets_end(); ++x)
967 
968   /*{\Mtext
969   \headerline{Iteration Statements}
970 
971   {\bf forall\_ch\_vertices}($v,C$)
972   $\{$ ``the vertices of $C$ are successively assigned to $v$'' $\}$
973 
974   {\bf forall\_ch\_simplices}($s,C$)
975   $\{$ ``the simplices of $C$ are successively assigned to $s$'' $\}$
976 
977   {\bf forall\_ch\_facets}($f,C$)
978   $\{$ ``the facets of $C$ are successively assigned to $f$'' $\}$
979 
980   }*/
981 
982 
983   /*{\Mimplementation The implementation of type |\Mtype| is based on
984   \cgalCite{cms:fourresults} and \cgalCite{BMS:degeneracy}.  The details of the
985   implementation can be found in the implementation document available
986   at the download site of this package.
987 
988   The time and space requirements are input dependent.  Let $C_1$, $C_2$,
989   $C_3$, \ldots be the sequence of hulls constructed and for a point $x$
990   let $k_i$ be the number of facets of $C_i$ that are visible from $x$
991   and that are not already facets of $C_{i-1}$. Then the time for
992   inserting $x$ is $O(|dim| \sum_i k_i)$ and the number of new simplices
993   constructed during the insertion of $x$ is the number of facets of the
994   hull which were not already facets of the hull before the insertion.
995 
996   The data type |\Mtype| is derived from |Regular_complex_d|. The space
997   requirement of regular complexes is essentially $12(|dim| +2)$ bytes
998   times the number of simplices plus the space for the points. |\Mtype|
999   needs an additional $8 + (4 + x)|dim|$ bytes per simplex where $x$ is
1000   the space requirement of the underlying number type and an additional
1001   $12$ bytes per point. The total is therefore $(16 + x)|dim| + 32$
1002   bytes times the number of simplices plus $28 + x \cdot |dim|$ bytes
1003   times the number of points.}*/
1004 
1005   /*{\Mtext\headerline{Traits requirements}
1006 
1007   |\Mname| requires the following types from the kernel traits |R|:
1008   \begin{Mverb}
1009     Point_d Vector_d Ray_d Hyperplane_d
1010   \end{Mverb}
1011   and uses the following function objects from the kernel traits:
1012   \begin{Mverb}
1013     Construct_vector_d
1014     Construct_hyperplane_d
1015     Vector_to_point_d / Point_to_vector_d
1016     Orientation_d
1017     Orthogonal_vector_d
1018     Oriented_side_d / Has_on_positive_side_d
1019     Affinely_independent_d
1020     Contained_in_simplex_d
1021     Contained_in_affine_hull_d
1022     Intersect_d
1023   \end{Mverb}
1024   }*/
1025 
1026 }; // Convex_hull_d<R>
1027 
1028 
1029 
1030 template <class R>
Convex_hull_d(int d,const R & Kernel)1031 Convex_hull_d<R>::Convex_hull_d(int d, const R& Kernel) : Base(d,Kernel)
1032 {
1033   origin_simplex_ = Simplex_handle();
1034   start_facet_ = Facet_handle();
1035   anti_origin_ = Vertex_handle();
1036   num_of_vertices = 0;
1037   num_of_unbounded_simplices = num_of_bounded_simplices = 0;
1038   num_of_visibility_tests = 0;
1039   typename R::Construct_vector_d create =
1040     kernel().construct_vector_d_object();
1041   quasi_center_ = create(d,NULL_VECTOR);
1042 }
1043 
1044 template <class R>
1045 bool Convex_hull_d<R>::
contains_in_base_facet(Simplex_handle s,const Point_d & x)1046 contains_in_base_facet(Simplex_handle s, const Point_d& x) const
1047 {
1048   typename R::Contained_in_simplex_d contained_in_simplex =
1049     kernel().contained_in_simplex_d_object();
1050   return contained_in_simplex(s->points_begin()+1,
1051     s->points_begin()+current_dimension()+1,x);
1052 }
1053 
1054 template <class R>
1055 void Convex_hull_d<R>::
compute_equation_of_base_facet(Simplex_handle S)1056 compute_equation_of_base_facet(Simplex_handle S)
1057 {
1058   typename R::Construct_hyperplane_d hyperplane_through_points =
1059     kernel().construct_hyperplane_d_object();
1060   S->set_hyperplane_of_base_facet( hyperplane_through_points(
1061     S->points_begin()+1, S->points_begin()+1+current_dimension(),
1062     center(), ON_NEGATIVE_SIDE)); // skip the first point !
1063 
1064   #ifdef CGAL_CHECK_EXPENSIVE
1065   { /* Let us check */
1066     typename R::Oriented_side_d side = kernel().oriented_side_d_object();
1067     for (int i = 1; i <= current_dimension(); i++)
1068       CGAL_assertion_msg(side(S->hyperplane_of_base_facet(),
1069                               point_of_simplex(S,i)) == ON_ORIENTED_BOUNDARY,
1070         " hyperplane does not support base ");
1071     CGAL_assertion_msg(side(S->hyperplane_of_base_facet(),center()) ==
1072                        ON_NEGATIVE_SIDE,
1073       " hyperplane has quasi center on wrong side ");
1074   }
1075   #endif
1076 
1077 
1078 }
1079 
1080 template <class R>
1081 typename Convex_hull_d<R>::Vertex_handle
insert(const Point_d & x)1082 Convex_hull_d<R>::insert(const Point_d& x)
1083 {
1084   Vertex_handle z = Vertex_handle();
1085   all_pnts_.push_back(x);
1086   if (current_dimension() == -1) {
1087 
1088     Simplex_handle outer_simplex; // a pointer to the outer simplex
1089     dcur = 0;  // we jump from dimension - 1 to dimension 0
1090     origin_simplex_ = new_simplex();  num_of_bounded_simplices ++;
1091     outer_simplex  = new_simplex();   num_of_unbounded_simplices ++;
1092     start_facet_ = origin_simplex_;
1093     z = new_vertex(x);                num_of_vertices ++;
1094     associate_vertex_with_simplex(origin_simplex_,0,z);
1095       // z is the only point and the peak
1096     associate_vertex_with_simplex(outer_simplex,0,anti_origin_);
1097     set_neighbor(origin_simplex_,0,outer_simplex,0);
1098     typename R::Point_to_vector_d to_vector =
1099       kernel().point_to_vector_d_object();
1100     quasi_center_ = to_vector(x);
1101 
1102 
1103   } else if ( is_dimension_jump(x) ) {
1104     dcur++;
1105     z = new_vertex(x); num_of_vertices++;
1106     typename R::Point_to_vector_d to_vector =
1107       kernel().point_to_vector_d_object();
1108     quasi_center_ = quasi_center_ + to_vector(x);
1109     dimension_jump(origin_simplex_, z);
1110     clear_visited_marks(origin_simplex_);
1111     Simplex_iterator S;
1112     forall_rc_simplices(S,*this) compute_equation_of_base_facet(S);
1113     num_of_unbounded_simplices += num_of_bounded_simplices;
1114     if (dcur > 1) {
1115       start_facet_ = opposite_simplex(origin_simplex_,dcur);
1116       CGAL_assertion(vertex_of_simplex(start_facet_,0)==Vertex_handle());
1117     }
1118 
1119 
1120   } else {
1121     if ( current_dimension() == 0 ) {
1122       z = vertex_of_simplex(origin_simplex_,0);
1123       associate_point_with_vertex(z,x);
1124       return z;
1125     }
1126     std::list<Simplex_handle> visible_simplices;
1127     int location = -1;
1128     Facet_handle f;
1129 
1130     std::size_t num_of_visited_simplices = 0;
1131 
1132     visibility_search(origin_simplex_, x, visible_simplices,
1133                       num_of_visited_simplices, location, f);
1134 
1135     num_of_visibility_tests += num_of_visited_simplices;
1136 
1137     #ifdef COUNTS
1138       cout << "\nthe number of visited simplices in this iteration is ";
1139       cout << num_of_visited_simplices << endl;
1140     #endif
1141 
1142     clear_visited_marks(origin_simplex_);
1143 
1144 
1145     #ifdef COUNTS
1146       cout << "\nthe number of bounded simplices constructed ";
1147       cout << " in this iteration is  " << visible_simplices.size() << endl;
1148     #endif
1149 
1150     num_of_bounded_simplices += visible_simplices.size();
1151 
1152     switch (location) {
1153       case -1:
1154         return Vertex_handle();
1155       case 0:
1156         { for (int i = 0; i < current_dimension(); i++) {
1157             if ( x == point_of_facet(f,i) ) {
1158               z = vertex_of_facet(f,i);
1159               associate_point_with_vertex(z,x);
1160               return z;
1161             }
1162           }
1163           return Vertex_handle();
1164         }
1165       case 1:
1166         { num_of_vertices++;
1167           z = new_vertex(x);
1168           std::list<Simplex_handle> NewSimplices; // list of new simplices
1169           typename std::list<Simplex_handle>::iterator it;
1170 
1171           for (it = visible_simplices.begin();
1172                it != visible_simplices.end(); ++it) {
1173             Simplex_handle S = *it;
1174             associate_vertex_with_simplex(S,0,z);
1175             for (int k = 1; k <= dcur; k++) {
1176               if (!is_base_facet_visible(opposite_simplex(S,k),x)) {
1177                 Simplex_handle T = new_simplex();
1178                 NewSimplices.push_back(T);
1179 
1180                 /* set the vertices of T as described above */
1181                 for (int i = 1; i < dcur; i++) {
1182                   if ( i != k )
1183                     associate_vertex_with_simplex(T,i,vertex_of_simplex(S,i));
1184                 }
1185                 if (k != dcur)
1186                   associate_vertex_with_simplex(T,k,vertex_of_simplex(S,dcur));
1187                 associate_vertex_with_simplex(T,dcur,z);
1188                 associate_vertex_with_simplex(T,0,anti_origin_);
1189                 /* in the above, it is tempting to drop the tests ( i != k )
1190                    and ( k != dcur ) since the subsequent lines after will
1191                    correct the erroneous assignment.  This reasoning is
1192                    fallacious as the procedure assoc_vertex_with_simplex also
1193                    the internal data of the third argument. */
1194 
1195                 /* compute the equation of its base facet */
1196                 compute_equation_of_base_facet(T);
1197 
1198                 /* record adjacency information for the two known neighbors */
1199                 set_neighbor(T,dcur,opposite_simplex(S,k),
1200                              index_of_vertex_in_opposite_simplex(S,k));
1201                 set_neighbor(T,0,S,k);
1202 
1203 
1204               }
1205             }
1206           }
1207           num_of_unbounded_simplices -= visible_simplices.size();
1208           if ( vertex_of_simplex(start_facet_,0) != Vertex_handle() )
1209             start_facet_ = *(--NewSimplices.end());
1210           CGAL_assertion( vertex_of_simplex(start_facet_,0)==Vertex_handle() );
1211           for (it = NewSimplices.begin(); it != NewSimplices.end(); ++it) {
1212             Simplex_handle Af = *it;
1213             for (int k = 1; k < dcur ; k++) {
1214               // neighbors 0 and dcur are already known
1215               if (opposite_simplex(Af,k) == Simplex_handle()) {
1216                 // we have not performed the walk in the opposite direction yet
1217                 Simplex_handle T = opposite_simplex(Af,0);
1218                 int y1 = 0;
1219                 while ( vertex_of_simplex(T,y1) != vertex_of_simplex(Af,k) )
1220                   y1++;
1221                 // exercise: show that we can also start with y1 = 1
1222                 int y2 = index_of_vertex_in_opposite_simplex(Af,0);
1223 
1224                 while ( vertex_of_simplex(T,0) == z ) {
1225                   // while T has peak x do find new y_1 */
1226                   int new_y1 = 0;
1227                   while (vertex_of_simplex(opposite_simplex(T,y1),new_y1) !=
1228                          vertex_of_simplex(T,y2))
1229                     new_y1++;
1230                     // exercise: show that we can also start with new_y1 = 1
1231                   y2 = index_of_vertex_in_opposite_simplex(T,y1);
1232                   T =  opposite_simplex(T,y1);
1233                   y1 = new_y1;
1234                 }
1235                 set_neighbor(Af,k,T,y1); // update adjacency information
1236               }
1237             }
1238           }
1239 
1240 
1241         }
1242     }
1243 
1244   }
1245 #ifdef CGAL_CHECK_EXPENSIVE
1246   CGAL_assertion(is_valid(true));
1247 #endif
1248   return z;
1249 }
1250 
1251 
1252 template <class R>
1253 void Convex_hull_d<R>::
visibility_search(Simplex_handle S,const Point_d & x,std::list<Simplex_handle> & visible_simplices,std::size_t & num_of_visited_simplices,int & location,Simplex_handle & f)1254 visibility_search(Simplex_handle S, const Point_d& x,
1255                   std::list< Simplex_handle >& visible_simplices,
1256                   std::size_t& num_of_visited_simplices, int& location,
1257                   Simplex_handle& f) const
1258 {
1259   num_of_visited_simplices ++;
1260   S->visited() = true; // we have visited S and never come back ...
1261   for(int i = 0; i <= current_dimension(); ++i) {
1262     Simplex_handle T = opposite_simplex(S,i); // for all neighbors T of S
1263     if ( !T->visited() ) {
1264       typename R::Oriented_side_d side_of =
1265         kernel().oriented_side_d_object();
1266       int side = side_of(T->hyperplane_of_base_facet(),x);
1267       if ( is_unbounded_simplex(T) ) {
1268         if ( side == ON_POSITIVE_SIDE ) {
1269           // T is an unbounded simplex with x-visible base facet
1270           visible_simplices.push_back(T);
1271           location = 1;
1272         }
1273         if ( side == ON_ORIENTED_BOUNDARY &&
1274              location == -1 && contains_in_base_facet(T,x) ) {
1275           location = 0; f = T;
1276           return;
1277         }
1278       }
1279       if ( side == ON_POSITIVE_SIDE ||
1280            (side == ON_ORIENTED_BOUNDARY && location == -1) ) {
1281         visibility_search(T,x,visible_simplices,
1282                           num_of_visited_simplices,location,f);
1283         // do the recursive search
1284       }
1285     } // end visited
1286     else {
1287     }
1288   } // end for
1289 }
1290 
1291 template <class R>
clear_visited_marks(Simplex_handle S)1292 void Convex_hull_d<R>::clear_visited_marks(Simplex_handle S) const
1293 {
1294   S->visited() = false; // clear the visit - bit
1295   for(int i = 0; i <= current_dimension(); i++) // for all neighbors of S
1296     if (opposite_simplex(S,i)->visited())
1297       // if the i - th neighbor has been visited
1298       clear_visited_marks(opposite_simplex(S,i));
1299       // clear its bit recursively
1300 }
1301 
1302 template <class R>
1303 std::list< typename Convex_hull_d<R>::Simplex_handle >
facets_visible_from(const Point_d & x)1304 Convex_hull_d<R>::facets_visible_from(const Point_d& x)
1305 {
1306   std::list<Simplex_handle> visible_simplices;
1307   int location = -1;                       // intialization is important
1308   std::size_t num_of_visited_simplices = 0;     // irrelevant
1309   Facet_handle f;                          // irrelevant
1310 
1311   visibility_search(origin_simplex_, x, visible_simplices,
1312                     num_of_visited_simplices, location, f);
1313   clear_visited_marks(origin_simplex_);
1314   return visible_simplices;
1315 }
1316 
1317 template <class R>
bounded_side(const Point_d & x)1318 Bounded_side Convex_hull_d<R>::bounded_side(const Point_d& x)
1319 {
1320   if ( is_dimension_jump(x) ) return ON_UNBOUNDED_SIDE;
1321   std::list<Simplex_handle> visible_simplices;
1322   int location = -1;                       // intialization is important
1323   std::size_t num_of_visited_simplices = 0;     // irrelevant
1324   Facet_handle f;
1325 
1326   visibility_search(origin_simplex_, x, visible_simplices,
1327                     num_of_visited_simplices, location, f);
1328   clear_visited_marks(origin_simplex_);
1329   switch (location) {
1330     case -1: return ON_BOUNDED_SIDE;
1331     case  0: return ON_BOUNDARY;
1332     case  1: return ON_UNBOUNDED_SIDE;
1333   }
1334   CGAL_error(); return ON_BOUNDARY; // never come here
1335 }
1336 
1337 
1338 template <class R>
1339 void Convex_hull_d<R>::
dimension_jump(Simplex_handle S,Vertex_handle x)1340 dimension_jump(Simplex_handle S, Vertex_handle x)
1341 {
1342   Simplex_handle S_new;
1343   S->visited() = true;
1344   associate_vertex_with_simplex(S,dcur,x);
1345   if ( !is_unbounded_simplex(S) ) { // S is bounded
1346     S_new = new_simplex();
1347     set_neighbor(S,dcur,S_new,0);
1348     associate_vertex_with_simplex(S_new,0,anti_origin_);
1349     for (int k = 1; k <= dcur; k++) {
1350       associate_vertex_with_simplex(S_new,k,vertex_of_simplex(S,k-1));
1351     }
1352 
1353   }
1354   /* visit unvisited neighbors 0 to dcur - 1 */
1355   for (int k = 0; k <= dcur - 1; k++) {
1356     if ( !opposite_simplex(S,k) -> visited() ) {
1357       dimension_jump(opposite_simplex(S,k), x);
1358     }
1359   }
1360   /* the recursive calls ensure that all neighbors exist */
1361   if ( is_unbounded_simplex(S) ) {
1362     set_neighbor(S,dcur,opposite_simplex(opposite_simplex(S,0),dcur),
1363                  index_of_vertex_in_opposite_simplex(S,0) + 1);
1364 
1365   } else {
1366     for (int k = 0; k < dcur; k++) {
1367       if ( is_unbounded_simplex(opposite_simplex(S,k)) ) {
1368         // if F' is unbounded
1369         set_neighbor(S_new,k + 1,opposite_simplex(S,k),dcur);
1370         // the neighbor of S_new opposite to v is S' and
1371         // x is in position dcur
1372       } else { // F' is bounded
1373         set_neighbor(S_new,k + 1,opposite_simplex(opposite_simplex(S,k),dcur),
1374                      index_of_vertex_in_opposite_simplex(S,k) + 1);
1375         // neighbor of S_new opposite to v is S_new'
1376         // the vertex opposite to v remains the same but ...
1377         // remember the shifting of the vertices one step to the right
1378       }
1379     }
1380 
1381   }
1382 }
1383 
1384 template <class R>
is_valid(bool throw_exceptions)1385 bool Convex_hull_d<R>::is_valid(bool throw_exceptions) const
1386 {
1387   this->check_topology();
1388   if (current_dimension() < 1) return true;
1389 
1390   /* Recall that center() gives us the center-point of the origin
1391      simplex. We check whether it is locally inside with respect to
1392      all hull facets.  */
1393 
1394   typename R::Oriented_side_d side =
1395     kernel().oriented_side_d_object();
1396   Point_d centerpoint = center();
1397   Simplex_const_iterator S;
1398   forall_rc_simplices(S,*this) {
1399     if ( is_unbounded_simplex(S) &&
1400          side(S->hyperplane_of_base_facet(),centerpoint) !=
1401          ON_NEGATIVE_SIDE) {
1402       if (throw_exceptions)
1403         throw chull_has_center_on_wrong_side_of_hull_facet();
1404       return false;
1405     }
1406   }
1407   /* next we check convexity at every ridge. Let |S| be any hull
1408      simplex and let |v| be any vertex of its base facet. The vertex
1409      opposite to |v| must not be on the positive side of the base
1410      facet.*/
1411 
1412   forall_rc_simplices(S,*this) {
1413     if ( is_unbounded_simplex(S) ) {
1414       for (int i = 1; i <= dcur; i++) {
1415         int k = index_of_vertex_in_opposite_simplex(S,i);
1416         if (side(S->hyperplane_of_base_facet(),
1417             point_of_simplex(opposite_simplex(S,i),k)) ==
1418             ON_POSITIVE_SIDE) {
1419           if (throw_exceptions)
1420             throw chull_has_local_non_convexity();
1421           return false;
1422         }
1423       }
1424     }
1425   }
1426 
1427   /* next we select one hull facet */
1428 
1429   Simplex_const_handle selected_hull_simplex;
1430   forall_rc_simplices(S,*this) {
1431     if ( is_unbounded_simplex(S) ) { selected_hull_simplex = S; break; }
1432   }
1433 
1434   /* we compute the center of gravity of the base facet of the
1435      hull simplex */
1436 
1437   typename R::Point_to_vector_d to_vector =
1438     kernel().point_to_vector_d_object();
1439   typename R::Vector_to_point_d to_point =
1440     kernel().vector_to_point_d_object();
1441   typename R::Construct_vector_d create =
1442     kernel().construct_vector_d_object();
1443   Vector_d center_of_hull_facet = create(dimension(),NULL_VECTOR);
1444   for (int i = 1; i <= current_dimension(); i++) {
1445     center_of_hull_facet = center_of_hull_facet +
1446     to_vector(point_of_simplex(selected_hull_simplex,i));
1447   }
1448   Point_d center_of_hull_facet_point =
1449     to_point(center_of_hull_facet/RT(dcur));
1450 
1451   /* we set up the ray from the center to the center of the hull facet */
1452 
1453   Ray_d l(centerpoint, center_of_hull_facet_point);
1454 
1455   /* and check whether it intersects the interior of any hull facet */
1456 
1457   typename R::Contained_in_simplex_d contained_in_simplex =
1458     kernel().contained_in_simplex_d_object();
1459   typename R::Intersect_d intersect =
1460     kernel().intersect_d_object();
1461 
1462   forall_rc_simplices(S,*this) {
1463     if ( is_unbounded_simplex(S) && S != selected_hull_simplex ) {
1464       Point_d p; Object op;
1465       Hyperplane_d  h = S->hyperplane_of_base_facet();
1466       if ( (op = intersect(l,h), assign(p,op)) ) {
1467         if ( contained_in_simplex(S->points_begin()+1,
1468                S->points_begin()+1+current_dimension(),p) ) {
1469           if ( throw_exceptions )
1470             throw chull_has_double_coverage();
1471           return false;
1472         }
1473       }
1474     }
1475   }
1476   return true;
1477 }
1478 
1479 template <class R>
1480 void Convex_hull_d<R>::
visible_facets_search(Simplex_handle S,const Point_d & x,std::list<Facet_handle> & VisibleFacets,std::size_t & num_of_visited_facets)1481 visible_facets_search(Simplex_handle S, const Point_d& x,
1482                       std::list< Facet_handle >& VisibleFacets,
1483                       std::size_t& num_of_visited_facets) const
1484 {
1485   ++num_of_visited_facets;
1486   S->visited() = true; // we have visited S and never come back ...
1487   for(int i = 1; i <= current_dimension(); ++i) {
1488     Simplex_handle T = opposite_simplex(S,i); // for all neighbors T of S
1489     if ( !T->visited() ) {
1490       typename R::Oriented_side_d side_of =
1491         kernel().oriented_side_d_object();
1492       int side = side_of(T->hyperplane_of_base_facet(),x);
1493       CGAL_assertion( is_unbounded_simplex(T) );
1494       if ( side == ON_POSITIVE_SIDE ) {
1495         VisibleFacets.push_back(T);
1496         visible_facets_search(T,x,VisibleFacets,num_of_visited_facets);
1497         // do the recursive search
1498       }
1499     } // end visited
1500   } // end for
1501 }
1502 
1503 
1504 
1505 
1506 } //namespace CGAL
1507 #endif // CGAL_CONVEX_HULL_D_H
1508