713 lines
24 KiB
C
713 lines
24 KiB
C
|
// Copyright (c) 1997
|
||
|
// Utrecht University (The Netherlands),
|
||
|
// ETH Zurich (Switzerland),
|
||
|
// INRIA Sophia-Antipolis (France),
|
||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||
|
//
|
||
|
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||
|
// modify it under the terms of the GNU Lesser General Public License as
|
||
|
// published by the Free Software Foundation; either version 3 of the License,
|
||
|
// or (at your option) any later version.
|
||
|
//
|
||
|
// 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$
|
||
|
// SPDX-License-Identifier: LGPL-3.0+
|
||
|
//
|
||
|
//
|
||
|
// Author(s) : Lutz Kettner <kettner@inf.ethz.ch>
|
||
|
// Pedro Machado Manhaes de Castro <pmmc@cin.ufpe.br>
|
||
|
// Alexandru Tifrea
|
||
|
// Maxime Gimeno
|
||
|
|
||
|
|
||
|
#ifndef CGAL_POINT_GENERATORS_2_H
|
||
|
#define CGAL_POINT_GENERATORS_2_H 1
|
||
|
|
||
|
#include <CGAL/disable_warnings.h>
|
||
|
|
||
|
#include <CGAL/generators.h>
|
||
|
#include <CGAL/number_type_basic.h>
|
||
|
#include <CGAL/internal/Generic_random_point_generator.h>
|
||
|
#include <CGAL/iterator.h>
|
||
|
|
||
|
#include <iterator>
|
||
|
|
||
|
namespace CGAL {
|
||
|
|
||
|
template < class P, class Creator =
|
||
|
Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P> >
|
||
|
class Random_points_in_disc_2 : public Random_generator_base<P>{
|
||
|
void generate_point();
|
||
|
public:
|
||
|
typedef Random_points_in_disc_2<P,Creator> This;
|
||
|
Random_points_in_disc_2( double r = 1, Random& rnd = CGAL::get_default_random())
|
||
|
// g is an input iterator creating points of type `P' uniformly
|
||
|
// distributed in the open disc with radius r, i.e. |`*g'| < r .
|
||
|
// Two random numbers are needed from `rnd' for each point.
|
||
|
: Random_generator_base<P>(r, rnd) { generate_point(); }
|
||
|
This& operator++() {
|
||
|
generate_point();
|
||
|
return *this;
|
||
|
}
|
||
|
This operator++(int) {
|
||
|
This tmp = *this;
|
||
|
++(*this);
|
||
|
return tmp;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template < class P, class Creator >
|
||
|
void
|
||
|
Random_points_in_disc_2<P,Creator>::
|
||
|
generate_point() {
|
||
|
typedef typename Creator::argument_type T;
|
||
|
double alpha = this->_rnd.get_double() * 2.0 * CGAL_PI;
|
||
|
double r = this->d_range * std::sqrt( this->_rnd.get_double());
|
||
|
Creator creator;
|
||
|
this->d_item = creator( T(r * std::cos(alpha)),
|
||
|
T(r * std::sin(alpha)));
|
||
|
}
|
||
|
|
||
|
|
||
|
template < class P, class Creator =
|
||
|
Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT, P> >
|
||
|
class Random_points_on_circle_2 : public Random_generator_base<P> {
|
||
|
void generate_point();
|
||
|
public:
|
||
|
typedef Random_points_on_circle_2<P,Creator> This;
|
||
|
Random_points_on_circle_2( double r = 1, Random& rnd = CGAL::get_default_random())
|
||
|
// g is an input iterator creating points of type `P' uniformly
|
||
|
// distributed on the circle with radius r, i.e. |`*g'| == r . A
|
||
|
// single random number is needed from `rnd' for each point.
|
||
|
: Random_generator_base<P>(r, rnd) { generate_point(); }
|
||
|
This& operator++() {
|
||
|
generate_point();
|
||
|
return *this;
|
||
|
}
|
||
|
This operator++(int) {
|
||
|
This tmp = *this;
|
||
|
++(*this);
|
||
|
return tmp;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template < class P, class Creator >
|
||
|
void
|
||
|
Random_points_on_circle_2<P,Creator>::
|
||
|
generate_point() {
|
||
|
typedef typename Creator::argument_type T;
|
||
|
double a = this->_rnd.get_double() * 2.0 * CGAL_PI;
|
||
|
Creator creator;
|
||
|
this->d_item = creator( T(this->d_range * std::cos(a)),
|
||
|
T(this->d_range * std::sin(a)));
|
||
|
}
|
||
|
|
||
|
|
||
|
template < class P, class Creator =
|
||
|
Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P> >
|
||
|
class Random_points_in_square_2 : public Random_generator_base<P> {
|
||
|
void generate_point();
|
||
|
public:
|
||
|
typedef Random_points_in_square_2<P,Creator> This;
|
||
|
Random_points_in_square_2( double a = 1, Random& rnd = CGAL::get_default_random())
|
||
|
// g is an input iterator creating points of type `P' uniformly
|
||
|
// distributed in the half-open square with side length a,
|
||
|
// centered around the origin, i.e. \forall p = `*g': -\frac{a}{2}
|
||
|
// <= p.x() < \frac{a}{2} and -\frac{a}{2} <= p.y() < \frac{a}{2}
|
||
|
// . Two random numbers are needed from `rnd' for each point.
|
||
|
: Random_generator_base<P>( a, rnd) { generate_point(); }
|
||
|
This& operator++() {
|
||
|
generate_point();
|
||
|
return *this;
|
||
|
}
|
||
|
This operator++(int) {
|
||
|
This tmp = *this;
|
||
|
++(*this);
|
||
|
return tmp;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template < class P, class Creator >
|
||
|
void
|
||
|
Random_points_in_square_2<P,Creator>::
|
||
|
generate_point() {
|
||
|
typedef typename Creator::argument_type T;
|
||
|
Creator creator;
|
||
|
this->d_item =
|
||
|
creator( T(this->d_range * (2 * this->_rnd.get_double() - 1.0)),
|
||
|
T(this->d_range * (2 * this->_rnd.get_double() - 1.0)));
|
||
|
}
|
||
|
|
||
|
|
||
|
template < class P, class Creator =
|
||
|
Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P> >
|
||
|
class Random_points_on_square_2 : public Random_generator_base<P> {
|
||
|
void generate_point();
|
||
|
public:
|
||
|
typedef Random_points_on_square_2<P,Creator> This;
|
||
|
Random_points_on_square_2( double a = 1, Random& rnd = CGAL::get_default_random())
|
||
|
// g is an input iterator creating points of type `P' uniformly
|
||
|
// distributed on the boundary of the square with side length a,
|
||
|
// centered around the origin, i.e. \forall p = `*g': one
|
||
|
// coordinate is either \frac{a}{2} or -\frac{a}{2} and for the
|
||
|
// other coordinate c holds -\frac{a}{2} <= c < \frac{a}{2} . A
|
||
|
// single random number is needed from `rnd' for each point.
|
||
|
: Random_generator_base<P>( a, rnd) { generate_point(); }
|
||
|
This& operator++() {
|
||
|
generate_point();
|
||
|
return *this;
|
||
|
}
|
||
|
This operator++(int) {
|
||
|
This tmp = *this;
|
||
|
++(*this);
|
||
|
return tmp;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template < class P, class Creator >
|
||
|
void
|
||
|
Random_points_on_square_2<P,Creator>::
|
||
|
generate_point() {
|
||
|
typedef typename Creator::argument_type T;
|
||
|
double d = this->_rnd.get_double() * 4.0;
|
||
|
int k = int(d);
|
||
|
d = this->d_range * (2 * (d - k) - 1.0);
|
||
|
CGAL_assertion( - this->d_range <= d && d < this->d_range);
|
||
|
Creator creator;
|
||
|
switch (k) {
|
||
|
case 0:
|
||
|
this->d_item = creator( T(d), T(-this->d_range));
|
||
|
break;
|
||
|
case 1:
|
||
|
this->d_item = creator( T(d), T(this->d_range));
|
||
|
break;
|
||
|
case 2:
|
||
|
this->d_item = creator( T(-this->d_range), T(d));
|
||
|
break;
|
||
|
case 3:
|
||
|
this->d_item = creator( T( this->d_range), T(d));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
template < class P, class Creator =
|
||
|
Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P> >
|
||
|
class Random_points_in_iso_rectangle_2 : public Random_generator_base<P> {
|
||
|
double left, right, top, bottom;
|
||
|
void generate_point();
|
||
|
public:
|
||
|
typedef Random_points_in_iso_rectangle_2<P,Creator> This;
|
||
|
Random_points_in_iso_rectangle_2( const P&p, const P& q, Random& rnd = CGAL::get_default_random())
|
||
|
: Random_generator_base<P>( 1.0 , rnd)
|
||
|
{
|
||
|
left = (std::min)(to_double(p.x()), to_double(q.x()));
|
||
|
right = (std::max)(to_double(p.x()), to_double(q.x()));
|
||
|
top = (std::min)(to_double(p.y()), to_double(q.y()));
|
||
|
bottom = (std::max)(to_double(p.y()), to_double(q.y()));
|
||
|
generate_point();
|
||
|
}
|
||
|
|
||
|
This& operator++() {
|
||
|
generate_point();
|
||
|
return *this;
|
||
|
}
|
||
|
This operator++(int) {
|
||
|
This tmp = *this;
|
||
|
++(*this);
|
||
|
return tmp;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template < class P, class Creator >
|
||
|
void
|
||
|
Random_points_in_iso_rectangle_2<P,Creator>::
|
||
|
generate_point() {
|
||
|
typedef typename Creator::argument_type T;
|
||
|
Creator creator;
|
||
|
this->d_item =
|
||
|
creator( T(this->_rnd.get_double(left,right)),
|
||
|
T(this->_rnd.get_double(top,bottom)));
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
template < class P, class Creator =
|
||
|
Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P> >
|
||
|
class Random_points_on_segment_2 : public Random_generator_base<P> {
|
||
|
P _p;
|
||
|
P _q;
|
||
|
void generate_point();
|
||
|
public:
|
||
|
typedef Random_points_on_segment_2<P,Creator> This;
|
||
|
Random_points_on_segment_2( const P& p = P( -1, 0),
|
||
|
const P& q = P( 1, 0),
|
||
|
Random& rnd = CGAL::get_default_random())
|
||
|
// g is an input iterator creating points of type `P' uniformly
|
||
|
// distributed on the segment from p to q except q, i.e. `*g' ==
|
||
|
// \lambda p + (1-\lambda)\, q where 0 <= \lambda < 1 . A single
|
||
|
// random number is needed from `rnd' for each point.
|
||
|
: Random_generator_base<P>( (std::max)( (std::max)( to_double(p.x()), to_double(q.x())),
|
||
|
(std::max)( to_double(p.y()),
|
||
|
to_double(q.y()))),
|
||
|
rnd) , _p(p), _q(q)
|
||
|
{
|
||
|
generate_point();
|
||
|
}
|
||
|
const P& source() const { return _p; }
|
||
|
const P& target() const { return _q; }
|
||
|
This& operator++() {
|
||
|
generate_point();
|
||
|
return *this;
|
||
|
}
|
||
|
This operator++(int) {
|
||
|
This tmp = *this;
|
||
|
++(*this);
|
||
|
return tmp;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template < class P, class Creator >
|
||
|
void
|
||
|
Random_points_on_segment_2<P,Creator>::
|
||
|
generate_point() {
|
||
|
typedef typename Creator::argument_type T;
|
||
|
double la = this->_rnd.get_double();
|
||
|
double mu = 1.0 - la;
|
||
|
Creator creator;
|
||
|
this->d_item = creator(T(mu * to_double(_p.x()) + la * to_double(_q.x())),
|
||
|
T(mu * to_double(_p.y()) + la * to_double(_q.y())));
|
||
|
}
|
||
|
|
||
|
template < class P >
|
||
|
class Points_on_segment_2 : public Generator_base<P> {
|
||
|
P _p;
|
||
|
P _q;
|
||
|
std::size_t d_i;
|
||
|
std::size_t d_mx;
|
||
|
void generate_point();
|
||
|
public:
|
||
|
typedef Points_on_segment_2<P> This;
|
||
|
Points_on_segment_2() {}
|
||
|
Points_on_segment_2( const P& p, const P& q,
|
||
|
std::size_t mx, std::size_t i = 0)
|
||
|
: Generator_base<P>( (std::max)( (std::max)( to_double(p.x()), to_double(q.x())),
|
||
|
(std::max)( to_double(p.y()), to_double(q.y())))),
|
||
|
_p(p), _q(q), d_i(i), d_mx(mx)
|
||
|
{
|
||
|
generate_point();
|
||
|
}
|
||
|
const P& source() const { return _p; }
|
||
|
const P& target() const { return _q; }
|
||
|
// Sufficient equality test.
|
||
|
bool operator==( const This& base) const { return ( d_i == base.d_i); }
|
||
|
bool operator!=( const This& base) const { return ! operator==(base); }
|
||
|
This& operator++() {
|
||
|
d_i++;
|
||
|
generate_point();
|
||
|
return *this;
|
||
|
}
|
||
|
This operator++(int) {
|
||
|
This tmp = *this;
|
||
|
++(*this);
|
||
|
return tmp;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template < class P >
|
||
|
void
|
||
|
Points_on_segment_2<P>::
|
||
|
generate_point() { this->d_item = _p + (_q-_p) * static_cast<double>(d_i) / (static_cast<double>(d_mx)-1); }
|
||
|
|
||
|
template <class OutputIterator, class Creator>
|
||
|
OutputIterator
|
||
|
points_on_square_grid_2( double a, std::size_t n, OutputIterator o,
|
||
|
Creator creator)
|
||
|
{
|
||
|
typedef typename Creator::argument_type T;
|
||
|
if (n == 0)
|
||
|
return o;
|
||
|
int m = int(std::ceil(std::sqrt(static_cast<double>(n))));
|
||
|
double base = -a; // Left and bottom boundary.
|
||
|
double step = (2*a)/(m - 1);
|
||
|
int j = 0;
|
||
|
double px = base;
|
||
|
double py = base;
|
||
|
*o++ = creator( T(px), T(py));
|
||
|
for (std::size_t i = 1; i < n; i++) {
|
||
|
j++;
|
||
|
if ( j == m) {
|
||
|
px = base;
|
||
|
py = py + step;
|
||
|
j = 0;
|
||
|
} else {
|
||
|
px = px + step;
|
||
|
}
|
||
|
*o++ = creator( T(px), T(py));
|
||
|
}
|
||
|
return o;
|
||
|
}
|
||
|
|
||
|
template <class OutputIterator>
|
||
|
OutputIterator
|
||
|
points_on_square_grid_2( double a, std::size_t n, OutputIterator o)
|
||
|
{
|
||
|
typedef std::iterator_traits<OutputIterator> ITraits;
|
||
|
typedef typename ITraits::value_type P;
|
||
|
return points_on_square_grid_2(a, n, o,
|
||
|
Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P>());
|
||
|
}
|
||
|
|
||
|
template <class P, class OutputIterator>
|
||
|
OutputIterator
|
||
|
points_on_segment_2( const P& p, const P& q, std::size_t n,
|
||
|
OutputIterator o)
|
||
|
// creates n points regular spaced on the segment from p to q, i.e.
|
||
|
// \forall i: 0 <= i < n: o[i] := \frac{n-i-1}{n-1} p + \frac{i}{n-1
|
||
|
// } q.
|
||
|
{
|
||
|
for (std::size_t i = 0; i < n; i++) {
|
||
|
*o++ = p + (q-p) * static_cast<typename Kernel_traits<P>::Kernel::FT>(static_cast<double>(i) / (static_cast<double>(n)-1));
|
||
|
}
|
||
|
return o;
|
||
|
}
|
||
|
|
||
|
template <class ForwardIterator, class Creator>
|
||
|
void perturb_points_2( ForwardIterator first,
|
||
|
ForwardIterator last,
|
||
|
double xeps,
|
||
|
double yeps,
|
||
|
Random& rnd,
|
||
|
Creator creator)
|
||
|
// perturbs the points in the range [`first',`last') by replacing
|
||
|
// each point with a random point from the rectangle `xeps' \times
|
||
|
// `yeps' centered around the original point. Two random numbers are
|
||
|
// needed from `rnd' for each point. Precondition:
|
||
|
// The expression `to_double((*first).x())' and `to_double((
|
||
|
// *begin).y())' must be legal.
|
||
|
{
|
||
|
typedef typename Creator::argument_type T;
|
||
|
xeps *= 2.0;
|
||
|
yeps *= 2.0;
|
||
|
for ( ; first != last; ++first) {
|
||
|
double x = to_double( (*first).x());
|
||
|
double y = to_double( (*first).y());
|
||
|
x += xeps * (rnd.get_double() - 0.5);
|
||
|
y += yeps * (rnd.get_double() - 0.5);
|
||
|
*first = creator( T(x), T(y));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
template <class ForwardIterator>
|
||
|
void perturb_points_2( ForwardIterator first,
|
||
|
ForwardIterator last,
|
||
|
double xeps,
|
||
|
double yeps,
|
||
|
Random& rnd)
|
||
|
{
|
||
|
typedef std::iterator_traits<ForwardIterator> ITraits;
|
||
|
typedef typename ITraits::value_type P;
|
||
|
perturb_points_2( first, last, xeps, yeps, rnd,
|
||
|
Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P>());
|
||
|
}
|
||
|
|
||
|
template <class ForwardIterator>
|
||
|
inline
|
||
|
void perturb_points_2( ForwardIterator first,
|
||
|
ForwardIterator last,
|
||
|
double xeps,
|
||
|
Random& rnd)
|
||
|
{
|
||
|
perturb_points_2( first, last, xeps, xeps, rnd);
|
||
|
}
|
||
|
|
||
|
template <class ForwardIterator>
|
||
|
void perturb_points_2( ForwardIterator first,
|
||
|
ForwardIterator last,
|
||
|
double xeps,
|
||
|
double yeps)
|
||
|
{
|
||
|
perturb_points_2( first, last, xeps, yeps, CGAL::get_default_random());
|
||
|
}
|
||
|
|
||
|
template <class ForwardIterator>
|
||
|
void perturb_points_2( ForwardIterator first,
|
||
|
ForwardIterator last,
|
||
|
double xeps)
|
||
|
{
|
||
|
perturb_points_2( first, last, xeps, xeps, CGAL::get_default_random());
|
||
|
}
|
||
|
template <class RandomAccessIterator, class OutputIterator, class Creator>
|
||
|
OutputIterator random_collinear_points_2(
|
||
|
RandomAccessIterator first,
|
||
|
RandomAccessIterator last,
|
||
|
std::size_t n,
|
||
|
OutputIterator first2,
|
||
|
Random& rnd,
|
||
|
Creator creator)
|
||
|
{
|
||
|
typedef typename Creator::result_type Point;
|
||
|
typedef typename Creator::argument_type T;
|
||
|
|
||
|
std::ptrdiff_t m = last - first;
|
||
|
for ( std::size_t i = 0; i < n; i++) {
|
||
|
const Point& p = first[ rnd.uniform_int<std::ptrdiff_t>( 0, m-1)];
|
||
|
const Point& q = first[ rnd.uniform_int<std::ptrdiff_t>( 0, m-1)];
|
||
|
double la = rnd.get_double();
|
||
|
double mu = 1.0 - la;
|
||
|
*first2++ = creator(T(mu * to_double(p.x()) +
|
||
|
la * to_double(q.x())),
|
||
|
T(mu * to_double(p.y()) +
|
||
|
la * to_double(q.y())));
|
||
|
}
|
||
|
return first2;
|
||
|
}
|
||
|
|
||
|
template <class RandomAccessIterator, class OutputIterator>
|
||
|
OutputIterator random_collinear_points_2(
|
||
|
RandomAccessIterator first,
|
||
|
RandomAccessIterator last,
|
||
|
std::size_t n,
|
||
|
OutputIterator first2,
|
||
|
Random& rnd)
|
||
|
// choose two random points from the range [`first',`last'), create a
|
||
|
// random third point on the segment connecting this two points, and
|
||
|
// write it to `first2'. Repeat this n times, thus writing n points to
|
||
|
// `first2' that are collinear with points in the range [`first',
|
||
|
// `last'). Three random numbers are needed from `rnd' for each point.
|
||
|
// Returns the value of `first2' after inserting the n points.
|
||
|
// Precondition: The expression `to_double((*first).x()
|
||
|
// )' and `to_double((*first).y())' must be legal.
|
||
|
{
|
||
|
typedef std::iterator_traits<RandomAccessIterator> ITraits;
|
||
|
typedef typename ITraits::value_type P;
|
||
|
return random_collinear_points_2( first, last, n, first2, rnd,
|
||
|
Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P>());
|
||
|
}
|
||
|
|
||
|
template <class RandomAccessIterator, class OutputIterator>
|
||
|
OutputIterator random_collinear_points_2(
|
||
|
RandomAccessIterator first,
|
||
|
RandomAccessIterator last,
|
||
|
std::size_t n,
|
||
|
OutputIterator first2)
|
||
|
{
|
||
|
return random_collinear_points_2( first, last, n, first2,
|
||
|
CGAL::get_default_random());
|
||
|
}
|
||
|
|
||
|
template < class P, class Creator =
|
||
|
Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT,P> >
|
||
|
class Random_points_in_triangle_2 : public Random_generator_base<P> {
|
||
|
P _p,_q,_r;
|
||
|
void generate_point();
|
||
|
public:
|
||
|
typedef P result_type;
|
||
|
typedef Random_points_in_triangle_2<P, Creator> This;
|
||
|
typedef typename Kernel_traits<P>::Kernel::Triangle_2 Triangle_2;
|
||
|
Random_points_in_triangle_2() {}
|
||
|
Random_points_in_triangle_2( const This& x,Random& rnd)
|
||
|
: Random_generator_base<P>( 1, rnd ),_p(x._p),_q(x._q),_r(x._r) {
|
||
|
generate_point();
|
||
|
}
|
||
|
Random_points_in_triangle_2( const P& p, const P& q, const P& r, Random& rnd = get_default_random())
|
||
|
: Random_generator_base<P>( 1, rnd ),_p(p),_q(q),_r(r) {
|
||
|
generate_point();
|
||
|
}
|
||
|
Random_points_in_triangle_2( const Triangle_2& triangle,Random& rnd = get_default_random())
|
||
|
: Random_generator_base<P>( 1,
|
||
|
rnd),_p(triangle[0]),_q(triangle[1]),_r(triangle[2]) {
|
||
|
generate_point();
|
||
|
}
|
||
|
This& operator++() {
|
||
|
generate_point();
|
||
|
return *this;
|
||
|
}
|
||
|
This operator++(int) {
|
||
|
This tmp = *this;
|
||
|
++(*this);
|
||
|
return tmp;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template<class P, class Creator >
|
||
|
void Random_points_in_triangle_2<P, Creator>::generate_point() {
|
||
|
typedef typename Creator::argument_type T;
|
||
|
Creator creator;
|
||
|
double a1 = this->_rnd.get_double(0,1);
|
||
|
double a2 = this->_rnd.get_double(0,1);
|
||
|
if(a1>a2) std::swap(a1,a2);
|
||
|
double b1 = a1;
|
||
|
double b2 = a2-a1;
|
||
|
double b3 = 1.0-a2;
|
||
|
this->d_item = creator(T(to_double(_p.x())*b1+to_double(_q.x())*b2+to_double(_r.x())*b3),
|
||
|
T(to_double(_p.y())*b1+to_double(_q.y())*b2+to_double(_r.y())*b3));
|
||
|
}
|
||
|
|
||
|
namespace internal {
|
||
|
|
||
|
//Functor returning Triangle_2 from Triangulation_2 Faces
|
||
|
template <class T>
|
||
|
class Triangle_from_face_2
|
||
|
{
|
||
|
typedef typename T::Triangle Triangle;
|
||
|
public:
|
||
|
typedef Triangle result_type;
|
||
|
Triangle_from_face_2() {}
|
||
|
|
||
|
Triangle operator()(typename T::Finite_faces_iterator face) const {
|
||
|
return Triangle(face->vertex(0)->point(), face->vertex(1)->point(), face->vertex(2)->point());
|
||
|
}
|
||
|
};
|
||
|
|
||
|
struct Is_not_in_domain
|
||
|
{
|
||
|
typedef bool result_type;
|
||
|
|
||
|
template <class FH>
|
||
|
result_type operator()(const FH fh) const {
|
||
|
return (!fh->is_in_domain());
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <class T>
|
||
|
class In_domain_finite_faces_iterator
|
||
|
: public Filter_iterator<typename T::Finite_faces_iterator, Is_not_in_domain>
|
||
|
{
|
||
|
typedef CGAL::Filter_iterator<typename T::Finite_faces_iterator, Is_not_in_domain> Base;
|
||
|
typedef In_domain_finite_faces_iterator<T> Self;
|
||
|
|
||
|
typedef typename T::Face_handle Face_handle;
|
||
|
typedef typename T::Finite_faces_iterator Finite_faces_iterator;
|
||
|
|
||
|
public:
|
||
|
In_domain_finite_faces_iterator() : Base() {}
|
||
|
In_domain_finite_faces_iterator(const Base &b) : Base(b) {}
|
||
|
Self & operator++() { Base::operator++(); return *this; }
|
||
|
Self & operator--() { Base::operator--(); return *this; }
|
||
|
Self operator++(int) { Self tmp(*this); ++(*this); return tmp; }
|
||
|
Self operator--(int) { Self tmp(*this); --(*this); return tmp; }
|
||
|
operator Finite_faces_iterator() const { return Base::base(); }
|
||
|
operator Face_handle() const { return Face_handle(Base::base()); }
|
||
|
};
|
||
|
|
||
|
}//end namespace internal
|
||
|
|
||
|
template <class P,
|
||
|
class T,
|
||
|
class Creator = Creator_uniform_2<typename Kernel_traits<P>::Kernel::RT, P> >
|
||
|
class Random_points_in_triangle_mesh_2
|
||
|
: public Generic_random_point_generator<internal::In_domain_finite_faces_iterator<T>,
|
||
|
internal::Triangle_from_face_2<T>,
|
||
|
Random_points_in_triangle_2<P, Creator>,
|
||
|
P>
|
||
|
{
|
||
|
public:
|
||
|
typedef Generic_random_point_generator<internal::In_domain_finite_faces_iterator<T>,
|
||
|
internal::Triangle_from_face_2<T>,
|
||
|
Random_points_in_triangle_2<P, Creator>,
|
||
|
P> Base;
|
||
|
typedef typename T::Face_handle Id;
|
||
|
typedef P result_type;
|
||
|
typedef Random_points_in_triangle_mesh_2<P, T, Creator> This;
|
||
|
|
||
|
Random_points_in_triangle_mesh_2(const T& triangulation, Random& rnd = get_default_random())
|
||
|
: Base(CGAL::make_prevent_deref_range(
|
||
|
CGAL::filter_iterator(triangulation.finite_faces_end(),
|
||
|
internal::Is_not_in_domain(),
|
||
|
triangulation.finite_faces_begin()),
|
||
|
CGAL::filter_iterator(triangulation.finite_faces_end(),
|
||
|
internal::Is_not_in_domain())),
|
||
|
internal::Triangle_from_face_2<T>(),
|
||
|
typename Kernel_traits<P>::Kernel::Compute_area_2(),
|
||
|
rnd)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
This& operator++() {
|
||
|
Base::generate_point();
|
||
|
return *this;
|
||
|
}
|
||
|
This operator++(int) {
|
||
|
This tmp = *this;
|
||
|
++(*this);
|
||
|
return tmp;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
namespace internal
|
||
|
{
|
||
|
|
||
|
template<class T>
|
||
|
class Deref
|
||
|
{
|
||
|
public:
|
||
|
typedef const T& result_type;
|
||
|
const T& operator()(const T* triangle) const
|
||
|
{
|
||
|
return *triangle;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template<class A>
|
||
|
struct Address_of {
|
||
|
typedef const A* result_type;
|
||
|
const A* operator()(const A& a) const
|
||
|
{
|
||
|
return &a;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
}//namesapce internal
|
||
|
|
||
|
template <class Point_2,
|
||
|
class Triangle_2=typename Kernel_traits<Point_2>::Kernel::Triangle_2,
|
||
|
class Creator =
|
||
|
Creator_uniform_2<typename Kernel_traits<Point_2>::Kernel::RT,Point_2> >
|
||
|
struct Random_points_in_triangles_2
|
||
|
: public Generic_random_point_generator<const Triangle_2*,
|
||
|
internal::Deref<Triangle_2>,
|
||
|
Random_points_in_triangle_2<Point_2>,
|
||
|
Point_2>
|
||
|
{
|
||
|
typedef Generic_random_point_generator<const Triangle_2*,
|
||
|
internal::Deref<Triangle_2>,
|
||
|
Random_points_in_triangle_2<Point_2, Creator>,
|
||
|
Point_2> Base;
|
||
|
typedef const Triangle_2* Id;
|
||
|
typedef Point_2 result_type;
|
||
|
typedef Random_points_in_triangles_2<Point_2, Triangle_2, Creator> This;
|
||
|
|
||
|
template<typename TriangleRange>
|
||
|
Random_points_in_triangles_2( const TriangleRange& triangles, Random& rnd = get_default_random())
|
||
|
: Base(make_range( boost::make_transform_iterator(triangles.begin(), internal::Address_of<Triangle_2>()),
|
||
|
boost::make_transform_iterator(triangles.end(), internal::Address_of<Triangle_2>()) ),
|
||
|
internal::Deref<Triangle_2>(),
|
||
|
typename Kernel_traits<Point_2>::Kernel::Compute_area_2(),
|
||
|
rnd )
|
||
|
{
|
||
|
}
|
||
|
This& operator++() {
|
||
|
Base::generate_point();
|
||
|
return *this;
|
||
|
}
|
||
|
This operator++(int) {
|
||
|
This tmp = *this;
|
||
|
++(*this);
|
||
|
return tmp;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
} //namespace CGAL
|
||
|
#include <CGAL/enable_warnings.h>
|
||
|
|
||
|
#endif // CGAL_POINT_GENERATORS_2_H //
|
||
|
// EOF //
|