Mehr

Finden der Schnittmenge zweier Kreise bei gegebenem Lat/Lon und Radius?


Ich versuche, den Schnittpunkt zweier Kreise auf der Erde mit einem bestimmten Breitengrad, Längengrad und Radius zu berechnen. Ich begann mit diesem Berechnen des Schnittpunkts zweier Kreise?

Diese Kreise werden nie einen Durchmesser von mehr als 100 km haben und normalerweise "nah" beieinander liegen, was zwei Schnittpunkte für das Kreispaar bedeutet.

Ich habe im Code unten an der Stelle, an der das Problem auftritt, einen Kommentar hinzugefügt.

Ich habe diese Frage ursprünglich auf StackOverflow gestellt, aber da dies so räumlich ist, habe ich keine Antworten erhalten.

var circle1 = {lat:37.673442, lon:-90.234036, r:107.5}; var circle2 = {lat:36.109997, lon:-90.953669, r:145}; Funktion findInterscetionOfTwoCircles(circle1, circle2){ var c1 = latLonToGeocentricCoords(circle1); var c2 = latLonToGeocentricCoords(circle2); var r1 = convertRadius(circle1.r); var r2 = convertRadius(circle2.r); var c1dotc2 = berechneDotProduct(c1, c2); // Hier tritt das Problem auf. // Der Wert von 'a' sollte 0,9735030 sein, aber ich erhalte 46,770178816522844. // Ich bin mir sicher, dass r1 und r2 korrekt sind (mit den Werten im Originalbeitrag übereinstimmen). Außerdem glaube ich, dass die FunktioncalculateDotProduct // korrekt ist, sodass c1dotc2 korrekt ist. Ich glaube, ich habe // jeden Fehler in der Reihenfolge der Operationen ausgeschlossen. Vielleicht ist es eine Grad/Radiant-Umrechnung // Problem oder so ähnlich? Ich habe verschiedene Variationen ausprobiert und bin nun // aus Ideen raus. var a = (Math.cos(r1) - (Math.cos(r2) * c1dotc2)) / (1 - (c1dotc2 * c1dotc2)); var b = (Math.cos(r2) - (Math.cos(r1) * c1dotc2)) / (1 - (c1dotc2 * c1dotc2)); // -45.83805010474024, sollte 0,0260194 sein var n = berechnenCrossProduct(c1, c2); var x0 = berechneLinearCombination(a, b, c1, c2); var ndotn = berechneDotProduct(n, n); // var t = Math.sqrt((1 - berechnenDotProduct(x0,x0))/calculateDotProduct(n,n)); // Beende den Algorithmus } function latLonToGeocentricCoords(circle){ var x = Math.cos(degToRad(circle.lon)) * Math.cos(degToRad(circle.lat)); var y = Math.sin(degToRad(circle.lon)) * Math.cos(degToRad(circle.lat)); var z = Math.sin(degToRad(circle.lat)); Rückgabe {x:x, y:y, z:z}; } Funktion geocentricCoordsToLatLon(x, y, z){ var lon = Math.atan2(x,y) var lat = Math.atan2(Math.sqrt((x*x)+(y*y)), z) return { lat: lat, lon: lon}; } Funktion convertRadius (radius) {// konvertiert NM jetzt zurück degToRad (radius) / 60; } Funktion berechneDotProduct(input1, input2){ if(arguments.length !== 2){ throw new Error('Sie müssen dieser Methode zwei Argumente liefern.'); } if(Array.isArray(input1) !== Array.isArray(input2) || typeof input1 !== typeof input2){ throw new Error('Eingaben müssen vom gleichen Typ sein.'); } var dotProduct = 0; if(Array.isArray(input1)){ // als parallele Arrays verarbeiten if(input1.length === input2.length){ throw new Error('Eingabelängen müssen gleich sein.'); } for(var i = 0, len = input1.length; i < len; i++){ dotProduct += input1[i] * input2[i]; } } else if(typeof input1 === 'object' && !Array.isArray(input1)){ // als Schlüsselwertobjekt verarbeiten for(var key in input1){ if (input1.hasOwnProperty(key)) { if (!input2[key]){ throw new Error('Beide Eingaben müssen die gleichen Eigenschaften haben, um verarbeitet zu werden.'); } PunktProdukt += Eingabe1[Taste] * Eingabe2[Taste]; } } } return dotProduct; } Funktion berechneCrossProduct(circle1, circle2){ var x = (circle1.y * circle2.z) - (circle1.z * circle2.y); var y = (Kreis1.z * Kreis2.x) - (Kreis1.x * Kreis2.z); var z = (Kreis1.x * Kreis2.y) - (Kreis1.y * Kreis2.x); Rückgabe {x: x, y: y, z: z}; } Funktion berechneLinearCombination(a, b, c1, c2){ var x = {x: a * c1.x, y: a * c1.y, z: a * c1.z}; var y = {x: b * c2.x, y: b * c2.y, z: b * c2.z}; Rückgabe berechnenDotProduct(x, y); } Funktion degToRad (Grad) { Rückgabegrad * Math.PI / 180; } Funktion radToDeg (Radiant) { Radiant zurückgeben / Math.PI * 180; }

circle1 mit r=107.5 naut.mile und circle2 mit r=145 naut.mile schneiden sich an Punkten wie im Bild gezeigt:

Für diese Art von Arbeit sollte ein projiziertes (kartesisches) Koordinatensystem verwendet werden. Ich habe an der UTM-Zone 15 gearbeitet, da beide Kreismittelpunkte in dieser Zone liegen. Wenn Sie versuchen, dies manuell / mathematisch mit dem Polarkoordinatensystem zu tun, wird es aufgrund der unvollkommenen Erdform sehr kompliziert. Man kann eine genauere Berechnung durchführen, indem man das beste Projektions-/Koordinatensystem für diesen Bereich übernimmt.