how to generate a random/unifom points on the perimeter of the convex polygon?

Viewed 423

What do I have?

I have a convex polygon looks like that:

enter image description here

using the following code:

import numpy as np
from scipy.spatial import ConvexHull
import matplotlib.pyplot as plt


# Generate some random points for the demo.
np.random.seed(4321)
pts = 0.1 + 0.8*np.random.rand(15, 2)

ch = ConvexHull(pts)

# Get the indices of the hull points.
hull_indices = ch.vertices

# These are the actual points.
hull_pts = pts[hull_indices, :]

plt.plot(hull_pts[:, 0], hull_pts[:, 1], 'ko', markersize=10)
plt.fill(hull_pts[:, 0], hull_pts[:, 1], fill=False, edgecolor='b')
plt.xlim(0, 1)
plt.ylim(0, 1)
plt.show()

What do I want?

  1. I want to genarete N random points on the perimeter of the polygon
  2. I want to genarete N points in eaqul perimeter on the scope

can I do that using scipy.spatial? and how?

1 Answers

This code maps values from interval (0,1) to polygon perimeter and does 1. (2. is trivial, given this solution):

from scipy.spatial.distance import pdist

class IntervalToPerimeter:
    def __init__(self, vertices):
        self.vertices = np.concatenate([vertices, vertices[0][None]])
        self.mapping = np.array([pdist(self.vertices[i:i+2]) for i in range(len(self.vertices)-1)]).cumsum()
        self.mapping /= self.mapping.max()
        
    def transform(self, points):
        indices = (points[:, None] < self.mapping).argmax(axis=1)
        a, b = np.concatenate([[0], self.mapping])[indices], self.mapping[indices]
        
        return ((points - a)[:, None] * self.vertices[indices] + (b-points)[:, None] * self.vertices[indices+1])/(b-a)[:, None]

itp = IntervalToPerimeter(hull_pts)

transformed_points = itp.transform(np.random.uniform(size=50))

enter image description here

Related