Math 在圆内生成随机点(均匀)

Math 在圆内生成随机点(均匀),math,random,geometry,probability,Math,Random,Geometry,Probability,我需要在半径为R的圆内生成一个均匀随机点 我意识到,只要在区间[0…2π]中选取一个均匀随机的角度,在区间(0…R)中选取一个均匀随机的半径,我就会得到更多的点朝向中心,因为对于两个给定的半径,较小半径中的点将比较大半径中的点更接近彼此 我找到了一篇关于这个的博客文章,但我不理解他的推理。我想这是正确的,但我真的想了解他从哪里得到(2/R2)×r,以及他是如何得出最终解决方案的。 更新:发布这个问题7年后,我仍然没有收到关于平方根算法背后的数学的实际问题的满意答案。因此我花了一天时间自己写了一

我需要在半径为R的圆内生成一个均匀随机点

我意识到,只要在区间[0…2π]中选取一个均匀随机的角度,在区间(0…R)中选取一个均匀随机的半径,我就会得到更多的点朝向中心,因为对于两个给定的半径,较小半径中的点将比较大半径中的点更接近彼此

我找到了一篇关于这个的博客文章,但我不理解他的推理。我想这是正确的,但我真的想了解他从哪里得到(2/R2)×r,以及他是如何得出最终解决方案的。



更新:发布这个问题7年后,我仍然没有收到关于平方根算法背后的数学的实际问题的满意答案。因此我花了一天时间自己写了一个答案。

半径和“附近”的点数之间存在线性关系这个半径,所以他需要使用一个半径分布,使半径附近的数据点的数量与半径成正比。如果你有一个矩形,其中一个轴是半径,一个是角度,你在这个矩形内取接近半径0的点。这些都是错误的l非常接近原点(即在圆上靠得很近)。但是,半径R附近的点,都会落在圆的边缘附近(即彼此相距很远)

这可能会让你了解为什么会有这种行为

在该链接上导出的因子告诉您,一旦矩形映射到圆上,需要调整矩形中的相应面积,使其不依赖于半径

bool[,] getMatrix(System.Drawing.Rectangle r) {
    bool[,] matrix = new bool[r.Width, r.Height];
    return matrix;
}

void fillMatrix(ref bool[,] matrix, Vector center) {
    double radius = center.X;
    Random r = new Random();
    for (int y = 0; y < matrix.GetLength(0); y++) {
        for (int x = 0; x < matrix.GetLength(1); x++)
        {
            double distance = (center - new Vector(x, y)).Length;
            if (distance < radius) {
                matrix[x, y] = r.NextDouble() > 0.5;
            }
        }
    }

}

private void drawMatrix(Vector centerPoint, double radius, bool[,] matrix) {
    var g = this.CreateGraphics();

    Bitmap pixel = new Bitmap(1,1);
    pixel.SetPixel(0, 0, Color.Black);

    for (int y = 0; y < matrix.GetLength(0); y++)
    {
        for (int x = 0; x < matrix.GetLength(1); x++)
        {
            if (matrix[x, y]) {
                g.DrawImage(pixel, new PointF((float)(centerPoint.X - radius + x), (float)(centerPoint.Y - radius + y)));
            }
        }
    }

    g.Dispose();
}

private void button1_Click(object sender, EventArgs e)
{
    System.Drawing.Rectangle r = new System.Drawing.Rectangle(100,100,200,200);
    double radius = r.Width / 2;
    Vector center = new Vector(r.Left + radius, r.Top + radius);
    Vector normalizedCenter = new Vector(radius, radius);
    bool[,] matrix = getMatrix(r);
    fillMatrix(ref matrix, normalizedCenter);
    drawMatrix(center, radius, matrix);
}
编辑:所以他在你分享的链接中写道,“通过计算累积分布的倒数,这很容易做到,我们得到r:”

这里的基本前提是,你可以通过将均匀性映射为所需概率密度函数的累积分布函数的反函数,从均匀性中创建一个具有所需分布的变量。为什么?现在只是想当然,但这是事实

这是我对数学的一些直观的解释。密度函数f(r)相对于r必须与r本身成正比。理解这一事实是任何基本微积分书籍的一部分。参见关于极区元素的章节。其他一些海报也提到了这一点

我们称之为f(r)=C*r

这是大部分的工作。现在,因为f(r)应该是一个概率密度,你可以很容易地看到,通过在区间(0,r)上积分f(r),你可以得到C=2/r^2(这是读者的练习。)

因此,f(r)=2*r/r^2

好的,这就是你在链接中得到公式的方式

然后,最后一部分是从(0,1)中的均匀随机变量u开始,你必须通过这个期望密度f(r)的累积分布函数的反函数进行映射。要理解为什么会出现这种情况,你需要找到一个高级概率文本,比如Papoulis(或者自己推导)

积分f(r)得到f(r)=r^2/r^2

要找到这个函数的反函数,可以设置u=r^2/r^2,然后求r,得到r=r*sqrt(u)


这在直觉上也完全有道理,u=0应该映射到r=0。此外,u=1应该映射到r=r。此外,它通过平方根函数,这是有意义的,并且与链接匹配。

圆中的面积元素是dA=rdr*dphi。额外的因子r破坏了你随机选择r和phi的想法。当phi是平面分布时,r是不是,但在1/r方向是平的(即,你比“靶心”更可能击中边界)

因此,要生成均匀分布在圆上的点,请从平面分布拾取φ,从1/r分布拾取r

或者使用Mehrdad提出的蒙特卡罗方法

编辑

要在1/r中选择一个随机的r平面,你可以从区间[1/r,无穷大]中选择一个随机的x,然后计算r=1/x。然后r在1/r中均匀分布


