public static ConnectionInfo FindConnection(TileRegion regionA, TileRegion regionB) { Assert.IsNotNull(regionA); Assert.IsNotNull(regionB); Assert.AreNotEqual(regionA, regionB); var bestConnection = new TempConnection(Coord.zero, Coord.zero, float.MaxValue); int indexA = 0; while (indexA < regionA.Count) { int indexB = 0; var bestThisLoop = new TempConnection(regionA[indexA], Coord.zero, float.MaxValue); while (indexB < regionB.Count) { Coord tileB = regionB[indexB]; float distance = bestThisLoop.tileA.Distance(tileB); if (distance < bestThisLoop.distance) { bestThisLoop = new TempConnection(bestThisLoop.tileA, tileB, distance); } indexB += (int)distance; // distance is never < 1, as minimum occurs with diagonally adjacent tiles } if (bestThisLoop.distance < bestConnection.distance) { bestConnection = bestThisLoop; } indexA += (int)bestThisLoop.distance; } return(new ConnectionInfo(bestConnection.tileA, bestConnection.tileB, regionA.Index, regionB.Index, bestConnection.distance)); }
/* * Input : Coordinates of source (outgoing = true) or target node (outgoing = false) at (a,b) and initialized quadtree p. * Output: Adds the connections that are in bands of the two-dimensional cross-section of the * hypercube containing the source or target node to the connections list. * */ public void PruneAndExpress(float a, float b, ref List <TempConnection> connections, QuadPoint node, bool outgoing, float maxDepth) { float left = 0.0f, right = 0.0f, top = 0.0f, bottom = 0.0f; if (node.childs[0] == null) { return; } // Traverse quadtree depth-first foreach (QuadPoint c in node.childs) { float childVariance = variance(c); if (childVariance >= varianceThreshold) { PruneAndExpress(a, b, ref connections, c, outgoing, maxDepth); } else //this should always happen for at least the leaf nodes because their variance is zero { // Determine if point is in a band by checking neighbor CPPN values if (outgoing) { left = Math.Abs(c.w - queryCPPN(a, b, c.x - node.width, c.y)); right = Math.Abs(c.w - queryCPPN(a, b, c.x + node.width, c.y)); top = Math.Abs(c.w - queryCPPN(a, b, c.x, c.y - node.width)); bottom = Math.Abs(c.w - queryCPPN(a, b, c.x, c.y + node.width)); } else { left = Math.Abs(c.w - queryCPPN(c.x - node.width, c.y, a, b)); right = Math.Abs(c.w - queryCPPN(c.x + node.width, c.y, a, b)); top = Math.Abs(c.w - queryCPPN(c.x, c.y - node.width, a, b)); bottom = Math.Abs(c.w - queryCPPN(c.x, c.y + node.width, a, b)); } if (Math.Max(Math.Min(top, bottom), Math.Min(left, right)) > bandThrehold) { TempConnection tc; if (outgoing) { tc = new TempConnection(a, b, c.x, c.y, c.w); } else { tc = new TempConnection(c.x, c.y, a, b, c.w); } connections.Add(tc); } } } }
/* * Input : Coordinates of source (outgoing = true) or target node (outgoing = false) at (a,b) and initialized quadtree p. * Output: Adds the connections that are in bands of the two-dimensional cross-section of the * hypercube containing the source or target node to the connections list. * */ public void PruneAndExpress(float a, float b, ref List<TempConnection> connections, QuadPoint node, bool outgoing, float maxDepth) { float left = 0.0f, right = 0.0f, top = 0.0f, bottom = 0.0f; if (node.childs[0] == null) return; // Traverse quadtree depth-first foreach (QuadPoint c in node.childs) { float childVariance = variance(c); if (childVariance >= varianceThreshold) { PruneAndExpress(a, b, ref connections, c, outgoing, maxDepth); } else //this should always happen for at least the leaf nodes because their variance is zero { // Determine if point is in a band by checking neighbor CPPN values if (outgoing) { left = Math.Abs(c.w - queryCPPNWeight(a, b, c.x - node.width, c.y)); right = Math.Abs(c.w - queryCPPNWeight(a, b, c.x + node.width, c.y)); top = Math.Abs(c.w - queryCPPNWeight(a, b, c.x, c.y - node.width)); bottom = Math.Abs(c.w - queryCPPNWeight(a, b, c.x, c.y + node.width)); } else { left = Math.Abs(c.w - queryCPPNWeight(c.x - node.width, c.y, a, b)); right = Math.Abs(c.w - queryCPPNWeight(c.x + node.width, c.y, a, b)); top = Math.Abs(c.w - queryCPPNWeight(c.x, c.y - node.width, a, b)); bottom = Math.Abs(c.w - queryCPPNWeight(c.x, c.y + node.width, a, b)); } if (Math.Max(Math.Min(top, bottom), Math.Min(left, right)) > bandThrehold) { TempConnection tc = null; if (outgoing) { //check for LEO if(useLEO && c.Outputs[1] > 0) tc = new TempConnection(a, b, c.x, c.y, c.w, c.Outputs); else if(!useLEO) tc = new TempConnection(a, b, c.x, c.y, c.w, c.Outputs); } else { //check against leo! if (useLEO && c.Outputs[1] > 0) tc = new TempConnection(c.x, c.y, a, b, c.w, c.Outputs); else if(!useLEO) tc = new TempConnection(c.x, c.y, a, b, c.w, c.Outputs); } if(tc!= null) connections.Add(tc); } } } }