圆形内部随机分布的点

3

我正在使用以下代码随机生成位于圆内的一些x和y:

// r is distance from the center and a is angle
// R is radius of circle
// M is center

r = R * Math.random();
a = 2 * Math.PI * Math.random();

x = Math.round(r * Math.cos(a) + M);
y = Math.round(r * Math.sin(a) + M);

问题在于,当接近圆心时,该位置获取x,y的机会越来越大。但我想要的只是在整个圆内随机获取x,y。如何实现这一点?

一个关于这个问题的有趣讨论:Bertrand悖论(维基百科) - Robert Dodier
3个回答

4

由于雅可比行列式,您需要取平方根。

r = R *  Math.sqrt(Math.random());

这不是一个计算效率高的算法。 - Alnitak
拒绝抽样可能会更快。 - Lee Daniel Crocker

2
为了在圆内均匀分布点,只需在一个边长为2R的正方形内随机选择点,然后舍弃任何落在圆外的点。
这可以在不使用任何三角或超越运算的情况下完成。
let x, y;
do {
    x = 2 * Math.random() - 1.0;  // range [-1, +1)
    y = 2 * Math.random() - 1.0;
} while ((x * x + y * y) >= 1);   // check unit circle

// scale and translate the points
x = x * R + Mx;
y = y * R + My;

在每次循环中,大约有21.5%的点将被丢弃,但这仍然比使用sincos要快。

1
你可以在一个边长为R的正方形内生成随机的x和y,然后检查它们是否位于圆内。
x = 2 * R * Math.random()
y = 2 * R * Math.random()
r = Math.sqrt((x - M)*(x - M) + (y - M) * (y - M))
if(r < R) {
    // show x,y
}

几乎正确的答案 - 但与R ^ 2相比,避免使用昂贵的sqrt()操作。同时使用例如x = R *(Math.random()-0.5) - Alnitak
你说得对,那样更便宜 - 我只是想传达这个想法。 - Stephen O'Connor
我认为你在负坐标(缺乏)方面存在问题。 - Alnitak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接