Создайте случайную точку внутри круга (равномерно)

Мне нужно создать равномерно случайную точку в круге радиуса R.

Я понимаю, что, просто выбирая равномерно случайный угол в интервале [0... 2π) и равномерно случайный радиус в интервале (0... R), я получаю больше точек к центру, так как для двух заданных радиусы, точки меньшего радиуса будут ближе друг к другу, чем точки большего радиуса.

Я нашел запись в блоге по этому поводу здесь, но я не понимаю его рассуждения. Я полагаю, что это правильно, но я бы очень хотел понять, откуда он (2/R 2) × r, и как он получает окончательное решение.


Обновление: через 7 лет после публикации этого вопроса я до сих пор не получил удовлетворительного ответа на фактический вопрос относительно математики за алгоритмом квадратного корня. Поэтому я потратил целый день на письменный ответ. Ссылка на мой ответ.

Ответ 1

Как сгенерировать случайную точку внутри круга радиуса R:

r = R * sqrt(random())
theta = random() * 2 * PI

(Предполагая, что random() дает значение от 0 до 1 равномерно)

Если вы хотите преобразовать это в декартовы координаты, вы можете сделать

x = centerX + r * cos(theta)
y = centerY + r * sin(theta)


Почему sqrt(random())?

Давайте посмотрим на математику, которая приводит к sqrt(random()). Предположим для простоты, что мы работаем с единичным кругом, т.е. R = 1.

Среднее расстояние между точками должно быть одинаковым независимо от того, как далеко от центра мы смотрим. Это означает, например, что, глядя на периметр окружности с окружностью 2, мы должны найти вдвое больше точек, чем количество точек на периметре окружности с окружностью 1.


pVRoc.png

Поскольку окружность окружности (2π r) растет линейно с ростом r, отсюда следует, что число случайных точек должно расти линейно с ростом r. Другими словами, искомая функция плотности вероятности (PDF) растет линейно. Так как PDF должен иметь площадь, равную 1, а максимальный радиус равен 1, мы имеем


fSjce.png

Итак, мы знаем, как должна выглядеть желаемая плотность наших случайных значений. Теперь: как мы генерируем такое случайное значение, когда все, что у нас есть, это равномерное случайное значение между 0 и 1?

Мы используем трюк, называемый выборкой обратного преобразования

  1. Из PDF создайте накопительную функцию распределения (CDF)
  2. Отразите это вдоль y = x
  3. Примените полученную функцию к равномерному значению от 0 до 1.

Звучит сложно? Позвольте мне вставить желтое поле с небольшим боковым отступом, которое передает интуицию:

Предположим, мы хотим создать случайную точку со следующим распределением:

tZWu8.png

То есть

  • 1/5 баллов равномерно между 1 и 2, и
  • 4/5 баллов равномерно между 2 и 3.

CDF - это, как следует из названия, кумулятивная версия PDF. Интуитивно понятно: в то время как PDF (x) описывает количество случайных значений в точке x, CDF (x) описывает количество случайных значений меньше значения x.

В этом случае CDF будет выглядеть так:

uK9tl.png

Чтобы увидеть, как это полезно, представьте, что мы стреляем пулями слева направо на равномерно распределенных высотах. Когда пули попадают в линию, они падают на землю:

UkUCk.png

Посмотрите, как плотность пуль на земле соответствует нашему желаемому распределению! Мы почти там!

Проблема в том, что для этой функции ось y является выходной, а ось x является входной. Мы можем только "стрелять пулями прямо с земли"! Нам нужна обратная функция!

Вот почему мы отражаем все это; х становится у, а у становится х:

219SY.png

Мы называем это CDF -1. Чтобы получить значения в соответствии с желаемым распределением, мы используем CDF -1 (random()).

… Итак, вернемся к генерации случайных значений радиуса, где наш PDF равен 2 х.

Шаг 1: Создайте CDF:

Поскольку мы работаем с реалами, CDF выражается как интеграл PDF.

CDF (x) = ∫ 2 x= x 2

Шаг 2: Зеркально отразите CDF вдоль y = x:

