我想在annulus内获得一个统一获得的随机点,即位于半径为R1
的圆内,但在半径为R2
的圆外的区域,其中R1 > R2
和两个圆圈都在同一点居中。我想避免使用拒绝抽样。
如果可能,我希望解决方案类似于this one - 用于计算圆内的随机点 - 我发现它非常优雅和直观。也就是说,我也想避免使用平方根。
答案 0 :(得分:2)
编辑: 请注意,此解决方案可能不一致。请参阅下面的Mark Dickinson的评论。
好的,我想我已经明白了。请注意,此解决方案受到this answer的启发,并且r1 = R1 / R1且r2 = R2 / R1。
的伪代码:
t = 2*pi*random()
u = random()+random()
r = if u>1 then 2-u else u
r = if r<r2 then r2+r*((R1-R2)/R2) else r
[r*cos(t), r*sin(t)]
这是在Mathematica。
f[] := Block[{u, t, r}, u = Random[] + Random[];
r1 = 1; r2 = 0.3;
t = Random[] 2 Pi;
r = If[u > 1, 2 - u, u];
r = If[r < r2, r2 + r*((R1 - R2)/R2), r];
{r Cos[t], r Sin[t]}]
ListPlot[Table[f[], {10000}], AspectRatio -> Automatic]
它的作用是将落入内圈内的所有数字重新映射到环空中,均匀地展开。如果有人发现有关此解决方案一致性的问题,请发表评论。
与找到here的其他解决方案进行比较:
答案 1 :(得分:1)
非常容易。使用极坐标,即为角度值θ生成一个随机值,并为距离原点生成一个随机值。由于你的圈子都是同一个起源,因此非常容易。
但请注意:你可以通过一个统一的随机函数生成theta值,这很好,但是对于你不能做到的距离,那么这些点会围绕原点聚集。 你必须考虑到圆的周长在^ 2中增长(你必须使用平方根的倒数)。
使用统一的分布式随机函数rnd
(0..1),它将是这样的:
theta = 360 * rnd();
dist = sqrt(rnd()*(R1^2-R2^2)+R2^2);
编辑:要转换为cartesion坐标,您只需计算:
x = dist * cos(theta);
y = dist * sin(theta);
答案 2 :(得分:-1)
最简单的方法是使用rejection sampling。在边长2 * R2的正方形中均匀生成大量点,然后将这些样本过滤到外圆内而不是内圆中。
不漂亮或有效,但在大多数情况下,足够。