public IslandTileEdge (VoronoiEdge e) { edge = e; // Corner Index are assumed to be populated from IslandTile cornerA = IslandTileCorner.Index[e.VVertexA]; cornerB = IslandTileCorner.Index[e.VVertexB]; }
/// <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 VEdgeNode(VoronoiEdge E, bool Flipped) { this.Edge = E; this.Flipped = Flipped; }
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.Vertices.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); }
private bool newFix(VoronoiEdge edge) { double x1 = edge.VVertexA[0]; double y1 = edge.VVertexA[1]; double x2 = edge.VVertexB[0]; double y2 = edge.VVertexB[1]; //if both ends are in map, not much to do if ((DotInMap(x1, y1) && DotInMap(x2, y2))) return true; //if one end is out of map if ((DotInMap(x1, y1) && !DotInMap(x2, y2)) || (!DotInMap(x1, y1) && DotInMap(x2, y2))) { double b = 0.0d, slope = 0.0d; //and that point is actually a number ( not going to infinite ) if (!(double.IsNaN(x2) || double.IsNaN(y2))) { slope = ((y2 - y1) / (x2 - x1)); b = edge.VVertexA[1] - (slope * edge.VVertexA[0]); // y = ( slope * x ) + b if (edge.VVertexA[0] < 0) edge.VVertexA = new Vector(0, b); if (edge.VVertexA[0] > App.MapSize) edge.VVertexA = new Vector(App.MapSize, (App.MapSize * slope) + b); if (edge.VVertexA[1] < 0) edge.VVertexA = new Vector((-b / slope), 0); if (edge.VVertexA[1] > App.MapSize) edge.VVertexA = new Vector((App.MapSize - b) / slope, App.MapSize); if (edge.VVertexB[0] < 0) edge.VVertexB = new Vector(0, b); if (edge.VVertexB[0] > App.MapSize) edge.VVertexB = new Vector(App.MapSize, (App.MapSize * slope) + b); if (edge.VVertexB[1] < 0) edge.VVertexB = new Vector((-b / slope), 0); if (edge.VVertexB[1] > App.MapSize) edge.VVertexB = new Vector((App.MapSize - b) / slope, App.MapSize); } else { //and if that end is actually not a number ( going go infinite ) if (double.IsNaN(x2) || double.IsNaN(y2)) { var x3 = (edge.LeftData[0] + edge.RightData[0]) / 2; var y3 = (edge.LeftData[1] + edge.RightData[1]) / 2; slope = ((y3 - y1) / (x3 - x1)); slope = Math.Abs(slope); b = edge.VVertexA[1] - (slope * edge.VVertexA[0]); // y = ( slope * x ) + b var i = 0.0d; if(x3 < y3) { if(App.MapSize - x3 > y3) { i = b; if (i > 0 && i < 400) edge.VVertexB = new BenTools.Mathematics.Vector(0, i); } else { i = (App.MapSize - b) / slope; if (i > 0 && i < 400) edge.VVertexB = new BenTools.Mathematics.Vector(i, App.MapSize); } } else { if (App.MapSize - x3 > y3) { i = (-b / slope); if (i > 0 && i < 400) edge.VVertexB = new BenTools.Mathematics.Vector(i, 0); } else { i = (App.MapSize * slope) + b; if (i > 0 && i < 400) edge.VVertexB = new BenTools.Mathematics.Vector(App.MapSize, i); } } //if (x3 < App.MapSize / 4) //{ // i = b; // if (i > 0 && i < 400) // edge.VVertexB = new BenTools.Mathematics.Vector(0, i); // //left //} //if (x3 > App.MapSize * 3 / 4) //{ // i = (App.MapSize * slope) + b; // if (i > 0 && i < 400) // edge.VVertexB = new BenTools.Mathematics.Vector(App.MapSize, i); // //right //} //if (y3 > App.MapSize * 3 / 4) //{ // i = (App.MapSize - b) / slope; // if (i > 0 && i < 400) // edge.VVertexB = new BenTools.Mathematics.Vector(i, App.MapSize); // //bottom //} //if (y3 < App.MapSize / 4) //{ // i = (-b / slope); // if (i > 0 && i < 400) // edge.VVertexB = new BenTools.Mathematics.Vector(i, 0); // //top //} } } return true; } return false; }
private int NumConnectedEdges(VoronoiEdge edge, HashSet<IslandTileEdge> es) { int numConnectedEdges = 0; foreach(IslandTileEdge e in es) { if (e.edge.VVertexA == edge.VVertexA || e.edge.VVertexA == edge.VVertexB || e.edge.VVertexB == edge.VVertexA || e.edge.VVertexB == edge.VVertexB) { numConnectedEdges++; } } return numConnectedEdges; }
private void AddCorners (VoronoiEdge e) { IslandTileCorner cA = AddCorner(e.VVertexA); IslandTileCorner cB = AddCorner(e.VVertexB); cA.protrudes.Add(e); cA.adjacent.Add(cB); cA.touches.Add(this); cB.protrudes.Add(e); cB.adjacent.Add(cA); cB.touches.Add(this); }
private void AddEdge (VoronoiEdge e) { bool isInf = (e.VVertexA == Fortune.VVInfinite) || (e.VVertexB == Fortune.VVInfinite); if (isInf) { return; } AddCorners(e); edges.Add(new IslandTileEdge(e)); if (e.LeftData == center) { neighbors.Add(e.RightData); } else { neighbors.Add(e.LeftData); } }
private bool EdgeBelongsToTile (VoronoiEdge e) { return (e.LeftData == center) || (e.RightData == center); }
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; }
/// <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 bool EdgeInBounds(VoronoiEdge e) { return VectorInBounds(e.VVertexA) && VectorInBounds(e.VVertexB); }