1 // Copyright (c) 1997
2 // Utrecht University (The Netherlands),
3 // ETH Zurich (Switzerland),
4 // INRIA Sophia-Antipolis (France),
5 // Max-Planck-Institute Saarbruecken (Germany),
6 // and Tel-Aviv University (Israel). All rights reserved.
7 //
8 // This file is part of CGAL (www.cgal.org)
9 //
10 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Generator/include/CGAL/point_generators_2.h $
11 // $Id: point_generators_2.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
12 // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
13 //
14 //
15 // Author(s) : Lutz Kettner <kettner@inf.ethz.ch>
16 // Pedro Machado Manhaes de Castro <pmmc@cin.ufpe.br>
17 // Alexandru Tifrea
18 // Maxime Gimeno
19
20
21 #ifndef CGAL_POINT_GENERATORS_2_H
22 #define CGAL_POINT_GENERATORS_2_H 1
23
24 #include <CGAL/disable_warnings.h>
25
26 #include <CGAL/generators.h>
27 #include <CGAL/number_type_basic.h>
28 #include <CGAL/internal/Generic_random_point_generator.h>
29 #include <CGAL/iterator.h>
30
31 #include <iterator>
32
33 namespace CGAL {
34
35 template < class P, class Creator =
36 Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P> >
37 class Random_points_in_disc_2 : public Random_generator_base<P>{
38 void generate_point();
39 public:
40 typedef Random_points_in_disc_2<P,Creator> This;
41 Random_points_in_disc_2( double r = 1, Random& rnd = CGAL::get_default_random())
42 // g is an input iterator creating points of type `P' uniformly
43 // distributed in the open disc with radius r, i.e. |`*g'| < r .
44 // Two random numbers are needed from `rnd' for each point.
45 : Random_generator_base<P>(r, rnd) { generate_point(); }
46 This& operator++() {
47 generate_point();
48 return *this;
49 }
50 This operator++(int) {
51 This tmp = *this;
52 ++(*this);
53 return tmp;
54 }
55 };
56
57 template < class P, class Creator >
58 void
59 Random_points_in_disc_2<P,Creator>::
generate_point()60 generate_point() {
61 typedef typename Creator::argument_type T;
62 double alpha = this->_rnd.get_double() * 2.0 * CGAL_PI;
63 double r = this->d_range * std::sqrt( this->_rnd.get_double());
64 Creator creator;
65 this->d_item = creator( T(r * std::cos(alpha)),
66 T(r * std::sin(alpha)));
67 }
68
69
70 template < class P, class Creator =
71 Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT, P> >
72 class Random_points_on_circle_2 : public Random_generator_base<P> {
73 void generate_point();
74 public:
75 typedef Random_points_on_circle_2<P,Creator> This;
76 Random_points_on_circle_2( double r = 1, Random& rnd = CGAL::get_default_random())
77 // g is an input iterator creating points of type `P' uniformly
78 // distributed on the circle with radius r, i.e. |`*g'| == r . A
79 // single random number is needed from `rnd' for each point.
80 : Random_generator_base<P>(r, rnd) { generate_point(); }
81 This& operator++() {
82 generate_point();
83 return *this;
84 }
85 This operator++(int) {
86 This tmp = *this;
87 ++(*this);
88 return tmp;
89 }
90 };
91
92 template < class P, class Creator >
93 void
94 Random_points_on_circle_2<P,Creator>::
generate_point()95 generate_point() {
96 typedef typename Creator::argument_type T;
97 double a = this->_rnd.get_double() * 2.0 * CGAL_PI;
98 Creator creator;
99 this->d_item = creator( T(this->d_range * std::cos(a)),
100 T(this->d_range * std::sin(a)));
101 }
102
103
104 template < class P, class Creator =
105 Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P> >
106 class Random_points_in_square_2 : public Random_generator_base<P> {
107 void generate_point();
108 public:
109 typedef Random_points_in_square_2<P,Creator> This;
110 Random_points_in_square_2( double a = 1, Random& rnd = CGAL::get_default_random())
111 // g is an input iterator creating points of type `P' uniformly
112 // distributed in the half-open square with side length a,
113 // centered around the origin, i.e. \forall p = `*g': -\frac{a}{2}
114 // <= p.x() < \frac{a}{2} and -\frac{a}{2} <= p.y() < \frac{a}{2}
115 // . Two random numbers are needed from `rnd' for each point.
116 : Random_generator_base<P>( a, rnd) { generate_point(); }
117 This& operator++() {
118 generate_point();
119 return *this;
120 }
121 This operator++(int) {
122 This tmp = *this;
123 ++(*this);
124 return tmp;
125 }
126 };
127
128 template < class P, class Creator >
129 void
130 Random_points_in_square_2<P,Creator>::
generate_point()131 generate_point() {
132 typedef typename Creator::argument_type T;
133 Creator creator;
134 this->d_item =
135 creator( T(this->d_range * (2 * this->_rnd.get_double() - 1.0)),
136 T(this->d_range * (2 * this->_rnd.get_double() - 1.0)));
137 }
138
139
140 template < class P, class Creator =
141 Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P> >
142 class Random_points_on_square_2 : public Random_generator_base<P> {
143 void generate_point();
144 public:
145 typedef Random_points_on_square_2<P,Creator> This;
146 Random_points_on_square_2( double a = 1, Random& rnd = CGAL::get_default_random())
147 // g is an input iterator creating points of type `P' uniformly
148 // distributed on the boundary of the square with side length a,
149 // centered around the origin, i.e. \forall p = `*g': one
150 // coordinate is either \frac{a}{2} or -\frac{a}{2} and for the
151 // other coordinate c holds -\frac{a}{2} <= c < \frac{a}{2} . A
152 // single random number is needed from `rnd' for each point.
153 : Random_generator_base<P>( a, rnd) { generate_point(); }
154 This& operator++() {
155 generate_point();
156 return *this;
157 }
158 This operator++(int) {
159 This tmp = *this;
160 ++(*this);
161 return tmp;
162 }
163 };
164
165 template < class P, class Creator >
166 void
167 Random_points_on_square_2<P,Creator>::
generate_point()168 generate_point() {
169 typedef typename Creator::argument_type T;
170 double d = this->_rnd.get_double() * 4.0;
171 int k = int(d);
172 d = this->d_range * (2 * (d - k) - 1.0);
173 CGAL_assertion( - this->d_range <= d && d < this->d_range);
174 Creator creator;
175 switch (k) {
176 case 0:
177 this->d_item = creator( T(d), T(-this->d_range));
178 break;
179 case 1:
180 this->d_item = creator( T(d), T(this->d_range));
181 break;
182 case 2:
183 this->d_item = creator( T(-this->d_range), T(d));
184 break;
185 case 3:
186 this->d_item = creator( T( this->d_range), T(d));
187 break;
188 default:
189 CGAL_assume(false);
190 }
191 }
192
193
194 template < class P, class Creator =
195 Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P> >
196 class Random_points_in_iso_rectangle_2 : public Random_generator_base<P> {
197 double left, right, top, bottom;
198 void generate_point();
199 public:
200 typedef Random_points_in_iso_rectangle_2<P,Creator> This;
201 Random_points_in_iso_rectangle_2( const P&p, const P& q, Random& rnd = CGAL::get_default_random())
202 : Random_generator_base<P>( 1.0 , rnd)
203 {
204 left = (std::min)(to_double(p.x()), to_double(q.x()));
205 right = (std::max)(to_double(p.x()), to_double(q.x()));
206 top = (std::min)(to_double(p.y()), to_double(q.y()));
207 bottom = (std::max)(to_double(p.y()), to_double(q.y()));
208 generate_point();
209 }
210
211 This& operator++() {
212 generate_point();
213 return *this;
214 }
215 This operator++(int) {
216 This tmp = *this;
217 ++(*this);
218 return tmp;
219 }
220 };
221
222 template < class P, class Creator >
223 void
224 Random_points_in_iso_rectangle_2<P,Creator>::
generate_point()225 generate_point() {
226 typedef typename Creator::argument_type T;
227 Creator creator;
228 this->d_item =
229 creator( T(this->_rnd.get_double(left,right)),
230 T(this->_rnd.get_double(top,bottom)));
231 }
232
233
234
235 template < class P, class Creator =
236 Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P> >
237 class Random_points_on_segment_2 : public Random_generator_base<P> {
238 P _p;
239 P _q;
240 void generate_point();
241 public:
242 typedef Random_points_on_segment_2<P,Creator> This;
243 Random_points_on_segment_2( const P& p = P( -1, 0),
244 const P& q = P( 1, 0),
245 Random& rnd = CGAL::get_default_random())
246 // g is an input iterator creating points of type `P' uniformly
247 // distributed on the segment from p to q except q, i.e. `*g' ==
248 // \lambda p + (1-\lambda)\, q where 0 <= \lambda < 1 . A single
249 // random number is needed from `rnd' for each point.
250 : Random_generator_base<P>( (std::max)( (std::max)( to_double(p.x()), to_double(q.x())),
251 (std::max)( to_double(p.y()),
252 to_double(q.y()))),
253 rnd) , _p(p), _q(q)
254 {
255 generate_point();
256 }
source()257 const P& source() const { return _p; }
target()258 const P& target() const { return _q; }
259 This& operator++() {
260 generate_point();
261 return *this;
262 }
263 This operator++(int) {
264 This tmp = *this;
265 ++(*this);
266 return tmp;
267 }
268 };
269
270 template < class P, class Creator >
271 void
272 Random_points_on_segment_2<P,Creator>::
generate_point()273 generate_point() {
274 typedef typename Creator::argument_type T;
275 double la = this->_rnd.get_double();
276 double mu = 1.0 - la;
277 Creator creator;
278 this->d_item = creator(T(mu * to_double(_p.x()) + la * to_double(_q.x())),
279 T(mu * to_double(_p.y()) + la * to_double(_q.y())));
280 }
281
282 template < class P >
283 class Points_on_segment_2 : public Generator_base<P> {
284 P _p;
285 P _q;
286 std::size_t d_i;
287 std::size_t d_mx;
288 void generate_point();
289 public:
290 typedef Points_on_segment_2<P> This;
Points_on_segment_2()291 Points_on_segment_2() {}
292 Points_on_segment_2( const P& p, const P& q,
293 std::size_t mx, std::size_t i = 0)
294 : Generator_base<P>( (std::max)( (std::max)( to_double(p.x()), to_double(q.x())),
295 (std::max)( to_double(p.y()), to_double(q.y())))),
296 _p(p), _q(q), d_i(i), d_mx(mx)
297 {
298 generate_point();
299 }
source()300 const P& source() const { return _p; }
target()301 const P& target() const { return _q; }
302 // Sufficient equality test.
303 bool operator==( const This& base) const { return ( d_i == base.d_i); }
304 bool operator!=( const This& base) const { return ! operator==(base); }
305 This& operator++() {
306 d_i++;
307 generate_point();
308 return *this;
309 }
310 This operator++(int) {
311 This tmp = *this;
312 ++(*this);
313 return tmp;
314 }
315 };
316
317 template < class P >
318 void
319 Points_on_segment_2<P>::
generate_point()320 generate_point() { this->d_item = _p + (_q-_p) * static_cast<double>(d_i) / (static_cast<double>(d_mx)-1); }
321
322 template <class OutputIterator, class Creator>
323 OutputIterator
points_on_square_grid_2(double a,std::size_t n,OutputIterator o,Creator creator)324 points_on_square_grid_2( double a, std::size_t n, OutputIterator o,
325 Creator creator)
326 {
327 typedef typename Creator::argument_type T;
328 if (n == 0)
329 return o;
330 int m = int(std::ceil(std::sqrt(static_cast<double>(n))));
331 double base = -a; // Left and bottom boundary.
332 double step = (2*a)/(m - 1);
333 int j = 0;
334 double px = base;
335 double py = base;
336 *o++ = creator( T(px), T(py));
337 for (std::size_t i = 1; i < n; i++) {
338 j++;
339 if ( j == m) {
340 px = base;
341 py = py + step;
342 j = 0;
343 } else {
344 px = px + step;
345 }
346 *o++ = creator( T(px), T(py));
347 }
348 return o;
349 }
350
351 template <class OutputIterator>
352 OutputIterator
points_on_square_grid_2(double a,std::size_t n,OutputIterator o)353 points_on_square_grid_2( double a, std::size_t n, OutputIterator o)
354 {
355 typedef std::iterator_traits<OutputIterator> ITraits;
356 typedef typename ITraits::value_type P;
357 return points_on_square_grid_2(a, n, o,
358 Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P>());
359 }
360
361 template <class P, class OutputIterator>
362 OutputIterator
points_on_segment_2(const P & p,const P & q,std::size_t n,OutputIterator o)363 points_on_segment_2( const P& p, const P& q, std::size_t n,
364 OutputIterator o)
365 // creates n points regular spaced on the segment from p to q, i.e.
366 // \forall i: 0 <= i < n: o[i] := \frac{n-i-1}{n-1} p + \frac{i}{n-1
367 // } q.
368 {
369 for (std::size_t i = 0; i < n; i++) {
370 *o++ = p + (q-p) * static_cast<typename Kernel_traits<P>::Kernel::FT>(static_cast<double>(i) / (static_cast<double>(n)-1));
371 }
372 return o;
373 }
374
375 template <class ForwardIterator, class Creator>
perturb_points_2(ForwardIterator first,ForwardIterator last,double xeps,double yeps,Random & rnd,Creator creator)376 void perturb_points_2( ForwardIterator first,
377 ForwardIterator last,
378 double xeps,
379 double yeps,
380 Random& rnd,
381 Creator creator)
382 // perturbs the points in the range [`first',`last') by replacing
383 // each point with a random point from the rectangle `xeps' \times
384 // `yeps' centered around the original point. Two random numbers are
385 // needed from `rnd' for each point. Precondition:
386 // The expression `to_double((*first).x())' and `to_double((
387 // *begin).y())' must be legal.
388 {
389 typedef typename Creator::argument_type T;
390 xeps *= 2.0;
391 yeps *= 2.0;
392 for ( ; first != last; ++first) {
393 double x = to_double( (*first).x());
394 double y = to_double( (*first).y());
395 x += xeps * (rnd.get_double() - 0.5);
396 y += yeps * (rnd.get_double() - 0.5);
397 *first = creator( T(x), T(y));
398 }
399 }
400
401 template <class ForwardIterator>
perturb_points_2(ForwardIterator first,ForwardIterator last,double xeps,double yeps,Random & rnd)402 void perturb_points_2( ForwardIterator first,
403 ForwardIterator last,
404 double xeps,
405 double yeps,
406 Random& rnd)
407 {
408 typedef std::iterator_traits<ForwardIterator> ITraits;
409 typedef typename ITraits::value_type P;
410 perturb_points_2( first, last, xeps, yeps, rnd,
411 Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P>());
412 }
413
414 template <class ForwardIterator>
415 inline
perturb_points_2(ForwardIterator first,ForwardIterator last,double xeps,Random & rnd)416 void perturb_points_2( ForwardIterator first,
417 ForwardIterator last,
418 double xeps,
419 Random& rnd)
420 {
421 perturb_points_2( first, last, xeps, xeps, rnd);
422 }
423
424 template <class ForwardIterator>
perturb_points_2(ForwardIterator first,ForwardIterator last,double xeps,double yeps)425 void perturb_points_2( ForwardIterator first,
426 ForwardIterator last,
427 double xeps,
428 double yeps)
429 {
430 perturb_points_2( first, last, xeps, yeps, CGAL::get_default_random());
431 }
432
433 template <class ForwardIterator>
perturb_points_2(ForwardIterator first,ForwardIterator last,double xeps)434 void perturb_points_2( ForwardIterator first,
435 ForwardIterator last,
436 double xeps)
437 {
438 perturb_points_2( first, last, xeps, xeps, CGAL::get_default_random());
439 }
440 template <class RandomAccessIterator, class OutputIterator, class Creator>
random_collinear_points_2(RandomAccessIterator first,RandomAccessIterator last,std::size_t n,OutputIterator first2,Random & rnd,Creator creator)441 OutputIterator random_collinear_points_2(
442 RandomAccessIterator first,
443 RandomAccessIterator last,
444 std::size_t n,
445 OutputIterator first2,
446 Random& rnd,
447 Creator creator)
448 {
449 typedef typename Creator::result_type Point;
450 typedef typename Creator::argument_type T;
451
452 std::ptrdiff_t m = last - first;
453 for ( std::size_t i = 0; i < n; i++) {
454 const Point& p = first[ rnd.uniform_int<std::ptrdiff_t>( 0, m-1)];
455 const Point& q = first[ rnd.uniform_int<std::ptrdiff_t>( 0, m-1)];
456 double la = rnd.get_double();
457 double mu = 1.0 - la;
458 *first2++ = creator(T(mu * to_double(p.x()) +
459 la * to_double(q.x())),
460 T(mu * to_double(p.y()) +
461 la * to_double(q.y())));
462 }
463 return first2;
464 }
465
466 template <class RandomAccessIterator, class OutputIterator>
random_collinear_points_2(RandomAccessIterator first,RandomAccessIterator last,std::size_t n,OutputIterator first2,Random & rnd)467 OutputIterator random_collinear_points_2(
468 RandomAccessIterator first,
469 RandomAccessIterator last,
470 std::size_t n,
471 OutputIterator first2,
472 Random& rnd)
473 // choose two random points from the range [`first',`last'), create a
474 // random third point on the segment connecting this two points, and
475 // write it to `first2'. Repeat this n times, thus writing n points to
476 // `first2' that are collinear with points in the range [`first',
477 // `last'). Three random numbers are needed from `rnd' for each point.
478 // Returns the value of `first2' after inserting the n points.
479 // Precondition: The expression `to_double((*first).x()
480 // )' and `to_double((*first).y())' must be legal.
481 {
482 typedef std::iterator_traits<RandomAccessIterator> ITraits;
483 typedef typename ITraits::value_type P;
484 return random_collinear_points_2( first, last, n, first2, rnd,
485 Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P>());
486 }
487
488 template <class RandomAccessIterator, class OutputIterator>
random_collinear_points_2(RandomAccessIterator first,RandomAccessIterator last,std::size_t n,OutputIterator first2)489 OutputIterator random_collinear_points_2(
490 RandomAccessIterator first,
491 RandomAccessIterator last,
492 std::size_t n,
493 OutputIterator first2)
494 {
495 return random_collinear_points_2( first, last, n, first2,
496 CGAL::get_default_random());
497 }
498
499 template < class P, class Creator =
500 Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P> >
501 class Random_points_in_triangle_2 : public Random_generator_base<P> {
502 P _p,_q,_r;
503 void generate_point();
504 public:
505 typedef P result_type;
506 typedef Random_points_in_triangle_2<P, Creator> This;
507 typedef typename Kernel_traits<P>::Kernel::Triangle_2 Triangle_2;
Random_points_in_triangle_2()508 Random_points_in_triangle_2() {}
Random_points_in_triangle_2(const This & x,Random & rnd)509 Random_points_in_triangle_2( const This& x,Random& rnd)
510 : Random_generator_base<P>( 1, rnd ),_p(x._p),_q(x._q),_r(x._r) {
511 generate_point();
512 }
513 Random_points_in_triangle_2( const P& p, const P& q, const P& r, Random& rnd = get_default_random())
514 : Random_generator_base<P>( 1, rnd ),_p(p),_q(q),_r(r) {
515 generate_point();
516 }
517 Random_points_in_triangle_2( const Triangle_2& triangle,Random& rnd = get_default_random())
518 : Random_generator_base<P>( 1,
519 rnd),_p(triangle[0]),_q(triangle[1]),_r(triangle[2]) {
520 generate_point();
521 }
522 This& operator++() {
523 generate_point();
524 return *this;
525 }
526 This operator++(int) {
527 This tmp = *this;
528 ++(*this);
529 return tmp;
530 }
531 };
532
533 template<class P, class Creator >
generate_point()534 void Random_points_in_triangle_2<P, Creator>::generate_point() {
535 typedef typename Creator::argument_type T;
536 Creator creator;
537 double a1 = this->_rnd.get_double(0,1);
538 double a2 = this->_rnd.get_double(0,1);
539 if(a1>a2) std::swap(a1,a2);
540 double b1 = a1;
541 double b2 = a2-a1;
542 double b3 = 1.0-a2;
543 this->d_item = creator(T(to_double(_p.x())*b1+to_double(_q.x())*b2+to_double(_r.x())*b3),
544 T(to_double(_p.y())*b1+to_double(_q.y())*b2+to_double(_r.y())*b3));
545 }
546
547 namespace internal {
548
549 //Functor returning Triangle_2 from Triangulation_2 Faces
550 template <class T>
551 class Triangle_from_face_2
552 {
553 typedef typename T::Triangle Triangle;
554 public:
555 typedef Triangle result_type;
Triangle_from_face_2()556 Triangle_from_face_2() {}
557
operator()558 Triangle operator()(typename T::Finite_faces_iterator face) const {
559 return Triangle(face->vertex(0)->point(), face->vertex(1)->point(), face->vertex(2)->point());
560 }
561 };
562
563 struct Is_not_in_domain
564 {
565 typedef bool result_type;
566
567 template <class FH>
operatorIs_not_in_domain568 result_type operator()(const FH fh) const {
569 return (!fh->is_in_domain());
570 }
571 };
572
573 template <class T>
574 class In_domain_finite_faces_iterator
575 : public Filter_iterator<typename T::Finite_faces_iterator, Is_not_in_domain>
576 {
577 typedef CGAL::Filter_iterator<typename T::Finite_faces_iterator, Is_not_in_domain> Base;
578 typedef In_domain_finite_faces_iterator<T> Self;
579
580 typedef typename T::Face_handle Face_handle;
581 typedef typename T::Finite_faces_iterator Finite_faces_iterator;
582
583 public:
In_domain_finite_faces_iterator()584 In_domain_finite_faces_iterator() : Base() {}
In_domain_finite_faces_iterator(const Base & b)585 In_domain_finite_faces_iterator(const Base &b) : Base(b) {}
586 Self & operator++() { Base::operator++(); return *this; }
587 Self & operator--() { Base::operator--(); return *this; }
588 Self operator++(int) { Self tmp(*this); ++(*this); return tmp; }
589 Self operator--(int) { Self tmp(*this); --(*this); return tmp; }
Finite_faces_iterator()590 operator Finite_faces_iterator() const { return Base::base(); }
Face_handle()591 operator Face_handle() const { return Face_handle(Base::base()); }
592 };
593
594 }//end namespace internal
595
596 template <class P,
597 class T,
598 class Creator = Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT, P> >
599 class Random_points_in_triangle_mesh_2
600 : public Generic_random_point_generator<internal::In_domain_finite_faces_iterator<T>,
601 internal::Triangle_from_face_2<T>,
602 Random_points_in_triangle_2<P, Creator>,
603 P>
604 {
605 public:
606 typedef Generic_random_point_generator<internal::In_domain_finite_faces_iterator<T>,
607 internal::Triangle_from_face_2<T>,
608 Random_points_in_triangle_2<P, Creator>,
609 P> Base;
610 typedef typename T::Face_handle Id;
611 typedef P result_type;
612 typedef Random_points_in_triangle_mesh_2<P, T, Creator> This;
613
614 Random_points_in_triangle_mesh_2(const T& triangulation, Random& rnd = get_default_random())
615 : Base(CGAL::make_prevent_deref_range(
616 CGAL::filter_iterator(triangulation.finite_faces_end(),
617 internal::Is_not_in_domain(),
618 triangulation.finite_faces_begin()),
619 CGAL::filter_iterator(triangulation.finite_faces_end(),
620 internal::Is_not_in_domain())),
621 internal::Triangle_from_face_2<T>(),
622 typename Kernel_traits<P>::Kernel::Compute_area_2(),
623 rnd)
624 {
625 }
626
627 This& operator++() {
628 Base::generate_point();
629 return *this;
630 }
631 This operator++(int) {
632 This tmp = *this;
633 ++(*this);
634 return tmp;
635 }
636 };
637
638 namespace internal
639 {
640
641 template<class T>
642 class Deref
643 {
644 public:
645 typedef const T& result_type;
operator()646 const T& operator()(const T* triangle) const
647 {
648 return *triangle;
649 }
650 };
651
652 template<class A>
653 struct Address_of {
654 typedef const A* result_type;
operatorAddress_of655 const A* operator()(const A& a) const
656 {
657 return &a;
658 }
659 };
660
661 }//namesapce internal
662
663 template <class Point_2,
664 class Triangle_2=typename Kernel_traits<Point_2>::Kernel::Triangle_2,
665 class Creator =
666 Creator_uniform_2<typename Kernel_traits<Point_2>::Kernel::RT,Point_2> >
667 struct Random_points_in_triangles_2
668 : public Generic_random_point_generator<const Triangle_2*,
669 internal::Deref<Triangle_2>,
670 Random_points_in_triangle_2<Point_2>,
671 Point_2>
672 {
673 typedef Generic_random_point_generator<const Triangle_2*,
674 internal::Deref<Triangle_2>,
675 Random_points_in_triangle_2<Point_2, Creator>,
676 Point_2> Base;
677 typedef const Triangle_2* Id;
678 typedef Point_2 result_type;
679 typedef Random_points_in_triangles_2<Point_2, Triangle_2, Creator> This;
680
681 template<typename TriangleRange>
682 Random_points_in_triangles_2( const TriangleRange& triangles, Random& rnd = get_default_random())
683 : Base(make_range( boost::make_transform_iterator(triangles.begin(), internal::Address_of<Triangle_2>()),
684 boost::make_transform_iterator(triangles.end(), internal::Address_of<Triangle_2>()) ),
685 internal::Deref<Triangle_2>(),
686 typename Kernel_traits<Point_2>::Kernel::Compute_area_2(),
687 rnd )
688 {
689 }
690 This& operator++() {
691 Base::generate_point();
692 return *this;
693 }
694 This operator++(int) {
695 This tmp = *this;
696 ++(*this);
697 return tmp;
698 }
699 };
700
701 } //namespace CGAL
702 #include <CGAL/enable_warnings.h>
703
704 #endif // CGAL_POINT_GENERATORS_2_H //
705 // EOF //
706