9

可能重复:
在环内创建随机数

我想在annulus内获得一个均匀获得的随机点,即位于半径圆内R1但在半径圆外的区域R2R1 > R2两个圆都以同一点为中心。我想避免使用拒绝抽样。

如果可能的话,我希望解决方案与这个类似——用于计算圆内的随机点——我觉得它非常优雅和直观。也就是说,我也想避免使用square root

4

3 回答 3

5

它很容易。使用极坐标,即为角度值theta 生成一个随机值,为与原点的距离生成一个随机值。由于您的圈子都在同一个原点,这变得非常容易。

但是注意:您可以通过统一的随机函数生成 theta 值,这很好,但是对于您不能这样做的距离,因为那时这些点将聚集在原点周围。您必须考虑到圆的周长在 ^2 中增长(您必须使用平方根的倒数)。

使用均匀分布的随机函数rnd(0..1) 会是这样的:

theta = 360 * rnd();
dist = sqrt(rnd()*(R1^2-R2^2)+R2^2);

编辑:要转换为笛卡尔坐标,您只需计算:

x =  dist * cos(theta);
y =  dist * sin(theta);
于 2012-10-25T09:11:30.157 回答
2

编辑: 请注意,此解决方案可能不统一。请参阅下面的 Mark Dickinson 的评论。

好吧,我想我明白了。请注意,此解决方案在此答案中受到很大启发,并且 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]

简单算法的分布

它所做的是将落在内圈内的所有数字重新映射到环形空间中,均匀地分布它们。如果有人发现有关此解决方案的一致性的问题,请发表评论。

与此处找到的其他解决方案进行比较:

sqrt算法的分布

于 2012-10-25T11:20:17.340 回答
1

最简单的方法是使用拒绝抽样。在边长为 2*R2 的正方形中均匀生成大量点,然后将这些样本过滤到外圆内而不是内圆内。

不漂亮或效率不高,但在大多数情况下,足够了。

于 2012-10-25T08:57:25.963 回答