2011-12-21 3 views
0

쿼드 트리를 구현할 때 문제가 있습니다.
Quadtree의 개체가 이동하면 Quadtree에서 해당 개체의 위치를 ​​업데이트해야합니다. 직접 업데이트 기능을 코딩하려고하지만 작동하지 않습니다. * (무효 UpdatePosition (QuadNode 루트, 부울 & OK))

아래 내 쿼드 트리 클래스 :쿼드 트리 업데이트 개체가 실패했습니다.

class QuadNode 
    { 
    public: 
     vector<Object*> listObj; 

     RECT*  _rect; 
     QuadNode* LT,*RT,*LB,*RB; 
     QuadNode() 
     { 
      _rect=NULL; 
      LT=RT=LB=RB=NULL; 
     } 
     QuadNode(int left,int top,int width,int height) 
     { 
      _rect=new RECT(); 
      _rect->left=left; 
      _rect->top=top; 
      _rect->right=_rect->left+width; 
      _rect->bottom=_rect->top+height; 
      LT=RT=LB=RB=NULL; 
     } 
    }; 

    class QuadTree 
    { 
    public: 
     bool CheckRECTInRECT(RECT r,RECT rect); 
     bool CheckPointInRECT(int x,int y,RECT rect); 
     void GetObjInRec(QuadNode* root,RECT Screen,vector<Object*> &result); 

     QuadNode* _pRoot; 
     int   _mapWidth; 
     int   _mapHeight; 
     int   _count; 

     QuadTree(int w,int h); 
     ~QuadTree(void); 

     void Add(QuadNode *root,Object *Ob); 
     void OutPutTree(QuadNode *root); 
     QuadNode* getTreeRoot(){ return _pRoot; }; 
     //Chi in nhung cai nam tren main hinh hien tai 
     void DrawObjects(RECT Screen); 
     Object* CheckCollision(QuadNode *root,RECT r,int Seq); 
     void CheckCollision(QuadNode *root,RECT r,vector<Object*>&result); 
     bool IsOnObject(RECT *rect,int Seq);//duoi chan object la object khac hay la khoang trong 
     void UpdatePosition(QuadNode *root,bool& OK); 
     void GetAllObj(QuadNode *root,vector<Object*> &result); 
     void RemoveAll(QuadNode *root); 
    }; 


과 :

