Сформировать равномерно случайную точку в кольце (кольце)
Возможный дубликат:
Создать случайное число в кольцевом пространстве
Я хотел бы получить равномерно полученную случайную точку внутри annulus, то есть область, лежащую внутри круга радиус R1
, но вне круга радиуса R2
, где R1 > R2
и обе окружности центрированы в одной и той же точке. Я хотел бы избежать использования отбраковки.
Если возможно, я хотел бы, чтобы решение было похоже на этот > , используемый для вычисления случайных точек в круге, который я считаю чрезвычайно элегантным и интуитивным. То есть, я также хотел бы избежать использования квадратного корня.
Ответы
Ответ 1
РЕДАКТИРОВАТЬ: Обратите внимание, что это решение может быть неравномерным. См. Комментарии Марка Дикинсона ниже.
Хорошо, думаю, я понял это. Обратите внимание, что это решение сильно вдохновлено этим ответом и что r1 = R1/R1 и r2 = R2/R1.
Псевдо-код:
t = 2*pi*random()
u = random()+random()
r = if u>1 then 2-u else u
r = if r<r2 then r2+r*((R1-R2)/R2) else r
[r*cos(t), r*sin(t)]
Здесь он находится в Mathematica.
f[] := Block[{u, t, r}, u = Random[] + Random[];
r1 = 1; r2 = 0.3;
t = Random[] 2 Pi;
r = If[u > 1, 2 - u, u];
r = If[r < r2, r2 + r*((R1 - R2)/R2), r];
{r Cos[t], r Sin[t]}]
ListPlot[Table[f[], {10000}], AspectRatio -> Automatic]
![Distribution of the simple algorithm]()
То, что он делает, состоит в том, чтобы переназначить все числа, попадающие внутри внутреннего круга, в кольцевое пространство, равномерно распределяя их. Если кто-то найдет проблему относительно единообразия этого решения, прокомментируйте.
Сравните с этим другим решением здесь:
![Distribution of the sqrt algorithm]()
Ответ 2
Это очень легко. Используйте полярные координаты, т.е. Вы генерируете одно случайное значение для значения angular theta, а другое - для расстояния от начала координат. Поскольку ваши круги имеют одинаковое происхождение, это очень легко.
НО ВНИМАНИЕ: вы можете генерировать значение theta с помощью равномерной случайной функции, это нормально, но на расстояние, которое вы не можете сделать, поскольку тогда точки будут группироваться вокруг начала координат.
Вы должны учитывать, что периметр круга растет в ^ 2 (вы должны использовать инверсию, которая является квадратным корнем).
Используя однородную распределенную случайную функцию rnd
(0..1), она будет выглядеть так:
theta = 360 * rnd();
dist = sqrt(rnd()*(R1^2-R2^2)+R2^2);
EDIT. Для преобразования в координаты корзины вы просто вычисляете:
x = dist * cos(theta);
y = dist * sin(theta);
Ответ 3
Самый простой способ сделать это - использовать выборку отклонения. Сгенерируйте большое количество точек равномерно на квадрате боковой длины 2 * R2, затем отфильтруйте эти образцы по окружности, а не по внутреннему кругу.
Не очень или эффективно, но в большинстве случаев достаточно.