int QuickHullPartition(List <CGPoint> points, int low, int high) { int fp = CGUtils.LeftFarmostPointFromLine(points[low], points[high], points); if (fp == -1) { return(-1); } CGPoint from = points[low]; low++; high--; points.Swap(low, fp); CGPoint pivot = points[low]; while (low < high) { while (low < high && !CGUtils.ToLeft(from, pivot, points[high])) { high--; } points[low] = points[high]; while (low < high && CGUtils.ToLeft(from, pivot, points[high])) { low++; } points[high] = points[low]; } points[low] = pivot; return(low); }
public static Vertex CreateVertex(CGPoint p) { if (p == null) { return(null); } var ret = new Vertex() { point = p, e = CGEdge.CreateEdge(p, p.succ), }; if (p.y > p.succ.y && p.y > p.pred.y) { ret.type = CGUtils.ToLeft(p.pred, p.succ, p) ? Type.Split : Type.Start; } else if (p.y < p.succ.y && p.y < p.pred.y) { ret.type = CGUtils.ToLeft(p.pred, p.succ, p) ? Type.Merge : Type.End; } else { ret.type = Type.Normal; } return(ret); }
public void QuickHull() { var ltl = CGUtils.LowestThenLeftmost(points); var htr = CGUtils.HighestThenRightmost(points); List <CGPoint> leftPoints = new List <CGPoint>(); List <CGPoint> rightPoints = new List <CGPoint>(); leftPoints.Add(ltl); rightPoints.Add(htr); for (int i = 0; i < points.Count; i++) { if (points[i] != ltl && points[i] != htr) { if (CGUtils.ToLeft(ltl, htr, points[i])) { leftPoints.Add(points[i]); } else { rightPoints.Add(points[i]); } } } leftPoints.Add(htr); rightPoints.Add(ltl); QuickHull(leftPoints, 0, leftPoints.Count - 1); QuickHull(rightPoints, 0, rightPoints.Count - 1); }
public void GrahamScan() { Reset(); if (points.Count < 3) { return; } CGPoint ltl = CGUtils.LowestThenLeftmost(points); int ltlIndex = points.FindIndex(o => o == ltl); if (ltlIndex > 0) { CGPoint temp = points[ltlIndex]; points[ltlIndex] = points[0]; points[0] = temp; } PolarAnglePointCompare compare = new PolarAnglePointCompare() { piovt = ltl }; points.Sort(1, points.Count - 1, compare); Stack <CGPoint> t = new Stack <CGPoint>(); Stack <CGPoint> s = new Stack <CGPoint>(); s.Push(points[0]); s.Push(points[1]); for (int i = points.Count - 1; i > 1; i--) { t.Push(points[i]); } while (t.Count != 0) { var topOfS = s.Pop(); if (CGUtils.ToLeft(s.Peek(), topOfS, t.Peek())) { s.Push(topOfS); s.Push(t.Pop()); } } var last = s.Peek(); CGPoint curr = null; while (s.Count > 0) { curr = s.Pop(); curr.isExtreme = true; if (s.Count == 0) { break; } curr.pred = s.Peek(); s.Peek().succ = curr; } last.succ = curr; curr.pred = last; }
bool isTangentPoint(CGPoint from, CGPoint to, bool isLeft) { bool toIsSingle = to.pred == to && to.succ == to; if (toIsSingle) { return(true); } bool predIsLeft = CGUtils.ToLeft(from, to, to.pred) == isLeft; bool succIsLeft = CGUtils.ToLeft(from, to, to.succ) == isLeft; bool toPredAndToSuccAreSameSide = predIsLeft && succIsLeft; return(toPredAndToSuccAreSameSide); }
public bool ContentIsOnTheRightSideOfPoint() { CGPoint lowY = null; CGPoint highY = null; if (pred.y < succ.y) { lowY = pred; highY = succ; } else { lowY = succ; highY = pred; } var isLeft = CGUtils.ToLeft(lowY, highY, this); return(IsConvex() ? isLeft : !isLeft); }
public static float GetRotateAngleInRadians(CGPoint from, CGPoint common, CGPoint to) { CGPoint fromVector = from - common; CGPoint toVector = to - common; float cos = CGPoint.Dot(fromVector, toVector) / (fromVector.Length * toVector.Length); if (Math.Abs(cos - 1.0) <= epsilon) { return(0f); } else if (Math.Abs(cos + 1.0) <= epsilon) { return((float)(Math.Acos(-1) * (180 / Math.PI))); } else { //float rad = (float)Math.Acos(cos); //return CGUtils.ToLeft(from, to, common) ? rad : (float)(2 * Math.PI - rad); float rad = (float)Math.Acos(cos) * (float)(180 / Math.PI); return(CGUtils.ToLeft(from, to, common) ? rad : 360f - rad); } }
public void JarvisMarch() { Reset(); CGPoint ltl = CGUtils.LowestThenLeftmost(points); CGPoint curr = ltl; CGPoint next = null; do { curr.isExtreme = true; next = null; for (int i = 0; i < points.Count; i++) { if (points[i] != curr && (next == null || !CGUtils.ToLeft(curr, next, points[i]))) { next = points[i]; } } curr.succ = next; next.pred = curr; curr = next; } while (ltl != curr); }
bool IsTopConvex(CGPoint curr, CGPoint top, CGPoint sec) { bool left = CGUtils.ToLeft(sec, curr, top); return(top.pred == curr ? left : !left); }
public bool IsConvex() { return(!CGUtils.ToLeft(pred, succ, this)); }
public int Compare(CGPoint x, CGPoint y) { return(CGUtils.ToLeft(piovt, x, y) ? -1 : 1); }