// 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 // Pedro Machado Manhaes de Castro // Alexandru Tifrea // Maxime Gimeno #ifndef CGAL_POINT_GENERATORS_2_H #define CGAL_POINT_GENERATORS_2_H 1 #include #include #include #include #include #include namespace CGAL { template < class P, class Creator = Creator_uniform_2::Kernel::RT,P> > class Random_points_in_disc_2 : public Random_generator_base

{ void generate_point(); public: typedef Random_points_in_disc_2 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

(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:: 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::Kernel::RT, P> > class Random_points_on_circle_2 : public Random_generator_base

{ void generate_point(); public: typedef Random_points_on_circle_2 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

(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:: 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::Kernel::RT,P> > class Random_points_in_square_2 : public Random_generator_base

{ void generate_point(); public: typedef Random_points_in_square_2 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

( 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:: 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::Kernel::RT,P> > class Random_points_on_square_2 : public Random_generator_base

{ void generate_point(); public: typedef Random_points_on_square_2 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

( 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:: 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::Kernel::RT,P> > class Random_points_in_iso_rectangle_2 : public Random_generator_base

{ double left, right, top, bottom; void generate_point(); public: typedef Random_points_in_iso_rectangle_2 This; Random_points_in_iso_rectangle_2( const P&p, const P& q, Random& rnd = CGAL::get_default_random()) : Random_generator_base

( 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:: 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::Kernel::RT,P> > class Random_points_on_segment_2 : public Random_generator_base

{ P _p; P _q; void generate_point(); public: typedef Random_points_on_segment_2 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

( (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:: 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 _q; std::size_t d_i; std::size_t d_mx; void generate_point(); public: typedef Points_on_segment_2

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

( (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

:: generate_point() { this->d_item = _p + (_q-_p) * static_cast(d_i) / (static_cast(d_mx)-1); } template 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(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 OutputIterator points_on_square_grid_2( double a, std::size_t n, OutputIterator o) { typedef std::iterator_traits ITraits; typedef typename ITraits::value_type P; return points_on_square_grid_2(a, n, o, Creator_uniform_2::Kernel::RT,P>()); } template 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::Kernel::FT>(static_cast(i) / (static_cast(n)-1)); } return o; } template 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 void perturb_points_2( ForwardIterator first, ForwardIterator last, double xeps, double yeps, Random& rnd) { typedef std::iterator_traits ITraits; typedef typename ITraits::value_type P; perturb_points_2( first, last, xeps, yeps, rnd, Creator_uniform_2::Kernel::RT,P>()); } template inline void perturb_points_2( ForwardIterator first, ForwardIterator last, double xeps, Random& rnd) { perturb_points_2( first, last, xeps, xeps, rnd); } template void perturb_points_2( ForwardIterator first, ForwardIterator last, double xeps, double yeps) { perturb_points_2( first, last, xeps, yeps, CGAL::get_default_random()); } template void perturb_points_2( ForwardIterator first, ForwardIterator last, double xeps) { perturb_points_2( first, last, xeps, xeps, CGAL::get_default_random()); } template 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( 0, m-1)]; const Point& q = first[ rnd.uniform_int( 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 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 ITraits; typedef typename ITraits::value_type P; return random_collinear_points_2( first, last, n, first2, rnd, Creator_uniform_2::Kernel::RT,P>()); } template 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::Kernel::RT,P> > class Random_points_in_triangle_2 : public Random_generator_base

{ P _p,_q,_r; void generate_point(); public: typedef P result_type; typedef Random_points_in_triangle_2 This; typedef typename Kernel_traits

::Kernel::Triangle_2 Triangle_2; Random_points_in_triangle_2() {} Random_points_in_triangle_2( const This& x,Random& rnd) : Random_generator_base

( 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

( 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

( 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 void Random_points_in_triangle_2::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 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 result_type operator()(const FH fh) const { return (!fh->is_in_domain()); } }; template class In_domain_finite_faces_iterator : public Filter_iterator { typedef CGAL::Filter_iterator Base; typedef In_domain_finite_faces_iterator 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 ::Kernel::RT, P> > class Random_points_in_triangle_mesh_2 : public Generic_random_point_generator, internal::Triangle_from_face_2, Random_points_in_triangle_2, P> { public: typedef Generic_random_point_generator, internal::Triangle_from_face_2, Random_points_in_triangle_2, P> Base; typedef typename T::Face_handle Id; typedef P result_type; typedef Random_points_in_triangle_mesh_2 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(), typename Kernel_traits

::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 Deref { public: typedef const T& result_type; const T& operator()(const T* triangle) const { return *triangle; } }; template struct Address_of { typedef const A* result_type; const A* operator()(const A& a) const { return &a; } }; }//namesapce internal template ::Kernel::Triangle_2, class Creator = Creator_uniform_2::Kernel::RT,Point_2> > struct Random_points_in_triangles_2 : public Generic_random_point_generator, Random_points_in_triangle_2, Point_2> { typedef Generic_random_point_generator, Random_points_in_triangle_2, Point_2> Base; typedef const Triangle_2* Id; typedef Point_2 result_type; typedef Random_points_in_triangles_2 This; template 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()), boost::make_transform_iterator(triangles.end(), internal::Address_of()) ), internal::Deref(), typename Kernel_traits::Kernel::Compute_area_2(), rnd ) { } This& operator++() { Base::generate_point(); return *this; } This operator++(int) { This tmp = *this; ++(*this); return tmp; } }; } //namespace CGAL #include #endif // CGAL_POINT_GENERATORS_2_H // // EOF //