示例#1
0
        void Add(RBox box, int id, int level)
        {
            Node n       = ChooseNode(box, level);
            Node newLeaf = null;

            if (n.entryCount < maxNodeEntries)
            {
                n.AddEntryNoCopy(box, id);
            }
            else
            {
                newLeaf = SplitNode(n, box, id);
            }
            Node newNode = AdjustTree(n, newLeaf);

            if (newNode != null)
            {
                int  oldRootNodeId = rootNodeId;
                Node oldRoot       = nodeMap[oldRootNodeId];

                rootNodeId = GetNextNodeId();
                treeHeight++;
                Node root = new Node(rootNodeId, treeHeight, maxNodeEntries);
                root.AddEntry(newNode.mbr, newNode.nodeId);
                root.AddEntry(oldRoot.mbr, oldRoot.nodeId);
                nodeMap.Add(rootNodeId, root);
            }
        }
示例#2
0
 public bool Intersects(RBox box)
 {
     if (max.X < box.min.X)
     {
         return(false);
     }
     if (min.X > box.max.X)
     {
         return(false);
     }
     if (max.Y < box.min.Y)
     {
         return(false);
     }
     if (min.Y > box.max.Y)
     {
         return(false);
     }
     if (max.Z < box.min.Z)
     {
         return(false);
     }
     if (min.Z > box.max.Z)
     {
         return(false);
     }
     return(true);
 }
示例#3
0
 public float Enlargement(RBox box)
 {
     return((Math.Max(max.X, box.max.X) - Math.Min(min.X, box.min.X)) *
            (Math.Max(max.Y, box.max.Y) - Math.Min(min.Y, box.min.Y)) *
            (Math.Max(max.Z, box.max.Z) - Math.Min(min.Z, box.min.Z))
            - area);
 }
示例#4
0
        Node ChooseNode(RBox box, int level)
        {
            Node n = nodeMap[rootNodeId];

            parents.Clear();
            parentsEntry.Clear();
            while (true)
            {
                if (n.level == level)
                {
                    return(n);
                }
                double leastEnlargement = n.GetEntry(0).Enlargement(box);
                int    index            = 0;
                for (int i = 1; i < n.entryCount; i++)
                {
                    RBox   tempBox         = n.GetEntry(i);
                    double tempEnlargement = tempBox.Enlargement(box);
                    if ((tempEnlargement < leastEnlargement) ||
                        ((tempEnlargement == leastEnlargement) &&
                         (tempBox.area < n.GetEntry(index).area)))
                    {
                        index            = i;
                        leastEnlargement = tempEnlargement;
                    }
                }
                parents.Push(n.nodeId);
                parentsEntry.Push(index);
                n = nodeMap[n.ids[index]];
            }
        }
示例#5
0
        public void Add(RBox box, T item)
        {
            idcounter++;
            int id = idcounter;

            items.Add(id, item);
            Add(box.Copy(), id, 1);
        }
示例#6
0
 public void Add(RBox box)
 {
     min.X = Math.Min(box.min.X, min.X);
     min.Y = Math.Min(box.min.Y, min.Y);
     min.Z = Math.Min(box.min.Z, min.Z);
     max.X = Math.Max(box.max.X, max.X);
     max.Y = Math.Max(box.max.Y, max.Y);
     max.Z = Math.Max(box.max.Z, max.Z);
     area  = (max.X - min.X) * (max.Y - min.Y) * (max.Z - min.Z);
 }
示例#7
0
        public List <T> Intersects(RBox box)
        {
            List <T> retval = new List <T>();

            Intersects(box, delegate(int id)
            {
                retval.Add(items[id]);
            });
            return(retval);
        }
示例#8
0
 public void AddEntryNoCopy(RBox box, int id)
 {
     ids[entryCount]     = id;
     entries[entryCount] = box;
     entryCount++;
     if (mbr == null)
     {
         mbr = box.Copy();
     }
     else
     {
         mbr.Add(box);
     }
 }
示例#9
0
        Node SplitNode(Node n, RBox newBox, int newId)
        {
            System.Array.Copy(initialEntryStatus, 0, entryStatus, 0, maxNodeEntries);

            Node newNode = null;

            newNode = new Node(GetNextNodeId(), n.level, maxNodeEntries);
            nodeMap.Add(newNode.nodeId, newNode);

            PickSeeds(n, newBox, newId, newNode);

            while (n.entryCount + newNode.entryCount < maxNodeEntries + 1)
            {
                if (maxNodeEntries + 1 - newNode.entryCount == minNodeEntries)
                {
                    for (int i = 0; i < maxNodeEntries; i++)
                    {
                        if (entryStatus[i] == ENTRY_STATUS_UNASSIGNED)
                        {
                            entryStatus[i] = ENTRY_STATUS_ASSIGNED;
                            n.mbr.Add(n.entries[i]);
                            n.entryCount++;
                        }
                    }
                    break;
                }
                if (maxNodeEntries + 1 - n.entryCount == minNodeEntries)
                {
                    for (int i = 0; i < maxNodeEntries; i++)
                    {
                        if (entryStatus[i] == ENTRY_STATUS_UNASSIGNED)
                        {
                            entryStatus[i] = ENTRY_STATUS_ASSIGNED;
                            newNode.AddEntryNoCopy(n.entries[i], n.ids[i]);
                            n.entries[i] = null;
                        }
                    }
                    break;
                }
                PickNext(n, newNode);
            }

            n.Reorganize(maxNodeEntries - 1);
            return(newNode);
        }
