Найдите середину перекрытия между кругом и прямоугольником

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

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

Я представляю каждую форму в основном:

Круг:

  • float x, y (в центре)
  • поплавок r (радиус)

Прямоугольник:

  • float x, y (в центре)
  • float w, h (значения ширины и высоты, они представляют собой расстояние по осям x и y от центра до соответствующего края).

РЕДАКТИРОВАТЬ:

Поскольку, похоже, возникла путаница по поводу того, что я имею в виду под «средней точкой», позвольте мне уточнить:

Учитывая, что круг и прямоугольник пересекаются, существует область, созданная их перекрытием. Я хочу определить географический центр этой области (либо точно, либо определить приблизительно).

Пример: http://en.wikipedia.org/wiki/Centroid.


РЕДАКТИРОВАТЬ № 2:

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


Заключительные мысли:

Я пометил ответ Гарета как принятый, потому что он дал мне идеи относительно того, что я в конечном итоге использовал, но моя окончательная реализация отличается от его, поэтому я объясню это здесь.

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

Метод 1. Фрагментация формы:

Пример фрагментации формы

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

В показанном здесь примере есть три части: центральный прямоугольник, занимающий большую часть площади, и два изогнутых сегмента для краев круга.

Метод 2: интерполяция строк

Пример интерполяции строк

Во-первых, вам нужно вычислить точку в прямоугольнике, которая будет базовым местоположением. Это должна быть точка, которую легко вычислить, и она должна совпадать. Для этой точки я использую среднее значение всех пересечений краев круга и прямоугольника (если пересечений краев не существует, я по умолчанию использую расположение круга, поскольку это означает, что одна форма содержится внутри другой).

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

Этот метод неточен, но всегда создает точку внутри обоих объектов, а результирующая точка, как правило, находится близко к середине (так что обычному глазу она "выглядит" хорошо). Кроме того, это намного проще и быстрее, поэтому я пошел с этим.


person CodeBunny    schedule 11.03.2012    source источник
comment
Что вы имеете в виду под серединой? Вам нужен центроид?   -  person Gareth Rees    schedule 11.03.2012
comment
Центр пересекаемой области.   -  person CodeBunny    schedule 11.03.2012
comment
Также имейте в виду, что круг и прямоугольник могут пересекаться по-разному.   -  person Oliver Charlesworth    schedule 11.03.2012
comment
@CodeBunny: Хорошо, определите центр пересекаемой области.   -  person Oliver Charlesworth    schedule 11.03.2012
comment
Да, по сути центроид. Однако это не обязательно должен быть центроид, просто близкий.   -  person CodeBunny    schedule 11.03.2012
comment
Если вам нужно что-то действительно быстрое, но неточное, вы можете вместо этого представить сферу ее ограничивающей рамкой.   -  person Vaughn Cato    schedule 12.03.2012


Ответы (4)


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

прямоугольник, разделенный на квадраты, показывающий, какие квадраты принадлежат пересечению с кругом»></p>

<p>Затем примените <a target='_blank' href='http://en.wikipedia.org/wiki/Centroid#By_geometric_decomposition'>формулу центроида</a>,</p>

<blockquote>
  <p>Центроид плоской фигуры можно вычислить, разделив ее на конечное число более простых фигур, вычислив центроид C <sub>i</sub> и площадь A <sub>i</sub> каждой части, а затем вычислив  Σ C <sub>i</sub> A <sub>i</sub> / Σ A <sub>i</sub>.</p>
</blockquote>

<p>что особенно просто в данном случае, потому что центроид квадрата является его центром, и все A <sub>i</sub> равны.</p>

<p>(Геометрическое рассечение как <a target='_blank' href='https://stackoverflow.com/a/9658390/68063'>, предложенное Воном Като</a>, даст точный ответ, но этот приблизительный метод имеет преимущество простоты: он  гораздо сложнее запрограммировать его неправильно.)</p>

<hr>

