Метод случайных точек в круге неравномерно распределен

У меня есть следующий метод в 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 ответа

Конечно когда r мал, сгенерированные точки ближе друг к другу.

Как сказал @DBrowne, вы можете регулировать плотность с помощью обратного трюка CDF.

Кроме того, вы можете сэкономить оценки функций, рисуя единые точки в [-R,R]x[-R,R] и отвергая те, что X²+Y²>R² (около 21% из них). Метод обобщается на любую форму, известную своим неявным уравнением.

Ваша математика ошибочна. Вот объяснение, почему и правильное решение:

Задача состоит в том, чтобы генерировать равномерно распределенные числа внутри круга радиуса R в плоскости (x,y). Сначала полярные координаты кажутся отличной идеей, и наивным решением является выбор радиуса 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/

Другие вопросы по тегам