Я видел много алгоритмов для точки внутри многоугольника. То, что я узнал до сих пор, пришло с этого сайта: http://alienryderflex.com/polygon/
Лучший алгоритм обычно выглядит так:
var inside = false;
for (int i = poly.Count - 1, j = 0; j < poly.Count; i = j++)
{
var p1 = poly.Vertices[i];
var p2 = poly.Vertices[j];
if ((p1.Y < testY != p2.Y < testY) && //at least one point is below the Y threshold and the other is above or equal
(p1.X >= testX || p2.X >= testX)) //optimisation: at least one point must be to the right of the test point
{
if (p1.X + (testY - p1.Y) / (p2.Y - p1.Y) * (p2.X - p1.X) > testX)
inside = !inside;
}
}
Но сегменты составного многоугольника могут быть либо прямой линией, либо дугой. Сегменты дуги определяются двумя нормальными точками и выпуклостью, которая используется для определения центра и радиуса дуги. Две точки используются для нахождения начального и конечного угла дуги.
Используя тестовую точку Y и Math.Asin((testY - arc.Center.Y) / arc.Radius)
, я могу найти угол, под которым тестовая линия пересекает окружность. Когда тестовая линия пересекает окружность, есть 2 точки пересечения. После этого я проверяю угол, чтобы узнать, находятся ли точки пересечения на дуге.
Пока что мой результат довольно хорош, за исключением того, что когда происходит контрольная точка, у нее точно такое же y
, что и у вершины. Он будет засчитан для 2 соседних сегментов. Для обычного сегмента этого случая можно избежать с помощью if (p1.Y < testY != p2.Y < testY)
Я не могу найти аналогичную реализацию составного многоугольника для дуговой части. Кто-то когда-либо должен был сделать что-то подобное или иметь какой-либо намек?