繁体   English   中英

如何在圆形分布中生成随机点

[英]How to generate random points in a circular distribution

我想知道如何生成出现在循环分布中的随机数。

我能够在矩形分布中生成随机点,以便在 (0 <= x < 1000, 0 <= y < 1000) 的正方形内生成点:

我将如何继续生成圆内的点,以便:

(x−500)^2 + (y−500)^2 < 250000 ?

import random
import math

# radius of the circle
circle_r = 10
# center of the circle (x, y)
circle_x = 5
circle_y = 7

# random angle
alpha = 2 * math.pi * random.random()
# random radius
r = circle_r * math.sqrt(random.random())
# calculating coordinates
x = r * math.cos(alpha) + circle_x
y = r * math.sin(alpha) + circle_y

print("Random point", (x, y))

在您的示例中, circle_x是 500,而circle_y是。 circle_r是 500。

另一个版本的计算半径以获得均匀分布的点,基于这个答案

u = random.random() + random.random()
r = circle_r * (2 - u if u > 1 else u)

第一个答案:一个简单的解决方案是在继续之前检查结果是否满足您的等式。

生成 x, y(有一些方法可以随机化到一个选择范围内)

检查 ((x−500)^2 + (y−500)^2 < 250000) 是否为真,如果不是,则重新生成。

唯一的缺点是效率低下。

第二个答案:

或者,你可以做一些类似于 riemann sums 的事情,比如近似积分。 通过将其分成许多矩形来近似您的圆。 (矩形越多,越准确),并为圆内的每个矩形使用矩形算法。

你需要的是从(极性形式)采样:

r, theta = [math.sqrt(random.randint(0,500))*math.sqrt(500), 2*math.pi*random.random()]

然后,您可以通过以下方式将rtheta转换回笛卡尔坐标xy

x = 500 + r * math.cos(theta) 
y = 500 + r * math.sin(theta)

相关(虽然不是 Python),但给出了想法。

您可以使用下面的代码,如果想了解更多https://programming.guide/random-point-within-circle.html

import random
import math
circle_x = 500
circle_y = 500
a = random.randint(0,500) * 2 * math.pi
r = 1 * math.sqrt(random.randint(0,500))
x = r * math.cos(a) + circle_x
y = r * math.sin(a) + circle_y

这是一个示例,希望可以帮助某人:)。

randProba = lambda a: a/sum(a)
npoints = 5000 # points to chose from
r = 1 # radius of the circle

plt.figure(figsize=(5,5))
t = np.linspace(0, 2*np.pi, npoints, endpoint=False)
x = r * np.cos(t)
y = r * np.sin(t)
plt.scatter(x, y, c='0.8')

n = 2 # number of points to chose
t = np.linspace(0, 2*np.pi, npoints, endpoint=False)[np.random.choice(range(npoints), n, replace=False, p=randProba(np.random.random(npoints)))]
x = r * np.cos(t)
y = r * np.sin(t)

plt.scatter(x, y)

在此处输入图片说明

我会使用极坐标:

r_squared, theta = [random.randint(0,250000), 2*math.pi*random.random()]

那么 r 总是小于或等于半径,并且 theta 总是在 0 到 2*pi 弧度之间。

由于 r 不在原点,如果我理解正确,您将始终将其转换为以 500, 500 为中心的向量

x = 500 + math.sqrt(r_squared)*math.cos(theta) y = 500 + math.sqrt(r_squared)*math.sin(theta)

选择随机r_squared因为

您可以使用拒绝采样,在覆盖圆的(2r)×(2r)方格内生成一个随机点,重复直到在圆内得到一个点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM