public HalfEdge2D Split() { var m = (to.p + p) * 0.5f; var e = new HalfEdge2D(m); to.from = e; e.to = to; this.to = e; e.from = this; return(e); }
// Disable to intersect more than two edges static List <HalfEdge2D> SplitEdges(List <HalfEdge2D> edges) { HalfEdge2D start = edges[0]; HalfEdge2D cur = start; while (true) { HalfEdge2D from = cur, to = from.to; HalfEdge2D from2 = to.to, to2 = from2.to; int intersections = 0; while (to2 != from.from) { if (Utils2D.Intersect(from.p, to.p, from2.p, to2.p)) { intersections++; if (intersections >= 2) { break; } } // next from2 = from2.to; to2 = to2.to; } if (intersections >= 2) { edges.Add(cur.Split()); } else { // next cur = cur.to; if (cur == start) { break; } } } return(edges); }
public static Polygon2D Contour(Vector2[] points) { var n = points.Length; var edges = new List <HalfEdge2D>(); for (int i = 0; i < n; i++) { edges.Add(new HalfEdge2D(points[i])); } for (int i = 0; i < n; i++) { var e = edges[i]; e.from = edges[(i == 0) ? (n - 1) : (i - 1)]; e.to = edges[(i + 1) % n]; } edges = Polygon2D.SplitEdges(edges); var result = new List <Vector2>(); HalfEdge2D start = edges[0]; result.Add(start.p); HalfEdge2D current = start; while (true) { HalfEdge2D from = current, to = current.to; HalfEdge2D from2 = to.to, to2 = from2.to; bool flag = false; while (from2 != start && to2 != from) { if (flag = Utils2D.Intersect(from.p, to.p, from2.p, to2.p)) { break; } from2 = to2; to2 = to2.to; } if (!flag) { result.Add(to.p); current = to; // step to next } else { result.Add(from2.p); // reconnect from.to = from2; from2.to = from; // invert this edge later to.from = to2; to.Invert(); to2.from = to; HalfEdge2D e = from2; while (e != to) { e.Invert(); e = e.to; } current = from2; } if (current == start) { break; } } result.RemoveAt(result.Count - 1); // remove last return(new Polygon2D(result.ToArray())); }
public void Invert() { var tmp = from; from = to; to = tmp; }