internal _EdgeEvent(float distance, Vector2 intersectionPoint, SkeletonVertex vertex_a, SkeletonVertex vertex_b) { this.Distance = distance; this.IntersectionPoint = intersectionPoint; this.vertex_a = vertex_a; this.vertex_b = vertex_b; }
internal _SplitEvent(float distance, Vector2 intersectionPoint, SkeletonVertex vertex, SkeletonLineSegment oppositeEdge) { this.Distance = distance; this.IntersectionPoint = intersectionPoint; this.Vertex = vertex; this.OppositeEdge = oppositeEdge; }
internal static SkeletonVertices FromChain(SkeletonVertex head, SkeletonVertices slav) { SkeletonVertices lav = new SkeletonVertices(); lav.Head = head; lav.Add(head); var t = lav.Head.Next; lav.Add(t); while (t.Point != lav.Head.Point) { t = t.Next; lav.Add(t); } lav.RemoveAt(lav.Count - 1); foreach (var vertex in lav) { vertex.Vertices = lav; } return(lav); }
internal SkeletonEventResult Handle_Split_Event(_SplitEvent splitEvent) { var lav = splitEvent.Vertex.Vertices; //Debug.WriteLine("{0} Split event at intersection {1} from vertex {2}, for edge {3} in {4}", splitEvent.Distance, splitEvent.IntersectionPoint, splitEvent.Vertex, splitEvent.OppositeEdge, lav); var sinks = new List <Vector2>() { splitEvent.Vertex.Point }; var vertices = new List <SkeletonVertex>(); SkeletonVertex x = null; // right vertex SkeletonVertex y = null; // left vertex var norm = splitEvent.OppositeEdge.V.Normalized(); foreach (var childLav in this) { foreach (var v in childLav) { //Debug.WriteLine("{0} in {1}", v, v.LAV); if (norm == v.EdgeLeft.V.Normalized() && splitEvent.OppositeEdge.P == v.EdgeLeft.P) { x = v; y = x.Previous; } else if (norm == v.EdgeRight.V.Normalized() && splitEvent.OppositeEdge.P == v.EdgeRight.P) { y = v; x = y.Next; } if (x != null) { var yIntersectionAsPoint = (new Vector2(splitEvent.IntersectionPoint.X - y.Point.X, splitEvent.IntersectionPoint.Y - y.Point.Y)).Normalized(); var yLeftBiSectorAsPoint = new PointF(y.BiSector.V.Normalized().X, y.BiSector.V.Normalized().Y); var xleft = Helpers.MathHelper.Cross(yLeftBiSectorAsPoint, new PointF(yIntersectionAsPoint.X, yIntersectionAsPoint.Y)) >= 0; var xIntersectionAsPoint = (new Vector2(splitEvent.IntersectionPoint.X - x.Point.X, splitEvent.IntersectionPoint.Y - x.Point.Y)).Normalized(); var xLeftBiSectorAsPoint = new PointF(x.BiSector.V.Normalized().X, x.BiSector.V.Normalized().Y); var xright = Helpers.MathHelper.Cross(xLeftBiSectorAsPoint, new PointF(xIntersectionAsPoint.X, xIntersectionAsPoint.Y)) <= 0; //Debug.WriteLine("Vertex {0} holds edge as {1} edge ({2}, {3})", v, (x == v ? "left" : "right"), xleft, xright); if (xleft && xright) { break; } else { x = null; y = null; } } } } if (x == null) { //Debug.WriteLine("Failed split event {0} (equivalent edge event is expected to follow)", splitEvent); return(new SkeletonEventResult(null, null)); } var v1 = new SkeletonVertex(splitEvent.IntersectionPoint, splitEvent.Vertex.EdgeLeft, splitEvent.OppositeEdge); var v2 = new SkeletonVertex(splitEvent.IntersectionPoint, splitEvent.OppositeEdge, splitEvent.Vertex.EdgeRight); v1.Previous = splitEvent.Vertex.Previous; v1.Next = x; splitEvent.Vertex.Previous.Next = v1; x.Previous = v1; v2.Previous = y; v2.Next = splitEvent.Vertex.Next; splitEvent.Vertex.Next.Previous = v2; y.Next = v2; List <SkeletonVertices> new_lavs = new List <SkeletonVertices>(); this.Remove(lav); if (lav.Count != x.Vertices.Count) { this.Remove(x.Vertices); new_lavs.Add(SkeletonVerticesCollection.FromChain(v1, lav)); } else { new_lavs.Add(SkeletonVerticesCollection.FromChain(v1, lav)); new_lavs.Add(SkeletonVerticesCollection.FromChain(v2, lav)); } foreach (var l in new_lavs) { if (l.Count > 2) { this.Add(l); vertices.Add(l.Head); } else { sinks.Add(l.Head.Next.Point); foreach (var v in l) { v.Invalidate(); } } } var events = new List <IEvent>(); foreach (var vertex in vertices) { var nextEvent = vertex.NextEvent(lav._originalEdges); if (nextEvent != null) { events.Add(nextEvent); } } splitEvent.Vertex.Invalidate(); return(new SkeletonEventResult(new SkeletonSubtree(splitEvent.IntersectionPoint, splitEvent.Distance, sinks), events)); }
internal void Invalidate(SkeletonVertex vertex) { vertex._valid = false; }