在环(环)内生成均匀随机点

Ric*_*aez 6 random math geometry probability

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

我想在一个内获得一个统一获得的随机点,即位于半径圆内R1但在半径圆外的区域R2,其中R1 > R2和两个圆都在同一点的中心.我想避免使用拒绝抽样.

如果可能的话,我希望解决方案与类似- 用于计算圆圈内的随机点 - 我发现它非常优雅和直观.也就是说,我也想避免使用平方根.

flo*_*olo 7

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

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

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

theta = 360 * rnd();
dist = sqrt(rnd()*(R1^2-R2^2)+R2^2);
Run Code Online (Sandbox Code Playgroud)

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

x =  dist * cos(theta);
y =  dist * sin(theta);
Run Code Online (Sandbox Code Playgroud)


Ric*_*aez 2

编辑: 请注意,此解决方案可能不统一。请参阅下面马克·迪金森的评论。

好吧,我想我明白了。请注意,该解决方案深受此答案的启发,并且 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)]
Run Code Online (Sandbox Code Playgroud)

这是 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]
Run Code Online (Sandbox Code Playgroud)

简单算法的分布

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

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

sqrt算法的分布

  • 这是一个简洁的答案,但不幸的是结果并不统一。如果您尝试使用例如“R2 = 0.95”和“R1 = 1.0”,您会发现靠近环面外侧的点受到青睐。生成合适的“r”的正确方法是采用随机变量“u”和“v”,其中“u”在“[R2,R1]”中统一选择,“v”在“[0,R2 + R1”中统一选择]`,然后如果“v &lt; u”则取“r = u”,如果“v &gt;= u”则取“r = R2 + R1 - u”。 (5认同)