|
tgen 1.5.0
|
Geometry utilities. More...
Classes | |
| struct | tgen::geometry::point< T > |
| Point on the plane. More... | |
Functions | |
| std::vector< point< long long > > | tgen::geometry::random_points_general_position (int n, long long min_coord, long long max_coord) |
| Generates random points in general position inside a coordinate box. | |
| std::vector< point< long long > > | tgen::geometry::random_simple_polygon_through_points (const std::vector< point< long long > > &points) |
| Generates a random simple polygon through given points. | |
| std::vector< point< long long > > | tgen::geometry::random_simple_polygon (int n, long long min_coord, long long max_coord, bool strict=false) |
| Generates a random simple polygon given coordinate range. | |
| std::vector< point< long long > > | tgen::geometry::random_convex_polygon (int n, long long min_coord, long long max_coord, bool strict=false) |
| Generates a random convex polygon with given coordinate range. | |
| std::vector< point< long long > > | tgen::geometry::random_orthogonal_polygon (int n, long long min_coord, long long max_coord, bool strict=false) |
| Generates a random orthogonal simple polygon. | |
Geometry utilities.
Vector operations on integer coordinates.
Coordinate equality is exact, including for floating-point types.
Generates points in general position (no three collinear) inside a box.
Generates convex polygon.
Generates a simple polygon.
Simple polygon through a grid of points.
Generates a random orthogonal (axis-aligned) simple polygon.
|
inline |
Generates a random convex polygon with given coordinate range.
| n | Number of vertices. |
| min_coord | Minimum allowed coordinate on each axis. |
| max_coord | Maximum allowed coordinate on each axis. |
| strict | If true, the polygon is strictly convex. If false, collinear vertices may occur. |
Uses Valtr's classical construction: choose m distinct sorted x and y coordinates in [min_coord, max_coord] via tgen::distinct_range (with m = n when strict is false, and m > n when strict is true), build monotone signed edge components, shuffle the y-components, pair with the x-components, and sort by polar angle, then prefix-sum to obtain vertex coordinates. When strict is true, collinear boundary vertices are removed and the walk is subsampled to n vertices. The polygon is then translated by a random amount so it lies inside the requested box.
| std::runtime_error | if the coordinate range is not large enough, or the prime-sized sampling pool would exceed INT_MAX elements. |
O(n log n).
|
inline |
Generates a random orthogonal simple polygon.
| n | Target number of boundary vertices. |
| min_coord | Minimum allowed coordinate on each axis. |
| max_coord | Maximum allowed coordinate on each axis. |
| strict | If true, every vertex turns 90 degrees (no three consecutive collinear vertices). If false, collinear vertices may appear on straight horizontal or vertical edges. |
The polygon is built in local steps that each preserve full simplicity (no edge crossings, overlaps, or boundary self-contact).
n <= 1000 bump on a square whose side is about sqrt(n):
n > 1000 scale-up macro shape, then fill:
Finally, the polygon is translated into [min_coord, max_coord] (retrying up to 8 times if the bounding box is too large for the coordinate range) and cyclically shifted.
| std::runtime_error | if the coordinate range is too small or no attempt fits inside the box. |
O(n^2) for n <= 1000;
O(n) otherwise.
|
inline |
Generates random points in general position inside a coordinate box.
| n | Number of points to generate. |
| min_coord | Minimum allowed coordinate on each axis. |
| max_coord | Maximum allowed coordinate on each axis. |
The construction samples n distinct values (x, x^-1) from F_p then applies several random invertible shears over F_p, then translates the result into [min_coord, max_coord]^2. Affine maps preserve (non-)collinearity, and the graph of inversion over F_p meets any line in at most two points.
| std::runtime_error | if the coordinate range is not large enough, or the prime-sized sampling pool would exceed INT_MAX elements. |
O(n).
|
inline |
Generates a random simple polygon given coordinate range.
| n | Number of vertices to generate. |
| min_coord | Minimum allowed coordinate on each axis. |
| max_coord | Maximum allowed coordinate on each axis. |
| strict | If true, the vertex set has no three collinear points. If false, there might be collinear triplets and three consecutive collinear points in the polygon. |
When strict is true, the point set is built with random_points_general_position, othwerwise randomly generated. Points are polygonized by random_simple_polygon_through_points.
| std::runtime_error | if the coordinate range is not large enough, or the prime-sized sampling pool would exceed INT_MAX elements. |
O(n log n) expected.
|
inline |
Generates a random simple polygon through given points.
| points | Distinct points. |
Uses a randomized divide-and-conquer Hamiltonian-path construction on the leftmost and rightmost vertices.
O(|points| log|points|) expected for every valid fixed input, including inputs with collinear triples. The expectation is over the algorithm's random choices; the input need not be randomly distributed. O(|points|^2) worst case.
The expected bound follows by tracking each point while it remains a non-endpoint point. Even with collinear points and discrete split weights, within at most two recursive splits there is a constant probability that its subproblem shrinks by a constant factor or terminates. Each point is therefore processed in O(log n) calls in expectation. Sorting the entirely collinear terminal subproblems costs O(n log n) in total, so the overall expected work is O(n log n), where n is the input size.