我在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());
}
这确实会在定义的圆圈中返回一个点,但是,当您多次执行此操作并绘制点数时,您可以清楚地看到大多数点将朝向中心。
这是为什么?我不知道我的数学如何做到这一点。
如果您希望我在图中添加点的图像,请注释,如果您认为这可能会有所帮助。
答案 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/