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);
                    }
                }
            }
        }
Esempio n. 3
0
        /*
         * 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);
                    }

                }
            }
        }