Я пытаюсь реализовать алгоритм числа обмоток, чтобы проверить, находится ли точка внутри другого многоугольника. Хотя результаты моего алгоритма неверны и не соответствуют. Я работал над этим целую вечность, и это стало чем-то вроде боли!
Я в основном конвертировал псевдокод из заметок и веб-сайтов, например, softsurfer.com
Я успешно обнаружил, перекрываются ли границы моего игрока и строительного объекта. Я возвращаю результат в структуру (BoxResult), которая сообщает мне, было ли столкновение, и возвращает окно, с которым он столкнулся (ниже)
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;
}
По причинам, которые я не понимаю, acs = acos (angle) всегда возвращает 1. # IND000.
Кстати, вы знаете, я просто тестирую алгоритм на другом квадрате, отсюда два оператора if, если i == 3 и if i <3. </p>
Также, если вам нужно знать это, wy и wx - это мировые координаты, которые переводятся. Таким образом перемещая игрока по всему миру, например чтобы переместить игрока вперед все переводится на минус число для wy.
Кроме того, объект Building будет выглядеть примерно так, как показано ниже:
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)
}
Если кто-нибудь может помочь, я был бы удивительно благодарен! Я просто хотел бы видеть, где все идет не так! (Что-то, я уверен, что все программисты сказали там время lol) Спасибо за чтения ...