2013-04-23 5 views
7

Gegeben zwei Lager, wie finde ich den kleinsten Winkel zwischen ihnen?Finden Sie den Winkel zwischen zwei Lager

Wenn zum Beispiel 1 Kurs 340 Grad und der zweite 10 Grad beträgt, ist der kleinste Winkel 30 Grad.

Ich habe ein Bild beigefügt, um zu zeigen, was ich meine. Ich habe versucht, einen von dem anderen zu subtrahieren, aber das hat wegen des Wrap-Around-Effekts eines Kreises nicht funktioniert. Ich habe auch versucht, negative Graden zu verwenden (180 - 359 ist -180 bis 0), aber das wurde verwirrt, wenn man versucht, den Winkel zwischen positiver und negativer Zahl zu berechnen.

Ich bin sicher, dass es einen leichteren Weg geben muss, dass viele if Aussagen haben.

Vielen Dank für Ihre Hilfe. Adam

BTW. Dies ist eine Navigationsfrage, daher ist der Radius des Kreises unbekannt.

Finding the angle between two headings

+0

Der Mod Operator hier helfen. Viel. –

+0

hoppla! behoben! –

Antwort

6
float getDifference(float a1, float a2) { 
    return Math.min((a1-a2)<0?a1-a2+360:a1-a2, (a2-a1)<0?a2-a1+360:a2-a1) 
} 
+0

Danke, dass ein Leckerbissen funktioniert. Ich habe versucht, dies für 6 Stunden zu lösen! –

+1

äquivalent: 'Math.min ((a1 - a2 + 360)% 360, (a2 - a1 + 360)% 360)' (Verwenden Sie 'fmod',' IEERemainder' usw. für andere Sprachen, in denen '%' doesn Fließkommawerte werden nicht unterstützt.) –

+0

Awesome, du hast meinen Tag gemacht. – FerDensetsu

4

Was:

angle = Math.abs(a1-a2); 
if (angle > 180) 
    angle = 360 - angle; 

Sie erwähnen ein Problem in Bezug auf positive und negative Zahlen, so vielleicht gibt es etwas, das ich nicht hier unter Berücksichtigung ...

+0

Ich glaube, dass Ihre Antwort mir entspricht, obwohl vielleicht ein bisschen leichter zu verstehen. Eine andere Option, die wie eine Kreuzung zwischen den beiden aussieht, ist "Math.min (Math.abs (a1-a2), 360 - Math.abs (a1-a2));' –

+0

Sie sind äquivalent in das Gefühl, dass sie beide richtig und gültig sind. Meiner Meinung nach behandelt Ihre Implementierung das Problem als ein Problem der Korrektheit des OP-Algorithmus, während ich es als ein Problem der Formatierung eines bereits korrekten Wertes betrachtete. Beides sind gültige Methoden, um das Problem zu betrachten, und ich denke, es gibt genügend Unterschiede in der Herangehensweise, die beide von Wert sind. – femtoRgon

0

Sie müssen den Unterschied in beiden Richtungen berücksichtigen.

public static double bearingDiff(double a, double b) { 
    double maxBearing = Math.max(a, b); 
    double minBearing = Math.min(a, b); 
    double antiClockwiseDiff = maxBearing - minBearing; 
    double clockwiseDiff = minBearing + 360 - maxBearing; 
    return Math.min(antiClockwiseDiff, clockwiseDiff); 
} 
10

I landete auf this message board gefunden mit der folgenden Formel I, da das Ergebnis benötigen basierend auf die Richtung (im Uhrzeigersinn oder gegen den Uhrzeigersinn) unterzeichnet werden. Es hat eine gute Erklärung für genau das, was vor sich geht.

((((bearing - heading) % 360) + 540) % 360) - 180 
0

Wenn Winkelrichtung benötigt wird, dann wird diese Arbeit:

int maxBearing = Math.max(bearing0, bearing1); 
    int minBearing = Math.min(bearing0, bearing1); 
    int firstDir = maxBearing - minBearing; 
    int secondDir = minBearing + 360 - maxBearing; 
    int diff = Math.min(firstDir, secondDir); 

    boolean anticlock_dir = false; 

    int anticlock = bearing1 + diff; 
    if (anticlock >= 360) 
     anticlock = anticlock - 360; 

    if (anticlock == bearing0) 
     anticlock_dir = true;