Математически это сводится к обмену x и y и решению для y:

CDF: y = x 2
Обмен: х = у 2
Решить: у = √ х
CDF -1: y = √ x

Шаг 3: применить полученную функцию к равномерному значению от 0 до 1

CDF -1 (random()) = √random()

Что мы и собираемся извлечь :-)

Ответ 2

Подходим к этому, как это сделал Архимед.

Как мы можем генерировать точку равномерно в треугольнике ABC, где | AB | = | BC |? Позвольте сделать это проще, перейдя к параллелограмму ABCD. Легко создавать точки равномерно в ABCD. Мы равномерно выбираем случайную точку X на AB и Y на BC и выбираем Z такой, что XBYZ является параллелограммом. Чтобы получить равномерно выбранную точку в исходном треугольнике, мы просто складываем любые точки, которые появляются в ADC, обратно вниз до ABC вдоль AC.

Теперь рассмотрим круг. В пределе мы можем рассматривать это как бесконечное множество изоцелевых треугольников ABC с B в начале координат и A и C на окружности, исчезающе близкой друг к другу. Мы можем выбрать один из этих треугольников, просто выбрав угол тета. Поэтому нам нужно создать расстояние от центра, выбрав точку в ABC. Опять же, переходим к ABCD, где D теперь вдвое больше радиуса от центра окружности.

Выбор случайной точки в ABCD легко с использованием вышеуказанного метода. Выберите случайную точку на AB. Равномерно выберите случайную точку на ВС. То есть. выберем пару случайных чисел х и у равномерно на [0, R], давая расстояния от центра. Наш треугольник - тонкая лента, так что AB и BC по существу параллельны. Таким образом, точка Z является просто расстоянием x + y от начала координат. Если x + y > R отбрасываем назад.

Здесь полный алгоритм для R = 1. Надеюсь, вы согласитесь на это довольно просто. Он использует триггер, но вы можете дать гарантию того, сколько времени потребуется, и сколько ему нужно random(), в отличие от выборки отбраковки.

t = 2*pi*random()
u = random()+random()
r = if u>1 then 2-u else u
[r*cos(t), r*sin(t)]

Здесь он находится в Mathematica.

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]

enter image description here

Ответ 3

Вот быстрое и простое решение.

Выберите два случайных числа в диапазоне (0, 1), а именно a и b. Если b < a, замените их. Ваша точка (b*R*cos(2*pi*a/b), b*R*sin(2*pi*a/b)).

Вы можете подумать об этом решении следующим образом. Если бы вы взяли круг, разрезали его, а затем выпрямили, вы получили прямоугольный треугольник. Масштабируйте треугольник вниз, и у вас будет треугольник от (0, 0) до (1, 0) до (1, 1) и обратно до (0, 0). Все эти преобразования меняют плотность равномерно. То, что вы сделали, равномерно выбрали случайную точку в треугольнике и изменило процесс, чтобы получить точку в круге.

Ответ 4

Обратите внимание на плотность точек пропорционально обратному квадрату радиуса, поэтому вместо того, чтобы выбирать r из [0, r_max], выберите из [0, r_max^2], затем вычислите свои координаты как:

x = sqrt(r) * cos(angle)
y = sqrt(r) * sin(angle)

Это даст вам равномерное распределение точек на диске.

http://mathworld.wolfram.com/DiskPointPicking.html

Ответ 5

Подумайте об этом так. Если у вас есть прямоугольник, где одна ось равна радиусу, а одна - углу, и вы берете точки внутри этого прямоугольника, близкие к радиусу 0. Все они будут очень близки к началу координат (это близко к кругу). Однако, точки вблизи радиуса R, все они будут падать рядом с краем круга (то есть далеко друг от друга).

Это может дать вам некоторое представление о том, почему вы получаете такое поведение.

Коэффициент, полученный на этой ссылке, указывает вам, насколько соответствующая область в прямоугольнике должна быть скорректирована так, чтобы не зависеть от радиуса, когда она была сопоставлена ​​с кругом.

Изменить: Итак, что он пишет в ссылке, которую вы разделяете: "Это достаточно легко сделать, вычисляя обратное кумулятивное распределение, и мы получаем для r:".

