public Polygon Peel(Vector2 v1, float amount) { var v2 = GetNextVertex(v1); var n = GeometryHelpers.Scale(GeometryHelpers.Normalize(GeometryHelpers.Rotate90(v2 - v1)), amount); return(Cut(v1 + n, v2 + n, 0).First()); }
public Polygon Shrink(IList <float> shrinkAmounts) { var newPoly = new Polygon(this); ForEachEdge((p1, p2, index) => { var amount = shrinkAmounts[index]; if (amount > 0) { var n = GeometryHelpers.Scale(GeometryHelpers.Normalize(GeometryHelpers.Rotate90(p2 - p1)), amount); newPoly = newPoly.Cut(p1 + n, p2 + n, 0).First(); } }); return(newPoly); }
public Polygon Buffer(IList <float> shrinkAmounts) { var newPoly = new Polygon(); ForEachEdge((p1, p2, index) => { var amount = shrinkAmounts[index]; if (amount <= 0.01) { newPoly.Vertices.Add(p1); newPoly.Vertices.Add(p2); } else { var n = GeometryHelpers.Scale(GeometryHelpers.Normalize(GeometryHelpers.Rotate90(p2 - p1)), amount); newPoly.Vertices.Add(p1 + n); newPoly.Vertices.Add(p2 + n); } }); bool wasCut; var lastEdge = 0; do { wasCut = false; var n = newPoly.Vertices.Count; for (var i = lastEdge; i < n - 2; i++) { lastEdge = i; var p11 = newPoly.Vertices[i]; var p12 = newPoly.Vertices[i + 1]; var x1 = p11.x; var y1 = p11.y; var dx1 = p12.x - x1; var dy1 = p12.y - y1; var maxJ = i > 0 ? n : n - 1; for (var j = i + 2; j < maxJ; j++) { var p21 = newPoly.Vertices[j]; var p22 = j < n - 1 ? newPoly.Vertices[j + 1] : newPoly.Vertices[0]; var x2 = p21.x; var y2 = p21.y; var dx2 = p22.x - x2; var dy2 = p22.y - y2; var intersect = GeometryHelpers.IntersectLines(x1, y1, dx1, dy1, x2, y2, dx2, dy2); if (intersect.x > Delta && intersect.x < (1 - Delta) && intersect.y > Delta && intersect.y < (1 - Delta)) { var pn = new Vector2(x1 + dx1 * intersect.x, y1 + dy1 * intersect.x); newPoly.Vertices.Insert(j + 1, pn); newPoly.Vertices.Insert(i + 1, pn); wasCut = true; break; } } } } while (wasCut); var regular = Enumerable.Range(0, newPoly.Vertices.Count).ToList(); Polygon bestPart = null; var bestPartSq = float.MinValue; while (regular.Count > 0) { var indices = new List <int> (); var start = regular[0]; var i = start; do { indices.Add(i); regular.Remove(i); var next = (i + 1) % newPoly.Vertices.Count; var v = newPoly.Vertices[next]; var next1 = newPoly.Vertices.IndexOf(v); if (next1 == next) { next1 = newPoly.Vertices.LastIndexOf(v); } i = next1 == -1 ? next : next1; } while (i != start && indices.Count < 1000); if (indices.Count >= 999) { indices = indices.Take(4).ToList(); } var poly = new Polygon(indices.Select(v => newPoly.Vertices[v])); var s = poly.Area(); if (s > bestPartSq) { bestPart = poly; bestPartSq = s; } } return(bestPart); }