/// <summary> /// Implements gift wrapping algorithm. /// </summary> /// <param name="points">Set of points.</param> /// <returns>Polygon representing convex hull.</returns> public static Polygon ConvexHull(IList<Vector> points) { Debug.Assert(points != null); Debug.Assert(points.Count >= 3); // Leave only distinct points points = new List<Vector>(points.Distinct()); // Find first point Vector hullStart = points[0]; for (int i = 1; i < points.Count; ++i) { Vector point = points[i]; if (point.X < hullStart.X || (point.X == hullStart.X && point.Y < hullStart.Y)) hullStart = point; } Vector currentHullPoint = hullStart; Polygon result = new Polygon(); bool[] usedPoints = new bool[points.Count]; do { result.vertices.Add(currentHullPoint); int nextHullPointIndex = 0; for (int i = 1; i < points.Count; ++i) { if (usedPoints[nextHullPointIndex] || points[nextHullPointIndex] == currentHullPoint || Vector.CrossProduct(points[i] - currentHullPoint, points[nextHullPointIndex] - currentHullPoint) < 0) { nextHullPointIndex = i; } } currentHullPoint = points[nextHullPointIndex]; usedPoints[nextHullPointIndex] = true; } while (currentHullPoint != hullStart); return result; }
public static Polygon FromPoints(IEnumerable<Vector> vertices) { Polygon result = new Polygon(); result.vertices.AddRange(vertices); return result; }
public static Polygon FromPoints(params Vector[] vertices) { Polygon result = new Polygon(); result.vertices.AddRange(vertices); return result; }
private static void MinMaxDistanceForEdge( Vector point, Polygon convexHull, VertexConstraints constraints1, VertexConstraints constraints2, out double minDistanceSqr, out double maxDistanceSqr) { if (convexHull.IsPointInside(point)) minDistanceSqr = 0; else { minDistanceSqr = Double.PositiveInfinity; for (int i = 0; i < convexHull.Vertices.Count; ++i) { double distanceSqr = point.DistanceToSegmentSquared( convexHull.Vertices[i], convexHull.Vertices[(i + 1) % convexHull.Vertices.Count]); minDistanceSqr = Math.Min(minDistanceSqr, distanceSqr); } } maxDistanceSqr = 0; foreach (Vector vertex1 in constraints1.Corners) { foreach (Vector vertex2 in constraints2.Corners) { double distanceSqr = point.DistanceToSegmentSquared(vertex1, vertex2); maxDistanceSqr = Math.Max(maxDistanceSqr, distanceSqr); } } }