Warnung: Dies kann schwierig sein, wenn die Kreise / "Rechtecke" große Teile der Kugel umfassen, z.B.:
"Rechteck": min long = -90deg, max long = +90deg, min lat = +70deg, max lat = +80deg
Kreis: Zentrum = lat = +85deg, long = +160deg, Radius = 20deg (z.B. wenn Punkt A auf dem Kreis liegt und Punkt C das Zentrum des Kreises ist und Punkt O das Zentrum der Kugel ist, dann beträgt der Winkel AOC = 40deg).
Diese schneiden sich, aber die Mathematik hat wahrscheinlich mehrere Fälle zu überprüfen: Schnittpunkt/Enthalten. Die folgenden Punkte liegen auf dem oben beschriebenen Kreis: P1=(+65deg lat,+160deg long), P2=(+75deg lat, -20deg long). P1 liegt außerhalb des "Rechtecks" und P2 liegt innerhalb des "Rechtecks", daher schneiden sich Kreis/"Rechteck" mindestens an 2 Punkten.
OK, hier ist mein Versuch, eine Lösungsskizze zu geben:
Nehmen wir C = Kreiszentrum mit Radius R (ausgedrückt als sphärischer Winkel wie oben). C hat die Breitengrade LATC und Längengrade LONGC. Da das Wort "Rechteck" hier irgendwie irreführend ist (Linien konstanter Breitengrade sind keine Segmente großer Kreise), werde ich den Begriff "Begrenzungsrahmen" verwenden.
-
Funktion InsideCircle(P)
gibt +1,0 oder -1 zurück: +1, wenn der Punkt P innerhalb des Kreises liegt, 0 wenn der Punkt P auf dem Kreis liegt, und -1 wenn der Punkt P außerhalb des Kreises liegt: Die Berechnung des Großkreisabstands D (als sphärischer Winkel ausgedrückt) zwischen C und einem beliebigen Punkt P gibt Aufschluss darüber, ob P innerhalb des Kreises liegt oder nicht: InsideCircle(P) = Vorzeichen(R-D)
(Wie Benutzer @Die in Sente erwähnt hat, wurden Großkreisabstände bereits anderswo in diesem Forum gefragt)
-
Definiere PANG(x)
= der Hauptwinkel von x = MOD(x+180deg, 360deg)-180deg. PANG(x)
liegt immer zwischen -180deg und +180deg, inklusive (+180deg sollte auf -180deg abgebildet werden).
-
Um den Begrenzungsrahmen zu definieren, benötigen Sie 4 Zahlen, aber es gibt eine leichte Problematik mit dem Längengrad. LAT1 und LAT2 repräsentieren die Begrenzungsbreiten (unter der Annahme, dass LAT1 < LAT2); dort besteht keine Mehrdeutigkeit. LONG1 und LONG2 repräsentieren die Begrenzungslängengrade eines Längengradintervalls, aber das wird knifflig, und es ist einfacher, dieses Intervall als Zentrum und Breite umzuschreiben, mit LONGM = das Zentrum dieses Intervalls und LONGW = Breite. BEACHTEN Sie, dass es immer 2 Möglichkeiten für Längengradintervalle gibt. Sie müssen angeben, um welche dieser Fälle es sich handelt, ob Sie den 180deg-Meridian einschließen oder ausschließen, z.B. das kürzeste Intervall von -179deg bis +177deg hat LONGM = +179deg und LONGW = 4deg, aber das andere Intervall von -179deg bis +177deg hat LONGM = -1deg und LONGW = 356deg. Wenn Sie naiv "normale" Vergleiche mit dem Intervall [-179,177] durchführen, werden Sie das größere Intervall verwenden und das ist wahrscheinlich nicht das, was Sie wollen. Als Randnotiz, Punkt P, mit Breitengrad LATP und Längengrad LONGP, liegt innerhalb des Begrenzungsrahmens, wenn beide der folgenden Aussagen wahr sind:
- LAT1 <= LATP und LATP <= LAT2 (dieser Teil ist offensichtlich)
- abs(PANG(LONGP-LONGM)) < LONGW/2
Der Kreis schneidet den Begrenzungsrahmen, wenn IRGENDEIN der folgenden Punkte P in PTEST = Vereinigung (PCORNER, PLAT, PLONG), wie unten beschrieben, nicht alle das gleiche Ergebnis für InsideCircle()
zurückgeben:
- PCORNER = die 4 Ecken des Begrenzungsrahmens
- die Punkte PLAT auf den Seiten des Begrenzungsrahmens (es gibt entweder keine oder 2), die dieselbe Breite wie das Zentrum des Kreises teilen, wenn LATC zwischen LAT1 und LAT2 liegt, in welchem Fall diese Punkte den Breitengrad LATC und den Längengrad LONG1 und LONG2 haben.
- die Punkte PLONG auf den Seiten des Begrenzungsrahmens (es gibt entweder keine oder 2 oder 4!), die dieselbe Länge wie das Zentrum des Kreises teilen. Diese Punkte haben ENTWEDER Längengrad = LONGC ODER Längengrad PANG(LONGC-180). Wenn abs(PANG(LONGC-LONGM)) < LONGW/2 gilt, dann ist LONGC ein gültiger Längengrad. Wenn abs(PANG(LONGC-180-LONGM)) < LONGW/2 gilt, dann ist PANG(LONGC-180) ein gültiger Längengrad. Einer oder beide oder keiner dieser Längengrade können innerhalb des Längengradintervalls des Begrenzungsrahmens liegen. Wählen Sie Punkte PLONG mit gültigen Längengraden und Breitengraden LAT1 und LAT2.
Diese Punkte PLAT und PLONG wie oben aufgeführt sind die Punkte auf dem Begrenzungsrahmen, die dem Kreis am "nächsten" liegen (wenn die Ecken es nicht sind; ich verwende "nächste" im Sinne von Breiten- und Längengradentfernung und nicht Großkreisentfernung) und decken die Fälle ab, in denen das Zentrum des Kreises auf einer Seite der Begrenzungslinie des Begrenzungsrahmens liegt, aber Punkte auf dem Kreis "durchschlüpfen" die Begrenzungslinie des Begrenzungsrahmens.
Wenn alle Punkte P in PTEST InsideCircle(P)
== +1 zurückgeben (alle innerhalb des Kreises), dann enthält der Kreis den Begrenzungsrahmen in seiner Gesamtheit.
Wenn alle Punkte P in PTEST InsideCircle(P)
== -1 zurückgeben (alle außerhalb des Kreises), dann ist der Kreis vollständig im Begrenzungsrahmen enthalten.
Ansonsten gibt es mindestens einen Schnittpunkt zwischen dem Kreis und dem Begrenzungsrahmen. Beachten Sie, dass dies nicht berechnet, wo diese Punkte sind, obwohl, wenn Sie irgendeine 2 Punkte P1 und P2 in PTEST nehmen, wo InsideCircle(P1) = -InsideCircle(P2), könnten Sie einen Schnittpunkt (ineffizient) durch Bisektion finden. (Wenn InsideCircle(P) 0 zurückgibt, haben Sie einen Schnittpunkt, obwohl Gleichheit in der Gleitkommamathematik im Allgemeinen nicht vertraut werden sollte.)
Es gibt wahrscheinlich eine effizientere Möglichkeit, dies zu tun, aber das oben Genannte sollte funktionieren.