/// <summary>
 /// Sorts points by angle, relative to the center
 /// Time complexity O(N*logN)
 /// </summary>
 public static IList <PointInt2D> SortByAngle(IList <PointInt2D> points, PointInt2D center)
 {
     return(points.OrderBy(p => p, new MyComparer <PointInt2D>((a, b) =>
     {
         if (a.Y >= center.Y && b.Y < center.Y)
         {
             return -1;
         }
         if (b.Y >= center.Y && a.Y < center.Y)
         {
             return 1;
         }
         if (a.Y == center.Y && b.Y == center.Y)
         {
             if (a.X >= center.X)
             {
                 if (b.X >= center.X)
                 {
                     return a.X.CompareTo(b.X);
                 }
                 return -1;
             }
             else
             {
                 if (b.X >= center.X)
                 {
                     return 1;
                 }
                 return -a.X.CompareTo(b.X);
             }
         }
         var cross = (a - center) * (b - center);
         if (cross > 0)
         {
             return -1;
         }
         return cross < 0 ? 1 : (a - center).DistSq().CompareTo((b - center).DistSq());
     })).ToList());
 }
 /// <summary>
 /// Gets doubled square of the given triangle
 /// </summary>
 public static long TriangleDoubledSquare(PointInt2D p1, PointInt2D p2, PointInt2D p3) => Math.Abs((p2 - p1) * (p3 - p1));