mirror of https://github.com/CGAL/cgal
151 lines
4.6 KiB
C++
151 lines
4.6 KiB
C++
// ============================================================================
|
|
//
|
|
// Copyright (c) 2000 The CGAL Consortium
|
|
//
|
|
// This software and related documentation is part of an INTERNAL release
|
|
// of the Computational Geometry Algorithms Library (CGAL). It is not
|
|
// intended for general use.
|
|
//
|
|
// ----------------------------------------------------------------------------
|
|
//
|
|
// release : $CGAL_Revision $
|
|
// release_date : $CGAL_Date $
|
|
//
|
|
// file : include/CGAL/random_polygon_2.h
|
|
// package : $CGAL_Package: Generator 2.12 (28 Jul 1999) $
|
|
// chapter : Geometric Object Generators
|
|
//
|
|
// revision : $Revision$
|
|
// revision_date : $Date$
|
|
//
|
|
// author(s) : Susan Hert <hert@mpi-sb.mpg.de>
|
|
//
|
|
// coordinator : ETH Zurich (Bernd Gaertner <gaertner@inf.ethz.ch>)
|
|
//
|
|
// implementation: Random Simple Polygons
|
|
// ============================================================================
|
|
#ifndef CGAL_RANDOM_POLYGON_2_H
|
|
#define CGAL_RANDOM_POLYGON_2_H
|
|
|
|
#include <list>
|
|
#include <set>
|
|
#include <vector>
|
|
#include <assert.h>
|
|
#include <CGAL/Simplicity_sweep_2.h>
|
|
#include <CGAL/Random_polygon_traits_2.h>
|
|
|
|
namespace CGAL {
|
|
|
|
//
|
|
// Using the provided point generator, generates a set of n points and
|
|
// produces a simple polygon from the unique subset of points within this
|
|
// set.
|
|
//
|
|
// Each of the p possible simple polygons for the unique point set is
|
|
// generated with probability greater than 0 but the polygons are not
|
|
// generated with uniform probability.
|
|
//
|
|
template <class PointGenerator, class OutputIterator, class Traits>
|
|
OutputIterator random_polygon_2(int n, OutputIterator result,
|
|
const PointGenerator& pg, const Traits& traits)
|
|
{
|
|
typedef typename Traits::Point_2 Point_2;
|
|
typedef std::vector<Point_2> Vertex_list;
|
|
typedef typename Vertex_list::iterator Iterator;
|
|
|
|
std::pair<Iterator, Iterator> reverse_range;
|
|
Vertex_list vertices;
|
|
|
|
copy_n_unique(pg, n, std::back_inserter(vertices), traits);
|
|
CGAL_assertion(!duplicate_points(vertices.begin(), vertices.end(), traits));
|
|
|
|
std::random_shuffle(vertices.begin(), vertices.end());
|
|
|
|
bool changing = true;
|
|
|
|
Simplicity_sweep_2<Iterator,Traits> S(traits);
|
|
|
|
while (changing)
|
|
{
|
|
changing = S.sweep(vertices.begin(), vertices.end(), reverse_range);
|
|
|
|
// gets rid of an intersection by reversing the order of the vertices
|
|
// between the endpoints of two intersecting edges
|
|
if (changing)
|
|
std::reverse(reverse_range.first, ++reverse_range.second);
|
|
}
|
|
|
|
if (orientation_2(vertices.begin(), vertices.end()) == CLOCKWISE)
|
|
std::reverse(vertices.begin(), vertices.end());
|
|
|
|
|
|
CGAL_assertion(is_simple_2(vertices.begin(), vertices.end()));
|
|
for (Iterator it = vertices.begin(); it != vertices.end(); it++)
|
|
{
|
|
*result = *it;
|
|
result++;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
template <class PointGenerator, class OutputIterator>
|
|
inline
|
|
OutputIterator random_polygon_2( int n, OutputIterator result,
|
|
const PointGenerator& pg )
|
|
{
|
|
typedef typename PointGenerator::value_type Point_2;
|
|
return _random_polygon_2(n, result, pg, reinterpret_cast<Point_2*>(0));
|
|
}
|
|
|
|
template <class PointGenerator, class OutputIterator, class R>
|
|
inline
|
|
OutputIterator _random_polygon_2( int n, OutputIterator result,
|
|
const PointGenerator& pg, Point_2<R>*)
|
|
{
|
|
return random_polygon_2(n, result, pg, Random_polygon_traits_2<R>());
|
|
}
|
|
|
|
|
|
|
|
template <class ForwardIterator, class Traits>
|
|
bool duplicate_points(ForwardIterator first, ForwardIterator beyond,
|
|
const Traits& )
|
|
{
|
|
typedef typename Traits::Point_2 Point_2;
|
|
typedef typename Traits::Less_yx Less_yx;
|
|
std::set<Point_2,Less_yx> point_set;
|
|
int i = 0;
|
|
for (; first != beyond; first++, i++)
|
|
if (!(point_set.insert(*first)).second) return true;
|
|
return false;
|
|
}
|
|
|
|
// Copies the first n points from the input iterator to the output iterator,
|
|
// removing any duplicates. Thus fewer than n points may be inserted into
|
|
// the output iterator.
|
|
template <class InputIterator, class Size, class OutputIterator, class Traits>
|
|
OutputIterator copy_n_unique(InputIterator first, Size n,
|
|
OutputIterator result,
|
|
const Traits& )
|
|
{
|
|
typedef typename Traits::Point_2 Point_2;
|
|
typedef typename Traits::Less_yx Less_yx;
|
|
|
|
std::set<Point_2, Less_yx> sorted_point_set;
|
|
int i;
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
if (sorted_point_set.insert(*first).second)
|
|
{
|
|
*result = *first;
|
|
result++;
|
|
}
|
|
first++;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|