Mit SAT hab ich das ganze jetzt erstmal so umgesetzt. Code ist nicht sonderlich hübsch, hab ich grad in 20 minuten geschrieben. Funktionieren tuts ja. Aber iwie bin ich nicht wirklich zufrieden damit.
Sind schon ein paar kleine Optimierungen drin. So sorgt "getDirections()" zB dafür dass keine Richtungen/Normalen doppelt vorkommen.
Zeitlich komme ich auf eine Spanne von 15 bis 200 Mikrosekunden. Wobei die Ausgabe der Messergebnisse das ganze natürlich verfälscht ("wer misst, misst Mist").
Erstmal erzeuge ich die rotierten Vierecke ( hier einfach nur ein vector von linien)
Code: Alles auswählen
vector2df getNormal(const line2d& line)
{
vector2df dir = line.getDirection();
vector2df normal(-dir.Y, dir.X);
normal.normalize();
return normal;
}
vector<line2d> toLines(const line2d& line, f32 border)
{
vector2df normal = getNormal(line);
vector2df p1 = line.Start + normal * border;
vector2df p2 = line.Start - normal * border;
vector2df p3 = line.End + normal * border;
vector2df p4 = line.End - normal * border;
return {line2d(p1, p2), line2d(p2, p3), line2d(p3, p4), line2d(p4, p1)};
}
Dann der eigentlich collisioncode
Code: Alles auswählen
bool geometryTest(const vector<line2d>& lines1, const vector<line2d>& lines2)
{
// start of the projection ray,
// doesn't actually matter where it is
vector2df ray_start(0,0);
vector<vector2df> directions = getDirections(lines1, lines2);
for(auto direction: directions)
{
vector2df normal = getNormal(direction);
ray2d proj_ray(ray_start, normal);
vector<vector2df> points1;
vector<vector2df> points2;
for(auto it : lines1)
{
ray2d cur_ray1(it.Start, direction);
ray2d cur_ray2(it.End, direction);
pair<bool, vector2df> int1 = cur_ray1.intersection(proj_ray);
pair<bool, vector2df> int2 = cur_ray2.intersection(proj_ray);
if(int1.first)
points1.push_back(int1.second);
if(int2.first)
points1.push_back(int2.second);
}
for(auto it : lines2)
{
ray2d cur_ray1(it.Start, direction);
ray2d cur_ray2(it.End, direction);
pair<bool, vector2df> int1 = cur_ray1.intersection(proj_ray);
pair<bool, vector2df> int2 = cur_ray2.intersection(proj_ray);
if(int1.first)
points2.push_back(int1.second);
if(int2.first)
points2.push_back(int2.second);
}
rect2df bounds1 = getBoundaries(points1);
rect2df bounds2 = getBoundaries(points2);
if(!geometryTest(bounds1, bounds2))
return false;
}
// no gap found
return true;
}