예제 #1
0
        public List <CircleEvent> RemoveNode(CircleEvent ce, Leaf prev, Leaf remove, Leaf next)
        {
            var circleEvents = new List <CircleEvent>();

            var currentVector2 = prev.ListItem.Point;
            var newVector2     = next.ListItem.Point;
            var h1             = new PartialLine(currentVector2);
            var h2             = new PartialLine(newVector2);

            h1.Twin = h2;
            h2.Twin = h1;
            PartialLines.Add(h1);
            PartialLines.Add(h2);

            h1.CircleEvent = ce;
            var bp1 = new Breakpoint(prev.ListItem, next.ListItem);

            if (prev.BreakpointNode == remove.Parent)
            {
                prev.BreakpointNode = remove.BreakpointNode;
            }

            prev.BreakpointNode.Breakpoint = bp1;

            {
                var oldEdgeP = prev.ListItem.PartialLine;

                if (!oldEdgeP.Face.Equals(prev.ListItem.Point))
                {
                    oldEdgeP = oldEdgeP.Twin;
                }

                var n = oldEdgeP.Next;
                oldEdgeP.Next = h1;
                h1.Previous   = oldEdgeP;

                if (n != null)
                {
                    h1.Next    = n;
                    n.Previous = h1;
                }
            }

            {
                var oldEdgeN = next.ListItem.PartialLine;

                if (!oldEdgeN.Face.Equals(next.ListItem.Point))
                {
                    oldEdgeN = oldEdgeN.Twin;
                }

                var n = oldEdgeN.Next;

                oldEdgeN.Next = h2;
                h2.Previous   = oldEdgeN;

                if (n != null)
                {
                    h2.Next    = n;
                    n.Previous = h2;
                }
            }

            prev.ListItem.PartialLine = h1;

            if (remove.Parent.Parent == null)
            {
                Root = remove.Parent.Left == remove
                    ? remove.Parent.Right
                    : remove.Parent.Left;
                Root.Parent = null;
            }
            else
            {
                var grandparent = remove.Parent.Parent;
                var parent      = remove.Parent;

                if (remove == remove.Parent.Left)
                {
                    if (remove.Parent == grandparent.Left)
                    {
                        grandparent.Left    = parent.Right;
                        parent.Right.Parent = grandparent;
                    }
                    else
                    {
                        grandparent.Right   = parent.Right;
                        parent.Right.Parent = grandparent;
                    }
                }

                else
                {
                    if (remove.Parent == grandparent.Left)
                    {
                        grandparent.Left   = parent.Left;
                        parent.Left.Parent = grandparent;
                    }
                    else
                    {
                        grandparent.Right  = parent.Left;
                        parent.Left.Parent = grandparent;
                    }
                }

                remove.Parent = null;
            }

            var nextNextTree = next.GetNextLeaf();

            if (nextNextTree != null &&
                nextNextTree is Leaf nextNext)
            {
                var circleEvent        = new CircleEvent(prev, next, nextNext);
                var canCalculateCircle = circleEvent.CalculateCircle();

                next.BreakpointNode.Breakpoint = new Breakpoint(next.ListItem, nextNext.ListItem);

                bp1.InitializeBreakpoint(circleEvent.DistanceFromLine);

                next.BreakpointNode.Breakpoint.InitializeBreakpoint(circleEvent.DistanceFromLine);

                if (canCalculateCircle && circleEvent.CheckConvergence())
                {
                    next.DisappearEvent = circleEvent;

                    circleEvents.Add(circleEvent);
                }
            }

            var prevPrevTree = prev.GetPreviousLeaf();

            if (prevPrevTree != null &&
                prevPrevTree is Leaf prevPrev)
            {
                var circleEvent        = new CircleEvent(prevPrev, prev, next);
                var canCalculateCircle = circleEvent.CalculateCircle();

                prevPrev.BreakpointNode.Breakpoint = new Breakpoint(prevPrev.ListItem, prev.ListItem);
                bp1.InitializeBreakpoint(circleEvent.DistanceFromLine);

                prevPrev.BreakpointNode.Breakpoint.InitializeBreakpoint(circleEvent.DistanceFromLine);

                if (canCalculateCircle && circleEvent.CheckConvergence())
                {
                    prev.DisappearEvent = circleEvent;

                    circleEvents.Add(circleEvent);
                }
            }

            return(circleEvents);
        }
