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 override void OnMouseUp(MouseEventArgs e) { var newP = WinManager.Instance.CreatePoint(e.X, CGUtils.ReversedY(e.Y)); if (newP == null) { //var currP = form.currPt; //if (form.Points.Count > 1 && CGUtils.SqrtLength(form.Points[0], currP) < 500) { // form.Points[0].pred = lastP; // lastP.succ = form.Points[0]; // Draw.DrawLine(lastP, form.Points[0]); // Draw.DrawImage(); // lastP = null; //} return; } Draw.DrawPoint(newP); Draw.DrawLine(lastP, newP); var edge = CGEdge.CreateEdge(lastP, newP); edges.Add(edge); lastP.owner = edge; newP.owner = edge; lastP.succ = newP; newP.pred = lastP; lastP = null; }
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 void CreateRandomPoints(int count) { for (int i = 0; i < count; i++) { points.Add(CGUtils.CreateRandomCGPoint(PointsFillter)); } }
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 int Compare(CGPoint x, CGPoint y) { float rX = CGUtils.GetRotateAngleInRadians(from, piovt, x); float rY = CGUtils.GetRotateAngleInRadians(from, piovt, y); float ret = rX - rY; return(ret <0f ? -1 : ret> 0f ? 1 : 0); }
public override void OnMouseDown(MouseEventArgs e) { if (lastP == null) { lastP = WinManager.Instance.CreatePoint(e.X, CGUtils.ReversedY(e.Y)); Draw.DrawPoint(lastP); } Draw.DrawImage(); }
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; }
public static void DrawPoint(int x, int y, int radius = 4) { Rectangle rect = new Rectangle(x - radius / 2, CGUtils.ReversedY(y) - radius / 2, radius, radius); g.DrawEllipse(pen, rect); Brush b = new SolidBrush(pointColor); g.FillEllipse(b, rect); DrawImage(); }
private void toolStripButton3_Click(object sender, EventArgs e) { var ret = CGUtils.CreateInputBoxDialogue("Input points number: "); int pointsCount = 0; if (int.TryParse(ret, out pointsCount)) { WinManager.Instance.CreateRandomPoints(pointsCount); Draw.DrawPoints(Points, true); } }
private void pictureBox1_MouseMove(object sender, MouseEventArgs e) { currPt.X = e.X; currPt.Y = CGUtils.ReversedY(e.Y); toolStripStatusLabel1.Text = "Spt:" + Spt.X.ToString() + "," + Spt.Y.ToString(); toolStripStatusLabel2.Text = string.Format("CurrPoint: {0},{1}", currPt.X.ToString(), currPt.Y.ToString()); if (chapter != null) { chapter.OnMouseMove(e); } }
public override void DrawResult() { var ltl = CGUtils.LowestThenLeftmost(WinManager.Instance.data.points); var curr = ltl; do { Draw.DrawLine(curr, curr.succ); curr = curr.succ; } while (ltl != curr); Draw.DrawImage(); }
public CGPoint CreatePoint(float x, float y) { var ret = CGUtils.CreateCGPoint(x, y, PointsFillter); if (ret == null) { return(null); } points.Add(ret); ret.index = points.Count - 1; return(ret); }
public static void DrawPoint(CGPoint point, bool drawInfo = true, int radius = 4) { if (point == null) { return; } DrawPoint((int)point.x, (int)point.y, radius); if (drawInfo) { g.DrawString(point.id.ToString(), new Font("Arial", 10), new SolidBrush(Color.Black), (float)point.x - 3, (float)CGUtils.ReversedY(point.y - 3)); } }
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); }
void TestIntersection(CGEdge a, CGEdge b) { var intersection = CGUtils.Get2DSegmentIntersection(a, b); if (intersection != null) { var p = new Intersection(intersection, a, b); if (!intersections.Contains(p)) { intersections.Add(p); pq.AddEx(p); } } }
public override void OnMouseMove(MouseEventArgs e) { if (form.IsMouseDown) { var currP = form.currPt; for (int i = 0; i < form.Points.Count; i++) { if (form.Points[i] != lastP && CGUtils.SqrtLength(form.Points[i], currP) < 500) { currP.Y = CGUtils.ReversedY(currP.Y); Point p = form.PictureBox1.PointToScreen(new Point((int)form.Points[i].x, (int)CGUtils.ReversedY(form.Points[i].y))); SetCursorPos(p.X, p.Y); linkPoint = form.Points[i]; } } Draw.DrawImage(); } }
public void Merge(List <CGPoint> points, int low, int mid, int high) { var rtlleftHull = CGUtils.RightmostThenLowest(points, low, mid); var ltlRightHull = CGUtils.LeftmostThenLowest(points, mid, high); var leftHullUpperTanPooint = rtlleftHull; var rightHullUpperTanPooint = ltlRightHull; while (!isTangentPoint(leftHullUpperTanPooint, rightHullUpperTanPooint, false) || !isTangentPoint(rightHullUpperTanPooint, leftHullUpperTanPooint, true)) { while (!isTangentPoint(leftHullUpperTanPooint, rightHullUpperTanPooint, false)) { rightHullUpperTanPooint = rightHullUpperTanPooint.pred; } while (!isTangentPoint(rightHullUpperTanPooint, leftHullUpperTanPooint, true)) { leftHullUpperTanPooint = leftHullUpperTanPooint.succ; } } var leftHullLowerTanPooint = rtlleftHull; var rightHullLowerTanPooint = ltlRightHull; while (!isTangentPoint(leftHullLowerTanPooint, rightHullLowerTanPooint, true) || !isTangentPoint(rightHullLowerTanPooint, leftHullLowerTanPooint, false)) { while (!isTangentPoint(leftHullLowerTanPooint, rightHullLowerTanPooint, true)) { rightHullLowerTanPooint = rightHullLowerTanPooint.succ; } while (!isTangentPoint(rightHullLowerTanPooint, leftHullLowerTanPooint, false)) { leftHullLowerTanPooint = leftHullLowerTanPooint.pred; } } ResetCGPointsBetweenFromAndToPointsInCCWOrder(leftHullLowerTanPooint, leftHullUpperTanPooint); ResetCGPointsBetweenFromAndToPointsInCCWOrder(rightHullUpperTanPooint, rightHullLowerTanPooint); leftHullLowerTanPooint.isExtreme = true; rightHullLowerTanPooint.isExtreme = true; leftHullLowerTanPooint.succ = rightHullLowerTanPooint; rightHullLowerTanPooint.pred = leftHullLowerTanPooint; leftHullUpperTanPooint.isExtreme = true; rightHullUpperTanPooint.isExtreme = true; leftHullUpperTanPooint.pred = rightHullUpperTanPooint; rightHullUpperTanPooint.succ = leftHullUpperTanPooint; }
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); }
void InitLeftRightChain() { var htr = CGUtils.HighestThenRightmost(p.vertices); var ltl = CGUtils.LowestThenLeftmost(p.vertices); int index = 0; var leftCurr = htr; while (leftCurr != ltl) { leftChain.Add(index++, leftCurr); leftCurr = leftCurr.succ; } leftChain.Add(index++, ltl); var rightCurr = htr.pred; while (rightCurr != ltl) { rightChain.Add(index++, rightCurr); rightCurr = rightCurr.pred; } }
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 override void OnMouseUp(MouseEventArgs e) { var newP = WinManager.Instance.CreatePoint(e.X, CGUtils.ReversedY(e.Y)); if (newP == null) { var currP = form.currPt; if (CGUtils.SqrtLength(linkPoint, currP) < 500) { linkPoint.pred = lastP; lastP.succ = linkPoint; Draw.DrawLine(lastP, linkPoint); Draw.DrawImage(); lastP = null; } return; } Draw.DrawPoint(newP); Draw.DrawLine(lastP, newP); lastP.succ = newP; newP.pred = lastP; lastP = newP; }
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 int Compare(CGPoint x, CGPoint y) { return(CGUtils.ToLeft(piovt, x, y) ? -1 : 1); }
public bool IsConvex() { return(!CGUtils.ToLeft(pred, succ, this)); }
public static void DrawLine(float ax, float ay, float bx, float by, Graphics graphic = null) { graphic = graphic != null ? graphic : g; graphic.DrawLine(pen, ax, CGUtils.ReversedY(ay), bx, CGUtils.ReversedY(by)); }