Я сталкиваюсь с этой математической проблемой, которая необходима для завершения моего приложения, поэтому я прошу о помощи.
Для двух (или более, но в основном для 2) прямоугольников с двумя известными точками для каждого: Top-left (x1, y1) и Bottom-right (x2, y2) (я могу найти длину с этими данными, если это необходимо решить проблему).
TL(x1, y1) +-----------------+ | | | | TL(x3, y3) | | +---------------------------+ +-----------------+ | | BR(x2, y2) +---------------------------+ BR(x4, y4)
В любом случае, чтобы определить, имеют ли они пересечение, в области, я имею в виду, если какая-либо часть этого прямоугольника лежит на любой части другого?
Я искал и немного помог, но это не решает проблему:
Есть четыре условия, в которых два прямоугольника не будут пересекаться:
Левый край одного прямоугольника находится справа от правого края другого, означает, что первый полностью уложен на правой стороне второго, без пересечения.
Правый край одного прямоугольника находится слева от левого края другого, означает, что первый полностью уложен на левой стороне второго, без пересечения.
Верхний край одного прямоугольника находится под нижним краем другого, что означает, что первый полностью уложен под вторым, без пересечения.
Нижний край одного прямоугольника находится над верхним краем другого, означает, что первый полностью уложен над вторым, без пересечения.
Поэтому я попытался изменить условия, которые, если 4 из вышеизложенного не произойдет, прямоугольники могут пересекаться. Но я все еще могу найти условие (например, изображение выше), в котором 2 прямоугольника не выполняют никаких условий и все еще не пересекаются.
Любая помощь очень ценится, пожалуйста, покажите мне способ сделать это или алгоритм или код (только JS и PHP).
Большое спасибо!
[Икс]
Алгоритм обнаружения пересечения («перекрытия») любого числа прямоугольников мог бы работать следующим образом. Используются две структуры данных.
Алгоритм развертки по отсортированному списку S координат x:
Если текущая координата x является левым краем прямоугольника R, то y-координаты [y1, y2] of R сравниваются с деревом интервалов T. Если обнаружено совпадение, алгоритм останавливается и сообщает OVERLAP. Если в дереве T не было перекрытия, тогда в дерево вставляется интервал [y1, y2].
Если текущая координата x является правым краем прямоугольника R, то его y-интервал [y1, y2] удаляется из дерева интервалов T.
Если отсортированный список S полностью обработан, то не было перекрытия. Алгоритм останавливается и сообщает NO-OVERLAP.
Сложность времени для N прямоугольников – O (N * log (N)), потому что для каждой 2 * N x-координат выполняется поиск в дереве интервалов для N интервалов. Сложность пространства – O (N) для вспомогательных структур данных S и T.
Это мои два цента по проблеме. Дайте мне знать, если это можно улучшить. Примеры, которые я делаю сам, по-видимому, сохраняются с этим кодом, однако, если вы можете дать мне пример координат, которые делают это неудачным, я все равно хотел бы работать над этой проблемой 🙂
<?php //declare the points for your rectangles //'UL' means upper left points, and 'LR' means the lower right points $rectangle_array = array( $R1 = array("UL" => array("x" => 10, "y" => 20), "LR" => array("x" => 22, "y" => 5)), $R2 = array("UL" => array("x" => 32, "y" => 44), "LR" => array("x" => 65, "y" => 20)), $R3 = array("UL" => array("x" => 20, "y" => 16), "LR" => array("x" => 25, "y" => 10)) ); if (rectIntersect($rectangle_array)) { echo "THEY INTERSECT"; } else { echo "NO INTERSECTION"; } function rectIntersect($rectangles) { $num_rectangles = count($rectangles); for ($i = 0; $i < $num_rectangles; $i++) { //for each rectangle, compare points to every following rectangle $R1 = $rectangles[$i]; for ($k = $i; $k < ($num_rectangles - $i); $k++) { $R2 = $rectangles[$k + 1]; if ($R1['LR']['x'] > $R2['UL']['x'] && $R1['UL']['x'] < $R2['LR']['x']) { //rectangles cross on x-axis if (($R1['LR']['y'] < $R2['UL']['y'] && $R1['UR']['y'] < $R2['LR']['y']) || ($R1['UL']['y'] > $R2['LR']['y'] && $R1['LR']['y'] < $R2['UL']['y'])) { //rectangles intersect return true; } } } } return false; } ?>