Frage

Dies ist ein Followup auf diese Frage .

scheine ich auf diese stecken. Grundsätzlich muß ich in der Lage sein, hin und her zu konvertieren Koordinaten entweder im Standard-Grad-System zu beziehen oder durch eine Entfernung nördlich vom Südpol entlang der internationalen Datumslinie zu messen, und dann ein Abstand östlich von diesem Punkt beginnend mit dem Tag Linie. Um dies zu tun (sowie einige allgemeinere Abstandsmess Material), ich habe ein Verfahren zur Bestimmung der Entfernung zwischen zwei lat / lon Punkten, und ein anderes Verfahren, das eine lat / lon Punkt nimmt, eine Überschrift und eine Entfernung und kehrt die lat / lon Punkt am Ende dieses Kurses.

Hier sind die beiden statischen Methoden I definiert haben:

/* Takes two lon/lat pairs and returns the distance between them in kilometers.
*/
public static double distance (double lat1, double lon1, double lat2, double lon2) {
    double theta = toRadians(lon1-lon2);
    lat1 = toRadians(lat1);
    lon1 = toRadians(lon1);
    lat2 = toRadians(lat2);
    lon2 = toRadians(lon2);

    double dist = sin(lat1)*sin(lat2) + cos(lat1)*cos(lat2)*cos(theta);
    dist = toDegrees(acos(dist)) * 60 * 1.1515 * 1.609344 * 1000;

    return dist;
}

/* endOfCourse takes a lat/lon pair, a heading (in degrees clockwise from north), and a distance (in kilometers), and returns
 * the lat/lon pair that would be reached by traveling that distance in that direction from the given point.
 */
public static double[] endOfCourse (double lat1, double lon1, double tc, double dist) {
    double pi = Math.PI;
    lat1 = toRadians(lat1);
    lon1 = toRadians(lon1);
    tc = toRadians(tc);
    double dist_radians = toRadians(dist / (60 * 1.1515 * 1.609344 * 1000));
    double lat = asin(sin(lat1) * cos(dist_radians) + cos(lat1) * sin(dist_radians) * cos(tc));
    double dlon = atan2(sin(tc) * sin(dist_radians) * cos(lat1), cos(dist_radians) - sin(lat1) * sin(lat));
    double lon = ((lon1-dlon + pi) % (2*pi)) - pi;
    double[] endPoint = new double[2];
    endPoint[0] = lat; endPoint[1] = lon;
    return endPoint;
}

Und hier ist die Funktion Ich verwende es zu testen:

public static void main(String args[]) throws java.io.IOException, java.io.FileNotFoundException {
    double distNorth = distance(0.0, 0.0, 72.0, 0.0);
    double distEast = distance(72.0, 0.0, 72.0, 31.5);
    double lat1 = endOfCourse(0.0, 0.0, 0.0, distNorth)[0];
    double lon1 = endOfCourse(lat1, 0.0, 90.0, distEast)[1];
    System.out.println("end at: " + lat1 + " / " + lon1);
    return;
}

Die „endet bei“ Werte appx werden sollen. 72.0 / 31.5. Aber anstatt Ich bin etwa 1,25 / 0,021 erhalten.

Ich nehme an, ich muss etwas Dummes fehlt, vergessen Einheiten irgendwo zu konvertieren, oder so ... Jede Hilfe wäre sehr dankbar!

UPDATE 1:

hatte ich (richtig) der Distanzfunktion geschrieben Meter zurück, aber schrieb Kilometer in den Kommentaren versehentlich ... was natürlich mich verwirrt, als ich kam heute zurück, um es. Wie auch immer, das ist jetzt behoben, und ich habe den Factoring Fehler in der endOfCourse Methode festgelegt, und ich erkennen auch, hatte ich auch wieder auf Grad von Radianten in diesem Verfahren zur Umwandlung in Vergessenheit geraten. Wie dem auch sei: Während es ich Nummer jetzt bin immer die richtige Breite erscheint (71,99 ...), die Länge Zahl ist weg (ich 3,54 statt 11,5)

.

UPDATE 2: Ich hatte einen Fehler im Test, wie unten erwähnt. Es ist jetzt im Code festgelegt. Die Länge Zahl noch jedoch falsch: Ich bin immer jetzt -11,34 statt 11,5. Ich denke, es muss etwas falsch mit diesen Zeilen sein:

double dlon = atan2(sin(tc) * sin(dist_radians) * cos(lat1), cos(dist_radians) - sin(lat1) * sin(lat));
double lon = ((lon1-dlon + pi) % (2*pi)) - pi;
War es hilfreich?

