/// <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);
         }
     }
 }