public void Replace(VNode ChildOld, VNode ChildNew)
 {
     if (Left == ChildOld)
     Left = ChildNew;
      else if (Right == ChildOld)
     Right = ChildNew;
      else throw new Exception("Child not found!");
      ChildOld.Parent = null;
 }
        /// <summary>
        /// Will return the new root (unchanged except in start-up)
        /// </summary>
        public static VNode ProcessDataEvent(VDataEvent e, VNode Root, VoronoiGraph VG, double ys, out VDataNode[] CircleCheckList)
        {
            if (Root == null)
             {
            Root = new VDataNode(e.DataPoint);
            CircleCheckList = new VDataNode[] { (VDataNode)Root };
            return Root;
             }
             //1. Find the node to be replaced
             VNode C = VNode.FindDataNode(Root, ys, e.DataPoint[0]);
             //2. Create the subtree (ONE Edge, but two VEdgeNodes)
             VoronoiEdge VE = new VoronoiEdge();
             VE.LeftData = ((VDataNode)C).DataPoint;
             VE.RightData = e.DataPoint;
             VE.VVertexA = Fortune.VVUnkown;
             VE.VVertexB = Fortune.VVUnkown;
             VG.Edges.Add(VE);

             VNode SubRoot;
             if (Math.Abs(VE.LeftData[1] - VE.RightData[1]) < 1e-10)
             {
            if (VE.LeftData[0] < VE.RightData[0])
            {
               SubRoot = new VEdgeNode(VE, false);
               SubRoot.Left = new VDataNode(VE.LeftData);
               SubRoot.Right = new VDataNode(VE.RightData);
            }
            else
            {
               SubRoot = new VEdgeNode(VE, true);
               SubRoot.Left = new VDataNode(VE.RightData);
               SubRoot.Right = new VDataNode(VE.LeftData);
            }
            CircleCheckList = new VDataNode[] { (VDataNode)SubRoot.Left, (VDataNode)SubRoot.Right };
             }
             else
             {
            SubRoot = new VEdgeNode(VE, false);
            SubRoot.Left = new VDataNode(VE.LeftData);
            SubRoot.Right = new VEdgeNode(VE, true);
            SubRoot.Right.Left = new VDataNode(VE.RightData);
            SubRoot.Right.Right = new VDataNode(VE.LeftData);
            CircleCheckList = new VDataNode[] { (VDataNode)SubRoot.Left, (VDataNode)SubRoot.Right.Left, (VDataNode)SubRoot.Right.Right };
             }

             //3. Apply subtree
             if (C.Parent == null)
            return SubRoot;
             C.Parent.Replace(C, SubRoot);
             return Root;
        }
        public static VNode ProcessCircleEvent(VCircleEvent e, VNode Root, VoronoiGraph VG, double ys, out VDataNode[] CircleCheckList)
        {
            VDataNode a, b, c;
             VEdgeNode eu, eo;
             b = e.NodeN;
             a = VNode.LeftDataNode(b);
             c = VNode.RightDataNode(b);
             if (a == null || b.Parent == null || c == null || !a.DataPoint.Equals(e.NodeL.DataPoint) || !c.DataPoint.Equals(e.NodeR.DataPoint))
             {
            CircleCheckList = new VDataNode[] { };
            return Root; // Abbruch da sich der Graph verändert hat
             }
             eu = (VEdgeNode)b.Parent;
             CircleCheckList = new VDataNode[] { a, c };
             //1. Create the new Vertex
             Vector VNew = new Vector(e.Center[0], e.Center[1]);
             //			VNew[0] = Fortune.ParabolicCut(a.DataPoint[0],a.DataPoint[1],c.DataPoint[0],c.DataPoint[1],ys);
             //			VNew[1] = (ys + a.DataPoint[1])/2 - 1/(2*(ys-a.DataPoint[1]))*(VNew[0]-a.DataPoint[0])*(VNew[0]-a.DataPoint[0]);
             VG.Vertizes.Add(VNew);
             //2. Find out if a or c are in a distand part of the tree (the other is then b's sibling) and assign the new vertex
             if (eu.Left == b) // c is sibling
             {
            eo = VNode.EdgeToRightDataNode(a);

            // replace eu by eu's Right
            eu.Parent.Replace(eu, eu.Right);
             }
             else // a is sibling
             {
            eo = VNode.EdgeToRightDataNode(b);

            // replace eu by eu's Left
            eu.Parent.Replace(eu, eu.Left);
             }
             eu.Edge.AddVertex(VNew);
             //			///////////////////// uncertain
             //			if(eo==eu)
             //				return Root;
             //			/////////////////////

             //complete & cleanup eo
             eo.Edge.AddVertex(VNew);
             //while(eo.Edge.VVertexB == Fortune.VVUnkown)
             //{
             //    eo.Flipped = !eo.Flipped;
             //    eo.Edge.AddVertex(Fortune.VVInfinite);
             //}
             //if(eo.Flipped)
             //{
             //    Vector T = eo.Edge.LeftData;
             //    eo.Edge.LeftData = eo.Edge.RightData;
             //    eo.Edge.RightData = T;
             //}

             //2. Replace eo by new Edge
             VoronoiEdge VE = new VoronoiEdge();
             VE.LeftData = a.DataPoint;
             VE.RightData = c.DataPoint;
             VE.AddVertex(VNew);
             VG.Edges.Add(VE);

             VEdgeNode VEN = new VEdgeNode(VE, false);
             VEN.Left = eo.Left;
             VEN.Right = eo.Right;
             if (eo.Parent == null)
            return VEN;
             eo.Parent.Replace(eo, VEN);
             return Root;
        }
 public static VDataNode FirstDataNode(VNode Root)
 {
     VNode C = Root;
      while (C.Left != null)
     C = C.Left;
      return (VDataNode)C;
 }
 public static VDataNode FindDataNode(VNode Root, double ys, double x)
 {
     VNode C = Root;
      do
      {
     if (C is VDataNode)
        return (VDataNode)C;
     if (((VEdgeNode)C).Cut(ys, x) < 0)
        C = C.Left;
     else
        C = C.Right;
      } while (true);
 }
 public static void CleanUpTree(VNode Root)
 {
     if (Root is VDataNode)
     return;
      VEdgeNode VE = Root as VEdgeNode;
      while (VE.Edge.VVertexB == Fortune.VVUnkown)
      {
     VE.Edge.AddVertex(Fortune.VVInfinite);
     //				VE.Flipped = !VE.Flipped;
      }
      if (VE.Flipped)
      {
     Vector T = VE.Edge.LeftData;
     VE.Edge.LeftData = VE.Edge.RightData;
     VE.Edge.RightData = T;
      }
      VE.Edge.Done = true;
      CleanUpTree(Root.Left);
      CleanUpTree(Root.Right);
 }