Ich bin nicht in der Lage, einen Algorithmus zu finden, um schwach einfache Polygone zu erkennen (d. H. Polygone, bei denen die Seiten sich berühren dürfen, aber nicht überkreuzen). Derzeit suche ich nur nach Kreuzungen zwischen jeder Seite - hier ist die Funktion, die ich für alle nicht angrenzenden Seiten anrufe. Auf diese Weise sind nur einfache Polygone erlaubt (keine Berührung). Polygone sind Vektoren von Punkten.Testen, ob ein Polygon schwach einfach ist
bool linesIntersect(const point &a1, const point &a2, const point &b1, const point &b2) {
// Solve intersection of parametric lines using inverse matrix
// The equation of the parametric lines are line1 = (a2 - a1)*s + a1
// and line2 = (b2 - b1)*t + b1, where a1, a2, etc. are vectors.
// Two equations can be produced from the two components, and these
// this system of two equations can be solved for s and t
// If the parameters s and t are between 0 and 1, it means that the lines intersect
float x21 = a2.x - a1.x, x43 = b2.x - b1.x, x31 = b1.x - a1.x,
y21 = a2.y - a1.y, y43 = b2.y - b1.y, y31 = b1.y - a1.y;
float determinant = x43*y21 - x21*y43;
if(determinant == 0.) return false;
float s = float(x43*y31 - x31*y43)/determinant;
float t = float(x21*y31 - x31*y21)/determinant;
if(s <= 1. && s >= 0. && t <= 1. && t >= 0.) return true; // lines intersect
return false;
}
s < 1. && s > 0. && t < 1. && t > 0.
Mit funktioniert nicht, weil es einige komplexe Polygone so einfach akzeptiert.
Die erste Zahl in this question zeigt ein paar Beispiele. Unten ist ein typisches schwach einfaches Polygon, mit dem sich das Programm befassen würde.
würde ich Pseudo-Code, da die Mathematik Jargon in der oben genannten Frage (1) schreckt mich lieber, und ich glaube nicht, dass ich das Wissen jeden komplexen Algorithmus zu implementieren. Ich verwende Boost.Polygon für etwas anderes, wenn da etwas ist, aber ich habe nichts gefunden.
EDIT:
Hier ist, wie ich die Funktion verwenden. checkPts ist ein vector<point>
mit einer angenommenen Seite vom letzten Punkt zum ersten.
// Check for self-intersecting polygons
for(int i = 0; i < checkPts.size() - 2; ++i) {
for(int j = i + 2; j < checkPts.size() - 2; ++j) {
if(linesIntersect(checkPts[i], checkPts[i+1], checkPts[j], checkPts[j+1])) error("self-intersecting polygon");
}
}
Hier ist eine nette Berechnung, die Sie tun können, um zu überprüfen, ob Seiten sich überschneiden: http://Stackoverflow.com/a/7069702/3516541. – Ben
Ich kann nicht sicher sein, ob das im Wesentlichen das ist, was Sie tun. Ihre Schreibweise ist bei einem flüchtigen Blick ein wenig verwirrend. – Ben
Ihre Frage läuft darauf hinaus, Gleitkommazahlen für Gleichheit zu vergleichen. Sind Sie sicher, dass das, was Sie zu tun versuchen, wirklich wert ist? – Beta