Na dann ungefähr so: (eigene Daten am Anfang eintragen, dann mit "python spher.py" auf der Kommandozeile ausführen)
Code:
#!/usr/bin/python2
# encoding: utf8
# hier Kartengröße eintragen
map_x = 2048
map_y = 2048
# hier interessante Punkte eintragen
l1 = {
'm0': (60,13), #obere Ecke
'm2': (51,29), #rechte Ecke
'm1': (50,-1), #linke Ecke
'O20-': map(lambda x: (x,20), xrange(45,58)), # Meridian 20° ö.L. in 1er Schritten zwischen 45° n.B. und 58° n.B.
'Stockholm' : (59.331789, 18.066416), # einzelne Koordinaten (z.B. Städte)
'Paris' : (48.839413, 2.38266 ),
'München' : (48.10468 , 11.56929 ),
'Hamburg' : (53.541123, 9.989319),
'Zufallspunkte': [(52,12),(51,11),(50,10)], # Liste von Koordinaten (z.B. Flußverlauf)
}
from math import sin, cos, pi, atan, atan2, sqrt
deg=pi/180
r=6371
class Kart:
x=0
y=0
z=0
def __init__(self, x,y,z):
self.x=x
self.y=y
self.z=z
@classmethod
def fromSpher(cls, *args):
if len(args)==1:
r=args[0].r
a=args[0].a
m=args[0].m
else:
r=args[0]
a=args[1]
m=args[2]
return cls(
r*cos(m*deg)*cos(a*deg),
r*cos(m*deg)*sin(a*deg),
r*sin(m*deg))
def __str__(self):
return '{x: '+str(self.x)+', y: '+str(self.y)+', z: '+str(self.z)+'}'
def __repr__(self):
return self.__class__.__name__+'('+str(self.x)+','+str(self.y)+','+str(self.z)+')'
def __add__(self, other):
return Kart(self.x+other.x, self.y+other.y, self.z+other.z)
def __sub__(self, other):
return Kart(self.x-other.x, self.y-other.y, self.z-other.z)
def __mul__(self, other):
if isinstance(other, Kart):
"Kreuzprodukt"
return Kart(self.y*other.z-self.z*other.y, self.z*other.x-self.x*other.z, self.x*other.y-self.y*other.x)
else:
return Kart(self.x*other, self.y*other, self.z*other)
def __div__(self, other):
return Kart(self.x/other, self.y/other, self.z/other)
class Spher:
r=0
a=0
m=0
def __init__(self, x,y,z):
self.r=x
self.m=y
self.a=z
@classmethod
def fromKart(cls, *args):
if len(args)==1:
x=args[0].x
y=args[0].y
z=args[0].z
else:
x=args[0]
y=args[1]
z=args[2]
return cls(
sqrt(x*x+y*y+z*z),
atan2(y,x)/deg,
atan(z/sqrt(x*x+y*y))/deg)
def __str__(self):
return '{r: '+str(self.r)+', a: '+str(self.a)+'°, m: '+str(self.m)+'°}'
def __repr__(self):
return self.__class__.__name__+'('+str(self.r)+','+str(self.a)+','+str(self.m)+')'
def dist(x, y):
if isinstance(x, Spher):
x=Kart.fromSpher(x)
if isinstance(y, Spher):
y=Kart.fromSpher(y)
d=y-x
return sqrt(d.x*d.x + d.y*d.y + d.z*d.z)
def det(M):
return (+M[0][0]*M[1][1]*M[2][2]
+M[0][1]*M[1][2]*M[2][0]
+M[0][2]*M[1][0]*M[2][1]
-M[0][2]*M[1][1]*M[2][0]
-M[0][1]*M[1][0]*M[2][2]
-M[0][0]*M[1][2]*M[2][1])
def LGS(x,y,z,p):
A=[[x.x, y.x, z.x],[x.y,y.y,z.y],[x.z,y.z,z.z]]
A1=[[p.x, y.x, z.x],[p.y,y.y,z.y],[p.z,y.z,z.z]]
A2=[[x.x, p.x, z.x],[x.y,p.y,z.y],[x.z,p.z,z.z]]
A3=[[x.x, y.x, p.x],[x.y,y.y,p.y],[x.z,y.z,p.z]]
a=det(A)
return det(A1)/a, det(A2)/a, det(A3)/a
class Map:
o=Kart(0,0,0)
x=Kart(1,0,0)
y=Kart(0,1,0)
z=Kart(0,0,1)
xscale=1
yscale=1
def __init__(self, *args):
points=[]
for p in args[0:3]:
if isinstance(p, Spher):
p = Kart.fromSpher(p)
points.append(p)
self.o=points[0]
self.x=points[1]-self.o
self.y=points[2]-self.o
self.z=self.x*self.y
if len(args)>3:
self.xscale=args[3]
self.yscale=args[3]
if len(args)>4:
self.yscale=args[4]
self.x*=self.xscale
self.y*=self.yscale
self.z*=self.xscale*self.yscale
def check(self, p):
if isinstance(p, Spher):
p=Kart.fromSpher(p)
return LGS(self.x, self.y, self.z, p-self.o)
def checkall(self, l):
m=[]
for n,p in l.iteritems():
m.append((n, self.check(p)))
#m.sort(key=lambda (a,b): b[0]*b[0]+b[1]*b[1])
m.sort(key=lambda (a,b): a)
x=[]
for n,p in m:
if p[0]>0 and p[0]<1/self.xscale and p[1]>0 and p[1]<1/self.yscale:
print n, '%dx%d, %s'%(lambda (x,y,z): (int(round(x)),int(round(y)),hex(int(1/self.xscale*round(y)+round(x)))))(p)
else:
x.append((n,p))
print '--------- Außerhalb der Karte: ---------'
for n,p in x:
print n, '%dx%d, %s'%(lambda (x,y,z): (int(round(x)),int(round(y)),hex(int(1/self.xscale*round(y)+round(x)))))(p)
def get(self, *args):
if isinstance(args[0], Spher):
p=Kart.fromSpher(args[0])
elif isinstance(args[0], Kart):
p=args[0]
else:
p=Kart(*args)
return self.o + self.x*p.x + self.y*p.y + self.z*p.z
l={}
for n,p in l1.iteritems():
if isinstance(p, list):
for i, q in enumerate(p):
l[n+str(i)]=Spher(r,q[0], q[1])
else:
l[n]=Spher(r,p[0], p[1])
m1=Map(l['m0'],l['m1'],l['m2'],1./map_x,1./map_y)
m1.checkall(l)
lx= dist(l['m0'],l['m1'])
ly= dist(l['m0'],l['m2'])
print
print 'len_x=',lx
print 'len_y=',ly
print 'ratio=',lx*m1.xscale/(ly*m1.yscale)