PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Java] Mathe falsches Ergebnis


/dev/NULL
2007-05-14, 11:56:46
Ich versuche folgendes zu nutzen:
http://de.wikipedia.org/wiki/Orthodrome#Genauere_Formel_zur_Abstandsberechnung_auf_der_Erde

Allerdings rechnet meine Funktion falsch/ich hab wohl was falsch gemacht:
Ich will rechnen:
S := sin²(G)cos²(l) +cos²(F)sin²(l)

Meine Version, die sich verrechnet:

S=Math.pow(Math.sin(G),2)*Math.pow(Math.cos(l),2)+
Math.pow(Math.cos(F),2)*Math.pow(Math.sin(l),2);

(beim versuch das Beispiel aus Wikipdeia nachzurechnen stimmen die Zwischenwerte da nichtmehr, endgültiges Ergebniss ist noch falscher )

UliBär
2007-05-14, 12:13:26
Du weißt aber schon, daß die Funktionen ihr Argument in Vielfachen von pi erwarten und nicht als Winkel in Grad?
Umrechnung: 360° = 2*pi

/dev/NULL
2007-05-14, 12:14:38
öhh... *nachschau*

*test*

Hmm ein
S=Math.pow(Math.sin(Math.toRadians(G)),2)*Math.pow(Math.cos(Math.toRadians(l)),2 )+
Math.pow(Math.cos(Math.toRadians(F)),2)*Math.pow(Math.sin(Math.toRadians(l)),2);
taugt auch nicht.. (Sinus will laut Hilfe ein radians, aber auch to Degrees bringt nicht das gewünschte Ergebnis).

Was genau meinst Du?


private final static double EARTHFLATTENING = (1/298.257223563);
private final static double EQUATORRADIUS = 6378.14; //km

double calcDistance(double l1,double b1,double l2,double b2)
{
/* http://de.wikipedia.org/wiki/Orthodrome
* http://www.addressdoctor.com/de/support/faq/geocoding.asp

* b1 := Geografische Breite von Standort 1
* l1 := Geografische Länge von Standort 1
* b2 := Geografische Breite von Standort 2
* l2 := * Geografische Länge von Standort 2
* f := Abplattung der Erde (1/298,257223563) Hiuer: EARTHFLATTENING
* a := Äquatorradius der Erde (6378,14 km) Hier: EQUATORRADIUS
*
* F := (b1+b2)/2
* G := (b1-b2)/2
* l := (l1-l2)/2
* S := sin²(G)cos²(l) +cos²(F)sin²(l)
* C := cos²(G)cos²(l) + sin²(F)sin²(l)
* w := arctan(sqrt(S/C)) in rad
* R := sqrt(S*C)/w
* D := 2*w*a
* H1 :=(3R-1)/(2C)
* H2 := (3R+1)/(2S)
*
* Entfernung:
* s := D(1 + f*H1*sin²(F)cos²(G) - f*H2*cos²(F)sin²(G))
*/
System.out.println("L1: "+l1 + " L2: " + l2+" B1: "+ b1+ " B2: "+ b2);
System.out.println("EQUATORRADIUS: "+EQUATORRADIUS + " EARTHFLATTENING: " + EARTHFLATTENING);

double F,G,l,S,C,w,R,D,H1,H2,s;

F=(b1+b2)/2;
System.out.println("F:"+F);
G=(b1-b2)/2;
System.out.println("G:"+G);
l=(l1-l2)/2;
System.out.println("l:"+l);

S=Math.pow(Math.sin(Math.toDegrees(G)),2)*Math.pow(Math.cos(Math.toDegrees(l)),2 )+
Math.pow(Math.cos(Math.toDegrees(F)),2)*Math.pow(Math.sin(Math.toDegrees(l)),2);
System.out.println("S:"+S);
C=Math.pow(Math.cos(G),2)*Math.pow(Math.cos(l),2)+Math.pow(Math.sin(F),2)*Math.p ow(Math.sin(l),2);
System.out.println("C:"+C);
w=Math.atan(Math.sqrt((S/C)));
System.out.println("w:"+w);
R=Math.sqrt(S*C)/w;
System.out.println("R:"+R);
D=2*w*EQUATORRADIUS;
System.out.println("D:"+D);
H1=(3*R-1)/(2*C);
System.out.println("H1:"+H1);
H2=(3*R+1)/(2*S);
System.out.println("H2:"+H2);
s=D*(1 + (EARTHFLATTENING*H1*Math.pow(Math.sin(F),2)*Math.pow(Math.cos(G),2)-
EARTHFLATTENING*H2*Math.pow(Math.cos(F),2)*Math.pow(Math.sin(G),2)));
System.out.println("Entfernung s:"+s);
return s;
}


System.out.println(calcDistance(13.4000, 52.5167, 139.7667, 35.7000));


Nachtrag: Funktion hinzugefügt..

UliBär
2007-05-14, 12:16:15
Tip: Math.toRadians() und Math.toDegrees() ;)

