圆方法中的随机点不是均匀分布的

时间:2017-08-02 03:04:25

标签: java math random geometry uniform-distribution

我在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());
}

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

这是为什么?我不知道我的数学如何做到这一点。

如果您希望我在图中添加点的图像,请注释,如果您认为这可能会有所帮助。

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

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

  

任务是在圆圈内生成均匀分布的数字   在(x,y)平面中的半径为R.在第一极坐标似乎   一个好主意,天真的解决方案是统一选取半径r   分布在[0,R]中,然后角度θ均匀分布   在[0,2pi]。但是,你最终会在原点附近获得积分   (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/