Ich versuche, wenn ein Rechteck mit einer konkaven Polygon schneidet zu finden. Ist dieser Algorithmus das erreichen?

stimmen
7

Ich versuche, wenn ein Rechteck mit einer konkaven Polygon schneidet zu finden. Ich fand diesen Algorithmus:

double determinant(Vector2D vec1, Vector2D vec2){
    return vec1.x*vec2.y-vec1.y*vec2.x;
}

//one edge is a-b, the other is c-d
Vector2D edgeIntersection(Vector2D a, Vector2D b, Vector2D c, Vector2D d){
    double det=determinant(b-a,c-d);
    double t=determinant(c-a,c-d)/det;
    double u=determinant(b-a,c-a)/det;
    if ((t<0)||(u<0)||(t>1)||(u>1))return NO_INTERSECTION;
    return a*(1-t)+t*b;
}

Wenn ich diesen 4-mal durchführen (von oben nach rechts, von oben nach unten links, oben nach rechts unten, von unten nach rechts) * (alle Kanten meines Polygon) würde dies effektiv und mir genau sagen, ob das Rechteck Teil oder die ganzen konkaven Polygon innen? Wenn nicht, was fehlt?

Vielen Dank

Veröffentlicht am 11/08/2010 um 23:05
quelle vom benutzer
In anderen Sprachen...                            


3 antworten

stimmen
2

Ich denke, die folgenden sollte funktionieren:

(1) for each e1 in rectangle_edges, e2 in polygon_edges
    (1.1) if edgeIntersection(e1,e2) != NO_INTERSECTION
        (1.1.1) return true
(2) if (max_polygon_x < max_rectangle_x) and (min_polygon_x > min_rectangle_x) and (max_polygon_y < max_rectangle_y) and (min_polygon_y > min_rectangle_y)
    (2.1) return true
(2) return false

Bearbeiten : hinzugefügt Prüfung für ob das Polygon innerhalb des Rechtecks ist.

Beantwortet am 11/08/2010 um 23:12
quelle vom benutzer

stimmen
13

Der Code versucht, den Schnittpunkt von zwei Segmenten zu finden - AB und CD.

Es gibt viele verschiedene Möglichkeiten, zu erklären, wie es es tut, je nachdem, wie Sie diese Vorgänge interpretieren.

Nehmen wir an Punkt A die Koordinaten (xa, ya), B - (xb, yb) und so weiter. Sagen wir

dxAB = xb - xa
dyAB = yb - ya
dxCD = xd - xc
dyCD = yd - yc

Das folgende System von zwei linearen Gleichungen

| dxAB dxCD |   | t |   | xc-xa |
|           | * |   | = |       |
| dyAB dyCD |   | u |   | yc-ya |

wenn gelöst für tund u, gibt Ihnen die proportional Position des Schnittpunktes auf der Linie AB (Wert t) und auf der Linie CD (Wert u). Diese Werte liegen im Bereich von , [0, 1]wenn der Punkt gehört zu dem entsprechenden Segment und außerhalb dieses Bereichs , wenn der Punkt außerhalb des Segments liegt (auf der Linie, die das Segment).

Um dieses System von linearen Gleichungen zu lösen wir die bekannte können Cramer-Regel . Dafür müssen wir die Determinante

| dxAB dxCD |
|           |
| dyAB dyCD |

das ist genau das determinant(b - a, c - d)aus dem Code. (Eigentlich , was ich habe hier ist determinant(b - a, d - c), aber es ist nicht wirklich wichtig für die Zwecke dieser Erklärung. Der Code , den Sie aus irgendeinem Grunde geschrieben Swaps C und D, PS Anmerkung unten).

Und wir müssen auch Determinante

| xc-xa dxCD |
|            |
| yc-ya dyCD |

das ist genau das determinant(c-a,c-d)aus dem Code, und Determinante

| dxAB xc-xa |
|            |
| dyAB yc-ya |

was genau ist determinant(b-a,c-a).

Die Aufteilung dieser Determinanten in Übereinstimmung mit der Regel des Cramer wird uns die Werte tund u, das ist genau das, was in dem Code getan wird Sie auf dem Laufenden.

Der Code geht dann die Werte zu testen tund uzu überprüfen , ob die Segmente tatsächlich schneiden, dh ob beide tund ugehören [0, 1]zu reichen. Und wenn sie es tun, berechnet sie den tatsächlichen Schnittpunkt durch die Auswertung a*t+b*(1-t)(äquivalent, könnte es bewerten c*u+d*(1-u)). (Auch hier finden Sie in der PS Anmerkung unten).

PS In dem ursprünglichen Code der Punkte D und C „ausgelagert“ in dem Sinne , dass der Code tut c - d, wo ich d - cin meiner Erklärung. Aber das macht keinen Unterschied für die allgemeine Idee des Algorithmus, solange man die vorsichtig mit Zeichen.

Dieser Swap von C und D Punkt ist auch der Grund für die a*(1-t)+t*bExpression verwendet wird , wenn der Schnittpunkt zu bewerten. Normalerweise, wie es in meiner Erklärung, one'd erwarten so etwas wie zu sehen a*t+b*(1-t)gibt. (Ich habe meine Zweifel , obwohl dies. Ich würde erwarten , um zu sehen , a*t+b*(1-t)gibt es auch in Ihrer Version. Es könnte ein Fehler sein.)

PPS Der Autor , wenn der Code zu überprüfen vergessen det == 0(oder sehr nahe bei 0), die in dem Fall geschehen wird , wenn die Segmente parallel sind.

Beantwortet am 11/08/2010 um 23:30
quelle vom benutzer

stimmen
0

Soweit ich nach einem kurzen Blick erkennen kann, versucht es zu bestimmen, ob zwei Liniensegmente schneiden, und wenn sie es tun, was die Koordinaten des Schnittpunktes sind.

Nein, es ist nicht gut genug, um zu bestimmen, ob Ihr Rechteck und Ihre Polygon schneiden, weil Sie immer noch den Fall vermissen würden, wenn entweder das Polygon vollständig innerhalb des Rechtecks ​​ist, oder umgekehrt.

Beantwortet am 11/08/2010 um 23:56
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more