/dev/NULL
2007-05-14, 12:23:55
Hab ich doch gemacht, kommt auch kein besseres Ergebniss raus. (oder ich bin zu blöd.

Quellcode für die Funktion eingefügt.

Xmas
2007-05-14, 17:16:32
Ich sehe leider nun auch nicht gerade woran es liegen könnte, hätte aber ein paar kleine Tips zum effizienteren rechnen:
cos²(x) = 1 - sin²(x), daraus folgt C = 1 - S
x²y² = (xy)²
x² = x*x, pow(x, 2) ist ineffizient

/dev/NULL
2007-05-14, 18:47:16
Ich hab die Formel nicht selber geschrieben, Wikipedia --> und das kommt wohl aus nem Buch, über effizienz mach ich mir gedanken wenn ich das richtig rechnen kann (auch wenn Du natürlich recht hast)).

Sephiroth
2007-05-14, 20:15:50
öhh... *nachschau*

*test*

Hmm ein
S=Math.pow(Math.sin(Math.toRadians(G)),2)*Math.pow(Math.cos(Math.toRadians(l)),2 )+
Math.pow(Math.cos(Math.toRadians(F)),2)*Math.pow(Math.sin(Math.toRadians(l)),2);
taugt auch nicht.. (Sinus will laut Hilfe ein radians, aber auch to Degrees bringt nicht das gewünschte Ergebnis).

Du musst die Umrechnung ins Bogenmaß schon bei allen trigonometrischen Funktionen anwenden und nicht nur bei der Berechnung von S! (also bei C, w und s auch noch)

Am einfachsten machst du folgendes:

F=Math.toRadians((b1+b2)/2);
System.out.println("F: "+F);
G=Math.toRadians((b1-b2)/2);
System.out.println("G: "+G);
l=Math.toRadians((l1-l2)/2);
System.out.println("l: "+l);

/dev/NULL
2007-05-14, 23:42:56
Muß ich mal testen.. bei den ersten dreien F/G/l stimmten die Werte noch (verglichen mit den Wikipediawerten) ab S nicht mehr (daher hab ich dann "hinter" S nicht mehr weiterversucht.. wenn das erste Zwischenergebniss schon nicht taugt werden es die nächsten auch nicht tuen.

Sephiroth
2007-05-14, 23:47:31
F, G und l sind bei Wiki noch in Grad, hier dann aber in Rad.

Die anderen Ergebnisse stimmen dann überein ... glaub mir. ;)


public class Orthodrome
{
private final static double EARTHFLATTENING = 1/298.257223563;
private final static double EQUATORRADIUS = 6378.14; //km
private final static double G2R = Math.PI/180; // y = x*pi/180°
private final static double R2G = 180/Math.PI; // y*180°/pi = x

static double calcDistance(double l1,double b1,double l2,double b2)
{
/* http://de.wikipedia.org/wiki/Orthodrome
* http://www.addressdoctor.com/de/support/faq/geocoding.asp

* b1 := Geografische Breite von Standort 1
* l1 := Geografische Länge von Standort 1
* b2 := Geografische Breite von Standort 2
* l2 := * Geografische Länge von Standort 2
* f := Abplattung der Erde (1/298,257223563) Hiuer: EARTHFLATTENING
* a := Äquatorradius der Erde (6378,14 km) Hier: EQUATORRADIUS
*
* F := (b1+b2)/2
* G := (b1-b2)/2
* l := (l1-l2)/2
* S := sin²(G)cos²(l) +cos²(F)sin²(l)
* C := cos²(G)cos²(l) + sin²(F)sin²(l)
* w := arctan(sqrt(S/C)) in rad
* R := sqrt(S*C)/w
* D := 2*w*a
* H1 :=(3R-1)/(2C)
* H2 := (3R+1)/(2S)
*
* Entfernung:
* s := D(1 + f*H1*sin²(F)cos²(G) - f*H2*cos²(F)sin²(G))
*/
System.out.println("L1: " + l1 + " B1: " + b1 + "\nL2: " + l2 + " B2: " + b2);
System.out.println("EQUATORRADIUS: " + EQUATORRADIUS + "\nEARTHFLATTENING: " + EARTHFLATTENING);

double F, G, l, S, C, w, R, D, H1, H2, s;

F = G2R*(b1+b2)/2;
System.out.println("F: " + F);
G = G2R*(b1-b2)/2;
System.out.println("G: " + G);
l = G2R*(l1-l2)/2;
System.out.println("l: " + l);

S = Math.sin(G)*Math.sin(G)*Math.cos(l)*Math.cos(l) + Math.cos(F)*Math.cos(F)*Math.sin(l)*Math.sin(l);
System.out.println("S: " + S);
C = 1-S;
System.out.println("C: " + C);
w = Math.atan(Math.sqrt((S/C)));
System.out.println("w: "+w);
R = Math.sqrt(S*C)/w;
System.out.println("R: " + R);
D = 2*w*EQUATORRADIUS;
System.out.println("D: " + D);
H1=(3*R-1)/(2*C);
System.out.println("H1: "+H1);
H2 = (3*R+1)/(2*S);
System.out.println("H2: " + H2);
s = D*(1 + EARTHFLATTENING*H1*Math.sin(F)*Math.sin(F)*Math.cos(G)*Math.cos(G) - EARTHFLATTENING*H2*Math.cos(F)*Math.cos(F)*Math.sin(G)*Math.sin(G));
return s;
}

public static void main(String[] args) throws java.io.IOException
{
System.out.println("Entfernung s: " + calcDistance(13.4000, 52.5167, 139.7667, 35.7000));
System.in.read();
}
}

/dev/NULL
2007-05-15, 10:48:28
Ich glaub Dir.

Es geht.

DANKE!