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); } }
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); }
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); }
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]]; } }
public void Add(RBox box, T item) { idcounter++; int id = idcounter; items.Add(id, item); Add(box.Copy(), id, 1); }
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); }
public List <T> Intersects(RBox box) { List <T> retval = new List <T>(); Intersects(box, delegate(int id) { retval.Add(items[id]); }); return(retval); }
public void AddEntryNoCopy(RBox box, int id) { ids[entryCount] = id; entries[entryCount] = box; entryCount++; if (mbr == null) { mbr = box.Copy(); } else { mbr.Add(box); } }
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); }
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); } } } }
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); }
void Intersects(RBox box, intproc v) { Node rootNode = nodeMap[rootNodeId]; Intersects(box, v, rootNode); }
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); }