Основная предпосылка заключается в том, что вы можете создать переменную с желаемым распределением из равномерной путем сопоставления равномерной обратной функцией кумулятивной функции распределения желаемой функции плотности вероятности. Зачем? Просто возьмите это как должное, но это факт.

Вот мое немного интуитивное объяснение математики. Функция плотности f (r) по r должна быть пропорциональна самой r. Понимание этого факта является частью любых базовых книг по исчислению. См. Разделы о полярных элементах. Некоторые другие плакаты упомянули об этом.

Итак, будем называть его f (r) = C * r;

Это, как оказалось, большая часть работы. Теперь, так как f (r) должна быть плотностью вероятности, нетрудно видеть, что интегрируя f (r) на интервале (0, R), вы получаете, что C = 2/R ^ 2 (это упражнение для читателя.)

Таким образом, f (r) = 2 * r/R ^ 2

ОК, так как вы получите формулу в ссылке.

Тогда конечная часть идет от равномерной случайной величины u в (0,1), которую вы должны отобразить обратной функцией кумулятивной функции распределения из этой требуемой плотности f (r). Чтобы понять, почему это так, вам нужно найти расширенный текст вероятности, например, Папулис (или получить его самостоятельно).

Интегрируя f (r), вы получаете F (r) = r ^ 2/R ^ 2

Чтобы найти обратную функцию этого, вы задаете u = r ^ 2/R ^ 2, а затем решим для r, что дает вам r = R * sqrt (u)

Это тоже имеет смысл интуитивно, u = 0 следует отображать в r = 0. Кроме того, u = 1 shoudl map to r = R. Кроме того, это функция квадратного корня, которая имеет смысл и соответствует ссылке.

Ответ 6

Причина, по которой наивное решение не работает, заключается в том, что она дает более высокую плотность вероятности точкам, расположенным ближе к центру окружности. Другими словами, круг с радиусом r/2 имеет вероятность r/2 получения выбранной в нем точки, но имеет площадь (количество точек) pi * r ^ 2/4.

Поэтому мы хотим, чтобы плотность вероятности радиуса имела следующее свойство:

Вероятность выбора радиуса, меньшего или равного заданному r, должна быть пропорциональна площади окружности с радиусом r. (потому что мы хотим иметь равномерное распределение по точкам, а большие области - больше очков)

Другими словами, мы хотим, чтобы вероятность выбора радиуса между [0, r] была равна его доле общей площади круга. Общая площадь окружности равна pi * R ^ 2, а площадь круга с радиусом r равна pi * r ^ 2. Таким образом, мы хотели бы, чтобы вероятность выбора радиуса между [0, r] была (pi * r ^ 2)/(pi * R ^ 2) = r ^ 2/R ^ 2.

Теперь идет математика:

Вероятность выбора радиуса между [0, r] является интегралом от p (r) dr от 0 до r (это только потому, что мы добавляем все вероятности меньших радиусов). Таким образом, мы хотим, чтобы интеграл (p (r) dr) = r ^ 2/R ^ 2. Мы можем ясно видеть, что R ^ 2 является константой, поэтому нам нужно всего лишь выяснить, какая из p (r), когда интегрированная даст нам нечто вроде r ^ 2. Ответ явно r * постоянный. интеграл (r * const dr) = r ^ 2/2 * постоянный. Это должно быть равно r ^ 2/R ^ 2, поэтому константа = 2/R ^ 2. Таким образом, у вас есть распределение вероятности p (r) = r * 2/R ^ 2

Примечание. Еще один интуитивный способ подумать о проблеме состоит в том, чтобы представить, что вы пытаетесь дать каждой окружности радиуса вероятности вероятности равную пропорции количества очков, которые она имеет на своем длина окружности. Таким образом, окружность с радиусом r будет иметь 2 * pi * r "точки" по ее окружности. Общее число точек pi * R ^ 2. Таким образом, вы должны дать окружности r вероятность, равную (2 * pi * r)/(pi * R ^ 2) = 2 * r/R ^ 2. Это намного легче понять и более интуитивно понятным, но это не так, как математически здорово.

