⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtree.h

📁 最近点对问题
💻 H
📖 第 1 页 / 共 3 页
字号:
  return foundCount;}RTREE_TEMPLATEint RTREE_QUAL::Count(){  int count = 0;  CountRec(m_root, count);    return count;}RTREE_TEMPLATEvoid RTREE_QUAL::CountRec(Node* a_node, int& a_count){  if(a_node->IsInternalNode())  // not a leaf node  {    for(int index = 0; index < a_node->m_count; ++index)    {      CountRec(a_node->m_branch[index].m_child, a_count);    }  }  else // A leaf node  {    a_count += a_node->m_count;  }}RTREE_TEMPLATEbool RTREE_QUAL::Load(const char* a_fileName){  RemoveAll(); // Clear existing tree  RTFileStream stream;  if(!stream.OpenRead(a_fileName))  {    return false;  }  bool result = Load(stream);    stream.Close();  return result;};RTREE_TEMPLATEbool RTREE_QUAL::Load(RTFileStream& a_stream){  // Write some kind of header  int _dataFileId = ('R'<<0)|('T'<<8)|('R'<<16)|('E'<<24);  int _dataSize = sizeof(DATATYPE);  int _dataNumDims = NUMDIMS;  int _dataElemSize = sizeof(ELEMTYPE);  int _dataElemRealSize = sizeof(ELEMTYPEREAL);  int _dataMaxNodes = TMAXNODES;  int _dataMinNodes = TMINNODES;  int dataFileId = 0;  int dataSize = 0;  int dataNumDims = 0;  int dataElemSize = 0;  int dataElemRealSize = 0;  int dataMaxNodes = 0;  int dataMinNodes = 0;  a_stream.Read(dataFileId);  a_stream.Read(dataSize);  a_stream.Read(dataNumDims);  a_stream.Read(dataElemSize);  a_stream.Read(dataElemRealSize);  a_stream.Read(dataMaxNodes);  a_stream.Read(dataMinNodes);  bool result = false;  // Test if header was valid and compatible  if(    (dataFileId == _dataFileId)       && (dataSize == _dataSize)       && (dataNumDims == _dataNumDims)       && (dataElemSize == _dataElemSize)       && (dataElemRealSize == _dataElemRealSize)       && (dataMaxNodes == _dataMaxNodes)       && (dataMinNodes == _dataMinNodes)     )  {    // Recursively load tree    result = LoadRec(m_root, a_stream);  }  return result;}RTREE_TEMPLATEbool RTREE_QUAL::LoadRec(Node* a_node, RTFileStream& a_stream){  a_stream.Read(a_node->m_level);  a_stream.Read(a_node->m_count);  if(a_node->IsInternalNode())  // not a leaf node  {    for(int index = 0; index < a_node->m_count; ++index)    {      Branch* curBranch = &a_node->m_branch[index];      a_stream.ReadArray(curBranch->m_rect.m_min, NUMDIMS);      a_stream.ReadArray(curBranch->m_rect.m_max, NUMDIMS);      curBranch->m_child = AllocNode();      LoadRec(curBranch->m_child, a_stream);    }  }  else // A leaf node  {    for(int index = 0; index < a_node->m_count; ++index)    {      Branch* curBranch = &a_node->m_branch[index];      a_stream.ReadArray(curBranch->m_rect.m_min, NUMDIMS);      a_stream.ReadArray(curBranch->m_rect.m_max, NUMDIMS);      a_stream.Read(curBranch->m_data);    }  }  return true; // Should do more error checking on I/O operations}RTREE_TEMPLATEbool RTREE_QUAL::Save(const char* a_fileName){  RTFileStream stream;  if(!stream.OpenWrite(a_fileName))  {    return false;  }  bool result = Save(stream);  stream.Close();  return result;}RTREE_TEMPLATEbool RTREE_QUAL::Save(RTFileStream& a_stream){  // Write some kind of header  int dataFileId = ('R'<<0)|('T'<<8)|('R'<<16)|('E'<<24);  int dataSize = sizeof(DATATYPE);  int dataNumDims = NUMDIMS;  int dataElemSize = sizeof(ELEMTYPE);  int dataElemRealSize = sizeof(ELEMTYPEREAL);  int dataMaxNodes = TMAXNODES;  int dataMinNodes = TMINNODES;  a_stream.Write(dataFileId);  a_stream.Write(dataSize);  a_stream.Write(dataNumDims);  a_stream.Write(dataElemSize);  a_stream.Write(dataElemRealSize);  a_stream.Write(dataMaxNodes);  a_stream.Write(dataMinNodes);  // Recursively save tree  bool result = SaveRec(m_root, a_stream);    return result;}RTREE_TEMPLATEbool RTREE_QUAL::SaveRec(Node* a_node, RTFileStream& a_stream){  a_stream.Write(a_node->m_level);  a_stream.Write(a_node->m_count);  if(a_node->IsInternalNode())  // not a leaf node  {    for(int index = 0; index < a_node->m_count; ++index)    {      Branch* curBranch = &a_node->m_branch[index];      a_stream.WriteArray(curBranch->m_rect.m_min, NUMDIMS);      a_stream.WriteArray(curBranch->m_rect.m_max, NUMDIMS);      SaveRec(curBranch->m_child, a_stream);    }  }  else // A leaf node  {    for(int index = 0; index < a_node->m_count; ++index)    {      Branch* curBranch = &a_node->m_branch[index];      a_stream.WriteArray(curBranch->m_rect.m_min, NUMDIMS);      a_stream.WriteArray(curBranch->m_rect.m_max, NUMDIMS);      a_stream.Write(curBranch->m_data);    }  }  return true; // Should do more error checking on I/O operations}RTREE_TEMPLATEvoid RTREE_QUAL::RemoveAll(){  // Delete all existing nodes  Reset();  m_root = AllocNode();  m_root->m_level = 0;}RTREE_TEMPLATEvoid RTREE_QUAL::Reset(){#ifdef RTREE_DONT_USE_MEMPOOLS  // Delete all existing nodes  RemoveAllRec(m_root);#else // RTREE_DONT_USE_MEMPOOLS  // Just reset memory pools.  We are not using complex types  // EXAMPLE#endif // RTREE_DONT_USE_MEMPOOLS}RTREE_TEMPLATEvoid RTREE_QUAL::RemoveAllRec(Node* a_node){  ASSERT(a_node);  ASSERT(a_node->m_level >= 0);  if(a_node->IsInternalNode()) // This is an internal node in the tree  {    for(int index=0; index < a_node->m_count; ++index)    {      RemoveAllRec(a_node->m_branch[index].m_child);    }  }  FreeNode(a_node); }RTREE_TEMPLATEtypename RTREE_QUAL::Node* RTREE_QUAL::AllocNode(){  Node* newNode;#ifdef RTREE_DONT_USE_MEMPOOLS  newNode = new Node;#else // RTREE_DONT_USE_MEMPOOLS  // EXAMPLE#endif // RTREE_DONT_USE_MEMPOOLS  InitNode(newNode);  return newNode;}RTREE_TEMPLATEvoid RTREE_QUAL::FreeNode(Node* a_node){  ASSERT(a_node);#ifdef RTREE_DONT_USE_MEMPOOLS  delete a_node;#else // RTREE_DONT_USE_MEMPOOLS  // EXAMPLE#endif // RTREE_DONT_USE_MEMPOOLS}// Allocate space for a node in the list used in DeletRect to// store Nodes that are too empty.RTREE_TEMPLATEtypename RTREE_QUAL::ListNode* RTREE_QUAL::AllocListNode(){#ifdef RTREE_DONT_USE_MEMPOOLS  return new ListNode;#else // RTREE_DONT_USE_MEMPOOLS  // EXAMPLE#endif // RTREE_DONT_USE_MEMPOOLS}RTREE_TEMPLATEvoid RTREE_QUAL::FreeListNode(ListNode* a_listNode){#ifdef RTREE_DONT_USE_MEMPOOLS  delete a_listNode;#else // RTREE_DONT_USE_MEMPOOLS  // EXAMPLE#endif // RTREE_DONT_USE_MEMPOOLS}RTREE_TEMPLATEvoid RTREE_QUAL::InitNode(Node* a_node){  a_node->m_count = 0;  a_node->m_level = -1;}RTREE_TEMPLATEvoid RTREE_QUAL::InitRect(Rect* a_rect){  for(int index = 0; index < NUMDIMS; ++index)  {    a_rect->m_min[index] = (ELEMTYPE)0;    a_rect->m_max[index] = (ELEMTYPE)0;  }}// Inserts a new data rectangle into the index structure.// Recursively descends tree, propagates splits back up.// Returns 0 if node was not split.  Old node updated.// If node was split, returns 1 and sets the pointer pointed to by// new_node to point to the new node.  Old node updated to become one of two.// The level argument specifies the number of steps up from the leaf// level to insert; e.g. a data rectangle goes in at level = 0.RTREE_TEMPLATEbool RTREE_QUAL::InsertRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, Node** a_newNode, int a_level){  ASSERT(a_rect && a_node && a_newNode);  ASSERT(a_level >= 0 && a_level <= a_node->m_level);  int index;  Branch branch;  Node* otherNode;  // Still above level for insertion, go down tree recursively  if(a_node->m_level > a_level)  {    index = PickBranch(a_rect, a_node);    if (!InsertRectRec(a_rect, a_id, a_node->m_branch[index].m_child, &otherNode, a_level))    {      // Child was not split      a_node->m_branch[index].m_rect = CombineRect(a_rect, &(a_node->m_branch[index].m_rect));      return false;    }    else // Child was split    {      a_node->m_branch[index].m_rect = NodeCover(a_node->m_branch[index].m_child);      branch.m_child = otherNode;      branch.m_rect = NodeCover(otherNode);      return AddBranch(&branch, a_node, a_newNode);    }  }  else if(a_node->m_level == a_level) // Have reached level for insertion. Add rect, split if necessary  {    branch.m_rect = *a_rect;    branch.m_child = (Node*) a_id;    // Child field of leaves contains id of data record    return AddBranch(&branch, a_node, a_newNode);  }  else  {    // Should never occur    ASSERT(0);    return false;  }}// Insert a data rectangle into an index structure.// InsertRect provides for splitting the root;// returns 1 if root was split, 0 if it was not.// The level argument specifies the number of steps up from the leaf// level to insert; e.g. a data rectangle goes in at level = 0.// InsertRect2 does the recursion.//RTREE_TEMPLATEbool RTREE_QUAL::InsertRect(Rect* a_rect, const DATATYPE& a_id, Node** a_root, int a_level){  ASSERT(a_rect && a_root);  ASSERT(a_level >= 0 && a_level <= (*a_root)->m_level);#ifdef _DEBUG  for(int index=0; index < NUMDIMS; ++index)  {    ASSERT(a_rect->m_min[index] <= a_rect->m_max[index]);  }#endif //_DEBUG    Node* newRoot;  Node* newNode;  Branch branch;  if(InsertRectRec(a_rect, a_id, *a_root, &newNode, a_level))  // Root split  {    newRoot = AllocNode();  // Grow tree taller and new root    newRoot->m_level = (*a_root)->m_level + 1;    branch.m_rect = NodeCover(*a_root);    branch.m_child = *a_root;    AddBranch(&branch, newRoot, NULL);    branch.m_rect = NodeCover(newNode);    branch.m_child = newNode;    AddBranch(&branch, newRoot, NULL);    *a_root = newRoot;    return true;  }  return false;}// Find the smallest rectangle that includes all rectangles in branches of a node.RTREE_TEMPLATEtypename RTREE_QUAL::Rect RTREE_QUAL::NodeCover(Node* a_node){  ASSERT(a_node);    int firstTime = true;  Rect rect;  InitRect(&rect);    for(int index = 0; index < a_node->m_count; ++index)  {    if(firstTime)    {      rect = a_node->m_branch[index].m_rect;      firstTime = false;    }    else    {      rect = CombineRect(&rect, &(a_node->m_branch[index].m_rect));    }  }    return rect;}// Add a branch to a node.  Split the node if necessary.// Returns 0 if node not split.  Old node updated.// Returns 1 if node split, sets *new_node to address of new node.// Old node updated, becomes one of two.RTREE_TEMPLATEbool RTREE_QUAL::AddBranch(Branch* a_branch, Node* a_node, Node** a_newNode){  ASSERT(a_branch);  ASSERT(a_node);  if(a_node->m_count < MAXNODES)  // Split won't be necessary  {    a_node->m_branch[a_node->m_count] = *a_branch;    ++a_node->m_count;    return false;  }  else  {    ASSERT(a_newNode);        SplitNode(a_node, a_branch, a_newNode);    return true;  }}// Disconnect a dependent node.// Caller must return (or stop using iteration index) after this as count has changedRTREE_TEMPLATEvoid RTREE_QUAL::DisconnectBranch(Node* a_node, int a_index){  ASSERT(a_node && (a_index >= 0) && (a_index < MAXNODES));  ASSERT(a_node->m_count > 0);  // Remove element by swapping with the last element to prevent gaps in array  a_node->m_branch[a_index] = a_node->m_branch[a_node->m_count - 1];    --a_node->m_count;}// Pick a branch.  Pick the one that will need the smallest increase// in area to accomodate the new rectangle.  This will result in the// least total area for the covering rectangles in the current node.// In case of a tie, pick the one which was smaller before, to get// the best resolution when searching.RTREE_TEMPLATEint RTREE_QUAL::PickBranch(Rect* a_rect, Node* a_node){  ASSERT(a_rect && a_node);    bool firstTime = true;  ELEMTYPEREAL increase;  ELEMTYPEREAL bestIncr = (ELEMTYPEREAL)-1;  ELEMTYPEREAL area;  ELEMTYPEREAL bestArea;  int best;  Rect tempRect;  for(int index=0; index < a_node->m_count; ++index)  {    Rect* curRect = &a_node->m_branch[index].m_rect;    area = CalcRectVolume(curRect);    tempRect = CombineRect(a_rect, curRect);    increase = CalcRectVolume(&tempRect) - area;    if((increase < bestIncr) || firstTime)    {      best = index;      bestArea = area;      bestIncr = increase;      firstTime = false;    }    else if((increase == bestIncr) && (area < bestArea))    {      best = index;      bestArea = area;      bestIncr = increase;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -