I'm trying to devise a method for generating random 2D convex polygons. It has to have the following properties:
For example, generate random polygons that have 10 vertices and lie inside square [0..100]x[0..100].
What makes this task hard, is the fact that the coordinates should be integers.
The approach I tried was to generate random set of points in the given square and compute the convex hull of these points. But the resultant convex hull is very little vertices compared to N.
Any ideas?
Sum of all the interior angles of a polygon of n sides = (n – 2)180°. The diagonals of the convex polygon lie completely inside the polygon. Area of convex polygon can be determined by dividing the polygon into triangles and then finding the area of each triangle and summing up them.
A planar polygon is convex if it contains all the line segments connecting any pair of its points. Thus, for example, a regular pentagon is convex (left figure), while an indented pentagon is not (right figure). A planar polygon that is not convex is said to be a concave polygon.
The Convex Polygon Theorem states that the optimum (maximum or minimum) solution of a LLP is attained at least one of the corner points of the convex set over which the solution is feasible.
Regular convex polygons. All regular simple polygons (a simple polygon is one that does not intersect itself anywhere) are convex. Those having the same number of sides are also similar.
Here is the fastest algorithm I know that generates each convex polygon with equal probability. The output has exactly N vertices, and the running time is O(N log N), so it can generate even large polygons very quickly.
X
and Y
, of N random integers between 0 and C. Make sure there are no duplicates.X
and Y
and store their maximum and minimum elements.X1
and X2
, and Y1
and Y2
.minX
at the start of X1
and X2
, maxX
at the end, etc.).X1[i + 1] - X1[i]
), reversing the order for the second group (X2[i] - X2[i + 1]
). Store these in lists XVec
and YVec
.YVec
and treat each pair XVec[i]
and YVec[i]
as a 2D vector.An animation and Java implementation is available here: Generating Random Convex Polygons.
This algorithm is based on a paper by Pavel Valtr: “Probability that n random points are in convex position.” Discrete & Computational Geometry 13.1 (1995): 637-643.
Following @Mangara answer there is JAVA implementation, if someone is interested in Python port of it
import random
from math import atan2
def to_convex_contour(vertices_count,
x_generator=random.random,
y_generator=random.random):
"""
Port of Valtr algorithm by Sander Verdonschot.
Reference:
http://cglab.ca/~sander/misc/ConvexGeneration/ValtrAlgorithm.java
>>> contour = to_convex_contour(20)
>>> len(contour) == 20
True
"""
xs = [x_generator() for _ in range(vertices_count)]
ys = [y_generator() for _ in range(vertices_count)]
xs = sorted(xs)
ys = sorted(ys)
min_x, *xs, max_x = xs
min_y, *ys, max_y = ys
vectors_xs = _to_vectors_coordinates(xs, min_x, max_x)
vectors_ys = _to_vectors_coordinates(ys, min_y, max_y)
random.shuffle(vectors_ys)
def to_vector_angle(vector):
x, y = vector
return atan2(y, x)
vectors = sorted(zip(vectors_xs, vectors_ys),
key=to_vector_angle)
point_x = point_y = 0
min_polygon_x = min_polygon_y = 0
points = []
for vector_x, vector_y in vectors:
points.append((point_x, point_y))
point_x += vector_x
point_y += vector_y
min_polygon_x = min(min_polygon_x, point_x)
min_polygon_y = min(min_polygon_y, point_y)
shift_x, shift_y = min_x - min_polygon_x, min_y - min_polygon_y
return [(point_x + shift_x, point_y + shift_y)
for point_x, point_y in points]
def _to_vectors_coordinates(coordinates, min_coordinate, max_coordinate):
last_min = last_max = min_coordinate
result = []
for coordinate in coordinates:
if _to_random_boolean():
result.append(coordinate - last_min)
last_min = coordinate
else:
result.append(last_max - coordinate)
last_max = coordinate
result.extend((max_coordinate - last_min,
last_max - max_coordinate))
return result
def _to_random_boolean():
return random.getrandbits(1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With