59 #define ASSERT assert // RTree uses ASSERT( condition )
71 #define RTREE_TEMPLATE template<class DATATYPE, class ELEMTYPE, int NUMDIMS, class ELEMTYPEREAL, int TMAXNODES, int TMINNODES>
72 #define RTREE_QUAL RTree<DATATYPE, ELEMTYPE, NUMDIMS, ELEMTYPEREAL, TMAXNODES, TMINNODES>
74 #define RTREE_DONT_USE_MEMPOOLS // This version does not contain a fixed memory allocator, fill in lines with EXAMPLE to implement one.
75 #define RTREE_USE_SPHERICAL_VOLUME // Better split classification, may be slower on some systems
97 template<
class DATATYPE,
class ELEMTYPE,
int NUMDIMS,
98 class ELEMTYPEREAL = ELEMTYPE,
int TMAXNODES = 8,
int TMINNODES = TMAXNODES / 2>
125 void Insert(
const ELEMTYPE a_min[NUMDIMS],
const ELEMTYPE a_max[NUMDIMS],
const DATATYPE& a_dataId);
131 void Remove(
const ELEMTYPE a_min[NUMDIMS],
const ELEMTYPE a_max[NUMDIMS],
const DATATYPE& a_dataId);
139 int Search(
const ELEMTYPE a_min[NUMDIMS],
const ELEMTYPE a_max[NUMDIMS],
bool a_resultCallback(DATATYPE a_data,
void* a_context),
void* a_context);
148 bool Load(
const char* a_fileName);
154 bool Save(
const char* a_fileName);
204 void GetBounds(ELEMTYPE a_min[NUMDIMS], ELEMTYPE a_max[NUMDIMS])
210 for(
int index = 0; index < NUMDIMS; ++index)
256 Push(nextLevelnode, 0);
259 if(nextLevelnode->
IsLeaf())
304 Push(nextLevelnode, 0);
307 if(nextLevelnode->
IsLeaf())
345 if(first->IsInternalNode() && first->m_count > 1)
349 else if(first->IsLeaf())
366 bool IsNull(Iterator& a_it) {
return a_it.IsNull(); }
369 DATATYPE&
GetAt(Iterator& a_it) {
return *a_it; }
434 bool InsertRectRec(Rect* a_rect,
const DATATYPE& a_id, Node* a_node, Node** a_newNode,
int a_level);
435 bool InsertRect(Rect* a_rect,
const DATATYPE& a_id, Node** a_root,
int a_level);
437 bool AddBranch(Branch* a_branch, Node* a_node, Node** a_newNode);
441 void SplitNode(Node* a_node, Branch* a_branch, Node** a_newNode);
445 void GetBranches(Node* a_node, Branch* a_branch, PartitionVars* a_parVars);
447 void LoadNodes(Node* a_nodeA, Node* a_nodeB, PartitionVars* a_parVars);
448 void InitParVars(PartitionVars* a_parVars,
int a_maxRects,
int a_minFill);
450 void Classify(
int a_index,
int a_group, PartitionVars* a_parVars);
451 bool RemoveRect(Rect* a_rect,
const DATATYPE& a_id, Node** a_root);
452 bool RemoveRectRec(Rect* a_rect,
const DATATYPE& a_id, Node* a_node, ListNode** a_listNode);
456 void ReInsert(Node* a_node, ListNode** a_listNode);
457 bool Search(Node* a_node, Rect* a_rect,
int& a_foundCount,
bool a_resultCallback(DATATYPE a_data,
void* a_context),
void* a_context);
491 m_file = fopen(a_fileName,
"rb");
501 m_file = fopen(a_fileName,
"wb");
518 template<
typename TYPE >
522 return fwrite((
void*)&a_value,
sizeof(a_value), 1,
m_file);
525 template<
typename TYPE >
529 return fwrite((
void*)a_array,
sizeof(TYPE) *
a_count, 1,
m_file);
532 template<
typename TYPE >
536 return fread((
void*)&a_value,
sizeof(a_value), 1,
m_file);
539 template<
typename TYPE >
543 return fread((
void*)a_array,
sizeof(TYPE) *
a_count, 1,
m_file);
551 ASSERT(MAXNODES > MINNODES);
557 ASSERT(
sizeof(DATATYPE) ==
sizeof(
void*) ||
sizeof(DATATYPE) ==
sizeof(
int));
560 const float UNIT_SPHERE_VOLUMES[] = {
561 0.000000f, 2.000000f, 3.141593f,
562 4.188790f, 4.934802f, 5.263789f,
563 5.167713f, 4.724766f, 4.058712f,
564 3.298509f, 2.550164f, 1.884104f,
565 1.335263f, 0.910629f, 0.599265f,
566 0.381443f, 0.235331f, 0.140981f,
567 0.082146f, 0.046622f, 0.025807f,
570 m_root = AllocNode();
572 m_unitSphereVolume = (ELEMTYPEREAL)UNIT_SPHERE_VOLUMES[NUMDIMS];
584 void RTREE_QUAL::Insert(
const ELEMTYPE a_min[NUMDIMS],
const ELEMTYPE a_max[NUMDIMS],
const DATATYPE& a_dataId)
587 for(
int index=0; index<NUMDIMS; ++index)
589 ASSERT(a_min[index] <= a_max[index]);
595 for(
int axis=0; axis<NUMDIMS; ++axis)
597 rect.m_min[axis] = a_min[axis];
598 rect.m_max[axis] = a_max[axis];
601 InsertRect(&rect, a_dataId, &m_root, 0);
606 void RTREE_QUAL::Remove(
const ELEMTYPE a_min[NUMDIMS],
const ELEMTYPE a_max[NUMDIMS],
const DATATYPE& a_dataId)
609 for(
int index=0; index<NUMDIMS; ++index)
611 ASSERT(a_min[index] <= a_max[index]);
617 for(
int axis=0; axis<NUMDIMS; ++axis)
619 rect.m_min[axis] = a_min[axis];
620 rect.m_max[axis] = a_max[axis];
623 RemoveRect(&rect, a_dataId, &m_root);
628 int RTREE_QUAL::Search(
const ELEMTYPE a_min[NUMDIMS],
const ELEMTYPE a_max[NUMDIMS],
bool a_resultCallback(DATATYPE a_data,
void* a_context),
void* a_context)
631 for(
int index=0; index<NUMDIMS; ++index)
633 ASSERT(a_min[index] <= a_max[index]);
639 for(
int axis=0; axis<NUMDIMS; ++axis)
641 rect.m_min[axis] = a_min[axis];
642 rect.m_max[axis] = a_max[axis];
648 Search(m_root, &rect, foundCount, a_resultCallback, a_context);
655 int RTREE_QUAL::Count()
658 CountRec(m_root, count);
666 void RTREE_QUAL::CountRec(Node* a_node,
int&
a_count)
668 if(a_node->IsInternalNode())
670 for(
int index = 0; index < a_node->m_count; ++index)
672 CountRec(a_node->m_branch[index].m_child,
a_count);
683 bool RTREE_QUAL::Load(
const char* a_fileName)
693 bool result = Load(stream);
706 int _dataFileId = (
'R'<<0)|(
'T'<<8)|(
'R'<<16)|(
'E'<<24);
707 int _dataSize =
sizeof(DATATYPE);
708 int _dataNumDims = NUMDIMS;
709 int _dataElemSize =
sizeof(ELEMTYPE);
710 int _dataElemRealSize =
sizeof(ELEMTYPEREAL);
711 int _dataMaxNodes = TMAXNODES;
712 int _dataMinNodes = TMINNODES;
717 int dataElemSize = 0;
718 int dataElemRealSize = 0;
719 int dataMaxNodes = 0;
720 int dataMinNodes = 0;
722 a_stream.
Read(dataFileId);
723 a_stream.
Read(dataSize);
724 a_stream.
Read(dataNumDims);
725 a_stream.
Read(dataElemSize);
726 a_stream.
Read(dataElemRealSize);
727 a_stream.
Read(dataMaxNodes);
728 a_stream.
Read(dataMinNodes);
733 if( (dataFileId == _dataFileId)
734 && (dataSize == _dataSize)
735 && (dataNumDims == _dataNumDims)
736 && (dataElemSize == _dataElemSize)
737 && (dataElemRealSize == _dataElemRealSize)
738 && (dataMaxNodes == _dataMaxNodes)
739 && (dataMinNodes == _dataMinNodes)
743 result = LoadRec(m_root, a_stream);
751 bool RTREE_QUAL::LoadRec(Node* a_node,
RTFileStream& a_stream)
753 a_stream.
Read(a_node->m_level);
754 a_stream.
Read(a_node->m_count);
756 if(a_node->IsInternalNode())
758 for(
int index = 0; index < a_node->m_count; ++index)
760 Branch* curBranch = &a_node->m_branch[index];
762 a_stream.
ReadArray(curBranch->m_rect.m_min, NUMDIMS);
763 a_stream.
ReadArray(curBranch->m_rect.m_max, NUMDIMS);
765 curBranch->m_child = AllocNode();
766 LoadRec(curBranch->m_child, a_stream);
771 for(
int index = 0; index < a_node->m_count; ++index)
773 Branch* curBranch = &a_node->m_branch[index];
775 a_stream.
ReadArray(curBranch->m_rect.m_min, NUMDIMS);
776 a_stream.
ReadArray(curBranch->m_rect.m_max, NUMDIMS);
778 a_stream.
Read(curBranch->m_data);
787 bool RTREE_QUAL::Save(
const char* a_fileName)
795 bool result = Save(stream);
807 int dataFileId = (
'R'<<0)|(
'T'<<8)|(
'R'<<16)|(
'E'<<24);
808 int dataSize =
sizeof(DATATYPE);
809 int dataNumDims = NUMDIMS;
810 int dataElemSize =
sizeof(ELEMTYPE);
811 int dataElemRealSize =
sizeof(ELEMTYPEREAL);
812 int dataMaxNodes = TMAXNODES;
813 int dataMinNodes = TMINNODES;
815 a_stream.
Write(dataFileId);
816 a_stream.
Write(dataSize);
817 a_stream.
Write(dataNumDims);
818 a_stream.
Write(dataElemSize);
819 a_stream.
Write(dataElemRealSize);
820 a_stream.
Write(dataMaxNodes);
821 a_stream.
Write(dataMinNodes);
824 bool result = SaveRec(m_root, a_stream);
831 bool RTREE_QUAL::SaveRec(Node* a_node,
RTFileStream& a_stream)
833 a_stream.
Write(a_node->m_level);
834 a_stream.
Write(a_node->m_count);
836 if(a_node->IsInternalNode())
838 for(
int index = 0; index < a_node->m_count; ++index)
840 Branch* curBranch = &a_node->m_branch[index];
842 a_stream.
WriteArray(curBranch->m_rect.m_min, NUMDIMS);
843 a_stream.
WriteArray(curBranch->m_rect.m_max, NUMDIMS);
845 SaveRec(curBranch->m_child, a_stream);
850 for(
int index = 0; index < a_node->m_count; ++index)
852 Branch* curBranch = &a_node->m_branch[index];
854 a_stream.
WriteArray(curBranch->m_rect.m_min, NUMDIMS);
855 a_stream.
WriteArray(curBranch->m_rect.m_max, NUMDIMS);
857 a_stream.
Write(curBranch->m_data);
866 void RTREE_QUAL::RemoveAll()
871 m_root = AllocNode();
877 void RTREE_QUAL::Reset()
879 #ifdef RTREE_DONT_USE_MEMPOOLS
881 RemoveAllRec(m_root);
882 #else // RTREE_DONT_USE_MEMPOOLS
885 #endif // RTREE_DONT_USE_MEMPOOLS
890 void RTREE_QUAL::RemoveAllRec(Node* a_node)
893 ASSERT(a_node->m_level >= 0);
895 if(a_node->IsInternalNode())
897 for(
int index=0; index < a_node->m_count; ++index)
899 RemoveAllRec(a_node->m_branch[index].m_child);
907 typename RTREE_QUAL::Node* RTREE_QUAL::AllocNode()
910 #ifdef RTREE_DONT_USE_MEMPOOLS
912 #else // RTREE_DONT_USE_MEMPOOLS
914 #endif // RTREE_DONT_USE_MEMPOOLS
921 void RTREE_QUAL::FreeNode(Node* a_node)
925 #ifdef RTREE_DONT_USE_MEMPOOLS
927 #else // RTREE_DONT_USE_MEMPOOLS
929 #endif // RTREE_DONT_USE_MEMPOOLS
936 typename RTREE_QUAL::ListNode* RTREE_QUAL::AllocListNode()
938 #ifdef RTREE_DONT_USE_MEMPOOLS
940 #else // RTREE_DONT_USE_MEMPOOLS
942 #endif // RTREE_DONT_USE_MEMPOOLS
947 void RTREE_QUAL::FreeListNode(ListNode* a_listNode)
949 #ifdef RTREE_DONT_USE_MEMPOOLS
951 #else // RTREE_DONT_USE_MEMPOOLS
953 #endif // RTREE_DONT_USE_MEMPOOLS
958 void RTREE_QUAL::InitNode(Node* a_node)
961 a_node->m_level = -1;
962 for(
int i = 0; i < MAXNODES; ++i) a_node->m_wasChecked[i] =
false;
967 void RTREE_QUAL::InitRect(Rect* a_rect)
969 for(
int index = 0; index < NUMDIMS; ++index)
971 a_rect->m_min[index] = (ELEMTYPE)0;
972 a_rect->m_max[index] = (ELEMTYPE)0;
985 bool RTREE_QUAL::InsertRectRec(Rect* a_rect,
const DATATYPE& a_id, Node* a_node, Node** a_newNode,
int a_level)
987 ASSERT(a_rect && a_node && a_newNode);
988 ASSERT(a_level >= 0 && a_level <= a_node->m_level);
995 if(a_node->m_level > a_level)
997 index = PickBranch(a_rect, a_node);
999 if(index < 0)
return false;
1001 if (!InsertRectRec(a_rect, a_id, a_node->m_branch[index].m_child, &otherNode, a_level))
1004 a_node->m_branch[index].m_rect = CombineRect(a_rect, &(a_node->m_branch[index].m_rect));
1009 a_node->m_branch[index].m_rect = NodeCover(a_node->m_branch[index].m_child);
1010 branch.m_child = otherNode;
1011 branch.m_rect = NodeCover(otherNode);
1012 return AddBranch(&branch, a_node, a_newNode);
1015 else if(a_node->m_level == a_level)
1017 branch.m_rect = *a_rect;
1018 branch.m_child = (Node*) a_id;
1020 return AddBranch(&branch, a_node, a_newNode);
1039 bool RTREE_QUAL::InsertRect(Rect* a_rect,
const DATATYPE& a_id, Node** a_root,
int a_level)
1041 ASSERT(a_rect && a_root);
1042 ASSERT(a_level >= 0 && a_level <= (*a_root)->m_level);
1044 for(
int index=0; index < NUMDIMS; ++index)
1046 ASSERT(a_rect->m_min[index] <= a_rect->m_max[index]);
1054 if(InsertRectRec(a_rect, a_id, *a_root, &newNode, a_level))
1056 newRoot = AllocNode();
1057 newRoot->m_level = (*a_root)->m_level + 1;
1058 branch.m_rect = NodeCover(*a_root);
1059 branch.m_child = *a_root;
1060 AddBranch(&branch, newRoot, NULL);
1061 branch.m_rect = NodeCover(newNode);
1062 branch.m_child = newNode;
1063 AddBranch(&branch, newRoot, NULL);
1074 typename RTREE_QUAL::Rect RTREE_QUAL::NodeCover(Node* a_node)
1078 int firstTime =
true;
1082 for(
int index = 0; index < a_node->m_count; ++index)
1086 rect = a_node->m_branch[index].m_rect;
1091 rect = CombineRect(&rect, &(a_node->m_branch[index].m_rect));
1104 bool RTREE_QUAL::AddBranch(Branch* a_branch, Node* a_node, Node** a_newNode)
1109 if(a_node->m_count < MAXNODES)
1111 a_node->m_branch[a_node->m_count] = *a_branch;
1120 SplitNode(a_node, a_branch, a_newNode);
1129 void RTREE_QUAL::DisconnectBranch(Node* a_node,
int a_index)
1131 ASSERT(a_node && (a_index >= 0) && (a_index < MAXNODES));
1132 ASSERT(a_node->m_count > 0);
1135 a_node->m_branch[a_index] = a_node->m_branch[a_node->m_count - 1];
1147 int RTREE_QUAL::PickBranch(Rect* a_rect, Node* a_node)
1149 ASSERT(a_rect && a_node);
1151 bool firstTime =
true;
1152 ELEMTYPEREAL increase;
1153 ELEMTYPEREAL bestIncr = (ELEMTYPEREAL)-1;
1155 ELEMTYPEREAL bestArea = (ELEMTYPEREAL)-1;
1159 for(
int index=0; index < a_node->m_count; ++index)
1161 Rect* curRect = &a_node->m_branch[index].m_rect;
1162 area = CalcRectVolume(curRect);
1163 tempRect = CombineRect(a_rect, curRect);
1164 increase = CalcRectVolume(&tempRect) - area;
1165 if((increase < bestIncr) || firstTime)
1169 bestIncr = increase;
1172 else if((increase == bestIncr) && (area < bestArea))
1176 bestIncr = increase;
1185 typename RTREE_QUAL::Rect RTREE_QUAL::CombineRect(Rect* a_rectA, Rect* a_rectB)
1187 ASSERT(a_rectA && a_rectB);
1191 for(
int index = 0; index < NUMDIMS; ++index)
1193 newRect.m_min[index] = std::min(a_rectA->m_min[index], a_rectB->m_min[index]);
1194 newRect.m_max[index] = std::max(a_rectA->m_max[index], a_rectB->m_max[index]);
1207 void RTREE_QUAL::SplitNode(Node* a_node, Branch* a_branch, Node** a_newNode)
1213 PartitionVars localVars;
1214 PartitionVars* parVars = &localVars;
1218 level = a_node->m_level;
1219 GetBranches(a_node, a_branch, parVars);
1222 ChoosePartition(parVars, MINNODES);
1225 *a_newNode = AllocNode();
1226 (*a_newNode)->m_level = a_node->m_level = level;
1227 LoadNodes(a_node, *a_newNode, parVars);
1229 ASSERT((a_node->m_count + (*a_newNode)->m_count) == parVars->m_total);
1235 ELEMTYPEREAL RTREE_QUAL::RectVolume(Rect* a_rect)
1239 ELEMTYPEREAL volume = (ELEMTYPEREAL)1;
1241 for(
int index=0; index<NUMDIMS; ++index)
1243 volume *= a_rect->m_max[index] - a_rect->m_min[index];
1246 ASSERT(volume >= (ELEMTYPEREAL)0);
1254 ELEMTYPEREAL RTREE_QUAL::RectSphericalVolume(Rect* a_rect)
1258 ELEMTYPEREAL sumOfSquares = (ELEMTYPEREAL)0;
1259 ELEMTYPEREAL radius;
1261 for(
int index=0; index < NUMDIMS; ++index)
1263 ELEMTYPEREAL halfExtent = ((ELEMTYPEREAL)a_rect->m_max[index] - (ELEMTYPEREAL)a_rect->m_min[index]) * 0.5
f;
1264 sumOfSquares += halfExtent * halfExtent;
1267 radius = (ELEMTYPEREAL)sqrt(sumOfSquares);
1272 return (radius * radius * radius * m_unitSphereVolume);
1274 else if(NUMDIMS == 2)
1276 return (radius * radius * m_unitSphereVolume);
1280 return (ELEMTYPEREAL)(pow(radius, NUMDIMS) * m_unitSphereVolume);
1287 ELEMTYPEREAL RTREE_QUAL::CalcRectVolume(Rect* a_rect)
1289 #ifdef RTREE_USE_SPHERICAL_VOLUME
1290 return RectSphericalVolume(a_rect);
1291 #else // RTREE_USE_SPHERICAL_VOLUME
1292 return RectVolume(a_rect);
1293 #endif // RTREE_USE_SPHERICAL_VOLUME
1299 void RTREE_QUAL::GetBranches(Node* a_node, Branch* a_branch, PartitionVars* a_parVars)
1304 ASSERT(a_node->m_count == MAXNODES);
1307 for(
int index=0; index < MAXNODES; ++index)
1309 a_parVars->m_branchBuf[index] = a_node->m_branch[index];
1311 a_parVars->m_branchBuf[MAXNODES] = *a_branch;
1312 a_parVars->m_branchCount = MAXNODES + 1;
1315 a_parVars->m_coverSplit = a_parVars->m_branchBuf[0].m_rect;
1316 for(
int index=1; index < MAXNODES+1; ++index)
1318 a_parVars->m_coverSplit = CombineRect(&a_parVars->m_coverSplit, &a_parVars->m_branchBuf[index].m_rect);
1320 a_parVars->m_coverSplitArea = CalcRectVolume(&a_parVars->m_coverSplit);
1338 void RTREE_QUAL::ChoosePartition(PartitionVars* a_parVars,
int a_minFill)
1342 ELEMTYPEREAL biggestDiff;
1343 int group, chosen = -1, betterGroup = -1;
1345 InitParVars(a_parVars, a_parVars->m_branchCount, a_minFill);
1346 PickSeeds(a_parVars);
1348 while (((a_parVars->m_count[0] + a_parVars->m_count[1]) < a_parVars->m_total)
1349 && (a_parVars->m_count[0] < (a_parVars->m_total - a_parVars->m_minFill))
1350 && (a_parVars->m_count[1] < (a_parVars->m_total - a_parVars->m_minFill)))
1352 biggestDiff = (ELEMTYPEREAL) -1;
1353 for(
int index=0; index<a_parVars->m_total; ++index)
1355 if(!a_parVars->m_taken[index])
1357 Rect* curRect = &a_parVars->m_branchBuf[index].m_rect;
1358 Rect rect0 = CombineRect(curRect, &a_parVars->m_cover[0]);
1359 Rect rect1 = CombineRect(curRect, &a_parVars->m_cover[1]);
1360 ELEMTYPEREAL growth0 = CalcRectVolume(&rect0) - a_parVars->m_area[0];
1361 ELEMTYPEREAL growth1 = CalcRectVolume(&rect1) - a_parVars->m_area[1];
1362 ELEMTYPEREAL diff = growth1 - growth0;
1373 if(diff > biggestDiff)
1377 betterGroup = group;
1379 else if((diff == biggestDiff) && (a_parVars->m_count[group] < a_parVars->m_count[betterGroup]))
1382 betterGroup = group;
1386 Classify(chosen, betterGroup, a_parVars);
1390 if((a_parVars->m_count[0] + a_parVars->m_count[1]) < a_parVars->m_total)
1392 if(a_parVars->m_count[0] >= a_parVars->m_total - a_parVars->m_minFill)
1400 for(
int index=0; index<a_parVars->m_total; ++index)
1402 if(!a_parVars->m_taken[index])
1404 Classify(index, group, a_parVars);
1409 ASSERT((a_parVars->m_count[0] + a_parVars->m_count[1]) == a_parVars->m_total);
1410 ASSERT((a_parVars->m_count[0] >= a_parVars->m_minFill) &&
1411 (a_parVars->m_count[1] >= a_parVars->m_minFill));
1417 void RTREE_QUAL::LoadNodes(Node* a_nodeA, Node* a_nodeB, PartitionVars* a_parVars)
1423 for(
int index=0; index < a_parVars->m_total; ++index)
1425 ASSERT(a_parVars->m_partition[index] == 0 || a_parVars->m_partition[index] == 1);
1427 if(a_parVars->m_partition[index] == 0)
1429 AddBranch(&a_parVars->m_branchBuf[index], a_nodeA, NULL);
1431 else if(a_parVars->m_partition[index] == 1)
1433 AddBranch(&a_parVars->m_branchBuf[index], a_nodeB, NULL);
1441 void RTREE_QUAL::InitParVars(PartitionVars* a_parVars,
int a_maxRects,
int a_minFill)
1445 a_parVars->m_count[0] = a_parVars->m_count[1] = 0;
1446 a_parVars->m_area[0] = a_parVars->m_area[1] = (ELEMTYPEREAL)0;
1447 a_parVars->m_total = a_maxRects;
1448 a_parVars->m_minFill = a_minFill;
1449 for(
int index=0; index < a_maxRects; ++index)
1451 a_parVars->m_taken[index] =
false;
1452 a_parVars->m_partition[index] = -1;
1458 void RTREE_QUAL::PickSeeds(PartitionVars* a_parVars)
1460 int seed0 = -1, seed1 = -1;
1461 ELEMTYPEREAL worst, waste;
1462 ELEMTYPEREAL area[MAXNODES+1];
1464 for(
int index=0; index<a_parVars->m_total; ++index)
1466 area[index] = CalcRectVolume(&a_parVars->m_branchBuf[index].m_rect);
1469 worst = -a_parVars->m_coverSplitArea - 1;
1470 for(
int indexA=0; indexA < a_parVars->m_total-1; ++indexA)
1472 for(
int indexB = indexA+1; indexB < a_parVars->m_total; ++indexB)
1474 Rect oneRect = CombineRect(&a_parVars->m_branchBuf[indexA].m_rect, &a_parVars->m_branchBuf[indexB].m_rect);
1475 waste = CalcRectVolume(&oneRect) - area[indexA] - area[indexB];
1484 Classify(seed0, 0, a_parVars);
1485 Classify(seed1, 1, a_parVars);
1491 void RTREE_QUAL::Classify(
int a_index,
int a_group, PartitionVars* a_parVars)
1494 ASSERT(!a_parVars->m_taken[a_index]);
1497 a_parVars->m_partition[a_index] = a_group;
1498 a_parVars->m_taken[a_index] =
true;
1500 if (a_parVars->m_count[a_group] == 0)
1502 a_parVars->m_cover[a_group] = a_parVars->m_branchBuf[a_index].m_rect;
1506 a_parVars->m_cover[a_group] = CombineRect(&a_parVars->m_branchBuf[a_index].m_rect, &a_parVars->m_cover[a_group]);
1508 a_parVars->m_area[a_group] = CalcRectVolume(&a_parVars->m_cover[a_group]);
1509 ++a_parVars->m_count[a_group];
1518 bool RTREE_QUAL::RemoveRect(Rect* a_rect,
const DATATYPE& a_id, Node** a_root)
1520 ASSERT(a_rect && a_root);
1524 ListNode* reInsertList = NULL;
1526 if(!RemoveRectRec(a_rect, a_id, *a_root, &reInsertList))
1532 tempNode = reInsertList->m_node;
1534 for(
int index = 0; index < tempNode->m_count; ++index)
1536 InsertRect(&(tempNode->m_branch[index].m_rect),
1537 tempNode->m_branch[index].m_data,
1542 ListNode* remLNode = reInsertList;
1543 reInsertList = reInsertList->m_next;
1545 FreeNode(remLNode->m_node);
1546 FreeListNode(remLNode);
1550 if((*a_root)->m_count == 1 && (*a_root)->IsInternalNode())
1552 tempNode = (*a_root)->m_branch[0].m_child;
1572 bool RTREE_QUAL::RemoveRectRec(Rect* a_rect,
const DATATYPE& a_id, Node* a_node, ListNode** a_listNode)
1574 ASSERT(a_rect && a_node && a_listNode);
1575 ASSERT(a_node->m_level >= 0);
1577 if(a_node->IsInternalNode())
1579 for(
int index = 0; index < a_node->m_count; ++index)
1581 if(Overlap(a_rect, &(a_node->m_branch[index].m_rect)))
1583 if(!RemoveRectRec(a_rect, a_id, a_node->m_branch[index].m_child, a_listNode))
1585 if(a_node->m_branch[index].m_child->m_count >= MINNODES)
1588 a_node->m_branch[index].m_rect = NodeCover(a_node->m_branch[index].m_child);
1593 ReInsert(a_node->m_branch[index].m_child, a_listNode);
1594 DisconnectBranch(a_node, index);
1604 for(
int index = 0; index < a_node->m_count; ++index)
1606 if(a_node->m_branch[index].m_child == (Node*)a_id)
1608 DisconnectBranch(a_node, index);
1619 bool RTREE_QUAL::Overlap(Rect* a_rectA, Rect* a_rectB)
1621 ASSERT(a_rectA && a_rectB);
1623 for(
int index=0; index < NUMDIMS; ++index)
1625 if (a_rectA->m_min[index] > a_rectB->m_max[index] ||
1626 a_rectB->m_min[index] > a_rectA->m_max[index])
1638 void RTREE_QUAL::ReInsert(Node* a_node, ListNode** a_listNode)
1640 ListNode* newListNode;
1642 newListNode = AllocListNode();
1643 newListNode->m_node = a_node;
1644 newListNode->m_next = *a_listNode;
1645 *a_listNode = newListNode;
1651 bool RTREE_QUAL::Search(Node* a_node, Rect* a_rect,
int& a_foundCount,
bool a_resultCallback(DATATYPE a_data,
void* a_context),
void* a_context)
1654 ASSERT(a_node->m_level >= 0);
1657 if(a_node->IsInternalNode())
1659 for(
int index=0; index < a_node->m_count; ++index)
1661 if(Overlap(a_rect, &a_node->m_branch[index].m_rect))
1663 if(!Search(a_node->m_branch[index].m_child, a_rect, a_foundCount, a_resultCallback, a_context))
1672 for(
int index=0; index < a_node->m_count; ++index)
1674 if(Overlap(a_rect, &a_node->m_branch[index].m_rect))
1676 DATATYPE&
id = a_node->m_branch[index].m_data;
1682 if(!a_resultCallback(
id, a_context))
1695 #undef RTREE_TEMPLATE