public static Ngon Clone(this Ngon poly, Mat3x3 T) { Ngon clone = new Ngon(poly.Count); for (int i = 0; i < poly.Count; i++) { clone.Add(T * poly[i]); } return(clone); }
public static Ngon Clone(this Ngon poly, long shift_x, long shift_y, bool flip_first = false) { long scale = flip_first ? -1 : 1; Ngon clone = new Ngon(poly.Count); for (int i = 0; i < poly.Count; i++) { clone.Add(new IntPoint(scale * poly[i].X + shift_x, scale * poly[i].Y + shift_y)); } return(clone); }
public Ngons GetTransformedPoly() { Ngons n = new Ngons(poly.Count); for (int i = 0; i < poly.Count; i++) { Ngon nn = new Ngon(poly[i].Count); for (int j = 0; j < poly[i].Count; j++) { nn.Add(GetTransformedPoint(i, j)); } n.Add(nn); } return(n); }
private static Ngons MSumConvex(Ngon pattern, Ngons subject, bool flip_pattern) { Ngon h_p = ConvexHull(pattern.Clone(0, 0, flip_pattern)); Ngon h_s = ConvexHull(subject[0].Clone()); int n_p = h_p.Count; int n_s = h_s.Count; int sp = 0; for (int k = 0; k < n_p; k++) { if (h_p[k].Y < h_p[sp].Y) { sp = k; } } int ss = 0; for (int k = 0; k < n_s; k++) { if (h_s[k].Y < h_s[ss].Y) { ss = k; } } Ngon poly = new Ngon(n_p + n_s); int i = 0; int j = 0; while (i < n_p || j < n_s) { int ip = (sp + i + 1) % n_p; int jp = (ss + j + 1) % n_s; int ii = (sp + i) % n_p; int jj = (ss + j) % n_s; IntPoint sum = new IntPoint(h_p[ii].X + h_s[jj].X, h_p[ii].Y + h_s[jj].Y); IntPoint v = new IntPoint(h_p[ip].X - h_p[ii].X, h_p[ip].Y - h_p[ii].Y); IntPoint w = new IntPoint(h_s[jp].X - h_s[jj].X, h_s[jp].Y - h_s[jj].Y); poly.Add(sum); if (i == n_p) { j++; continue; } if (j == n_s) { i++; continue; } long cross = v.Y * w.X - v.X * w.Y; if (cross < 0) { i++; } else if (cross > 0) { j++; } else { long dot = v.X * w.X + v.Y * w.Y; if (dot > 0) { i++; j++; } else { throw new Exception(); } } } return(Clipper.SimplifyPolygon(poly)); }
public static Ngon ConvexHull(Ngon subject, double rigidness = 0) { if (subject.Count == 0) { return(new Ngon()); } if (rigidness >= 1) { return(subject.Clone()); } subject = subject.Clone(); if (Clipper.Area(subject) < 0) { Clipper.ReversePaths(new Ngons() { subject }); } Ngon last_hull = new Ngon(); Ngon hull = subject; double subj_area = Clipper.Area(hull); int last_vert = 0; for (int i = 1; i < subject.Count; i++) { if (hull[last_vert].Y > hull[i].Y) { last_vert = i; } } while (last_hull.Count != hull.Count) { last_hull = hull; hull = new Ngon(); hull.Add(last_hull[last_vert]); int steps_since_insert = 0; int max_steps = rigidness <= 0 ? int.MaxValue : (int)Math.Round(10 - (10 * rigidness)); int n = last_hull.Count; int start = last_vert; for (int i = 1; i < n; i++) { IntPoint a = last_hull[last_vert]; IntPoint b = last_hull[(start + i) % n]; IntPoint c = last_hull[(start + i + 1) % n]; IntPoint ab = new IntPoint(b.X - a.X, b.Y - a.Y); IntPoint ac = new IntPoint(c.X - a.X, c.Y - a.Y); if (ab.Y * ac.X < ab.X * ac.Y || steps_since_insert >= max_steps) { hull.Add(b); last_vert = (start + i) % n; steps_since_insert = -1; } steps_since_insert++; } last_vert = 0; double hull_area = Clipper.Area(hull); if (subj_area / hull_area < Math.Sqrt(rigidness)) { hull = Clipper.SimplifyPolygon(hull, PolyFillType.pftNonZero)[0]; break; } } return(hull); }