public void PrintFwd() { CDLL <T> node = this; do { node = node.next; } while (node != this); }
public static IList <Vec> convexhull(IList <Point> pointList) { var pts = new XPoint[pointList.Count]; int k = 0; foreach (var point in pointList) { pts[k++] = new XPoint(point.X, point.Y); } // Sort XPoints lexicographically by increasing (x, y) int N = pts.Length; Polysort.Quicksort <XPoint>(pts); XPoint left = pts[0], right = pts[N - 1]; // Partition into lower hull and upper hull CDLL <XPoint> lower = new CDLL <XPoint>(left), upper = new CDLL <XPoint>(left); for (int i = 0; i < N; i++) { double det = XPoint.Area2(left, right, pts[i]); if (det > 0) { upper = upper.Append(new CDLL <XPoint>(pts[i])); } else if (det < 0) { lower = lower.Prepend(new CDLL <XPoint>(pts[i])); } } lower = lower.Prepend(new CDLL <XPoint>(right)); upper = upper.Append(new CDLL <XPoint>(right)).Next; // Eliminate XPoints not on the hull eliminate(lower); eliminate(upper); /* phil : Eliminating duplicates leaves holes in the hull * // Eliminate duplicate endXPoints * if (lower.Prev.val.Equals(upper.val)) * lower.Prev.Delete(); * if (upper.Prev.val.Equals(lower.val)) * upper.Prev.Delete(); */ // Join the lower and upper hull XPoint[] res = new XPoint[lower.Size() + upper.Size()]; lower.CopyInto(res, 0); upper.CopyInto(res, lower.Size()); var result = new List <Vec>(); foreach (var r in res) { result.Add(new Vec(r.x, r.y)); } return(result); }
public void CopyInto(T[] vals, int i) { CDLL <T> node = this; do { vals[i++] = node.val; // still, implicit checkcasts at runtime node = node.next; } while (node != this); }
public int Size() { int count = 0; CDLL <T> node = this; do { count++; node = node.next; } while (node != this); return(count); }
// Graham's scan private static void eliminate(CDLL <XPoint> start) { CDLL <XPoint> v = start, w = start.Prev; bool fwd = false; while (v.Next != start || !fwd) { if (v.Next == w) { fwd = true; } if (XPoint.Area2(v.val, v.Next.val, v.Next.Next.val) < 0) // right turn { v = v.Next; } else { // left turn or straight v.Next.Delete(); v = v.Prev; } } }
public CDLL <T> Append(CDLL <T> elt) { elt.prev = this; elt.next = next; next.prev = elt; next = elt; return(elt); }
public CDLL <T> Prepend(CDLL <T> elt) { elt.next = this; elt.prev = prev; prev.next = elt; prev = elt; return(elt); }
// Delete: adjust the remaining elements, make this one XPoint nowhere public void Delete() { next.prev = prev; prev.next = next; next = prev = null; }
// A new CDLL node is a one-element circular list public CDLL(T val) { this.val = val; next = prev = this; }