Ответ 7

Это действительно зависит от того, что вы подразумеваете под "равномерно случайным". Это тонкая точка, и вы можете прочитать больше об этом на странице wiki здесь: http://en.wikipedia.org/wiki/Bertrand_paradox_%28probability%29, где та же проблема, дающая разные интерпретации "равномерно случайный" дает разные ответы!

В зависимости от того, как вы выбираете точки, распределение может меняться, хотя они в какой-то мере равномерны.

Кажется, что запись в блоге пытается сделать его равномерным случайным в следующем смысле: если вы возьмете субкруг круга с тем же центром, то вероятность того, что точка попадет в эту область, пропорциональна области региона. Это, я считаю, пытается следовать теперь стандартной интерпретации "равномерно случайных" для 2D-областей с областями, определенными на них: вероятность точки падение в любой области (с четко определенной областью) пропорционально площади этой области.

Ответ 8

Пусть ρ (радиус) и φ (азимут) две случайные величины, соответствующие полярным координатам произвольной точки внутри окружности. Если точки распределены равномерно, то какова функция распределения ρ и φ?

Для любого r: 0 <r <R вероятность радиусной координаты ρ меньше r равна

P [ρ <r] = P [точка находится в окружности радиуса r] = S1/S0 = (r/R) 2

Где S1 и S0 - площади круга радиуса r и R соответственно. Таким образом, CDF может быть дан как:

          0          if r<=0
  CDF =   (r/R)**2   if 0 < r <= R
          1          if r > R

И PDF:

PDF = d/dr(CDF) = 2 * (r/R**2) (0 < r <= R).

Обратите внимание, что для R = 1 случайная величина sqrt (X), где X равномерно на [0, 1), имеет этот точный CDF (потому что P [sqrt (X) <y] = P [x <y ** 2] = y * * 2 для 0 <y <= 1).

Распределение φ очевидно равномерно от 0 до 2 * π. Теперь вы можете создавать случайные полярные координаты и преобразовывать их в декартовы, используя тригонометрические уравнения:

x = ρ * cos(φ)
y = ρ * sin(φ)

Не могу удержаться, чтобы опубликовать код Python для R = 1.

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)

Ты получишь

enter image description here

Ответ 9

Вот мой код Python для генерации num случайных точек из круга радиуса rad:

import matplotlib.pyplot as plt
import numpy as np
rad = 10
num = 1000

t = np.random.uniform(0.0, 2.0*np.pi, num)
r = rad * np.sqrt(np.random.uniform(0.0, 1.0, num))
x = r * np.cos(t)
y = r * np.sin(t)

plt.plot(x, y, "ro", ms=1)
plt.axis([-15, 15, -15, 15])
plt.show()

Ответ 10

Я думаю, что в этом случае использование полярных координат является способом усложнения задачи, было бы намного проще выбрать случайные точки в квадрат со сторонами длины 2R и затем выбрать точки (x,y) такие, что x^2+y^2<=R^2.

Ответ 11

Решение в Java и пример распространения (2000 точек)

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);
}

Распределение 2000 баллов

на основе решения previum fooobar.com/questions/41617/... из @sigfpe

Ответ 12

Сначала мы сгенерируем cdf [x], который является

Вероятность того, что точка меньше расстояния x от центра круга. Предположим, что окружность имеет радиус R.

очевидно, если x равно нулю, то cdf [0] = 0

очевидно, если x равно R, то cdf [R] = 1

очевидно, если x = r, то cdf [r] = (Pi r ^ 2)/(Pi R ^ 2)

Это связано с тем, что каждая "небольшая область" на круге имеет такую ​​же вероятность быть выбрана, поэтому вероятность пропорциональна этой области. А площадь, заданная на расстоянии x от центра круга, равна Pi r ^ 2

поэтому cdf [x] = x ^ 2/R ^ 2, потому что Pi отменяют друг друга

имеем cdf [x] = x ^ 2/R ^ 2, где x переходит от 0 в R

Итак, мы решаем для x

