参考图片:

红色圆圈的半径为r
蓝色方块的边长为s
我的目标是在蓝色区域内生成一个随机点但不在红色区域中我已经有一个解决方案,但它涉及试错,这不是我喜欢的方法,是否有某种数学解决方案来解决这个问题?
这是我的方法
设rx和ry为随机变量
rx = random number between 0 and s
ry = random number between 0 and s
while (distance(rx,ry,0,0) < r)
{
rx = random number between 0 and s
ry = random number between 0 and s
}
return rx ry;Run Code Online (Sandbox Code Playgroud)
我建议你坚持你现在的想法,这被正式称为拒绝抽样,是一种相对常见的技术,只使用统一的随机数发生器从任意概率分布中进行采样.
随着维数增加而减速的问题简直是不可避免的 - 这通常被称为维度的诅咒.
虽然有些人建议将最终在圆圈中的点"推"到可接受/蓝色区域中的点,但在不牺牲完全一致的概率分布的情况下很难做到这一点.(例如,我可以将圆中的所有点推到圆的边界上的最近点,但这会使分布不均匀,因为圆的边界将被更频繁地采样.)
为了使您的代码尽可能高效,您应该在(distance(rx,ry,0,0)不调用任何函数的情况下进行计算,并使用主动运算符喜欢+和*,而不是像任何库函数exp(x,2).换句话说,x*x + y*y < r2直接在if语句中使用(在r2 = r*r;预定义的某处).
我不会参与数学与编程的讨论。对我来说这个问题两者都有。这是我的看法。
你可以尝试将[0,1]区间内生成的点映射到蓝色区域。如果两个形状都是同心圆,这应该给出正态分布。当你有一个正方形时,越靠近对角线,点就会越稀疏。
这个想法是在极坐标下工作:
(x,y)位置(0,0)。a生成区间内的数字[0,1]。w = 2 * pi * a。这将是您的极角。该方程y = x * tan(w)定义了一条穿过图片中心的直线。r并小于步骤 3 中定义的直线与正方形的交点。w“顶”侧适用于值从pi/4到 的情况3pi/4;“左侧”的w范围是从3pi/4到5pi/4;“底面”在和w之间;“右”侧有从到和从到。5pi/47pi/4w7pi/42pi0pi/4y = s / 2。3 中定义的线与顶边的交点位于位置s/2 = xi tan(w)。(xi, s/2)定义 rho 的最大值:R = sqrt(xi^2 + (s/2)^2)b现在在[0,1]区间内生成另一个值rho = r + b * RX = rho * cos(w),Y = rho * sin(w)它应该在蓝色区域。请注意,从第 5 步开始,您必须检查正方形的哪一侧是您应该考虑的一侧( 的值w)。
如上所述,问题在于对角线比沿主轴的方向更长,从而产生更稀疏的分布。这是否是一个问题取决于您。请注意,映射不会堆积靠近圆边缘的点。还要问问自己,对方向的检查是否实用(我假设正方形和圆形是您真正想要的粗略近似值)。