我正尝试实现绕数算法来测试一个点是否在另一个多边形内。虽然我的算法结果是错误且不一致的。我已经研究这个已经很久了,而且它已经成为了一个烦人的问题!
我基本上是从笔记和网站上转换了伪代码,例如:softsurfer.com。
我成功地检测到我的玩家对象和建筑物对象的边界框是否重叠。我将结果返回到一个结构体(BoxResult),它能让我知道是否发生了碰撞并返回它所发生碰撞的框(Below)。
struct BoxResult{
bool collide;
Building returned;
};
void buildingCollision(){
int wn = 0; //winding number count
BoxResult detect = boxDetection(); //detect if any bounding boxes intersect
if(detect.collide){ //If a bounding box has collided, excute Winding Number Algorithm.
for(int i = 0; i < player.getXSize(); i++){
Point p;
p.x = player.getXi(i);
p.y = player.getYi(i);
wn = windingNum(detect.returned,p);
cout << wn << endl;
//Continue code to figure out rebound reaction
}
}
}
然后我测试建筑物和玩家之间的碰撞(下面)。我尝试了5种不同的尝试和数小时的调试来理解错误出现的位置,然而我正在使用最不有效率的方法,仅使用数学(下面)。
int windingNum(Building & b, Point & p){
int result = 0; //Winding number is one, if point is in poly
float total; //Counts the total angle between different vertexs
double wn;
for(int i = 0; i <= b.getXSize()-1;i++){
float acs, nom, modPV, modPV1, denom, angle;
if(i == 3){
//Create the different points PVi . PVi+1
Point PV, PV1;
PV.x = (b.getXi(i) + wx) * p.x;
PV.y = (b.getYi(i) + wy) * p.y;
PV1.x = (b.getXi(0) + wx) * p.x;
PV1.y = (b.getYi(0) + wy) * p.y;
modPV = sqrt( (PV.x * PV.x) + (PV.y * PV.y)); //Get the modulus of PV
modPV1 = sqrt( (PV1.x * PV1.x) + (PV1.y * PV1.y)); //Get modulus of PV1
nom = (PV1.x * PV.x) + (PV1.y * PV.y); //Dot product of PV and PV1
denom = modPV * modPV1; //denomintor of winding number equation
angle = nom / denom;
acs = acos(angle) * 180/PI; //find the angle between the different points
total = total + acs; //add this angle, to the total angle count
}
if(i < 3){
//Create the different points PVi . PVi+1
Point PV, PV1;
PV.x = (b.getXi(i) + wx) * p.x;
PV.y = (b.getYi(i) + wy) * p.y;
PV1.x = (b.getXi(i+1) +wx) * p.x;
PV1.y = (b.getYi(i+1) +wy) * p.y;
modPV = sqrt((PV.x * PV.x) + (PV.y * PV.y)); //Get the modulus of PV
modPV1 = sqrt((PV1.x * PV1.x) + (PV1.y * PV1.y)); //Get modulus of PV1
nom = (PV1.x * PV.x) + (PV1.y * PV.y); //Dot product of PV and PV1
denom = modPV * modPV1; //denomintor of winding number equation
angle = nom / denom;
acs = acos(angle) * 180/PI; //find the angle between the different points
total = total + acs; //add this angle, to the total angle count
}
}
wn = total;
if(wn < 360){
result = 0;}
if(wn == 360){
result = 1;}
return result;
}
For reasons I do not understand acs = acos(angle) always returns 1.#IND000. Btw so you know, I am just testing the algorithm against another square, hence the two if statements if i == 3 and if i < 3.
而且,如果您需要知道,wy和wx是已经转换的世界坐标。因此,移动玩家在世界中的位置,例如向前移动玩家,所有坐标都需要被wy的负数所转换。
此外,一个楼房对象的结构将类似于以下的结构体:
struct Building {
vector<float> x; //vector storing x co-ords
vector<float> y; //vector storing y co-ords
float ymax, ymin, xmax, xmin //values for bounding box
vector<int> polygons; //stores the number points per polygon (not relevant to the problem)
}
如果有人能帮忙,我会感激不尽!我只希望能看到哪里出了问题!(我相信所有的程序员都曾说过这句话,哈哈)谢谢您的阅读...