예제 #2
0
        public List <CircleEvent> AddSeedEvent(Leaf current, TreeItem listItem)
        {
            var circleEvents = new List <CircleEvent>();

            var currentVector2 = current.ListItem.Point;
            var newVector2     = listItem.Point;
            var h1             = new PartialLine(currentVector2);
            var h2             = new PartialLine(newVector2);

            h1.Twin = h2;
            h2.Twin = h1;
            PartialLines.Add(h1);
            PartialLines.Add(h2);

            if (currentVector2.PartialLine == null)
            {
                currentVector2.PartialLine = h1;
            }

            newVector2.PartialLine = h2;

            var oldHe = current.ListItem.PartialLine;

            current.ListItem.PartialLine = h1;
            listItem.PartialLine         = h1;

            var prev = current.GetPreviousLeaf();
            var next = current.GetNextLeaf();

            var newNode  = new Leaf(listItem);
            var copy     = current.ListItem.Copy();
            var copyNode = new Leaf(copy);

            var bp1 = new Breakpoint(current.ListItem, listItem);

            bp1.InitializeBreakpoint(listItem.Point.Y - 1);

            var bp2 = new Breakpoint(listItem, copy);

            bp2.InitializeBreakpoint(listItem.Point.Y - 1);

            var bp1Node = new BreakpointNode(bp1);
            var bp2Node = new BreakpointNode(bp2);

            current.BreakpointNode = bp1Node;
            newNode.BreakpointNode = bp2Node;

            if (current.Parent != null)
            {
                if (current == current.Parent.Left)
                {
                    current.Parent.Left = bp1Node;
                    bp1Node.Parent      = current.Parent;
                }
                else
                {
                    current.Parent.Right = bp1Node;
                    bp1Node.Parent       = current.Parent;
                }
            }
            else
            {
                SetRoot(bp1Node);
                Root.Parent = null;
            }

            bp1Node.Left   = current;
            current.Parent = bp1Node;

            bp1Node.Right  = bp2Node;
            bp2Node.Parent = bp1Node;

            bp2Node.Left   = newNode;
            newNode.Parent = bp2Node;

            bp2Node.Right   = copyNode;
            copyNode.Parent = bp2Node;

            if (oldHe != null)
            {
                copyNode.ListItem.PartialLine = oldHe;
                var pre = copyNode.ListItem.PartialLine;

                if (!pre.Face.Equals(currentVector2))
                {
                    pre = pre.Twin;
                }

                var onext = pre.Next;
                pre.Next    = h1;
                h1.Previous = pre;

                if (onext != null)
                {
                    onext.Previous = h1;
                    h1.Next        = onext;
                }
            }

            if (prev != null && prev is Leaf prevLeaf)
            {
                var circleEvent        = new CircleEvent(prevLeaf, current, newNode);
                var canCalculateCircle = circleEvent.CalculateCircle();

                prevLeaf.BreakpointNode.Breakpoint = new Breakpoint(prevLeaf.ListItem, current.ListItem);

                bp1Node.Breakpoint.InitializeBreakpoint(circleEvent.DistanceFromLine);
                prevLeaf.BreakpointNode.Breakpoint.InitializeBreakpoint(circleEvent.DistanceFromLine);

                if (canCalculateCircle && circleEvent.CheckConvergence())
                {
                    current.DisappearEvent = circleEvent;
                    circleEvents.Add(circleEvent);
                }
            }

            if (next != null && next is Leaf nextLeaf)
            {
                var circleEvent        = new CircleEvent(newNode, copyNode, nextLeaf);
                var canCalculateCircle = circleEvent.CalculateCircle();

                copyNode.BreakpointNode            = (BreakpointNode)copyNode.GetNext();
                copyNode.BreakpointNode.Breakpoint = new Breakpoint(copy, nextLeaf.ListItem);

                bp2Node.Breakpoint.InitializeBreakpoint(circleEvent.DistanceFromLine);
                copyNode.BreakpointNode.Breakpoint.InitializeBreakpoint(circleEvent.DistanceFromLine);

                if (canCalculateCircle && circleEvent.CheckConvergence())
                {
                    copyNode.DisappearEvent = circleEvent;
                    circleEvents.Add(circleEvent);
                }
            }
            else
            {
                copyNode.ListItem.PartialLine = h1;
            }

            return(circleEvents);
        }