示例#10
0
 void Intersects(RBox box, intproc v, Node n)
 {
     for (int i = 0; i < n.entryCount; i++)
     {
         if (box.Intersects(n.entries[i]))
         {
             if (n.level == 1)
             {
                 v(n.ids[i]);
             }
             else
             {
                 Node childNode = nodeMap[n.ids[i]];
                 Intersects(box, v, childNode);
             }
         }
     }
 }
示例#11
0
 public bool Equal(RBox box)
 {
     return(min.X == box.min.X && min.Y == box.min.Y && min.Z == box.min.Z && max.X == box.max.X && max.Y == box.max.Y && max.Z == box.max.Z);
 }
示例#12
0
        void Intersects(RBox box, intproc v)
        {
            Node rootNode = nodeMap[rootNodeId];

            Intersects(box, v, rootNode);
        }
示例#13
0
        void PickSeeds(Node n, RBox newBox, int newId, Node newNode)
        {
            double maxNormalizedSeparation = 0;
            int    highestLowIndex         = 0;
            int    lowestHighIndex         = 0;

            n.mbr.Add(newBox);
            double mbrSizeX        = n.mbr.max.X - n.mbr.min.X;
            double mbrSizeY        = n.mbr.max.Y - n.mbr.min.Y;
            double mbrSizeZ        = n.mbr.max.Z - n.mbr.min.Z;
            double tempHighestLowX = newBox.min.X;
            double tempLowestHighX = newBox.max.X;

            double tempHighestLowY = newBox.min.Y;
            double tempLowestHighY = newBox.max.Y;

            double tempHighestLowZ = newBox.min.Z;
            double tempLowestHighZ = newBox.max.Z;

            for (int i = 0; i < n.entryCount; i++)
            {
                #region Get HighestLow  or LowestHigh X
                if (n.entries[i].min.X >= tempHighestLowX)
                {
                    tempHighestLowX = n.entries[i].min.X;
                }
                else
                {
                    if (n.entries[i].max.X <= tempLowestHighX)
                    {
                        tempLowestHighX = n.entries[i].max.X;
                    }
                }
                #endregion
                #region Get HighestLow  or LowestHigh Y
                if (n.entries[i].min.Y >= tempHighestLowY)
                {
                    tempHighestLowY = n.entries[i].min.Y;
                }
                else
                {
                    if (n.entries[i].max.Y <= tempLowestHighY)
                    {
                        tempLowestHighY = n.entries[i].max.Y;
                    }
                }
                #endregion
                #region Get HighestLow  or LowestHigh Z
                if (n.entries[i].min.Z >= tempHighestLowZ)
                {
                    tempHighestLowZ = n.entries[i].min.Z;
                }
                else
                {
                    if (n.entries[i].max.Z <= tempLowestHighZ)
                    {
                        tempLowestHighZ = n.entries[i].max.Z;
                    }
                }
                #endregion
                double sX = (tempHighestLowX - tempLowestHighX) / mbrSizeX;
                double sY = (tempHighestLowY - tempLowestHighY) / mbrSizeY;
                double sZ = (tempHighestLowZ - tempLowestHighZ) / mbrSizeZ;

                double normalizedSeparation = Math.Max(Math.Max(sX, sY), sZ);
                if (normalizedSeparation > maxNormalizedSeparation)
                {
                    maxNormalizedSeparation = normalizedSeparation;
                    highestLowIndex         = i;
                    lowestHighIndex         = i;
                }
            }

            if (highestLowIndex == -1)
            {
                newNode.AddEntry(newBox, newId);
            }
            else
            {
                newNode.AddEntryNoCopy(n.entries[highestLowIndex], n.ids[highestLowIndex]);
                n.entries[highestLowIndex] = null;
                n.entries[highestLowIndex] = newBox;
                n.ids[highestLowIndex]     = newId;
            }
            if (lowestHighIndex == -1)
            {
                lowestHighIndex = highestLowIndex;
            }

            entryStatus[lowestHighIndex] = ENTRY_STATUS_ASSIGNED;
            n.entryCount = 1;
            n.mbr.Set(n.entries[lowestHighIndex].min, n.entries[lowestHighIndex].max);
        }