0

我在Java中有以下方法:

public static Vector2d random(Circle circle) {
    // this returns a random number between 0 and Math.PI * 2
    double angle = MathUtils.random(0, Math.PI * 2);
    // give the point inside the unit circle
    // this returns a normalized vector from a given angle
    Vector2d point = new Vector2d(angle);
    // however, this is only along the edge
    // now add a random magnitude (because this is a normalized vector, we can just multiply it by the desired magnitude)
    double magnitude = Math.random();
    point = point.multiply(magnitude);
    // now expand this to fit the radius
    point = point.multiply(circle.getRadius());
    // now translate by circleCenter
    return point.add(circle.getCenter());
}

这确实会在定义的圆圈中返回一个点,但是,当您多次执行此操作并绘制点时,您可以清楚地看到大多数点将朝向中心。

为什么是这样?我不明白我的数学怎么能做到这一点。

如果您希望我在情节上添加点的图像,请发表评论,如果您认为这可能会有所帮助。

4

2 回答 2

2

当然,当r较小时,生成的点彼此更接近。

正如@DBrowne 所说,您可以通过逆 CDF 技巧调整密度。

或者,您可以通过绘制统一的点[-R,R]x[-R,R]并拒绝那些X²+Y²>R²(大约 21%)的点来节省功能评估。该方法推广到其隐式方程已知的任何形状。

于 2017-08-02T10:29:36.537 回答
1

你的数学有问题。以下是原因和正确解决方案的解释:

任务是在 (x,y) 平面中半径为 R 的圆内生成均匀分布的数字。起初极坐标似乎是个好主意,而简单的解决方案是选择均匀分布在 [0, R] 中的半径 r,然后选择均匀分布在 [0, 2pi] 中的角度 theta。但是,您最终会在原点 (0, 0) 附近获得大量点!这是错误的,因为如果我们查看某个角度间隔,比如 [theta, theta+dtheta],则需要在更远的地方(在大 r 处)生成更多的点,而不是接近于零。半径不能从均匀分布中选取,而是从

pdf_r = (2/R^2)*r

通过计算累积分布的倒数很容易做到这一点,我们得到 r:

r = R*sqrt(rand())

其中 rand() 是 [0, 1] 中的均匀随机数

http://www.anderswallin.net/2009/05/uniform-random-points-in-a-circle-using-polar-coordinates/

于 2017-08-02T03:10:59.980 回答