Random 如何生成随机凸多边形?
我正试图设计一种生成随机二维凸多边形的方法。它必须具有以下属性:Random 如何生成随机凸多边形?,random,geometry,Random,Geometry,我正试图设计一种生成随机二维凸多边形的方法。它必须具有以下属性: 坐标应该是整数 多边形应该位于具有角(0,0)和(C,C)的正方形内,其中C是给定的 多边形的顶点数应接近给定的N 例如,生成具有10个顶点且位于正方形[0..100]x[0..100]内的随机多边形 这项任务之所以困难,是因为坐标应该是整数 我尝试的方法是在给定的正方形中生成随机点集,并计算这些点的凸包。但是,与N相比,生成的凸包的顶点非常少 有什么想法吗?这还不完全,但它可能会给你一些想法 如果N
- 坐标应该是整数李>
- 多边形应该位于具有角(0,0)和(C,C)的正方形内,其中C是给定的李>
- 多边形的顶点数应接近给定的N
有什么想法吗?这还不完全,但它可能会给你一些想法 如果N<3,则退出。生成具有N个顶点的单位圆,并将其随机旋转[0..90]度 从原点向外随机挤出每个顶点,并使用每对相邻顶点与原点之间的叉积符号确定凸度。这是一个在速度和质量之间进行权衡的步骤
设置顶点后,从原点查找具有最大幅值的顶点。将每个顶点除以该大小以规格化多边形,然后将其放大(C/2)。转换为(C/2,C/2)并转换回整数。一个简单的算法是:
您的初始方法是正确的-计算凸包是满足随机性、凸性和整体性的唯一方法 我能想到的优化算法以获得“更多点”的唯一方法是将它们组织成一个圆圈,而不是完全随机的。你的点应该更靠近正方形的“边缘”,而不是靠近中心。在中心,概率应该是~0,因为多边形必须是凸的
一个简单的选择是为你的点设置一个最小半径,可能是C/2或C*0.75。计算C正方形的中心,如果某个点太近,将其从中心移开,直到达到最小距离。这是我知道的生成每个凸多边形的概率相等的最快算法。输出正好有N个顶点,并且运行时间为O(N logn),因此它可以非常快速地生成大型多边形
- 生成两个列表,
和X
,其中包含0和C之间的N个随机整数。确保没有重复项Y
- 排序
和X
并存储它们的最大和最小元素Y
- 将其他元素(不是最大值或最小值)随机分为两组:
和X1
,以及X2
和Y1
Y2
- 在这些列表的开始和结束处重新插入最小和最大元素(
在minX
和X1
的开始处,X2
在结束处,等等)maxX
- 找到连续的差异(
),颠倒第二组(X1[i+1]-X1[i]
)的顺序。将这些存储在列表中X2[i]-X2[i+1]
和XVec
YVec
- 随机(洗牌)
并将每对YVec
和XVec[i]
视为二维向量YVec[i]
- 按角度对这些向量进行排序,然后将它们端到端地放置以形成多边形
- 将多边形移动到原始的最小和最大坐标
随机导入
从数学导入atan2
def到凸形轮廓(顶点计数,
x_生成器=random.random,
y_生成器=随机。随机):
"""
Sander Verdonschot的Valtr端口算法。
参考:
http://cglab.ca/~sander/misc/convxgeneration/ValtrAlgorithm.java
>>>轮廓=至凸形轮廓(20)
>>>透镜(轮廓)==20
真的
"""
xs=[x_生成器()用于范围内的u(顶点数)]
ys=[y_生成器()用于范围内的u(顶点数)]
xs=已排序(xs)
ys=已排序(ys)
最小x,*xs,最大x=xs
最小y,*ys,最大y=ys
向量x=_到_向量x坐标(x,min,max)
vectors_ys=_至_vectors_坐标(ys,min_y,max_y)
随机。随机(向量)
def到_矢量_角度(矢量):
x、 y=向量
返回atan2(y,x)
向量=排序(zip(向量x,向量y),
键=到(矢量角度)
点x=点y=0
最小多边形x=最小多边形y=0
点数=[]
对于向量x,向量中的向量y:
点。附加((点x,点y))
点x+=向量x
点y+=向量y
最小多边形=最小(最小多边形,点)
min_polygon_y=min(min_polygon_y,point_y)
shift_x,shift_y=min_x-min_多边形,min_y-min_多边形
返回[(点x+移位x,点y+移位y)
对于点x,点y在点中]
定义向量坐标(坐标、最小坐标、最大坐标):
最后一个最小值=最后一个最大值=最小坐标
结果=[]
对于坐标中的坐标:
如果_to_random_boolean():
结果.追加(坐标-最后一分钟)
最后一分钟=坐标
其他: