public static bool IsInsideConvexPolygon(PointFr point, PolygonFr polygon) { var vertices = polygon.Vertices.ToList(); // wierzchołki posortowane przeciwnie do wskazówek zegara względem wnętrza wielokąta var edges = polygon.Edges().ToList(); if (vertices.Count < 3) { throw new ArgumentException("Polygon can't have less than 3 vertices"); } if (ConvexHullJarvis(vertices).Count != vertices.Count) // Powinno wystarczyć Count { throw new ArgumentException("Polygon must be convex"); } if (vertices.Count == 3) { return(!edges.Any(point.IsRightOf)); } var polyCenter = polygon.Center; if (polyCenter == null) { throw new Exception("Can't calculate center of the Polygon"); } var mid = (PointFr)polyCenter; while (edges.Count > 1) { var testSegment = new LineSegmentFr(mid, edges[edges.Count / 2].StartPoint); if (point.IsRightOf(testSegment)) { edges = edges.Take(edges.Count / 2).ToList(); } else if (point.IsLeftOf(testSegment)) { edges = edges.Skip(edges.Count / 2).ToList(); } else if (testSegment.Contains(point)) { return(true); } else { throw new Exception("Invalid calculations performed, it should never happen"); } } return(!point.IsRightOf(edges.Single())); // czyli IsLeftOf + Contains, jeżeli jest we wierzchołku to będzie spełniony ostatni warunek z while'a }
public static bool IsInsidePolygon(PointFr point, PolygonFr polygon) { if (polygon.Edges(true).Any(edge => edge.Contains(point))) { return(true); } var vertices = polygon.Vertices.ToList(); int i, j = vertices.Count - 1; var contains = false; for (i = 0; i < vertices.Count; i++) { if ((vertices[i].Y < point.Y && vertices[j].Y >= point.Y || vertices[j].Y < point.Y && vertices[i].Y >= point.Y) && (vertices[i].X <= point.X || vertices[j].X <= point.X)) { contains ^= (vertices[i].X + (point.Y - vertices[i].Y) / (vertices[j].Y - vertices[i].Y) * (vertices[j].X - vertices[i].X) < point.X); } j = i; } return(contains); }