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