Как найти случайную точку в четырехугольниках?

Я должен быть в состоянии установить случайное местоположение для путевой точки для полета sim. Задача математики проста:

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

Визуально вот так:

alt text

Например, четырехугольник ABCD: A: [21417.78 37105.97] B: [38197,3224009,74] C: [1364,19 2455,54] D: [1227.77 37378.81]

Заранее благодарим за любую помощь, которую вы можете предоставить.: -)

ИЗМЕНИТЬ Спасибо всем за ваши ответы. Я посмотрю на это на выходных и тогда приму признательный ответ. Кстати, я должен был упомянуть, что четырехугольник может быть CONVEX ИЛИ CONCAVE. Sry 'bout dat.

Ответ 1

Разделите ваш четырехangularьник на два треangularьника и затем используйте этот превосходный ответ SO, чтобы быстро найти случайную точку в одном из них.

Обновление:

Заимствование этой замечательной ссылки у Акусте при выборе случайной точки в треangularьнике.

main figure
(из MathWorld - веб-ресурс Wolfram: wolfram.com)

Дан треangularьник с одной вершиной в Происхождение и другие в позициях v 1 и v 2, выберите x
(из MathWorld - веб-ресурс Wolfram: wolfram.com)
 где A 1 и A 2 одинаковы изменяется в интервале [0,1], что дает точки равномерно распределены в четырехangularьник (левая фигура). точки не в интерьере треangularьника затем может быть либо отброшен, либо превращается в соответствующий указать внутри треangularьника (справа рисунок).

Ответ 2

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

Первый, упомянутый другими плакатами, - это найти самый маленький ограничивающий прямоугольник, который окружает прямоугольник, а затем создавать точки в этом поле, пока не найдете точку, которая находится внутри прямоугольника.

  Find Bounding box (x,y,width, height)
  Pick Random Point x1,y1 with ranges [x to x+width] and [y to y+height]
  while (x1 or y1 is no inside the quadrangle){
       Select new x1,y1
  }

Предполагая, что ваша область четырехугольника равна Q, а ограничивающий прямоугольник равен A, вероятность того, что вам нужно будет генерировать N пар точек, равна 1- (Q/A) ^ N, которая приближается к экспоненциальному экспоненциально.

Я бы рекомендовал вышеупомянутый подход, в двух измерениях. Очень быстро создавать точки и тестировать.

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

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

Дает очень хорошее объяснение

Ответ 3

Подход "грубой силы" просто прокручивается до тех пор, пока у вас не будет действительной координаты. В псевдокоде:

left   = min(pa.x, pb.x, pc.x, pd.x)
right  = max(pa.x, pb.x, pc.x, pd.x)
bottom = min(pa.y, pb.y, pc.y, pd.y)
top    = max(pa.y, pb.y, pc.y, pd.y)
do {
    x = left   + fmod(rand, right-left)
    y = bottom + fmod(rand, top-bottom)
} while (!isin(x, y, pa, pb, pc, pd));

Вы можете использовать функцию запаса, вытащенную из сети для "isin". Я понимаю, что это не самая быстрая вещь в мире, но я думаю, что это сработает.

Ответ 4

Итак, на этот раз мы рассмотрим, как определить, находится ли точка в квадрате:

Четыре ребра могут быть выражены в виде строк в форме y = mx + b. Проверьте, находится ли точка выше или ниже каждой из четырех линий, и вместе взятые вы можете выяснить, находится ли она внутри или снаружи.

Ответ 5

Вам разрешено просто повторять попытку в любом месте прямоугольника, который ограничивает четырехугольник, пока вы не получите что-то внутри квадроцикла? Может быть, это даже быстрее, чем какой-нибудь фантастический алгоритм, чтобы убедиться, что вы выбрали что-то в квадрате?

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

Ответ 6

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

Итак:

  • Найдите поле, содержащее все точки вашего многоугольника.
  • Создайте случайную точку внутри границ найденного ранее окна. Используйте случайные функции для генерации значений x и y.
  • Проверьте, находится ли эта точка внутри многоугольника (см. здесь или здесь)
  • Если эта точка находится внутри остановки многоугольника, вы закончите, если не переходите к шагу 2

Ответ 7

Я бы разделил ваш четырехугольник на несколько фигур, где каждая фигура является регулярным многоугольником с одной стороны (или с обеих сторон), параллельной одной из осей. Например, для фигуры выше я бы сначала нашел максимальный прямоугольник, который вписывается в четырехугольник, прямоугольник должен быть параллелен осям X/Y. Тогда в оставшейся области я бы поместил треугольники, такие треугольники будут смежными с каждой стороной прямоугольника.

то просто написать функцию:

1) получить фигуру наугад. 2) найдите случайную точку на рисунке.

Если фигура, выбранная в # 1, является прямоугольником, в ней должно быть довольно легко найти случайную точку. Трудная часть состоит в том, чтобы написать процедуру, которая может найти случайную точку внутри треугольника

Ответ 8

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

Здесь алгоритм:

  • Выберите случайную точку, которая находится внутри прямоугольника, который ограничивает четырехугольник.
  • Если он не находится в пределах четырехугольника (или любой другой формы), повторите.
  • Profit!

изменить

Я обновил первый шаг, указав ограничительную рамку, по предложению Барта К.

Ответ 9

Итак, это зависит от того, как вы хотите, чтобы ваш дистрибутив.

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

Билинейная интерполяция довольно проста. Создайте два случайных числа s и t в диапазоне [0..1]. Тогда, если ваши входные точки p0, p1, p2, p3, билинейная интерполяция:

bilerp(s,t) = t*(s*p3+(1-s)*p2) + (1-t)*(s*p1+(1-s)*p0)

Основное различие заключается в том, хотите ли вы, чтобы ваше распределение было равномерным в вашем 2d-пространстве (метод Якова) или равномерным в пространстве параметров.