Esempio n. 1
0
 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;
 }
Esempio n. 2
0
 internal _SplitEvent(float distance, Vector2 intersectionPoint, SkeletonVertex vertex, SkeletonLineSegment oppositeEdge)
 {
     this.Distance          = distance;
     this.IntersectionPoint = intersectionPoint;
     this.Vertex            = vertex;
     this.OppositeEdge      = oppositeEdge;
 }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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));
        }
Esempio n. 5
0
 internal void Invalidate(SkeletonVertex vertex)
 {
     vertex._valid = false;
 }