Lösung

Sie haben einen schweren Fall der magischen Zahlen im Code bekommen. Der Ausdruck:

 (60 * 1.1515 * 1.609344 * 1000)

erscheint zweimal, aber es gibt nicht viel Erklärung davon. Mit etwas Hilfe: 1.609344 ist die Anzahl der Kilometer in einer Meile; 60 ist die Anzahl der Minuten in einem Grad; 1000 ist die Anzahl von Metern in einem Kilometer; und 1,1515 ist die Zahl der Satzung Meilen in einer nautischen Meile (danke, DanM). Eine nautische Meile ist die Länge von einer Minute der Breite am Äquator.

Ich nehme an, Sie eine kugelförmige Erde Modell verwenden, anstatt einen kugeligen Erde? Die Algebra ist nicht komplex genug kugeligen zu sein.

Die erste Formel - Umwandlung zwischen zwei Breiten- und Längenpaaren - ungerade ist. Sie müssen sowohl die Delta-lat (Δλ) und Delta-lon (Δφ), um die Antwort zu sortieren. Ferner ist der Abstand zwischen den Paaren:

(60° N, 30° W), (60° N, 60° W)
(60° N, 60° W), (60° N, 90° W)

sollten gleich sein -. Aber ich bin mir ziemlich sicher, dass Ihr Code unterschiedliche Antworten erzeugt

Also, ich glaube, Sie zurück zu Ihren sphärischen Trigonometrie Referenzmaterialien gehen und sehen, was Sie falsch machen. (Es wäre mir eine Weile dauern, mein Buch zu diesem Thema zu finden -. Es müßte ausgepackt werden, von welcher es Kasten ist in)

[ ... die Zeit vergeht ... Auspacken getan ... ]

ein sphärisches Dreieck mit Winkeln Gegeben A , B , C an den Ecken und an den Seiten a , < em> B , c gegenüber diesen Eckpunkten (das heißt, Seite a ist von B bis C , etc.), die Cosinus-Formel lautet:

cos a = cos b . cos c + sin b . sin c . cos A

Angewandt auf das Problem, können wir die beiden Punkte nennen gegeben B und C , und wir schaffen ein Recht sphärisches Dreieck mit einem rechten Winkel in A .

ASCII-Art in ihrer schlimmsten Form:

                  + C
                 /|
                / |
            a  /  | b
              /   |
             /    |
            /     |
         B +------+ A
              c

Die Seiten c ist gleich den Unterschied in der Länge; die Seite b ist auf die Differenz in der Breite gleich; der Winkel A 90 °, so cos A = 0. Deshalb glaube ich, eine Gleichung für a ist:

cos a = cos Δλ . cos Δφ + sin Δλ . sin Δφ . cos 90°

a = arccos (cos Δλ . cos Δφ)

Der Winkel a in Radian ist dann durch Multiplikation mit dem Radius der Erde bis zu einer Entfernung umgewandelt. Alternativ dazu gegeben a in Grad (und Bruchteilen eines Grades), dann gibt es 60 nautische Meilen zu einem Grad, also 60 * 1,1515 Statut Meilen und 60 * 1,1515 * 1,609344 Kilometer zu einem Grad. Sofern Sie die Entfernung in Metern wollen, sehe ich keine Notwendigkeit für den Faktor 1000.

Paul Tomblin verweist auf Aviation Formulary V1.44 als Quelle der Gleichung -. und in der Tat, es ist da, zusammen mit einer numerisch stabilen Version für wenn die Differenz in der Position ist klein

zu grundlegenden Trigonometrie gehen, wir wissen auch, dass:

cos (A - B) = cos A . cos B + sin A . sin B

doppelt so hoch wie in der Gleichung anwenden gab ich könnte auch in der Formel in der Aviation Formulary enden.

(Mein Hinweis: "Astronomie: Principles and Practice, Fourth Edition" durch AE Roy und D Clarke (2003); mein Exemplar ist die erste Ausgabe von 1977, Adam Hilger, ISBN 0-85274-346-7)

.

NB Check out (Google) 'definieren: "nautische Meile"'; es scheint, dass eine nautische Meile jetzt 1.852 m (1.852 km) ist per Definition. Der Multiplikator 1,1515 entspricht die alte Definition der nautischen Meile als etwa 6080 ft Mit bc mit einer Skala von 10, die ich erhalte:.

(1852/(3*0.3048))/1760
1.1507794480

Welche Faktor für Sie hängt davon ab, was Ihre Basis ist.


