См. , это , это на c ++ и может быть сделано в c # таким же образом.
для выпуклого многоугольника слишком просто:
Если многоугольникявляется выпуклым, то многоугольник можно рассматривать как «путь» от первой вершины.Точка находится внутри этого многоугольника, если она всегда находится на одной стороне всех отрезков, составляющих путь.
Учитывая отрезок прямой между P0 (x0, y0) и P1 (x1, y1), другая точка P (x, y) имеет следующую связь с отрезком линии.Вычислить (y - y0) (x1 - x0) - (x - x0) (y1 - y0)
, если оно меньше 0, тогда P находится справа от отрезка, если оно больше 0слева, если равен 0, то он лежит на отрезке.
Вот его код в c #, я не проверял крайние случаи.
public static bool IsInPolygon(Point[] poly, Point point)
{
var coef = poly.Skip(1).Select((p, i) =>
(point.Y - poly[i].Y)*(p.X - poly[i].X)
- (point.X - poly[i].X) * (p.Y - poly[i].Y))
.ToList();
if (coef.Any(p => p == 0))
return true;
for (int i = 1; i < coef.Count(); i++)
{
if (coef[i] * coef[i - 1] < 0)
return false;
}
return true;
}
Я тестирую это с простым прямоугольником, работает нормально:
Point[] pts = new Point[] { new Point { X = 1, Y = 1 },
new Point { X = 1, Y = 3 },
new Point { X = 3, Y = 3 },
new Point { X = 3, Y = 1 } };
IsInPolygon(pts, new Point { X = 2, Y = 2 }); ==> true
IsInPolygon(pts, new Point { X = 1, Y = 2 }); ==> true
IsInPolygon(pts, new Point { X = 0, Y = 2 }); ==> false
Пояснение к запросу linq:
poly.Skip(1)
==> создает новый список, начинающийся с позиции 1
из poly
список, а затем (point.Y - poly[i].Y)*(p.X - poly[i].X) - (point.X - poly[i].X) * (p.Y - poly[i].Y)
мы собираемся вычислить направление (которое упомянуто в упомянутом абзаце).аналогичный пример (с другой операцией):
lst = 2,4,8,12,7,19
lst.Skip(1) ==> 4,8,12,7,19
lst.Skip(1).Select((p,i)=>p-lst[i]) ==> 2,4,4,-5,12