예제 #1
0
        private Int64 GetChildCode(LinearNode <T> node, Int32 direction)
        {
            Int64 childCode = node.Code;

            childCode += Convert.ToInt64(Math.Pow(4, _maxLevel - node.Region.Level - 1)) * direction;
            return(childCode);
        }
예제 #2
0
        private List <LinearNode <T> > CalculateLeafProperties()
        {
            // source: Aizawa, K. et al.: Constant Time Neighbor Finding in Quadtrees, ISCCSP 2008.

            _q = new List <LinearNode <T> >();
            LinearNode <T> node = new LinearNode <T>(_root, 0);

            _q.Add(node);
            LinearNode <T> firstGrey = GetFirstGrey(_q);

            while (firstGrey != null)
            {
                SetNeighbourLevels(firstGrey);
                _q.Remove(firstGrey);
                LinearNode <T>[] children = new LinearNode <T> [4];
                children[0] = CreateChildNode(firstGrey, 0);
                children[1] = CreateChildNode(firstGrey, 1);
                children[2] = CreateChildNode(firstGrey, 2);
                children[3] = CreateChildNode(firstGrey, 3);
                SetChildNeighbourLevels(firstGrey, children);
                _q.InsertRange(0, children);
                firstGrey = GetFirstGrey(_q);
            }
            return(_q);
        }
예제 #3
0
        /// <summary>
        /// Gets the neighbor of the given node in the given direction.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="d">The direction<./param>
        /// <returns>The neighbor, or <c>null</c> if there is no neighbor in the given direction.</returns>
        public LinearNode <T> GetNeighbor(LinearNode <T> node, Direction d)
        {
            // source: Aizawa, K. et al.: Constant Time Neighbor Finding in Quadtrees, ISCCSP 2008.

            Int32?dd  = null;
            long  dnq = 0;

            switch (d)
            {
            case Direction.North:
                dd  = node.North;
                dnq = _dn;
                break;

            case Direction.South:
                dd  = node.South;
                dnq = _ds;
                break;

            case Direction.East:
                dd  = node.East;
                dnq = _de;
                break;

            case Direction.West:
                dd  = node.West;
                dnq = _dw;
                break;
            }
            if (dd.HasValue)
            {
                Int64 mq;
                Int64 nq = node.Code;
                Int32 l  = node.Region.Level;
                if (dd < 0)
                {
                    mq = Add(((nq >> 2 * (_maxLevel - l - dd.Value)) << 2 * (_maxLevel - l - dd.Value)), dnq << (2 * (_maxLevel - l - dd.Value)));
                }
                else
                {
                    mq = Add(nq, dnq << (2 * (_maxLevel - l)));
                }
                //
                LinearNode <T> result = GetNode(mq, _q);
                // Fix the algorithm
                if (dd > 0 && (d == Direction.South || d == Direction.West))
                {
                    return(NodeOf(GetMostNorthEastRecursive(result.Region.Parent)));
                }
                return(result);
            }
            else
            {
                return(null);
            }
        }
예제 #4
0
        private void SetNeighbourLevels(LinearNode <T> firstGrey)
        {
            Int32 l = firstGrey.Region.Level;
            // EAST
            Int64          id   = Add(firstGrey.Code, (_de << (2 * (_maxLevel - l))));
            LinearNode <T> node = GetNode(id, _q);

            if (node != null)
            {
                LinearNode <T> n = node;
                if (node.Region.Level == l && node.West != null)
                {
                    n.West = node.West + 1;
                }
            }
            // NORTH
            id   = Add(firstGrey.Code, (_dn << (2 * (_maxLevel - l))));
            node = GetNode(id, _q);
            if (node != null)
            {
                LinearNode <T> n = node;
                if (node.Region.Level == l && node.South != null)
                {
                    n.South = node.South + 1;
                }
            }
            // WEST
            id   = Add(firstGrey.Code, (_dw << (2 * (_maxLevel - l))));
            node = GetNode(id, _q);
            if (node != null)
            {
                LinearNode <T> n = node;
                if (node.Region.Level == l && node.East != null)
                {
                    n.East = node.East + 1;
                }
            }
            // SOUTH
            id   = Add(firstGrey.Code, (_ds << (2 * (_maxLevel - l))));
            node = GetNode(id, _q);
            if (node != null)
            {
                LinearNode <T> n = node;
                if (node.Region.Level == l && node.North != null)
                {
                    n.North = node.North + 1;
                }
            }
        }
