[英]How to generate random points in a circular distribution
I am wondering how i could generate random numbers that appear in a circular distribution.我想知道如何生成出现在循环分布中的随机数。
I am able to generate random points in a rectangular distribution such that the points are generated within the square of (0 <= x < 1000, 0 <= y < 1000):我能够在矩形分布中生成随机点,以便在 (0 <= x < 1000, 0 <= y < 1000) 的正方形内生成点:
How would i go upon to generate the points within a circle such that:我将如何继续生成圆内的点,以便:
(x−500)^2 + (y−500)^2 < 250000 ? (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))
In your example circle_x
is 500 as circle_y
is.在您的示例中,
circle_x
是 500,而circle_y
是。 circle_r
is 500. circle_r
是 500。
Another version of calculating radius to get uniformly distributed points, based on this answer另一个版本的计算半径以获得均匀分布的点,基于这个答案
u = random.random() + random.random()
r = circle_r * (2 - u if u > 1 else u)
FIRST ANSWER: An easy solution would be to do a check to see if the result satisfies your equation before proceeding.第一个答案:一个简单的解决方案是在继续之前检查结果是否满足您的等式。
Generate x, y (there are ways to randomize into a select range)生成 x, y(有一些方法可以随机化到一个选择范围内)
Check if ((x−500)^2 + (y−500)^2 < 250000) is true if not, regenerate.检查 ((x−500)^2 + (y−500)^2 < 250000) 是否为真,如果不是,则重新生成。
The only downside would be inefficiency.唯一的缺点是效率低下。
SECOND ANSWER:第二个答案:
OR, you could do something similar to riemann sums like for approximating integrals.或者,你可以做一些类似于 riemann sums 的事情,比如近似积分。 Approximate your circle by dividing it up into many rectangles.
通过将其分成许多矩形来近似您的圆。 (the more rectangles, the more accurate), and use your rectangle algorithm for each rectangle within your circle.
(矩形越多,越准确),并为圆内的每个矩形使用矩形算法。
What you need is to sample from (polar form):你需要的是从(极性形式)采样:
r, theta = [math.sqrt(random.randint(0,500))*math.sqrt(500), 2*math.pi*random.random()]
You can then transform r
and theta
back to cartesian coordinates x
and y
via然后,您可以通过以下方式将
r
和theta
转换回笛卡尔坐标x
和y
x = 500 + r * math.cos(theta)
y = 500 + r * math.sin(theta)
Related (although not Python), but gives the idea. 相关(虽然不是 Python),但给出了想法。
You can use below the code and if want to learn more https://programming.guide/random-point-within-circle.html您可以使用下面的代码,如果想了解更多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
here's an example hope could help someone :).这是一个示例,希望可以帮助某人:)。
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)
I would use polar coordinates:我会使用极坐标:
r_squared, theta = [random.randint(0,250000), 2*math.pi*random.random()]
Then r is always less than or equal to the radius, and theta always between 0 and 2*pi radians.那么 r 总是小于或等于半径,并且 theta 总是在 0 到 2*pi 弧度之间。
Since r is not at the origin, you will always convert it to a vector centered at 500, 500, if I understand correctly由于 r 不在原点,如果我理解正确,您将始终将其转换为以 500, 500 为中心的向量
x = 500 + math.sqrt(r_squared)*math.cos(theta) y = 500 + math.sqrt(r_squared)*math.sin(theta)
您可以使用拒绝采样,在覆盖圆的(2r)×(2r)
方格内生成一个随机点,重复直到在圆内得到一个点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.