beim zweiten Problem Blickt man von ersten Prinzipien, haben wir eine etwas andere Einrichtung, und wir brauchen die ‚andere‘ sphärische Trigonometrie Gleichung, die Sinus-Formel:

sin A   sin B   sin C
----- = ----- = -----
sin a   sin b   sin c

Die Anpassung der vorherige Diagramm:

                  + C
                 /|
                / |
            a  /  | b
           |  /   |
           |X/    |
           |/     |
         B +------+ A
              c

Sie sind gegeben Ausgangspunkt B , Winkel X = 90 ° - B, Länge (Winkel) a und Winkel A = 90 °. Was Sie sind nachdem es b (das Delta in Breitengrad) und c (das Delta in der Länge).

So haben wir:

sin a   sin b
----- = ----
sin A   sin B

oder

        sin a . sin B
sin b = -------------
            sin A

Oder, da A = 90 °, sin A = 1 und sin B = sin (90 ° - X) = cos X:

sin b = sin a . cos X

Das heißt, Sie wandeln der Abstand in einen Winkel gereist a , nehmen Sie den Sinus, dass durch den Kosinus der Kursrichtung multiplizieren, und nehmen Sie die Arcussinus des Ergebnisses.

Da a b (nur berechnet) und A und B können wir die Cosinus-Formel anwenden zu bekommen c . Beachten Sie, dass wir die Sinus-Formel nicht einfach wieder anwenden können zu bekommen c , da wir den Wert nicht haben C und, weil wir mit der sphärischen Trigonometrie spielen, da 90 ° ist keine bequeme Regel, die C = - B (die Summe des Winkels in einem sphärischen Dreieck größer als 180 ° sein kann, ein gleichseitiges sphärisches Dreieck mit allen Winkeln gleich 90 ° ist, zu prüfen, die durchaus möglich ist)


Andere Tipps

Schauen Sie sich http://www.movable-type.co.uk /scripts/latlong.html

Diese Stelle hat viele verschiedene Formeln und Javascript-Code, der Ihnen helfen soll. Ich habe erfolgreich in C # und SQL Server UDF übersetzt und ich verwende sie alle über den Platz.

Zum Beispiel für Javascript Entfernung zu berechnen:

var R = 6371; // km
var φ1 = lat1.toRadians();
var φ2 = lat2.toRadians();
var Δφ = (lat2-lat1).toRadians();
var Δλ = (lon2-lon1).toRadians();

var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
        Math.cos(φ1) * Math.cos(φ2) *
        Math.sin(Δλ/2) * Math.sin(Δλ/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

var d = R * c; 

Genießen Sie!

Ihre Konvertierung zwischen km und Radiant ist falsch. Eine nautische Meile 1 / 60stel Grad ist, so dass 1,15 unter der Annahme ... ist die Umwandlung von Meilen auf nautische Meilen und 1,6 ... ist die Umwandlung von km zum Statut Meilen,

   nm = km /  (1.1515 * 1.609344);
   deg = nm / 60;
   rad = toRadians(deg);

Mit anderen Worten, ich glaube, du bist mit einem Faktor von 1000 aus.

In Bezug auf Ihre Frage aktualisiert: Sollte nicht

double lon1 = endOfCourse(lat1, 0.0, 90.0, distEast)[0];

sein

double lon1 = endOfCourse(lat1, 0.0, 90.0, distEast)[1];

dachte ich, mit diesen Formeln des großen Problem aus, abgesehen von den Implementierungsfehlern in den anderen Antworten und Updates erwähnt.

Das große Problem war: Die Entfernung Methode (für den Abstand zwischen zwei Punkten Berechnung) war Großkreisentfernungen zu berechnen. Was natürlich, macht Sinn - das ist der kürzeste Weg zwischen den beiden Punkten. Jedoch , die Großkreis Abstand zwischen zwei Punkten, die auf derselben parallel (Breitengradlinie) liegen ist nicht das gleiche wie der Abstand zwischen diesen beiden Punkten, wenn sie direkt entlang der Linie der Breite reisen, es sei denn, Sie ‚am Äquator erneut.

So: die Funktionen ordnungsgemäß funktionieren; jedoch erfordert das alternative Koordinatensystem I in der ursprünglichen Frage vorgeschlagen, dass wir nur in der Entfernung nach Norden entlang der IDL Blick durch den Abstand gefolgt Osten entlang der parallel zu der resultierenden Breite. Und entlang einer bestimmten parallelen Berechnung Abstand ist ganz anders als Abstand entlang einer großen Kreis Berechnung!

Wie auch immer, da haben Sie es.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top