예제 #5
0
 private LinearNode <T> CreateChildNode(LinearNode <T> parent, Int32 p)
 {
     return(new LinearNode <T>(parent.Region.Childs[p], GetChildCode(parent, p)));
 }
예제 #6
0
        private void SetChildNeighbourLevels(LinearNode <T> parent, LinearNode <T>[] children)
        {
            LinearNode <T> neighbor;
            Int32          l = parent.Region.Level + 1;

            children[0].East  = 0;
            children[0].North = 0;
            if (parent.West != null)
            {
                children[0].West = (parent.West - 1);
                neighbor         = GetNode(Add(children[0].Code, _dw << (2 * (_maxLevel - l))), _q);
                if (neighbor != null && neighbor.Region.Level == l)
                {
                    LinearNode <T> n = neighbor;
                    n.East = n.East + 1;
                }
            }
            if (parent.South != null)
            {
                children[0].South = parent.South - 1;
                neighbor          = GetNode(Add(children[0].Code, _ds << (2 * (_maxLevel - l))), _q);
                if (neighbor != null && neighbor.Region.Level == l)
                {
                    LinearNode <T> n = neighbor;
                    n.North = n.North + 1;
                }
            }
            children[1].North = 0;
            children[1].West  = 0;
            if (parent.East != null)
            {
                children[1].East = parent.East - 1;
                neighbor         = GetNode(Add(children[1].Code, _de << (2 * (_maxLevel - l))), _q);
                if (neighbor != null && neighbor.Region.Level == l)
                {
                    LinearNode <T> n = neighbor;
                    n.West = n.West + 1;
                }
            }
            if (parent.South != null)
            {
                children[1].South = parent.South - 1;
                neighbor          = GetNode(Add(children[1].Code, _ds << (2 * (_maxLevel - l))), _q);
                if (neighbor != null && neighbor.Region.Level == l)
                {
                    LinearNode <T> n = neighbor;
                    n.North = n.North + 1;
                }
            }

            children[2].South = 0;
            children[2].East  = 0;
            if (parent.North != null)
            {
                children[2].North = parent.North - 1;
                neighbor          = GetNode(Add(children[2].Code, _dn << (2 * (_maxLevel - l))), _q);
                if (neighbor != null && neighbor.Region.Level == l)
                {
                    LinearNode <T> n = neighbor;
                    n.South = n.South + 1;
                }
            }
            if (parent.West != null)
            {
                children[2].West = parent.West - 1;
                neighbor         = GetNode(Add(children[2].Code, _dw << (2 * (_maxLevel - l))), _q);
                if (neighbor != null && neighbor.Region.Level == l)
                {
                    LinearNode <T> n = neighbor;
                    n.East = n.East + 1;
                }
            }
            children[3].South = 0;
            children[3].West  = 0;
            if (parent.North != null)
            {
                children[3].North = parent.North - 1;
                neighbor          = GetNode(Add(children[3].Code, _dn << (2 * (_maxLevel - l))), _q);
                if (neighbor != null && neighbor.Region.Level == l)
                {
                    LinearNode <T> n = neighbor;
                    n.South = n.South + 1;
                }
            }
            if (parent.East != null)
            {
                children[3].East = parent.East - 1;
                neighbor         = GetNode(Add(children[3].Code, _de << (2 * (_maxLevel - l))), _q);
                if (neighbor != null && neighbor.Region.Level == l)
                {
                    LinearNode <T> n = neighbor;
                    n.West = n.West + 1;
                }
            }
        }