QuadTree::QuadTree(int w,int h) 
    { 
     _mapWidth=w; 
     _mapHeight=h; 
     _pRoot=new QuadNode(0,0,_mapWidth,_mapHeight); 
     //_count=0; 
    } 
    void QuadTree::Add(QuadNode *root,Object *Ob) 
    { 
     if(root!=NULL) 
     { 
      //0: Add ....1: Left_Top..... 2: Right_Top....... 3: Left_Bottom...... 4: Right_Bottom 
      int result=0;//add here 

      int objWidth = Ob->getObjectRect().right - Ob->getObjectRect().left; 
      int objHeight = Ob->getObjectRect().bottom - Ob->getObjectRect().top; 

      int rectWidth = root->_rect->right - root->_rect->left; 
      int rectHeight = root->_rect->bottom - root->_rect->top; 

      int rectWidthNew= (root->_rect->right + root->_rect->left)/2; //divide RECT root to quad RECT 
      int rectHeightNew= (root->_rect->bottom + root->_rect->top)/2; 

      if((objWidth*objHeight > rectWidth*rectHeight/4)/*kiem tra dien tich co lon hon 1/4 dien tich roof ko*/ 
       || (rectWidthNew > Ob->getObjectRect().left && rectWidthNew <= Ob->getObjectRect().right)|| 
       (rectHeightNew > Ob->getObjectRect().top && rectHeightNew <= Ob->getObjectRect().bottom)) 
       result=0;//Kiem tra xem objet nam o hon 1/4 cua root thi tra ve khong 
      else 
      { 
       if(Ob->getObjectRect().left >= root->_rect->left && 
        Ob->getObjectRect().left < rectWidthNew && 
        Ob->getObjectRect().top >= root->_rect->top && 
        Ob->getObjectRect().top < rectHeightNew)//Left_Top 
        result =1; 
       else 
        if(Ob->getObjectRect().left < root->_rect->right && 
         Ob->getObjectRect().left >= rectWidthNew && 
         Ob->getObjectRect().top >= root->_rect->top && 
         Ob->getObjectRect().top < rectHeightNew)//Right_Top 
         result =2; 
        else 
         if(Ob->getObjectRect().left >= root->_rect->left && 
          Ob->getObjectRect().left < rectWidthNew && 
          Ob->getObjectRect().top >= rectHeightNew && 
          Ob->getObjectRect().top < root->_rect->bottom)//Left_Bottom 
          result=3; 
         else//Right_Bottom 
          result=4; 
      } 

      if(result==0)//Add here 
      { 
       root->listObj.push_back(Ob); 
       _count++; 
      } 
      else 
      { 
       if(rectWidth/2 > LIM_W_H && rectHeight/2 > LIM_W_H) 
       { 
        switch(result) 
        { 
        case 1://Left_Top 
         if(root->LT==NULL) 
          root->LT=new QuadNode(root->_rect->left,root->_rect->top,rectWidth/2,rectHeight/2); 
         Add(root->LT,Ob); 
         break; 
        case 2://Right_Top 
         if(root->RT==NULL) 
          root->RT=new QuadNode(rectWidthNew,root->_rect->top,rectWidth/2,rectHeight/2); 
         Add(root->RT,Ob); 
         break; 
        case 3://Left_Bottom 
         if(root->LB==NULL) 
          root->LB=new QuadNode(root->_rect->left,rectHeightNew,rectWidth/2,rectHeight/2); 
         Add(root->LB,Ob); 
         break; 
        case 4://Right_Bottom 
         if(root->RB==NULL) 
          root->RB=new QuadNode(rectWidthNew,rectHeightNew,rectWidth/2,rectHeight/2); 
         Add(root->RB,Ob); 
         break; 
        } 
       } 
      } 
     } 
    } 

    bool QuadTree::CheckPointInRECT(int x,int y,RECT rect) 
    { 
     if(x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) 
      return true; 
     return false; 
    } 

    bool QuadTree::CheckRECTInRECT(RECT r,RECT rect) 
    { 
     if(CheckPointInRECT(r.left,r.top,rect) 
      ||CheckPointInRECT(r.right,r.top,rect) 
      ||CheckPointInRECT(r.left,r.bottom,rect) 
      ||CheckPointInRECT(r.right,r.bottom,rect) 
      ||(rect.top<=r.top&&rect.bottom>=r.bottom&&r.left<=rect.left&&r.right>=rect.right)) 
     { 
      return true; 
     } 
     return false; 
    } 
    void QuadTree::GetObjInRec(QuadNode* root,RECT Screen,vector<Object*> &result) 
    { 
     for(int i=0;i<root->listObj.size();i++) 
      if(CheckRECTInRECT(root->listObj[i]->getObjectRect(),Screen)||CheckRECTInRECT(Screen,root->listObj[i]->getObjectRect()))//active items on camera 
      { 
       result.push_back(root->listObj[i]); 
      } 
      if(root->LT!=NULL&&(CheckRECTInRECT(*root->LT->_rect,Screen)||CheckRECTInRECT(Screen,*root->LT->_rect))) 
       GetObjInRec(root->LT,Screen,result); 
      if(root->RT!=NULL&&(CheckRECTInRECT(*root->RT->_rect,Screen)||CheckRECTInRECT(Screen,*root->RT->_rect))) 
       GetObjInRec(root->RT,Screen,result); 
      if(root->LB!=NULL&&(CheckRECTInRECT(*root->LB->_rect,Screen)||CheckRECTInRECT(Screen,*root->LB->_rect))) 
       GetObjInRec(root->LB,Screen,result); 
      if(root->RB!=NULL&&(CheckRECTInRECT(*root->RB->_rect,Screen)||CheckRECTInRECT(Screen,*root->RB->_rect))) 
       GetObjInRec(root->RB,Screen,result); 
    } 
    void QuadTree::DrawObjects(RECT Screen) 
    { 
     vector<Object*> total; 
     this->GetAllObj(_pRoot,total); 

     vector<Object*> result; 
     //vector<Object*> allObjet; 
     //GetAllObj(_pRoot,allObjet); 
     GetObjInRec(_pRoot,Screen,result); 
     for (int i=0; i<result.size();i++) 
     { 
      result[i]->draw(Screen); 
     } 
    } 

