Точки в полигональных тестах уязвимы из-за ошибок округления с плавающей точкой.Они обычно работают только для нетривиальных полигонов.
Более надежный подход должен основываться на алгоритме линии сканирования, где вершины сначала сортируются в соответствии с их значениями x и y.Линия сканирования (или развертки) затем перемещается, например.слева направо.Затем алгоритм обычно поддерживает список линий, пересекающих линию сканирования, добавляя строку, когда ее левая вершина «попадает» на строку сканирования, и удаляя ее, когда ее правая вершина достигает линии.
После каждого перемещениялиния сканирования, пересечения текущих линий с линией сканирования обновляются, и линии переупорядочиваются в соответствии со значением y пересечения.Если во время сортировки необходимо переупорядочить две линии, это означает, что у них есть пересечение, которое затем можно записать.
После нахождения всех пересечений можно надежно идентифицировать контуры и отверстия.
Этот подход используется в следующих проектах:
Существуют другие, и на следующем сайте (который продвигает библиотеку PolyBoolean) сравниваются наиболее важные из них: http://www.complex -a5.ru / polyboolean / comp.html .
Как предупреждение: я сам реализовал библиотеку многоугольников, поддерживающую логические операции, а также обнаружение дырок.Эта библиотека используется в коммерческом продукте, и я потратил несколько лет (!) На точную настройку алгоритма, чтобы в кратчайшие сроки обеспечить правильный результат для любого заданного входного многоугольника (другие библиотеки могут быть на несколько% быстрее,но не с некоторыми входными данными).Фактически, алгоритм с одним подходом не может решить все возможные проблемы, поэтому мне пришлось реализовать несколько.
Удачи!