Kugelkoordinaten => Kartesische- => Kugel-

liebe wissende,
ich möchte folgende „aufgabe“ (in javascript) lösen:
ich habe koordinaten von punkten auf einer einheitskugel:
-die die einee nenne ich „ra“ (für „right ascension“) geht von 0 bis 2*Pi und entspricht grob gesagt der geographischen länge.
-die zweite nenne ich „dec“ (für „declination“) geht von -Pi/2 bis +Pi/2 und entspricht grob gesagt der geographischen breite.
nun möchte ich diese wie folgt in kartesische koordinaten (x,y,z) (rechtssystem) umwandeln:
-der urpsrung befindet sich im mittelpunkt der einheitskuggel.
-der punkt (ra,dec) = (0,0) befindet sich bei (x,y,z) = (0,0,-1)
-der punkt (ra,dec) = (pi*3/2,0) befindet sich bei (x,y,z) = (1,0,0)
-der punkt (ra,dec) = (0,pi/2) befindet sich bei (x,y,z) = (0,1,0) (ra ist hier ja eigentlich beliebig, da der „nordpol“ gemeint ist)

danach sollten diese koordinaten wieder umgewandelt werden zu den ursprünglichen koordinaten.
der grund für diese umformung ist, dass ich „dazwischen“ gewisse umformungen machen muss, die viel einfacher in kartesischen koordinaten zu bewerkstelligen sind.
meine code lautet nun

  1. umwandlung

    x = -Math.sin(ra)*Math.cos(dec);
    y = Math.sin(dec);
    z = -Math.cos(ra)*Math.cos(dec);

  2. umwandlung

    radiusxz = Math.sqrt(Math.pow(x,2)+Math.pow(z,2));
    ra = Math.acos(-z/radiusxz);
    dec = Math.asin(y/radiusxz);

also noch schöner dargestellt:

x := - sin(ra)*cos(dec)

y := sin(dec)

z := -cos(ra)*cos(dec)

rxz := \sqrt(x^2+z^2)

ra := \arccos(-z/rxz)

dec := \arcsin(y/rxz)

(radiusxz ist hier die projektion der strecke von nullpunkt zum punkt (x,y,z) auf die x-z-ebene)
wenn ich also einen punkt (ra,dec) durch diesen code lassen würde, sollte danach bis auf einen minimalen fehler wieder die selben koordinaten rauskommen, bei mir kommt aber für die eingabe
(ra,dec) = (4.719975360389818 , -0.5309928641961034)
die ausgabe
(ra’,dec’) = (1.5632099467897682 , -0.6276589377971391)
diese fehler sind meiner meinung nach viel zu gross, aber ich finde den fehler nicht.
kann mir jemand sagen, ob ich einen mathematischen fehler gemacht habe, oder ob das wirklich am javascript liegt (und wie man das allenfalls verbessern könnte)?

mit einer abweichung von vlt 1-2% könnte ich längstens leben, aber das ist ein wenig gar arg.
gruss niemand

Hallo,

ein Problem bei deiner Herangehensweise ist die Symmetrie des Kosinus. Deswegen kann aus dem Arkuskosinus allein nicht eindeutig der Winkel zurückgerechnet werden. Abhilfe schafft hier die atan2-Funktion, die in den meisten Programmiersprachen vorhanden sein sollte. Diese zieht sowohl den Sinus als auch den Kosinus heran, um den Winkel zu berechnen:

radiusdz = Math.sqrt(x \* x + z \* z);
ra2 = Math.atan2(-x, -z);
if (ra2 

Nico

erstmal vielen Dank für deinen Hinweis:

ein Problem bei deiner Herangehensweise ist die Symmetrie des
Kosinus. Deswegen kann aus dem Arkuskosinus allein nicht
eindeutig der Winkel zurückgerechnet werden.

das hatte ich ganz vergessen, das heisst ja das der arccos nur winkel von 0 bis pi zurückgeben kann und arcsin nur winkel von -pi/2 bis +pi/2, hätte ich eigentlich wissen sollen=)

Abhilfe schafft hier die atan2-Funktion, die in den meisten
Programmiersprachen vorhanden sein sollte.

diese funktion hingegen kannte ich nicht, tausend dank für diesen tipp!!!
ich habe erst jetzt gemerkt dass dies ja dann noch das nächste problem wäre…
wären denn aber rein mathematisch (mal abgesehen davon, dass sie nur in einem bestimmten wertebereich funktioniert) die umwnaldung die ich ‚ausgetüftelt‘ habe korrekt?

radiusdz = Math.sqrt(x * x + z * z);
ra2 = Math.atan2(-x, -z);
if (ra2

mit deiner version klappt es nun bestens (rundungsfehler erst ca. ab der 9. nachkommastelle, also bei weitem genug=)
nochmals vielen vielen dank für den hinweis wegen atan2, das wird mir auch in zukunft doch einiges kopfzerbrechen ersparen!!!
gruss niemand

Hallo niemand,

wären denn aber rein mathematisch (mal abgesehen davon, dass
sie nur in einem bestimmten wertebereich funktioniert) die
umwnaldung die ich ‚ausgetüftelt‘ habe korrekt?

ja. Der Grund für die riesigen Fehler, die Du Dir nicht erklären konntest, ist ein simpler Bug: In der Zuweisung

dec = arcsin(y/rxz)

ist das „/rxz“ zuviel. Wenn Du das korrigierst kannst Du mit Deiner Methode problemlos zwischen den Koordinaten hin- und zurückrechnen – solange die Input-Winkel hinreichend harmlos sind.

Trotzdem empfehle auch ich Dir wärmstens, für die Umwandlung von kartesischen in Polarkoordinaten die atan2-Funktion zu benutzen – dann geht’s im ganzen Winkelbereich klar.

Gruß
Martin

1 Like