/// <summary> /// Will return the new root (unchanged except in start-up) /// </summary> public static VNode ProcessDataEvent(VDataEvent e, VNode Root, VoronoiDiagram 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.X); //2. Create the subtree (ONE Edge, but two VEdgeNodes) VoronoiEdge VE = new VoronoiEdge(); VE.LeftData = ((VDataNode)C).DataPoint; VE.RightData = e.DataPoint; VE.VVertexA = VVUnkown; VE.VVertexB = 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[] { (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 ProcessDataEvent(VDataEvent vertexevent, VNode root, VoronoiGraph veronoigraphbox, double vertexeventycoord, out VDataNode[] circleCheckList) { if (root == null) { root = new VDataNode(vertexevent.DataPoint); circleCheckList = new VDataNode[] { (VDataNode)root }; return(root); } //1. Find the node to be replaced VNode C = NodeHandler.FindDataNode(root, vertexeventycoord, vertexevent.DataPoint[0]); //2. Create the subtree (ONE Edge, but two VEdgeNodes) VoronoiEdge VE = new VoronoiEdge(); VE.LeftData = ((VDataNode)C).DataPoint; VE.RightData = vertexevent.DataPoint; VE.VVertexA = Constants.VVUnkown; VE.VVertexB = Constants.VVUnkown; veronoigraphbox.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); }
private static VNode ProcessCircleEvent(VCircleEvent e, VNode Root, VoronoiGraph VG, double ys, out VDataNode[] CircleCheckList) { VDataNode a, b, c; VEdgeNode e1, e2; 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); // повертаємось, бо графік змінився } e1 = (VEdgeNode)b.Parent; CircleCheckList = new VDataNode[] { a, c }; //Створюємо нову вершину Vector VNew = new Vector(e.Center[0], e.Center[1]); VG.Vertizes.Add(VNew); //2. виясняємо, чи а або с знаходяться у віддаленій частині дерева (інший - брат b), і призначаємо нову вершину if (e1.Left == b) // c - брат { e2 = VNode.EdgeToRightDataNode(a); // замінюємо e1 правим нащадком e1.Parent.Replace(e1, e1.Right); } else // a - брат { e2 = VNode.EdgeToRightDataNode(b); // замінюємо e1 лівим нащадком e1.Parent.Replace(e1, e1.Left); } e1.Edge.AddVertex(VNew); e2.Edge.AddVertex(VNew); //Замінюємо e2 новим ребром 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 = e2.Left; VEN.Right = e2.Right; if (e2.Parent == null) { return(VEN); } e2.Parent.Replace(e2, VEN); return(Root); }
private 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); } //Знаходимо вузол для заміщення VNode C = VNode.FindDataNode(Root, ys, e.DataPoint[0]); //Створюємо піддерево з одним ребром, але двома 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 }; } //"Застосовуємо" піддерево if (C.Parent == null) { return(SubRoot); } C.Parent.Replace(C, SubRoot); return(Root); }
public static void CleanUpTree(VNode Root) { if (Root is VDataNode) { return; } VEdgeNode VE = Root as VEdgeNode; while (VE.Edge.VVertexB == Constants.VVUnkown) { VE.Edge.AddVertex(Constants.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); }
public static VNode ProcessCircleEvent(VCircleEvent e, VNode Root, VoronoiDiagram 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 Vector2 VNew = new Vector2(e.Center.X, e.Center.Y); // 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) //{ // Vector2 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); }
private 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; } //Знаходимо вузол для заміщення VNode C = VNode.FindDataNode(Root, ys, e.DataPoint[0]); //Створюємо піддерево з одним ребром, але двома 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 }; } //"Застосовуємо" піддерево if (C.Parent == null) return SubRoot; C.Parent.Replace(C, SubRoot); return Root; }
private static VNode ProcessCircleEvent(VCircleEvent e, VNode Root, VoronoiGraph VG, double ys, out VDataNode[] CircleCheckList) { VDataNode a, b, c; VEdgeNode e1, e2; 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; // повертаємось, бо графік змінився } e1 = (VEdgeNode)b.Parent; CircleCheckList = new VDataNode[] { a, c }; //Створюємо нову вершину Vector VNew = new Vector(e.Center[0], e.Center[1]); VG.Vertizes.Add(VNew); //2. виясняємо, чи а або с знаходяться у віддаленій частині дерева (інший - брат b), і призначаємо нову вершину if (e1.Left == b) // c - брат { e2 = VNode.EdgeToRightDataNode(a); // замінюємо e1 правим нащадком e1.Parent.Replace(e1, e1.Right); } else // a - брат { e2 = VNode.EdgeToRightDataNode(b); // замінюємо e1 лівим нащадком e1.Parent.Replace(e1, e1.Left); } e1.Edge.AddVertex(VNew); e2.Edge.AddVertex(VNew); //Замінюємо e2 новим ребром 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 = e2.Left; VEN.Right = e2.Right; if (e2.Parent == null) return VEN; e2.Parent.Replace(e2, VEN); return Root; }