Kugelkoordinaten in n-Dimensionen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
init-0
User
Beiträge: 38
Registriert: Samstag 22. Januar 2011, 18:46

Hallo,

Ich hab ein Programm geschrieben um in n-Dimensionen vom Kartesischen Koordinatensystem ins Kugelkoordinatensystem um zu rechnen

Code: Alles auswählen

import math

def toSpherical(kart, orig=None):
    if orig is not None:
        n = []
        for p in xrange(len(kart)):
            n.append(kart[p]-orig[p])
        kart = n
    
    rad = 0
    for i in xrange(len(kart)):
        rad += (kart[i])**2
    rad = rad**0.5

    angles = []
    
    for i in xrange(len(kart)-1):
        denominator = kart[i]
        numerator = 0.0

        for p in kart[i+1:]:
            numerator += p**2
        numerator = numerator**0.5

        omega = math.atan(numerator/denominator)
        
        angles.append(omega)
    return [rad]+angles

def toKartesian(spherical, orig=None):
    r = spherical[0]
    angles = spherical[1:]
    pos = []
    
    for i in xrange(len(angles)):
        angle = angles[i]
        x = r * math.cos(angle)
        for p in angles[:i]:
            x *= math.sin(p)
        pos.append(x)
    last = r
    for p in angles:
        last *= math.sin(p)
    pos.append(last)

    if orig is not None:
        n = []
        for i in xrange(len(pos)):
            n.append(pos[i] + orig[i])
        pos = n
    return pos
Leider funktioniert das nicht immer ganz:

Code: Alles auswählen

>>> for i in [(1,1),(1,-1),(-1,1),(-1,-1)]:
	print toKartesian(toSpherical(i))

	
[1.0000000000000002, 1.0]
[1.0000000000000002, 1.0]
[1.0000000000000002, -1.0]
[1.0000000000000002, -1.0]
Das Programm habe ich nach diesem Vorbild geschrieben: http://de.wikipedia.org/wiki/Kugelkoord ... oordinaten
Ich glaube das Problem liegt daran, dass das Programm immer nur einen Winkel zwischen -Pi/2 und pi/2 ausgibt.
Wenn also der Punkt rechts vom Ursprung liegt müsste man zu dem Winkel pi addieren, glaube ich.
Wenn das richtig ist wüsste ich aber nicht wie ich das in n-Dimensionen machen sollte.
Kann mir da jemand helfen?
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Die von dir zitierte Seite gibt sogar ein Rezept an, inklusive Fallunterscheidung. Wenn man das umsetzt (und die Rückrichtung auch entsprechend), kommt etwa folgendes heraus (sollte für 2.x und 3.x gehen):

Code: Alles auswählen

from __future__ import division
import math

def to_spherical(x):

    L = [x[0]]
    for xk in x[1:-1]:
        L.append(xk / abs(xk) * (xk ** 2 + L[-1] ** 2) ** 0.5)

    angles = [math.atan(Lk / xk1) for Lk, xk1 in zip(L, x[1:])]
    if x[-1] < 0:
        angles[-1] += math.pi
    
    radius = sum(xk ** 2 for xk in x) ** 0.5
    return [radius] + angles

def to_cartesian(spherical):
    r = spherical[0]
    angles = spherical[1:]
    pos = []
   
    for i, angle in enumerate(angles):
        x = r * math.cos(angle)
        for p in angles[i + 1:]:
            x *= math.sin(p)
        pos.append(x)
        
    first = r
    for p in angles:
        first *= math.sin(p)
    pos.insert(0, first)

    return pos


from itertools import product

for x in product([-1, 1], repeat=5):
	print(x, to_cartesian(to_spherical(x)))
mit dem Ergebnis

Code: Alles auswählen

