如何在凸多边形的周长上生成 random/unifom 个点?

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

我有什么?

我有一个像这样的凸多边形:

使用以下代码:

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

我想要什么?

  1. 我想在多边形的周长上生成 N 个随机点
  2. 我想在示波器上的 eaqul 周边生成 N 个点

我可以使用 scipy.spatial 做到这一点吗?以及如何?

此代码将值从区间 (0,1) 映射到多边形周长并执行 1。(给定此解决方案,2. 很简单):

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