簡體   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