要计算一个随机φ,从区间[0,1]中选取一个随机x,然后计算φ=2*pi*x。

这实际上取决于你所说的“一致随机”是什么意思。这是一个微妙的点,你可以在这里的wiki页面上读到更多关于它的内容:,其中相同的问题,对“一致随机”给出不同的解释,给出不同的答案

根据您选择点的方式,分布可能会有所不同,即使它们在某种意义上是均匀随机的


这篇博客文章似乎试图让它在以下意义上具有一致的随机性:如果你取圆的一个子圆,具有相同的中心,那么点落在该区域的概率与该区域的面积成正比。我相信,这是在试图遵循现在对“一致随机性”的标准解释'对于二维区域:点落在任何区域内的概率(区域定义明确)与该区域的面积成比例。

我认为在这种情况下,使用极坐标是使问题复杂化的一种方法,如果你将随机点选入一个边长为2R的正方形,然后选择点
(x,y)
,这样
x^2+y^2我曾经使用过这种方法:
这可能是完全未优化的(即它使用一个点阵列,因此无法用于较大的圆),但提供了足够的随机分布。如果愿意,您可以跳过创建矩阵并直接绘制。方法是将矩形中落在圆内的所有点随机化

bool[,] getMatrix(System.Drawing.Rectangle r) {
    bool[,] matrix = new bool[r.Width, r.Height];
    return matrix;
}

void fillMatrix(ref bool[,] matrix, Vector center) {
    double radius = center.X;
    Random r = new Random();
    for (int y = 0; y < matrix.GetLength(0); y++) {
        for (int x = 0; x < matrix.GetLength(1); x++)
        {
            double distance = (center - new Vector(x, y)).Length;
            if (distance < radius) {
                matrix[x, y] = r.NextDouble() > 0.5;
            }
        }
    }

}

private void drawMatrix(Vector centerPoint, double radius, bool[,] matrix) {
    var g = this.CreateGraphics();

    Bitmap pixel = new Bitmap(1,1);
    pixel.SetPixel(0, 0, Color.Black);

    for (int y = 0; y < matrix.GetLength(0); y++)
    {
        for (int x = 0; x < matrix.GetLength(1); x++)
        {
            if (matrix[x, y]) {
                g.DrawImage(pixel, new PointF((float)(centerPoint.X - radius + x), (float)(centerPoint.Y - radius + y)));
            }
        }
    }

    g.Dispose();
}

private void button1_Click(object sender, EventArgs e)
{
    System.Drawing.Rectangle r = new System.Drawing.Rectangle(100,100,200,200);
    double radius = r.Width / 2;
    Vector center = new Vector(r.Left + radius, r.Top + radius);
    Vector normalizedCenter = new Vector(radius, radius);
    bool[,] matrix = getMatrix(r);
    fillMatrix(ref matrix, normalizedCenter);
    drawMatrix(center, radius, matrix);
}
bool[,]getMatrix(System.Drawing.r){
bool[,]矩阵=新bool[r.宽度,r.高度];
收益矩阵;
}
空心填充矩阵(参考布尔[,]矩阵,向量中心){
双半径=中心.X;
随机r=新随机();
对于
f[] := Block[{u, t, r},
  u = Random[] + Random[];
  t = Random[] 2 Pi;
  r = If[u > 1, 2 - u, u];
  {r Cos[t], r Sin[t]}
]

ListPlot[Table[f[], {10000}], AspectRatio -> Automatic]
var X:Number = Math.random() * 2 - 1;
var YMin:Number = -Math.sqrt(1 - X * X);
var YMax:Number = Math.sqrt(1 - X * X);
var Y:Number = Math.random() * (YMax - YMin) + YMin;
var finalX:Number = X * radius + pos.x;
var finalY:Number = Y * radois + pos.y;
x = sqrt(r) * cos(angle)
y = sqrt(r) * sin(angle)
public void getRandomPointInCircle() {
    double t = 2 * Math.PI * Math.random();
    double r = Math.sqrt(Math.random());
    double x = r * Math.cos(t);
    double y = r * Math.sin(t);
    System.out.println(x);
    System.out.println(y);
}
          0          if r<=0
  CDF =   (r/R)**2   if 0 < r <= R
          1          if r > R
PDF = d/dr(CDF) = 2 * (r/R**2) (0 < r <= R).
x = ρ * cos(φ)
y = ρ * sin(φ)
from matplotlib import pyplot as plt
import numpy as np

rho = np.sqrt(np.random.uniform(0, 1, 5000))
phi = np.random.uniform(0, 2*np.pi, 5000)

x = rho * np.cos(phi)
y = rho * np.sin(phi)

plt.scatter(x, y, s = 4)
R^2 cdf[x] = x^2

x = R Sqrt[ cdf[x] ]
x = R Sqrt[ RandomReal[{0,1}] ]
r = R Sqrt[  RandomReal[{0,1}] ];
theta = 360 deg * RandomReal[{0,1}];
{r,theta}
import numpy
import math
import matplotlib.pyplot as plt

def sq_point_in_circle(r):
    """
    Generate a random point in an r radius circle 
    centered around the start of the axis
    """

    t = 2*math.pi*numpy.random.uniform()
    R = (numpy.random.uniform(0,1) ** 0.5) * r

    return(R*math.cos(t), R*math.sin(t))

R = 200 # Radius
N = 1000 # Samples

points = numpy.array([sq_point_in_circle(R) for i in range(N)])
plt.scatter(points[:, 0], points[:,1])
r = R * sqrt(random())
theta = random() * 2 * PI
x = centerX + r * cos(theta)
y = centerY + r * sin(theta)
x = r^2
sqrt(x) = r
length = random_0_1();
angle = random_0_2pi();
length = sqrt(random_0_1());
angle = random_0_2pi();