(-1, -1, -1, -1, -1) [-0.9999999999999999, -0.9999999999999999, -0.9999999999999999, -0.9999999999999997, -1.0000000000000004]
(-1, -1, -1, -1, 1) [-1.0, -1.0, -1.0, -0.9999999999999998, 1.0000000000000002]
(-1, -1, -1, 1, -1) [-1.0, -1.0, -1.0, 0.9999999999999998, -1.0]
(-1, -1, -1, 1, 1) [-1.0, -1.0, -1.0, 0.9999999999999998, 1.0000000000000002]
(-1, -1, 1, -1, -1) [-0.9999999999999999, -0.9999999999999999, 0.9999999999999999, -0.9999999999999997, -1.0000000000000004]
(-1, -1, 1, -1, 1) [-1.0, -1.0, 1.0, -0.9999999999999998, 1.0000000000000002]
(-1, -1, 1, 1, -1) [-1.0, -1.0, 1.0, 0.9999999999999998, -1.0]
(-1, -1, 1, 1, 1) [-1.0, -1.0, 1.0, 0.9999999999999998, 1.0000000000000002]
(-1, 1, -1, -1, -1) [-0.9999999999999999, 0.9999999999999999, -0.9999999999999999, -0.9999999999999997, -1.0000000000000004]
(-1, 1, -1, -1, 1) [-1.0, 1.0, -1.0, -0.9999999999999998, 1.0000000000000002]
(-1, 1, -1, 1, -1) [-1.0, 1.0, -1.0, 0.9999999999999998, -1.0]
(-1, 1, -1, 1, 1) [-1.0, 1.0, -1.0, 0.9999999999999998, 1.0000000000000002]
(-1, 1, 1, -1, -1) [-0.9999999999999999, 0.9999999999999999, 0.9999999999999999, -0.9999999999999997, -1.0000000000000004]
(-1, 1, 1, -1, 1) [-1.0, 1.0, 1.0, -0.9999999999999998, 1.0000000000000002]
(-1, 1, 1, 1, -1) [-1.0, 1.0, 1.0, 0.9999999999999998, -1.0]
(-1, 1, 1, 1, 1) [-1.0, 1.0, 1.0, 0.9999999999999998, 1.0000000000000002]
(1, -1, -1, -1, -1) [0.9999999999999999, -0.9999999999999999, -0.9999999999999999, -0.9999999999999997, -1.0000000000000004]
(1, -1, -1, -1, 1) [1.0, -1.0, -1.0, -0.9999999999999998, 1.0000000000000002]
(1, -1, -1, 1, -1) [1.0, -1.0, -1.0, 0.9999999999999998, -1.0]
(1, -1, -1, 1, 1) [1.0, -1.0, -1.0, 0.9999999999999998, 1.0000000000000002]
(1, -1, 1, -1, -1) [0.9999999999999999, -0.9999999999999999, 0.9999999999999999, -0.9999999999999997, -1.0000000000000004]
(1, -1, 1, -1, 1) [1.0, -1.0, 1.0, -0.9999999999999998, 1.0000000000000002]
(1, -1, 1, 1, -1) [1.0, -1.0, 1.0, 0.9999999999999998, -1.0]
(1, -1, 1, 1, 1) [1.0, -1.0, 1.0, 0.9999999999999998, 1.0000000000000002]
(1, 1, -1, -1, -1) [0.9999999999999999, 0.9999999999999999, -0.9999999999999999, -0.9999999999999997, -1.0000000000000004]
(1, 1, -1, -1, 1) [1.0, 1.0, -1.0, -0.9999999999999998, 1.0000000000000002]
(1, 1, -1, 1, -1) [1.0, 1.0, -1.0, 0.9999999999999998, -1.0]
(1, 1, -1, 1, 1) [1.0, 1.0, -1.0, 0.9999999999999998, 1.0000000000000002]
(1, 1, 1, -1, -1) [0.9999999999999999, 0.9999999999999999, 0.9999999999999999, -0.9999999999999997, -1.0000000000000004]
(1, 1, 1, -1, 1) [1.0, 1.0, 1.0, -0.9999999999999998, 1.0000000000000002]
(1, 1, 1, 1, -1) [1.0, 1.0, 1.0, 0.9999999999999998, -1.0]
(1, 1, 1, 1, 1) [1.0, 1.0, 1.0, 0.9999999999999998, 1.0000000000000002]
init-0
User
Beiträge: 38
Registriert: Samstag 22. Januar 2011, 18:46

Hmm das hab ich gar nicht gesehen. Danke ;)
Aber hierbei sollte doch eingentlich (1, pi/2) herauskommen oder?

Code: Alles auswählen

>>> to_spherical([0,1])
[1.0, 0.0]
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

init-0 hat geschrieben:Aber hierbei sollte doch eingentlich (1, pi/2) herauskommen oder?

Code: Alles auswählen

>>> to_spherical([0,1])
[1.0, 0.0]
Es gilt die Darstellung "nach Umnummerierung", d.h. x1 = 1 * sin(0), x2 = 1 * cos(0) - passt.
Antworten