//this function doesn't work 
    void QuadTree::UpdatePosition(QuadNode *root,bool& OK) 
    { 
     //vector<Object*> okconde; 
     //GetAllObj(_pRoot,okconde); 

     if (root->LT == NULL && root->LB==NULL && root->RB==NULL && root->RT==NULL) 
     { 
      return; 
     } 
     vector<Object*>::iterator begin, end; 
     begin=root->listObj.begin(); 
     end=root->listObj.end(); 

     while(begin!=end) 
     { 
      Object *Ob= *begin; 

      if(Ob->getObjectType()!=1) 
// get type of Object (if objectType !=1 so they are player or enemey which can move) 
      { 


       if(Ob->IsMoving()) 
// these statement never reach- I have debuged. 
       { 
        root->listObj.erase(begin); 
        this->Add(_pRoot,Ob); 
        OK=true; 
       } 
      } 
      else 
       begin++; 
     } 
     if(root->LT!=NULL) 
      UpdatePosition(root->LT,OK); 
     if(root->RT!=NULL) 
      UpdatePosition(root->RT,OK); 
     if(root->LB!=NULL) 
      UpdatePosition(root->LB,OK); 
     if(root->RB!=NULL) 
      UpdatePosition(root->RB,OK); 
    } 

    QuadTree::~QuadTree(void) 
    { 
    } 

    void QuadTree::GetAllObj(QuadNode *root,vector<Object*> &result) 
    { 

     for(int i=0;i<root->listObj.size();i++) 
      result.push_back(root->listObj[i]); 

     if(root->LT!=NULL) 
      GetAllObj(root->LT,result); 

     if(root->LB!=NULL) 
      GetAllObj(root->LB,result); 

     if(root->RT!=NULL) 
      GetAllObj(root->RT,result); 

     if(root->RB!=NULL) 
      GetAllObj(root->RB,result); 
    } 

    void QuadTree::RemoveAll(QuadNode *root) 
    { 
     if (root!=NULL) 
     { 
      root->listObj.clear(); 
     } 
     if (root->LB!=NULL) 
      RemoveAll(root->LB); 
     if (root->LT!=NULL) 
      RemoveAll(root->LB); 
     if (root->RB!=NULL) 
      RemoveAll(root->LB); 
     if (root->RT!=NULL) 
      RemoveAll(root->LB); 
    } 
+0

정말로 문제에 대해 조금 더 말해야합니다. 그것은 좋은 오류 설명이 작동하지 않습니다. 정확히 어디에서 실패할까요, 어떤 일이 일어나고 어떤 일이 일어날 것으로 예상됩니까? 또한 코드를 최소한의 예제로 트리밍하여 오류를 충분히 보여줄 수있는 좋은 방법으로 간주됩니다. 많은 사람들이 어딘가에서 오류를 찾기 위해 모든 코드를 수행 할 의사가 없습니다. – Grizzly

+0

조언 해 주셔서 감사합니다. –

답변

0

이 월 정확한 대답은 아니지만 나는 근래 여기에 느슨한 quadtree (그것은 quadtree보다 뛰어나지 만 여전히 같은 구조를 가지고 있습니다)를 작성했습니다.

pastebin.com/e6yCLzNm 
    Quadtree.h 
    pastebin.com/REKBQmte 
    Quadtree.cpp 

도움이 될만한 자료입니다.