public void CopyInto(IPosition[] vals, int i) { CDLL node = this; do { vals[i++] = node.val; // still, implicit checkcasts at runtime node = node.next; } while (node != this); }
public void PrintFwd() { CDLL node = this; do { Console.WriteLine(node.val); node = node.next; } while (node != this); Console.WriteLine(); }
public int Size() { int count = 0; CDLL node = this; do { count++; node = node.next; } while (node != this); return(count); }
/* * public SimplePositionSet ConvexHull(SimplePositionSet ps) * { * int n = ps.GetCount(); * Point[] pts = new Point[n]; * for (int i = 0; i < n; i++) * { * SimplePosition pos = ps.GetNextPosition(); * pts[i] = new Point(pos.GetX(), pos.GetY()); * } * Point[] resPts = _ConvexHull(pts); * SimplePositionSet result = new SimplePositionSet(); * for (int i = 0; i < resPts.Length; i++) * result.AddPosition(new SimplePosition(resPts[i].X, resPts[i].Y)); * return result; * } */ public IPositionSet ConvexHull(IPositionSet ps) { //转换成数组 IPosition[] posArr = (IPosition[])ps.ToArray(); int N = posArr.Length; //排序 Polysort.Quicksort(posArr); IPosition left = posArr[0]; IPosition right = posArr[N - 1]; // Partition into lower hull and upper hull CDLL lower = new CDLL(left), upper = new CDLL(left); for (int i = 0; i < N; i++) { double det = Area2(left, right, posArr[i]); if (det > 0) { upper = upper.Append(new CDLL(posArr[i])); } else if (det < 0) { lower = lower.Prepend(new CDLL(posArr[i])); } } lower = lower.Prepend(new CDLL(right)); upper = upper.Append(new CDLL(right)).Next; // Eliminate points not on the hull eliminate(lower); eliminate(upper); // Eliminate duplicate endpoints 消除重复点 /* * 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 IPosition[] res = new IPosition[lower.Size() + upper.Size()]; lower.CopyInto(res, 0); upper.CopyInto(res, lower.Size()); PositionSetEdit_ImplementByICollectionTemplate result = new PositionSetEdit_ImplementByICollectionTemplate(); for (int i = 0; i < res.Length - 1; i++) { result.AddPosition(res[i]); } return(result); }
// Graham's scan private void eliminate(CDLL start) { CDLL v = start, w = start.Prev; bool fwd = false; while (v.Next != start || !fwd) { if (v.Next == w) { fwd = true; } if (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 Append(CDLL elt) { elt.prev = this; elt.next = next; next.prev = elt; next = elt; return(elt); }
public CDLL Prepend(CDLL elt) { elt.next = this; elt.prev = prev; prev.next = elt; prev = elt; return(elt); }
// Delete: adjust the remaining elements, make this one Position 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(IPosition val) { this.val = val; next = prev = this; }