R^2 cdf[x] = x^2

x = R Sqrt[ cdf[x] ]

Теперь мы можем заменить cdf на случайное число от 0 до 1

x = R Sqrt[ RandomReal[{0,1}] ]

Наконец

r = R Sqrt[  RandomReal[{0,1}] ];
theta = 360 deg * RandomReal[{0,1}];
{r,theta}

получаем полярные координаты   {0,601168 R, 311,915 град.}

Ответ 13

Существует линейная зависимость между радиусом и числом точек "около" этого радиуса, поэтому ему необходимо использовать распределение радиуса, которое также делает число точек данных вблизи радиуса r пропорциональным r.

Ответ 14

Элемент области в круге равен dA = rdr * dphi. Этот дополнительный фактор разрушил вашу идею, чтобы случайным образом выбрать r и phi. В то время как phi распределена плоской, r не является, а плоской в ​​1/r (то есть вы с большей вероятностью попадете на границу, чем "бычий глаз" ).

Итак, чтобы создать точки, равномерно распределенные по кругу, выбрать phi из плоского распределения и r из распределения 1/r.

В качестве альтернативы можно использовать метод Монте-Карло, предложенный Мехрдадом.

ИЗМЕНИТЬ

Чтобы выбрать случайную r плоскую в 1/r, вы можете выбрать случайный x из интервала [1/R, бесконечность] и вычислить r = 1/x. r затем распределяется плотно в 1/r.

Чтобы вычислить случайный phi, выберите случайный x из интервала [0, 1] и вычислим phi = 2 * pi * x.

Ответ 15

Я использовал этот метод: Это может быть совершенно неоптимизировано (т.е. Использует массив точек, поэтому он непригоден для больших кругов), но дает случайное распределение. Вы можете пропустить создание матрицы и нарисовать напрямую, если хотите. Метод состоит в том, чтобы рандомизировать все точки в прямоугольнике, которые попадают внутрь круга.

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);
}

enter image description here

Ответ 16

Я не знаю, открыт ли этот вопрос для нового решения со всем ответом, который уже был дан, но я столкнулся с одним и тем же вопросом. Я попытался "разгадать" себя для решения, и нашел его. Это может быть то же самое, что некоторые из них уже предложены здесь, но в любом случае это:

для того, чтобы два элемента поверхности окружности были равны, если принять равные dr, мы должны иметь dtheta1/dtheta2 = r2/r1. Написание выражения вероятности для этого элемента как P (r, theta) = P {r1 < г < r1 + dr, theta1 < тета < theta + dtheta1} = f (r, theta) * dr * dtheta1 и устанавливая две вероятности (при r1 и r2) равными, мы приходим к (если r и theta независимы) f (r1)/r1 = f (r2 )/r2 = constant, что дает f (r) = c * r. Остальное, определяющее константу c, следует из условия, когда f (r) является PDF.

Ответ 17

Решение для программистов:

  • Создайте битовую карту (матрицу логических значений). Он может быть как можно большим.
  • Нарисуйте круг в этой битовой карте.
  • Создайте таблицу поиска точек окружности.
  • Выберите случайный индекс в этой таблице поиска.
const int RADIUS = 64;
const int MATRIX_SIZE = RADIUS * 2;

bool matrix[MATRIX_SIZE][MATRIX_SIZE] = {0};

struct Point { int x; int y; };

Point lookupTable[MATRIX_SIZE * MATRIX_SIZE];

void init()
{
  int numberOfOnBits = 0;

  for (int x = 0 ; x < MATRIX_SIZE ; ++x)
  {
    for (int y = 0 ; y < MATRIX_SIZE ; ++y)
    {
      if (x * x + y * y < RADIUS * RADIUS) 
      {
        matrix[x][y] = true;

        loopUpTable[numberOfOnBits].x = x;
        loopUpTable[numberOfOnBits].y = y;

        ++numberOfOnBits;

      } // if
    } // for
  } // for
} // ()

Point choose()
{
  int randomIndex = randomInt(numberOfBits);

  return loopUpTable[randomIndex];
} // ()

