/// <summary> /// Replace the specified ChildOld and ChildNew. /// </summary> /// <param name='ChildOld'> /// Child old. /// </param> /// <param name='ChildNew'> /// Child new. /// </param> /// <exception cref='Exception'> /// Represents errors that occur during application execution. /// </exception> 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> /// <summary> /// Processes the data event. /// </summary> /// <returns> /// The data event. /// </returns> /// <param name='e'> /// E. /// </param> /// <param name='Root'> /// Root. /// </param> /// <param name='VG'> /// V. /// </param> /// <param name='ys'> /// Ys. /// </param> /// <param name='CircleCheckList'> /// Circle check list. /// </param> /// <exception cref='Exception'> /// Represents errors that occur during application execution. /// </exception> 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[] {Root as VDataNode}; return Root; } //1. Find the node to be replaced VNode C = VNode.FindDataNode( Root, ys, e.DataPoint.X ); VDataNode cData = C as VDataNode; if( cData == null ) { throw new Exception( "Can't cast to data node" ); } //2. Create the subtree (ONE Edge, but two VEdgeNodes) VoronoiEdge VE = new VoronoiEdge(); VE.LeftData = cData.DataPoint; VE.RightData = e.DataPoint; VE.VVertexA = Fortune.VVUnkown; VE.VVertexB = Fortune.VVUnkown; VG.Edges.Add( VE ); VNode SubRoot; if( Math.Abs( VE.LeftData.Y - VE.RightData.Y ) < 1e-10 ) { if( VE.LeftData.X < VE.RightData.X ) { 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[] {SubRoot.Left as VDataNode, SubRoot.Right as VDataNode}; } 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[] {SubRoot.Left as VDataNode, SubRoot.Right.Left as VDataNode, SubRoot.Right.Right as VDataNode}; } //3. Apply subtree if( C.Parent == null ) { return SubRoot; } C.Parent.Replace( C, SubRoot ); return Root; }
/// <summary> /// Firsts the data node. /// </summary> /// <returns> /// The data node. /// </returns> /// <param name='Root'> /// Root. /// </param> public static VDataNode FirstDataNode( VNode Root ) { VNode C = Root; while( C.Left!=null ) { C = C.Left; } return C as VDataNode; }
/// <summary> /// Processes the circle event. /// </summary> /// <returns> /// The circle event. /// </returns> /// <param name='e'> /// E. /// </param> /// <param name='Root'> /// Root. /// </param> /// <param name='VG'> /// V. /// </param> /// <param name='ys'> /// Ys. /// </param> /// <param name='CircleCheckList'> /// Circle check list. /// </param> public static VNode ProcessCircleEvent( VCircleEvent e, VNode Root, VoronoiGraph VG, double ys, out VDataNode[] CircleCheckList ) { VDataNode a; VDataNode b; VDataNode c; VEdgeNode eu; VEdgeNode 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 0/00ndert hat } eu = b.Parent as VEdgeNode; CircleCheckList = new VDataNode[] {a,c}; //1. Create the new Vertex Vector2D VNew = new Vector2D( e.Center.X, e.Center.Y ); 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 ); eo.Edge.AddVertex( VNew ); //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; }
/// <summary> /// Finds the data node. /// </summary> /// <returns> /// The data node. /// </returns> /// <param name='Root'> /// Root. /// </param> /// <param name='ys'> /// Ys. /// </param> /// <param name='x'> /// X. /// </param> /// <exception cref='Exception'> /// Represents errors that occur during application execution. /// </exception> public static VDataNode FindDataNode( VNode Root, double ys, double x ) { VNode C = Root; do { if( C is VDataNode ) { return C as VDataNode; } VEdgeNode cEdge = C as VEdgeNode; if( cEdge == null ) { throw new Exception( "Can't cast to edge node" ); } if( cEdge.Cut( ys, x ) < 0 ) { C = C.Left; } else { C = C.Right; } } while(true); }