public static List <Vector> GetConvexHull(this PointString poly) { var points = new List <Vector>(); var collection = new List <Vector>(); int num = 0; var source = poly.Points.ToList(); source.Sort((p1, p2) => (p1.X - p2.X == 0) ? (int)(p1.Y - p2.Y) : (int)(p1.X - p2.X)); points.Add(source[0]); points.Add(source[1]); for (num = 2; num <= (source.Count - 1); num++) { points.Add(source[num]); while ((points.Count >= 3) && !IsTurnRight(points[points.Count - 3], points[points.Count - 2], points[points.Count - 1])) { points.RemoveAt(points.Count - 2); } } collection.Add(source[source.Count - 1]); collection.Add(source[source.Count - 2]); for (num = source.Count - 2; num >= 0; num--) { collection.Add(source[num]); while ((collection.Count >= 3) && !IsTurnRight(collection[collection.Count - 3], collection[collection.Count - 2], collection[collection.Count - 1])) { collection.RemoveAt(collection.Count - 2); } } collection.RemoveAt(collection.Count - 1); collection.RemoveAt(0); points.AddRange(collection); return(points); }
public static double DistToPoint(this PointString poly, Vector p, int divs) // newly 20130523 近似法 { var points = poly.Points; double delta = (double)(points.Count - 1) / divs; var pts = Enumerable.Range(0, divs + 1).Select(i => poly.Lerp(i * delta)).ToList(); return(pts.Min(pt => pt.Dist(p))); }
public static LineSeg GetSegAt(this PointString poly, int i) { var points = poly.Points; if (i < 0) { i = 0; } else if (i > points.Count - 1) { i = points.Count - 1; } int j = i >= points.Count - 1 ? 0 : i + 1; return(new LineSeg(points[i], points[j])); }
public static PointString Offset(this PointString poly, double offset) { var points0 = poly.Points; var points1 = new List <Vector>(); if (points0.Count <= 0) { //return null; } else if (points0.Count == 1) { var pt = new Vector(points0[0].X + offset, points0[0].Y); points1.Add(pt); } else if (points0.Count == 2) { points1 = GetOffsetSeg(points0[0], points0[1], offset); } else { var pt1 = GetOffsetSeg(points0[0], points0[1], offset)[0]; points1.Add(pt1); for (int count = 1; count <= points0.Count - 1; count++) { if (count == points0.Count - 1) { var pt = GetOffsetSeg(points0[count - 1], points0[count], offset)[1]; points1.Add(pt); } else { var p10 = GetOffsetSeg(points0[count - 1], points0[count], offset)[0]; var p11 = GetOffsetSeg(points0[count - 1], points0[count], offset)[1]; var p20 = GetOffsetSeg(points0[count], points0[count + 1], offset)[0]; var p21 = GetOffsetSeg(points0[count], points0[count + 1], offset)[1]; var d0 = new Vector(p11.X - p10.X, p11.Y - p10.Y); var d1 = new Vector(p20.X - p21.X, p20.Y - p21.Y); points1.Add(GetIntersection(p10, p21, d0, d1)); } } } return(new PointString(points1)); }
public static void ReducePoints(this PointString poly, double epsilon) { var points = poly.Points; var cleanList = new List <int>(); int j = 0; for (int i = 1; i < points.Count; i++) { if (points[i].Dist(points[j]) < epsilon) { cleanList.Add(i); } else { j = i; } } cleanList.Reverse(); cleanList.ForEach(x => points.RemoveAt(x)); }
public static PointString GetSubPoly(this PointString poly, double start, double end) { var points = poly.Points; start = (start < 0) ? 0 : start; end = (end > points.Count - 1) ? (points.Count - 1) : end; var pts = new List <Vector>(); double a = Math.Ceiling(start); double b = Math.Floor(end); for (int i = (int)a; i <= (int)b; i++) { pts.Add(points[i]); } if (start < a) { pts.Insert(0, poly.Lerp(start)); } if (end > b) { pts.Add(poly.Lerp(end)); } return(new PointString(pts)); }
public static double DistToPoint(this PointString poly, Vector p) { Vector foot; return(DistToPoint(poly, p, out foot)); }
public static double DistToPoint(this PointString poly, Vector p, out Vector footPos) { var points = poly.Points; double minDist = points.Min(x => x.Dist(p)); var minPoint = points.First(x => x.Dist(p) == minDist); if (minPoint.Equals(points.First())) { LineSeg seg1 = new LineSeg(points[0], points[1]); LineSegPointRelation relation1 = new LineSegPointRelation(seg1, p); if (relation1.Inner) { footPos = relation1.Foot; return(relation1.Dist); } else { footPos = minPoint; return(minDist); } } else if (minPoint.Equals(points.Last())) { int n = points.Count; LineSeg seg1 = new LineSeg(points[n - 2], points[n - 1]); LineSegPointRelation relation1 = new LineSegPointRelation(seg1, p); if (relation1.Inner) { footPos = relation1.Foot; return(relation1.Dist); } else { footPos = minPoint; return(minDist); } } else { int index = points.IndexOf(minPoint); LineSeg seg1 = new LineSeg(points[index - 1], points[index]); LineSeg seg2 = new LineSeg(points[index + 1], points[index]); LineSegPointRelation relation1 = new LineSegPointRelation(seg1, p); LineSegPointRelation relation2 = new LineSegPointRelation(seg2, p); if (relation1.Inner) { footPos = relation1.Foot; return(relation1.Dist); } else if (relation2.Inner) { footPos = relation1.Foot; return(relation2.Dist); } else { footPos = minPoint; return(minDist); } } }