Мне нужно проверить, попадает ли точка в многоугольник с отверстиями и островками.Я хотел бы понять, как я должен сделать это.Это не задокументировано, и я не могу найти никаких объяснений или примеров.
Что я делаю, так это подсчет +1
для каждого внешнего многоугольника попадания и -1
для каждого внутреннего многоугольника хит.Итоговая сумма:
- > 0: попадание;
- <= 0: промах (снаружи или в яме). </li>
HitData
класс разделяет пути на основе числа обмоток, чтобы избежать ненужного пересчета orientation
.С Clipper.PointInPolygon()
, примененным к каждому пути , сумма легко вычисляется.
Но есть два основных недостатка:
- Я должен применить
Clipper.PointInPolygon()
КАЖДЫЙ путь ; - Я не могу использовать иерархию
PolyTree
.
Может кто-то, кто имеет практическийопыт работы с Клиппером ( @ angus-johnson ?) разрешает эту путаницу?
Опять же, мой вопрос: как мне реализовать это ?Я заново изобретаю колесо, хотя в Библиотеке Clipper уже есть реальное решение?
Примечание: PolyTree
все еще требуется проверить EVERY путь, чтобы определить, в какой PolyNode
находится точка. Нет метода Clipper.PointInPolyTree()
и, таким образом, AFAIK PolyTree
не помогает.
Структура, разделяющая внешние и внутренние многоугольники:
public class HitData
{
public List<List<IntPoint>> Outer, Inner;
public HitData(List<List<IntPoint>> paths)
{
Outer = new List<List<IntPoint>>();
Inner = new List<List<IntPoint>>();
foreach (List<IntPoint> path in paths)
{
if (Clipper.Orientation(path))
{
Outer.Add(path);
} else {
Inner.Add(path);
}
}
}
}
И вот алгоритм, который проверяет точку:
public static bool IsHit(HitData data, IntPoint point)
{
int hits;
hits = 0;
foreach (List<IntPoint> path in data.Outer)
{
if (Clipper.PointInPolygon(point, path) != 0)
{
hits++;
}
}
foreach (List<IntPoint> path in data.Inner)
{
if (Clipper.PointInPolygon(point, path) != 0)
{
hits--;
}
}
return hits > 0;
}