Растровое изображение необходимо только для объяснения логики. Это код без растрового изображения:

const int RADIUS = 64;
const int MATRIX_SIZE = RADIUS * 2;

struct Point { int x; int y; };

Point lookupTable[MATRIX_SIZE * MATRIX_SIZE];

void init()
{
  int numberOfOnBits = 0;

  for (int x = 0 ; x < MATRIX_SIZE ; ++x)
  {
    for (int y = 0 ; y < MATRIX_SIZE ; ++y)
    {
      if (x * x + y * y < RADIUS * RADIUS) 
      {
        loopUpTable[numberOfOnBits].x = x;
        loopUpTable[numberOfOnBits].y = y;

        ++numberOfOnBits;
      } // if
    } // for
  } // for
} // ()

Point choose()
{
  int randomIndex = randomInt(numberOfBits);

  return loopUpTable[randomIndex];
} // ()

Ответ 18

Я все еще не уверен в точном '(2/R2) × r', но очевидно, что количество точек, которые необходимо распределить в данной единице 'dr', то есть увеличение r будет пропорционально r2, а не р.

проверьте этот путь... число точек под некоторым углом tta и между r (0.1r до 0.2r), то есть доля r и количество точек между r (0.6r to 0.7r) будут равны, если вы используете стандартная генерация, так как разница составляет всего 0,1r между двумя интервалами. но поскольку площадь, покрываемая между точками (0.6r до 0.7r), будет намного больше, чем площадь, лежащая между 0.1r до 0.2r, равное количество точек будет рассеянно разнесено в большей области, это я предполагаю, что вы уже знаете, поэтому функция для генерации случайных точек не должно быть линейным, но квадратичным (так как число точек, требуемых для распределения в данной единице "dr", то есть увеличение r будет пропорционально r2, а не r), поэтому в этом случае оно будет обратным квадратично, так как дельта у нас (0.1r) в обоих интервалах должна быть квадратной некоторой функции, поэтому она может действовать как начальное значение для линейной генерации точек (так как послесловие это семя используется линейно по функции sin и cos), поэтому мы знаете, dr должно быть квадратичным значением и сделать это семена квадратичным, нам нужно вывести эти значения из квадратного корня из r не r, я надеюсь, что это делает его более понятным.

Ответ 19

Такая забавная проблема.
Объяснение вероятности того, что выбранная точка опускается как расстояние от начала оси, объясняется несколько раз выше. Мы учитываем это, беря корень из U [0,1]. Здесь общее решение для положительного r в Python 3.

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])

enter image description here

Ответ 20

Вы также можете использовать свою интуицию.

Площадь круга равна pi*r^2

При r=1

Это дает нам область pi. Предположим, что мы имеем некоторую функцию f, которая равномерно распределяла бы N=10 точек внутри круга. Соотношение здесь 10/pi

Теперь мы удваиваем площадь и количество точек

При r=2 и N=20

Это дает площадь 4pi и теперь соотношение составляет 20/4pi или 10/2pi. Отношение будет становиться все меньше и меньше, чем больше радиус, так как его рост квадратичен, а N линейно.

Чтобы исправить это, мы можем просто сказать

x = r^2
sqrt(x) = r

Если вы создадите вектор в полярных координатах, как это

length = random_0_1();
angle = random_0_2pi();

Больше очков приземлится вокруг центра.

length = sqrt(random_0_1());
angle = random_0_2pi();

length уже не равномерно распределена, но теперь вектор будет равномерно распределен.

Ответ 21

1) Выберите случайный X между -1 и 1.

var X:Number = Math.random() * 2 - 1;

2) Используя формулу окружности, вычислим максимальное и минимальное значения Y, учитывая, что X и радиус 1:

var YMin:Number = -Math.sqrt(1 - X * X);
var YMax:Number = Math.sqrt(1 - X * X);

3) Выберите случайный Y между этими крайностями:

var Y:Number = Math.random() * (YMax - YMin) + YMin;

4) Включите ваши значения местоположения и радиуса в конечном значении:

var finalX:Number = X * radius + pos.x;
var finalY:Number = Y * radois + pos.y;