<p>CodeBunny запрашивает в комментариях «более простой результат, основанный на уравнениях».  Вот как вычислить результат с помощью уравнений, но я не думаю, что это «проще».</p>

<p>Во-первых, вы должны определить, в каком геометрическом случае вы находитесь, пересекая круг с каждым краем прямоугольника и подсчитывая количество пересечений.  Это оставляет вам, как мне кажется, один из следующих четырнадцати случаев:</p>

<p><img src =

Затем для каждого случая вы разрезаете пересечение на сумму круговых сегментов и выпуклых многоугольников. Вычислите площадь и центроид для каждого из них (формулы см. В Википедии: area и центроид кругового сегмента; площадь и центроид выпуклого многоугольника) и объедините их, используя формулу центроида, которую я дал выше.

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

person Gareth Rees    schedule 11.03.2012
comment
Это дало бы мне точный ответ, но это слишком сложно. Я надеюсь получить более простой результат, основанный на уравнениях. - person CodeBunny; 12.03.2012

Один из способов - разбить его на случаи:

  1. Обведите полностью внутри прямоугольника
  2. Прямоугольник полностью внутри круга
  3. Круг, пересекающий одну сторону прямоугольника
  4. Круг, пересекающий две смежные стороны прямоугольника (включая и исключая угол).
  5. Круг, пересекающий две противоположные стороны прямоугольника
  6. Круг, пересекающий три стороны прямоугольника
  7. Круг, пересекающий четыре стороны прямоугольника.

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

person Vaughn Cato    schedule 11.03.2012
comment
Такой подход кажется слишком упрощенным. Например, четвертый случай может выглядеть намного сложнее; в зависимости от того, как часто круг пересекает две стороны, вам не удастся получить один треугольник и один круговой сегмент. - person Reinstate Monica; 12.03.2012
comment
@WolframH: Верно. Я обновил свой список. Теперь я думаю, что было бы лучше рассматривать это как пересечение многоугольника / многоугольника. Может быть, найти все пересечения ребер / окружностей по порядку. У вас получится, что некоторые стороны будут отрезками прямых, а другие - круговыми. - person Vaughn Cato; 12.03.2012
comment
Это был только пример ... 5 похожа, и я не уверен, насколько сложны 6 и 7. (По моему опыту, часто бывает довольно сложно полностью перечислить все возможные комбинации геометрических проблем. Я бы действительно попытался избежать этого пути.) - person Reinstate Monica; 12.03.2012

Если я правильно понимаю ваше требование, вы хотите найти центр области, где две формы перекрываются?

Это правильно?

Есть круг с центром (x, y) и радиусом r. Есть прямоугольник с центром (x, y), шириной w и высотой h

Итак, вот первый пробел:

Вы не можете определить прямоугольник в плоскости x, y только с его центральной точкой, шириной и высотой. В каком направлении обращен прямоугольник?

Уравнение круга, описанное выше: (x-a) ^ 2 + (y-b) ^ 2 = r ^ 2

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

Второй пробел:

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

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

Это ни в коем случае не ответ типа «это ответ», но я надеюсь, что это немного поможет?

Стив

person Steve    schedule 11.03.2012
comment
Прямоугольник не имеет вращения, он находится на одном уровне с декартовой плоскостью. - person CodeBunny; 12.03.2012

Может, уже поздно ...

Это простой, точный и быстрый способ:

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

Затем вы должны рассмотреть пересечение этого треугольника ABO с кругом. В лучшем случае вы получите ABO, разделенный на два круговых сектора (APO, QBO) и субтреугольник (PQO). Для каждого из этих секторов и подтреугольников вы можете вычислить его среднюю точку и его площадь с особенностью учета отрицательной площади, когда угол между OA и OB направлен против часовой стрелки.

Затем, чтобы получить среднюю точку на пересечении прямоугольника и круга, вы должны вычислить медианное значение средних точек секторов и подтреугольников, взвешенных по их площадям со знаком.

person salva    schedule 13.05.2014