Python - 在中心点(x,y)位置周围生成随机顶点

4
我找不到有关此主题的文章或stackoverflow问题,因为我需要它。
我正在制作2D游戏,我想生成一个随机形状的小行星。每个小行星都有一个中心点,一个X,Y位置,我想围绕它生成大约8个顶点(顶点数可变)。

enter image description here

如果我现在可以实现这个形状,我想添加一个随机元素,比如一个变量和从中心随机距离来创建一个随机的岩石形状。

enter image description here

我研究了极坐标到笛卡尔坐标的一些三角概念,但还没有想出如何将其应用于这个目标。虽然有JavaScript的教程,但它使用了库和函数,我需要从头开始用Python编写。
编辑:所以你的答案专注于解释如何得到中心周围的顶点公式,这些是我已经知道如何做的事情,
1)在我使用的图形库中绘制多边形 2)获取随机数
非常感谢您的帮助!

你在这里准确地在问什么? - David Z
3
我试图解释我需要的内容,甚至制作了图形来帮助你理解。那么请告诉我您没有理解的部分先生。谢谢。 - Juan Bonnett
“我已经研究了一些三角学概念,称为极坐标转换为直角坐标,但是还没有弄清楚如何将其应用于这个目标。” 这是不清楚的部分。我知道什么是极坐标,但我不确定您想用它们做什么。 - David Z
感谢您的反馈,先生。 - Juan Bonnett
2个回答

6
你可以使用random库在极坐标中进行随机采样。先采样一个方向,然后再采样一个径向距离。在下面的示例中,我选择方向在[0, 2*pi]上均匀分布,半径则是以用户输入的平均值和标准差为参数的正态分布。
import random
import math

def generate_points(center_x, center_y, mean_radius, sigma_radius, num_points):
    points = []
    for i in range(num_points):
        theta = random.uniform(0, 2*math.pi)
        radius = random.gauss(mean_radius, sigma_radius)
        x = center_x + radius * math.cos(theta)
        y = center_y + radius * math.sin(theta)
        points.append([x,y])
    return points

作为如何调用它的示例。
>>> generate_points(5.0, 7.0, 1.0, 0.1, 8)
[[4.4478263120757875, 6.018608023032151],
 [4.407825651072504, 6.294849028359581],
 [5.0570272843718085, 6.17834681191539],
 [5.307793789416231, 6.156715230672773],
 [4.368508167422119, 7.712616387293795],
 [5.327972045495855, 5.917733119760926],
 [5.748935178651789, 6.437863588580371],
 [3.9312163910881033, 6.388093041756519]]

如果您希望点按特定顺序绕组,则可以使用类似于 numpy.linspace 的方法,以顺时针或逆时针方式遍历样本角度。例如:
import random
import math
import numpy as np

def generate_points(center_x, center_y, mean_radius, sigma_radius, num_points):
    points = []
    for theta in np.linspace(0, 2*math.pi - (2*math.pi/num_points), num_points):
        radius = random.gauss(mean_radius, sigma_radius)
        x = center_x + radius * math.cos(theta)
        y = center_y + radius * math.sin(theta)
        points.append([x,y])
    return points

如果您不想安装numpy,您可以编写自己类似的版本linspace

def linspace(start, stop, num_steps):
    values = []
    delta = (stop - start) / num_steps
    for i in range(num_steps):
        values.append(start + i * delta)
    return values

会尝试并告诉您是否需要进行调整。感谢您的回答,先生。 - Juan Bonnett
好的,在这个链接中,你可以看到我的代码和算法,但是我没有得到预期的结果,也许我在某个地方没有正确地输入数据。http://imgur.com/a/2aWl7 - Juan Bonnett
谢谢您先生!您有什么想法可以让它们顺时针或逆时针生成,因为它们将按顺序绘制?也许在这一行中:theta = random.uniform(0, 2*math.pi) 基于当前索引添加一些限制。 - Juan Bonnett
你确定我们需要那个库吗?我非常希望不必安装它,但如果它对此是绝对必要的,我会安装的。 - Juan Bonnett
非常完美的答案!非常感谢!现在它可以工作了 :) - Juan Bonnett

0
一个简单的方法是随机选择一个、两个或三个不相邻的顶点,然后将它们移动到最近顶点的距离之内的任意位置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接