Projekt aufgeräumt, gha1 getestet, Runge-Kutta angepasst (gha2_num sollte jetzt deutlich schneller sein)
This commit is contained in:
608
ellipsoide.py
608
ellipsoide.py
@@ -1,8 +1,9 @@
|
||||
import numpy as np
|
||||
from numpy import sin, cos, arctan, arctan2, sqrt
|
||||
from numpy import sin, cos, arctan, arctan2, sqrt, pi, arccos
|
||||
import winkelumrechnungen as wu
|
||||
import ausgaben as aus
|
||||
import jacobian_Ligas
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
class EllipsoidBiaxial:
|
||||
@@ -10,8 +11,8 @@ class EllipsoidBiaxial:
|
||||
self.a = a
|
||||
self.b = b
|
||||
self.c = a ** 2 / b
|
||||
self.e = np.sqrt(a ** 2 - b ** 2) / a
|
||||
self.e_ = np.sqrt(a ** 2 - b ** 2) / b
|
||||
self.e = sqrt(a ** 2 - b ** 2) / a
|
||||
self.e_ = sqrt(a ** 2 - b ** 2) / b
|
||||
|
||||
@classmethod
|
||||
def init_name(cls, name: str):
|
||||
@@ -40,28 +41,28 @@ class EllipsoidBiaxial:
|
||||
b = a - a * f
|
||||
return cls(a, b)
|
||||
|
||||
V = lambda self, phi: np.sqrt(1 + self.e_ ** 2 * np.cos(phi) ** 2)
|
||||
V = lambda self, phi: sqrt(1 + self.e_ ** 2 * cos(phi) ** 2)
|
||||
M = lambda self, phi: self.c / self.V(phi) ** 3
|
||||
N = lambda self, phi: self.c / self.V(phi)
|
||||
|
||||
beta2psi = lambda self, beta: np.arctan(self.a / self.b * np.tan(beta))
|
||||
beta2phi = lambda self, beta: np.arctan(self.a ** 2 / self.b ** 2 * np.tan(beta))
|
||||
beta2psi = lambda self, beta: arctan(self.a / self.b * np.tan(beta))
|
||||
beta2phi = lambda self, beta: arctan(self.a ** 2 / self.b ** 2 * np.tan(beta))
|
||||
|
||||
psi2beta = lambda self, psi: np.arctan(self.b / self.a * np.tan(psi))
|
||||
psi2phi = lambda self, psi: np.arctan(self.a / self.b * np.tan(psi))
|
||||
psi2beta = lambda self, psi: arctan(self.b / self.a * np.tan(psi))
|
||||
psi2phi = lambda self, psi: arctan(self.a / self.b * np.tan(psi))
|
||||
|
||||
phi2beta = lambda self, phi: np.arctan(self.b ** 2 / self.a ** 2 * np.tan(phi))
|
||||
phi2psi = lambda self, phi: np.arctan(self.b / self.a * np.tan(phi))
|
||||
phi2beta = lambda self, phi: arctan(self.b ** 2 / self.a ** 2 * np.tan(phi))
|
||||
phi2psi = lambda self, phi: arctan(self.b / self.a * np.tan(phi))
|
||||
|
||||
phi2p = lambda self, phi: self.N(phi) * np.cos(phi)
|
||||
phi2p = lambda self, phi: self.N(phi) * cos(phi)
|
||||
|
||||
def cart2ell(self, Eh, Ephi, x, y, z):
|
||||
p = np.sqrt(x**2+y**2)
|
||||
p = sqrt(x**2+y**2)
|
||||
# print(f"p = {round(p, 5)} m")
|
||||
|
||||
lamb = np.arctan(y/x)
|
||||
lamb = arctan(y/x)
|
||||
|
||||
phi_null = np.arctan(z/p*(1-self.e**2)**-1)
|
||||
phi_null = arctan(z/p*(1-self.e**2)**-1)
|
||||
|
||||
hi = [0]
|
||||
phii = [phi_null]
|
||||
@@ -69,9 +70,9 @@ class EllipsoidBiaxial:
|
||||
i = 0
|
||||
|
||||
while True:
|
||||
N = self.a*(1-self.e**2*np.sin(phii[i])**2)**(-1/2)
|
||||
h = p/np.cos(phii[i])-N
|
||||
phi = np.arctan(z/p*(1-(self.e**2*N)/(N+h))**(-1))
|
||||
N = self.a*(1-self.e**2*sin(phii[i])**2)**(-1/2)
|
||||
h = p/cos(phii[i])-N
|
||||
phi = arctan(z/p*(1-(self.e**2*N)/(N+h))**(-1))
|
||||
hi.append(h)
|
||||
phii.append(phi)
|
||||
dh = abs(hi[i]-h)
|
||||
@@ -86,11 +87,11 @@ class EllipsoidBiaxial:
|
||||
return phi, lamb, h
|
||||
|
||||
def ell2cart(self, phi, lamb, h):
|
||||
W = np.sqrt(1 - self.e**2 * np.sin(phi)**2)
|
||||
W = sqrt(1 - self.e**2 * sin(phi)**2)
|
||||
N = self.a / W
|
||||
x = (N+h) * np.cos(phi) * np.cos(lamb)
|
||||
y = (N+h) * np.cos(phi) * np.sin(lamb)
|
||||
z = (N * (1-self.e**2) + h) * np.sin(lamb)
|
||||
x = (N+h) * cos(phi) * cos(lamb)
|
||||
y = (N+h) * cos(phi) * sin(lamb)
|
||||
z = (N * (1-self.e**2) + h) * sin(lamb)
|
||||
return x, y, z
|
||||
|
||||
class EllipsoidTriaxial:
|
||||
@@ -98,15 +99,15 @@ class EllipsoidTriaxial:
|
||||
self.ax = ax
|
||||
self.ay = ay
|
||||
self.b = b
|
||||
self.ex = np.sqrt((self.ax**2 - self.b**2) / self.ax**2)
|
||||
self.ey = np.sqrt((self.ay**2 - self.b**2) / self.ay**2)
|
||||
self.ee = np.sqrt((self.ax**2 - self.ay**2) / self.ax**2)
|
||||
self.ex_ = np.sqrt((self.ax**2 - self.b**2) / self.b**2)
|
||||
self.ey_ = np.sqrt((self.ay**2 - self.b**2) / self.b**2)
|
||||
self.ee_ = np.sqrt((self.ax**2 - self.ay**2) / self.ay**2)
|
||||
self.Ex = np.sqrt(self.ax**2 - self.b**2)
|
||||
self.Ey = np.sqrt(self.ay**2 - self.b**2)
|
||||
self.Ee = np.sqrt(self.ax**2 - self.ay**2)
|
||||
self.ex = sqrt((self.ax**2 - self.b**2) / self.ax**2)
|
||||
self.ey = sqrt((self.ay**2 - self.b**2) / self.ay**2)
|
||||
self.ee = sqrt((self.ax**2 - self.ay**2) / self.ax**2)
|
||||
self.ex_ = sqrt((self.ax**2 - self.b**2) / self.b**2)
|
||||
self.ey_ = sqrt((self.ay**2 - self.b**2) / self.b**2)
|
||||
self.ee_ = sqrt((self.ax**2 - self.ay**2) / self.ay**2)
|
||||
self.Ex = sqrt(self.ax**2 - self.b**2)
|
||||
self.Ey = sqrt(self.ay**2 - self.b**2)
|
||||
self.Ee = sqrt(self.ax**2 - self.ay**2)
|
||||
|
||||
@classmethod
|
||||
def init_name(cls, name: str):
|
||||
@@ -156,22 +157,21 @@ class EllipsoidTriaxial:
|
||||
b = 4000000
|
||||
return cls(ax, ay, b)
|
||||
elif name == "KarneyTest2024":
|
||||
ax = np.sqrt(2)
|
||||
ax = sqrt(2)
|
||||
ay = 1
|
||||
b = 1 / np.sqrt(2)
|
||||
b = 1 / sqrt(2)
|
||||
return cls(ax, ay, b)
|
||||
|
||||
def point_on(self, point: np.ndarray) -> bool:
|
||||
"""
|
||||
Test, ob ein Punkt auf dem Ellipsoid liegt.
|
||||
:param point: kartesische 3D-Koordinaten
|
||||
:return: Punkt auf dem Ellispoid?
|
||||
"""
|
||||
value = point[0]**2/self.ax**2 + point[1]**2/self.ay**2 + point[2]**2/self.b**2
|
||||
if abs(1-value) < 0.000001:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
def func_H(self, x: float, y: float, z: float):
|
||||
return x ** 2 + y ** 2 / (1 - self.ee ** 2) ** 2 + z ** 2 / (1 - self.ex ** 2) ** 2
|
||||
|
||||
def func_n(self, x: float, y: float, z: float, H: float = None):
|
||||
if H is None:
|
||||
H = self.func_H(x, y, z)
|
||||
sqrtH = sqrt(H)
|
||||
return np.array([x / sqrtH,
|
||||
y / ((1 - self.ee ** 2) * sqrtH),
|
||||
z / ((1 - self.ex ** 2) * sqrtH)])
|
||||
|
||||
def ellu2cart(self, beta: float, lamb: float, u: float) -> np.ndarray:
|
||||
"""
|
||||
@@ -184,60 +184,12 @@ class EllipsoidTriaxial:
|
||||
:param u: Größe entlang der z-Achse
|
||||
:return: Punkt in kartesischen Koordinaten
|
||||
"""
|
||||
# s1 = u**2 - self.b**2
|
||||
# s2 = -self.ay**2 * np.sin(beta)**2 - self.b**2 * np.cos(beta)**2
|
||||
# s3 = -self.ax**2 * np.sin(lamb)**2 - self.ay**2 * np.cos(lamb)**2
|
||||
# print(s1, s2, s3)
|
||||
|
||||
# xe = np.sqrt(((self.ax**2+s1) * (self.ax**2+s2) * (self.ax**2+s3)) /
|
||||
# ((self.ax**2-self.ay**2) * (self.ax**2-self.b**2)))
|
||||
# ye = np.sqrt(((self.ay**2+s1) * (self.ay**2+s2) * (self.ay**2+s3)) /
|
||||
# ((self.ay**2-self.ax**2) * (self.ay**2-self.b**2)))
|
||||
# ze = np.sqrt(((self.b**2+s1) * (self.b**2+s2) * (self.b**2+s3)) /
|
||||
# ((self.b**2-self.ax**2) * (self.b**2-self.ay**2)))
|
||||
|
||||
x = np.sqrt(u**2 + self.Ex**2) * np.sqrt(np.cos(beta)**2 + self.Ee**2/self.Ex**2 * np.sin(beta)**2) * np.cos(lamb)
|
||||
y = np.sqrt(u**2 + self.Ey**2) * np.cos(beta) * np.sin(lamb)
|
||||
z = u * np.sin(beta) * np.sqrt(1 - self.Ee**2/self.Ex**2 * np.cos(lamb)**2)
|
||||
x = sqrt(u**2 + self.Ex**2) * sqrt(cos(beta)**2 + self.Ee**2/self.Ex**2 * sin(beta)**2) * cos(lamb)
|
||||
y = sqrt(u**2 + self.Ey**2) * cos(beta) * sin(lamb)
|
||||
z = u * sin(beta) * sqrt(1 - self.Ee**2/self.Ex**2 * cos(lamb)**2)
|
||||
|
||||
return np.array([x, y, z])
|
||||
|
||||
def ell2cart(self, beta: float | np.ndarray, lamb: float | np.ndarray) -> np.ndarray:
|
||||
"""
|
||||
Panou, Korakitis 2019 2
|
||||
:param beta: elliptische Breite [rad]
|
||||
:param lamb: elliptische Länge [rad]
|
||||
:return: Punkt in kartesischen Koordinaten
|
||||
"""
|
||||
beta = np.asarray(beta, dtype=float)
|
||||
lamb = np.asarray(lamb, dtype=float)
|
||||
|
||||
beta, lamb = np.broadcast_arrays(beta, lamb)
|
||||
|
||||
B = self.Ex ** 2 * np.cos(beta) ** 2 + self.Ee ** 2 * np.sin(beta) ** 2
|
||||
L = self.Ex ** 2 - self.Ee ** 2 * np.cos(lamb) ** 2
|
||||
|
||||
x = self.ax / self.Ex * np.sqrt(B) * np.cos(lamb)
|
||||
y = self.ay * np.cos(beta) * np.sin(lamb)
|
||||
z = self.b / self.Ex * np.sin(beta) * np.sqrt(L)
|
||||
|
||||
xyz = np.stack((x, y, z), axis=-1)
|
||||
|
||||
# Pole
|
||||
mask_south = beta == -np.pi / 2
|
||||
mask_north = beta == np.pi / 2
|
||||
xyz[mask_south] = np.array([0, 0, -self.b])
|
||||
xyz[mask_north] = np.array([0, 0, self.b])
|
||||
|
||||
# Äquator
|
||||
mask_eq = beta == 0
|
||||
xyz[mask_eq & (lamb == -np.pi / 2)] = np.array([0, -self.ay, 0])
|
||||
xyz[mask_eq & (lamb == np.pi / 2)] = np.array([0, self.ay, 0])
|
||||
xyz[mask_eq & (lamb == 0)] = np.array([self.ax, 0, 0])
|
||||
xyz[mask_eq & (lamb == np.pi)] = np.array([-self.ax, 0, 0])
|
||||
|
||||
return xyz
|
||||
|
||||
def cart2ellu(self, point: np.ndarray) -> tuple[float, float, float]:
|
||||
"""
|
||||
Panou 2014 15ff.
|
||||
@@ -253,25 +205,137 @@ class EllipsoidTriaxial:
|
||||
|
||||
p = (c2**2 - 3*c1) / 9
|
||||
q = (9*c1*c2 - 27*c0 - 2*c2**3) / 54
|
||||
omega = np.arccos(q / np.sqrt(p**3))
|
||||
omega = arccos(q / sqrt(p**3))
|
||||
|
||||
s1 = 2 * np.sqrt(p) * np.cos(omega/3) - c2/3
|
||||
s2 = 2 * np.sqrt(p) * np.cos(omega/3 - 2*np.pi/3) - c2/3
|
||||
s3 = 2 * np.sqrt(p) * np.cos(omega/3 - 4*np.pi/3) - c2/3
|
||||
s1 = 2 * sqrt(p) * cos(omega/3) - c2/3
|
||||
s2 = 2 * sqrt(p) * cos(omega/3 - 2*pi/3) - c2/3
|
||||
s3 = 2 * sqrt(p) * cos(omega/3 - 4*pi/3) - c2/3
|
||||
# print(s1, s2, s3)
|
||||
|
||||
beta = np.arctan(np.sqrt((-self.b**2 - s2) / (self.ay**2 + s2)))
|
||||
beta = arctan(sqrt((-self.b**2 - s2) / (self.ay**2 + s2)))
|
||||
if abs((-self.ay**2 - s3) / (self.ax**2 + s3)) > 1e-7:
|
||||
lamb = np.arctan(np.sqrt((-self.ay**2 - s3) / (self.ax**2 + s3)))
|
||||
lamb = arctan(sqrt((-self.ay**2 - s3) / (self.ax**2 + s3)))
|
||||
else:
|
||||
lamb = 0
|
||||
u = np.sqrt(self.b**2 + s1)
|
||||
u = sqrt(self.b**2 + s1)
|
||||
|
||||
return beta, lamb, u
|
||||
|
||||
def cart2ell(self, point: np.ndarray) -> tuple[float, float]:
|
||||
def ell2cart(self, beta: float | np.ndarray, lamb: float | np.ndarray) -> np.ndarray:
|
||||
"""
|
||||
Panou, Korakitis 2019 2f.
|
||||
Panou, Korakitis 2019 2
|
||||
:param beta: elliptische Breite [rad]
|
||||
:param lamb: elliptische Länge [rad]
|
||||
:return: Punkt in kartesischen Koordinaten
|
||||
"""
|
||||
beta = np.asarray(beta, dtype=float)
|
||||
lamb = np.asarray(lamb, dtype=float)
|
||||
|
||||
beta, lamb = np.broadcast_arrays(beta, lamb)
|
||||
|
||||
B = self.Ex ** 2 * cos(beta) ** 2 + self.Ee ** 2 * sin(beta) ** 2
|
||||
L = self.Ex ** 2 - self.Ee ** 2 * cos(lamb) ** 2
|
||||
|
||||
x = self.ax / self.Ex * sqrt(B) * cos(lamb)
|
||||
y = self.ay * cos(beta) * sin(lamb)
|
||||
z = self.b / self.Ex * sin(beta) * sqrt(L)
|
||||
|
||||
xyz = np.stack((x, y, z), axis=-1)
|
||||
|
||||
# Pole
|
||||
mask_south = beta == -pi / 2
|
||||
mask_north = beta == pi / 2
|
||||
xyz[mask_south] = np.array([0, 0, -self.b])
|
||||
xyz[mask_north] = np.array([0, 0, self.b])
|
||||
|
||||
# Äquator
|
||||
mask_eq = beta == 0
|
||||
xyz[mask_eq & (lamb == -pi / 2)] = np.array([0, -self.ay, 0])
|
||||
xyz[mask_eq & (lamb == pi / 2)] = np.array([0, self.ay, 0])
|
||||
xyz[mask_eq & (lamb == 0)] = np.array([self.ax, 0, 0])
|
||||
xyz[mask_eq & (lamb == pi)] = np.array([-self.ax, 0, 0])
|
||||
|
||||
return xyz
|
||||
|
||||
def ell2cart_bektas(self, beta: float | np.ndarray, omega: float | np.ndarray):
|
||||
"""
|
||||
Bektas 2015
|
||||
:param beta:
|
||||
:param omega:
|
||||
:return:
|
||||
"""
|
||||
x = self.ax * cos(omega) * sqrt((self.ax**2 - self.ay**2 * sin(beta)**2 - self.b**2 * cos(beta)**2) / (self.ax**2 - self.b**2))
|
||||
y = self.ay * cos(beta) * sin(omega)
|
||||
z = self.b * sin(beta) * sqrt((self.ax**2 * sin(omega)**2 + self.ay**2 * cos(omega)**2 - self.b**2) / (self.ax**2 - self.b**2))
|
||||
|
||||
return np.array([x, y, z])
|
||||
|
||||
def ell2cart_karney(self, beta: float | np.ndarray, lamb: float | np.ndarray) -> np.ndarray:
|
||||
"""
|
||||
Karney 2025 Geographic Lib
|
||||
:param beta:
|
||||
:param lamb:
|
||||
:return:
|
||||
"""
|
||||
e = sqrt(self.ax**2 - self.b**2) / self.ay
|
||||
k = sqrt(self.ay**2 - self.b**2) / sqrt(self.ax**2 - self.b**2)
|
||||
k_ = sqrt(self.ax**2 - self.ay**2) / sqrt(self.ax**2 - self.b**2)
|
||||
X = self.ax * cos(lamb) * sqrt(k**2*cos(beta)**2+k_**2)
|
||||
Y = self.ay * cos(beta) * sin(lamb)
|
||||
Z = self.b * sin(beta) * sqrt(k**2 + k_**2 * sin(lamb)**2)
|
||||
return np.array([X, Y, Z])
|
||||
|
||||
def cart2ell(self, point, eps=1e-12, maxI = 100) -> tuple[float, float]:
|
||||
"""
|
||||
Panou, Korakitis 2019 3f. (num)
|
||||
:param point:
|
||||
:param eps:
|
||||
:return:
|
||||
"""
|
||||
x, y, z = point
|
||||
beta, lamb = self.cart2ell_panou(point)
|
||||
delta_ell = np.array([np.inf, np.inf]).T
|
||||
|
||||
i = 0
|
||||
while np.sum(delta_ell) > eps and i < maxI:
|
||||
x0, y0, z0 = self.ell2cart(beta, lamb)
|
||||
delta_l = np.array([x-x0, y-y0, z-z0]).T
|
||||
|
||||
B = self.Ex ** 2 * cos(beta) ** 2 + self.Ee ** 2 * sin(beta) ** 2
|
||||
L = self.Ex ** 2 - self.Ee ** 2 * cos(lamb) ** 2
|
||||
|
||||
J = np.array([[(-self.ax * self.Ey ** 2) / (2 * self.Ex) * sin(2 * beta) / sqrt(B) * cos(lamb),
|
||||
-self.ax / self.Ex * sqrt(B) * sin(lamb)],
|
||||
[-self.ay * sin(beta) * sin(lamb),
|
||||
self.ay * cos(beta) * cos(lamb)],
|
||||
[self.b / self.Ex * cos(beta) * sqrt(L),
|
||||
(self.b * self.Ee ** 2) / (2 * self.Ex) * sin(beta) * sin(2 * lamb) / sqrt(L)]])
|
||||
|
||||
N = J.T @ J
|
||||
det = N[0,0] * N[1,1] - N[0,1] * N[1,0]
|
||||
if abs(det) < eps:
|
||||
det = eps
|
||||
N_inv = 1 / det * np.array([[N[1,1], -N[0,1]], [-N[1,0], N[0,0]]])
|
||||
delta_ell = N_inv @ J.T @ delta_l
|
||||
beta += delta_ell[0]
|
||||
lamb += delta_ell[1]
|
||||
i += 1
|
||||
|
||||
if i == maxI:
|
||||
raise Exception("Umrechung ist nicht konvergiert")
|
||||
|
||||
point_n = self.ell2cart(beta, lamb)
|
||||
delta_r = np.linalg.norm(point - point_n, axis=-1)
|
||||
|
||||
if delta_r > 1e-4:
|
||||
# raise Exception("Fehler in der Umrechnung cart2ell")
|
||||
print(f"Fehler in der Umrechnung cart2ell, deltaR = {delta_r}m")
|
||||
|
||||
return beta, lamb
|
||||
|
||||
def cart2ell_panou(self, point: np.ndarray) -> tuple[float, float]:
|
||||
"""
|
||||
Panou, Korakitis 2019 2f. (analytisch -> Näherung)
|
||||
:param point: Punkt in kartesischen Koordinaten
|
||||
:return: elliptische Breite, elliptische Länge
|
||||
"""
|
||||
@@ -280,18 +344,18 @@ class EllipsoidTriaxial:
|
||||
eps = 1e-9
|
||||
|
||||
if abs(x) < eps and abs(y) < eps: # Punkt in der z-Achse
|
||||
beta = np.pi / 2 if z > 0 else -np.pi / 2
|
||||
beta = pi / 2 if z > 0 else -pi / 2
|
||||
lamb = 0.0
|
||||
return beta, lamb
|
||||
|
||||
elif abs(x) < eps and abs(z) < eps: # Punkt in der y-Achse
|
||||
beta = 0.0
|
||||
lamb = np.pi / 2 if y > 0 else -np.pi / 2
|
||||
lamb = pi / 2 if y > 0 else -pi / 2
|
||||
return beta, lamb
|
||||
|
||||
elif abs(y) < eps and abs(z) < eps: # Punkt in der x-Achse
|
||||
beta = 0.0
|
||||
lamb = 0.0 if x > 0 else np.pi
|
||||
lamb = 0.0 if x > 0 else pi
|
||||
return beta, lamb
|
||||
|
||||
# ---- Allgemeiner Fall -----
|
||||
@@ -300,15 +364,18 @@ class EllipsoidTriaxial:
|
||||
c0 = (self.ax ** 2 * self.ay ** 2 + self.ax ** 2 * self.b ** 2 + self.ay ** 2 * self.b ** 2 -
|
||||
(self.ay ** 2 + self.b ** 2) * x ** 2 - (self.ax ** 2 + self.b ** 2) * y ** 2 - (
|
||||
self.ax ** 2 + self.ay ** 2) * z ** 2)
|
||||
t2 = (-c1 + np.sqrt(c1 ** 2 - 4 * c0)) / 2
|
||||
t2 = (-c1 + sqrt(c1 ** 2 - 4 * c0)) / 2
|
||||
if t2 == 0:
|
||||
t2 = 1e-14
|
||||
t1 = c0 / t2
|
||||
|
||||
num_beta = max(t1 - self.b ** 2, 0)
|
||||
den_beta = max(self.ay ** 2 - t1, 0)
|
||||
num_lamb = max(t2 - self.ay ** 2, 0)
|
||||
den_lamb = max(self.ax ** 2 - t2, 0)
|
||||
beta = np.arctan(np.sqrt(num_beta / den_beta))
|
||||
lamb = np.arctan(np.sqrt(num_lamb / den_lamb))
|
||||
|
||||
beta = arctan(sqrt(num_beta / den_beta))
|
||||
lamb = arctan(sqrt(num_lamb / den_lamb))
|
||||
|
||||
if z < 0:
|
||||
beta = -beta
|
||||
@@ -317,19 +384,62 @@ class EllipsoidTriaxial:
|
||||
lamb = -lamb
|
||||
|
||||
if x < 0:
|
||||
lamb = np.pi - lamb
|
||||
lamb = pi - lamb
|
||||
|
||||
if abs(x) < eps:
|
||||
lamb = -np.pi/2 if y < 0 else np.pi/2
|
||||
lamb = -pi/2 if y < 0 else pi/2
|
||||
|
||||
elif abs(y) < eps:
|
||||
lamb = 0 if x > 0 else np.pi
|
||||
lamb = 0 if x > 0 else pi
|
||||
|
||||
elif abs(z) < eps:
|
||||
beta = 0
|
||||
|
||||
return beta, lamb
|
||||
|
||||
def cart2ell_bektas(self, point, eps=1e-12, maxI = 100) -> tuple[float, float]:
|
||||
"""
|
||||
Bektas 2015
|
||||
:param point:
|
||||
:param eps:
|
||||
:param maxI:
|
||||
:return:
|
||||
"""
|
||||
x, y, z = point
|
||||
phi, lamb = self.cart2para(point)
|
||||
p = sqrt((self.ax**2 - self.ay**2) / (self.ax**2 - self.b**2))
|
||||
d_phi = np.inf
|
||||
d_lamb = np.inf
|
||||
|
||||
i = 0
|
||||
while d_phi > eps and d_lamb > eps and i < maxI:
|
||||
lamb_new = arctan2(self.ax * y * sqrt((p**2-1) * sin(phi)**2 + 1), self.ay * x * cos(phi))
|
||||
phi_new = arctan2(self.ay * z * sin(lamb), self.b * y * sqrt(1 - p**2 * cos(lamb)**2))
|
||||
d_phi = abs(phi_new - phi)
|
||||
phi = phi_new
|
||||
d_lamb = abs(lamb_new - lamb)
|
||||
lamb = lamb_new
|
||||
i += 1
|
||||
|
||||
if i == maxI:
|
||||
raise Exception("Umrechung ist nicht konvergiert")
|
||||
|
||||
return phi, lamb
|
||||
|
||||
def geod2cart(self, phi: float | np.ndarray, lamb: float | np.ndarray, h: float) -> np.ndarray:
|
||||
"""
|
||||
Ligas 2012, 250
|
||||
:param phi: geodätische Breite [rad]
|
||||
:param lamb: geodätische Länge [rad]
|
||||
:param h: Höhe über dem Ellipsoid
|
||||
:return: kartesische Koordinaten
|
||||
"""
|
||||
v = self.ax / sqrt(1 - self.ex**2*sin(phi)**2-self.ee**2*cos(phi)**2*sin(lamb)**2)
|
||||
xG = (v + h) * cos(phi) * cos(lamb)
|
||||
yG = (v * (1-self.ee**2) + h) * cos(phi) * sin(lamb)
|
||||
zG = (v * (1-self.ex**2) + h) * sin(phi)
|
||||
return np.array([xG, yG, zG])
|
||||
|
||||
def cart2geod(self, point: np.ndarray, mode: str = "ligas3", maxIter: int = 30, maxLoa: float = 0.005) -> tuple[float, float, float]:
|
||||
"""
|
||||
Ligas 2012
|
||||
@@ -344,24 +454,24 @@ class EllipsoidTriaxial:
|
||||
eps = 1e-9
|
||||
|
||||
if abs(xG) < eps and abs(yG) < eps: # Punkt in der z-Achse
|
||||
phi = np.pi / 2 if zG > 0 else -np.pi / 2
|
||||
phi = pi / 2 if zG > 0 else -pi / 2
|
||||
lamb = 0.0
|
||||
h = abs(zG) - self.b
|
||||
return phi, lamb, h
|
||||
|
||||
elif abs(xG) < eps and abs(zG) < eps: # Punkt in der y-Achse
|
||||
phi = 0.0
|
||||
lamb = np.pi / 2 if yG > 0 else -np.pi / 2
|
||||
lamb = pi / 2 if yG > 0 else -pi / 2
|
||||
h = abs(yG) - self.ay
|
||||
return phi, lamb, h
|
||||
|
||||
elif abs(yG) < eps and abs(zG) < eps: # Punkt in der x-Achse
|
||||
phi = 0.0
|
||||
lamb = 0.0 if xG > 0 else np.pi
|
||||
lamb = 0.0 if xG > 0 else pi
|
||||
h = abs(xG) - self.ax
|
||||
return phi, lamb, h
|
||||
|
||||
rG = np.sqrt(xG ** 2 + yG ** 2 + zG ** 2)
|
||||
rG = sqrt(xG ** 2 + yG ** 2 + zG ** 2)
|
||||
pE = np.array([self.ax * xG / rG, self.ax * yG / rG, self.ax * zG / rG], dtype=np.float64)
|
||||
|
||||
E = 1 / self.ax**2
|
||||
@@ -380,38 +490,98 @@ class EllipsoidTriaxial:
|
||||
invJ, fxE = jacobian_Ligas.case3(E, F, G, np.array([xG, yG, zG]), pE)
|
||||
pEi = pE.reshape(-1, 1) - invJ @ fxE.reshape(-1, 1)
|
||||
pEi = pEi.reshape(1, -1).flatten()
|
||||
loa = np.sqrt((pEi[0]-pE[0])**2 + (pEi[1]-pE[1])**2 + (pEi[2]-pE[2])**2)
|
||||
loa = sqrt((pEi[0]-pE[0])**2 + (pEi[1]-pE[1])**2 + (pEi[2]-pE[2])**2)
|
||||
pE = pEi
|
||||
i += 1
|
||||
|
||||
phi = np.arctan((1-self.ee**2) / (1-self.ex**2) * pE[2] / np.sqrt((1-self.ee**2)**2 * pE[0]**2 + pE[1]**2))
|
||||
lamb = np.arctan(1/(1-self.ee**2) * pE[1]/pE[0])
|
||||
h = np.sign(zG - pE[2]) * np.sign(pE[2]) * np.sqrt((pE[0] - xG) ** 2 + (pE[1] - yG) ** 2 + (pE[2] - zG) ** 2)
|
||||
phi = arctan((1-self.ee**2) / (1-self.ex**2) * pE[2] / sqrt((1-self.ee**2)**2 * pE[0]**2 + pE[1]**2))
|
||||
lamb = arctan(1/(1-self.ee**2) * pE[1]/pE[0])
|
||||
h = np.sign(zG - pE[2]) * np.sign(pE[2]) * sqrt((pE[0] - xG) ** 2 + (pE[1] - yG) ** 2 + (pE[2] - zG) ** 2)
|
||||
|
||||
if xG < 0 and yG < 0:
|
||||
lamb = -np.pi + lamb
|
||||
lamb = -pi + lamb
|
||||
|
||||
elif xG < 0:
|
||||
lamb = np.pi + lamb
|
||||
lamb = pi + lamb
|
||||
|
||||
if abs(zG) < eps:
|
||||
phi = 0
|
||||
|
||||
return phi, lamb, h
|
||||
|
||||
def geod2cart(self, phi: float | np.ndarray, lamb: float | np.ndarray, h: float) -> np.ndarray:
|
||||
def para2cart(self, u: float | np.ndarray, v: float | np.ndarray) -> np.ndarray:
|
||||
"""
|
||||
Ligas 2012, 250
|
||||
:param phi: geodätische Breite [rad]
|
||||
:param lamb: geodätische Länge [rad]
|
||||
:param h: Höhe über dem Ellipsoid
|
||||
:return: kartesische Koordinaten
|
||||
Panou, Korakitits 2020, 4
|
||||
:param u: Parameter u
|
||||
:param v: Parameter v
|
||||
:return: Punkt in kartesischen Koordinaten
|
||||
"""
|
||||
v = self.ax / np.sqrt(1 - self.ex**2*np.sin(phi)**2-self.ee**2*np.cos(phi)**2*np.sin(lamb)**2)
|
||||
xG = (v + h) * np.cos(phi) * np.cos(lamb)
|
||||
yG = (v * (1-self.ee**2) + h) * np.cos(phi) * np.sin(lamb)
|
||||
zG = (v * (1-self.ex**2) + h) * np.sin(phi)
|
||||
return np.array([xG, yG, zG])
|
||||
x = self.ax * cos(u) * cos(v)
|
||||
y = self.ay * cos(u) * sin(v)
|
||||
z = self.b * sin(u)
|
||||
z = np.broadcast_to(z, np.shape(x))
|
||||
return np.array([x, y, z])
|
||||
|
||||
def cart2para(self, point: np.ndarray) -> tuple[float, float]:
|
||||
"""
|
||||
Panou, Korakitits 2020, 4
|
||||
:param point: Punkt in kartesischen Koordinaten
|
||||
:return: parametrische Koordinaten
|
||||
"""
|
||||
x, y, z = point
|
||||
|
||||
u_check1 = z*sqrt(1 - self.ee**2)
|
||||
u_check2 = sqrt(x**2 * (1-self.ee**2) + y**2) * sqrt(1-self.ex**2)
|
||||
if u_check1 <= u_check2:
|
||||
u = arctan2(u_check1, u_check2)
|
||||
else:
|
||||
u = pi/2 - arctan2(u_check2, u_check1)
|
||||
|
||||
v_check1 = y
|
||||
v_check2 = x*sqrt(1-self.ee**2)
|
||||
v_factor = sqrt(x**2*(1-self.ee**2)+y**2)
|
||||
if v_check1 <= v_check2:
|
||||
v = 2 * arctan2(v_check1, v_check2 + v_factor)
|
||||
else:
|
||||
v = pi/2 - 2 * arctan2(v_check2, v_check1 + v_factor)
|
||||
|
||||
return u, v
|
||||
|
||||
def ell2para(self, beta: float, lamb: float) -> tuple[float, float]:
|
||||
cart = self.ell2cart(beta, lamb)
|
||||
return self.cart2para(cart)
|
||||
|
||||
def para2ell(self, u: float, v: float) -> tuple[float, float]:
|
||||
cart = self.para2cart(u, v)
|
||||
return self.cart2ell(cart)
|
||||
|
||||
def para2geod(self, u: float, v: float, mode: str = "ligas3", maxIter: int = 30, maxLoa: float = 0.005) -> tuple[float, float, float]:
|
||||
cart = self.para2cart(u, v)
|
||||
return self.cart2geod(cart, mode, maxIter, maxLoa)
|
||||
|
||||
def geod2para(self, phi: float, lamb: float, h: float) -> tuple[float, float]:
|
||||
cart = self.geod2cart(phi, lamb, h)
|
||||
return self.cart2para(cart)
|
||||
|
||||
def ell2geod(self, beta: float, lamb: float, mode: str = "ligas3", maxIter: int = 30, maxLoa: float = 0.005) -> tuple[float, float, float]:
|
||||
cart = self.ell2cart(beta, lamb)
|
||||
return self.cart2geod(cart, mode, maxIter, maxLoa)
|
||||
|
||||
def geod2ell(self, phi: float, lamb: float, h: float) -> tuple[float, float]:
|
||||
cart = self.geod2cart(phi, lamb, h)
|
||||
return self.cart2ell(cart)
|
||||
|
||||
def point_on(self, point: np.ndarray) -> bool:
|
||||
"""
|
||||
Test, ob ein Punkt auf dem Ellipsoid liegt.
|
||||
:param point: kartesische 3D-Koordinaten
|
||||
:return: Punkt auf dem Ellispoid?
|
||||
"""
|
||||
value = point[0]**2/self.ax**2 + point[1]**2/self.ay**2 + point[2]**2/self.b**2
|
||||
if abs(1-value) < 1e-6:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def cartonell(self, point: np.ndarray) -> tuple[np.ndarray, float, float, float]:
|
||||
"""
|
||||
@@ -434,144 +604,64 @@ class EllipsoidTriaxial:
|
||||
pointH = self. geod2cart(phi, lamb, h)
|
||||
return pointH
|
||||
|
||||
def para2cart(self, u: float | np.ndarray, v: float | np.ndarray) -> np.ndarray:
|
||||
"""
|
||||
Panou, Korakitits 2020, 4
|
||||
:param u: Parameter u
|
||||
:param v: Parameter v
|
||||
:return: Punkt in kartesischen Koordinaten
|
||||
"""
|
||||
x = self.ax * np.cos(u) * np.cos(v)
|
||||
y = self.ay * np.cos(u) * np.sin(v)
|
||||
z = self.b * np.sin(u)
|
||||
z = np.broadcast_to(z, np.shape(x))
|
||||
return np.array([x, y, z])
|
||||
|
||||
def cart2para(self, point: np.ndarray) -> tuple[float, float]:
|
||||
"""
|
||||
Panou, Korakitits 2020, 4
|
||||
:param point: Punkt in kartesischen Koordinaten
|
||||
:return: parametrische Koordinaten
|
||||
"""
|
||||
x, y, z = point
|
||||
|
||||
u_check1 = z*np.sqrt(1 - self.ee**2)
|
||||
u_check2 = np.sqrt(x**2 * (1-self.ee**2) + y**2) * np.sqrt(1-self.ex**2)
|
||||
if u_check1 <= u_check2:
|
||||
u = np.arctan2(u_check1, u_check2)
|
||||
else:
|
||||
u = np.pi/2 - np.arctan2(u_check2, u_check1)
|
||||
|
||||
v_check1 = y
|
||||
v_check2 = x*np.sqrt(1-self.ee**2)
|
||||
v_factor = np.sqrt(x**2*(1-self.ee**2)+y**2)
|
||||
if v_check1 <= v_check2:
|
||||
v = 2 * np.arctan2(v_check1, v_check2 + v_factor)
|
||||
else:
|
||||
v = np.pi/2 - 2 * np.arctan2(v_check2, v_check1 + v_factor)
|
||||
|
||||
return u, v
|
||||
|
||||
def ell2para(self, beta, lamb) -> tuple[float, float]:
|
||||
cart = self.ell2cart(beta, lamb)
|
||||
return self.cart2para(cart)
|
||||
|
||||
def para2ell(self, u, v) -> tuple[float, float]:
|
||||
cart = self.para2cart(u, v)
|
||||
return self.cart2ell(cart)
|
||||
|
||||
def para2geod(self, u: float, v: float, mode: str = "ligas3", maxIter: int = 30, maxLoa: float = 0.005) -> tuple[float, float, float]:
|
||||
cart = self.para2cart(u, v)
|
||||
return self.cart2geod(cart, mode, maxIter, maxLoa)
|
||||
|
||||
def geod2para(self, phi, lamb, h) -> tuple[float, float]:
|
||||
cart = self.geod2cart(phi, lamb, h)
|
||||
return self.cart2para(cart)
|
||||
|
||||
def ell2geod(self, beta, lamb, mode: str = "ligas3", maxIter: int = 30, maxLoa: float = 0.005) -> tuple[float, float, float]:
|
||||
cart = self.ell2cart(beta, lamb)
|
||||
return self.cart2geod(cart, mode, maxIter, maxLoa)
|
||||
|
||||
def func_H(self, x, y, z):
|
||||
return x ** 2 + y ** 2 / (1 - self.ee ** 2) ** 2 + z ** 2 / (1 - self.ex ** 2) ** 2
|
||||
|
||||
def func_n(self, x, y, z, H=None):
|
||||
if H is None:
|
||||
H = self.func_H(x, y, z)
|
||||
return np.array([x / sqrt(H),
|
||||
y / ((1 - self.ee ** 2) * sqrt(H)),
|
||||
z / ((1 - self.ex ** 2) * sqrt(H))])
|
||||
|
||||
def p_q(self, x, y, z) -> tuple[np.ndarray, np.ndarray]:
|
||||
"""
|
||||
Berechnung sämtlicher Größen
|
||||
:param x: x
|
||||
:param y: y
|
||||
:param z: z
|
||||
:return: Dictionary sämtlicher Größen
|
||||
"""
|
||||
n = self.func_n(x, y, z)
|
||||
|
||||
beta, lamb = self.cart2ell(np.array([x, y, z]))
|
||||
B = self.Ex ** 2 * np.cos(beta) ** 2 + self.Ee ** 2 * np.sin(beta) ** 2
|
||||
L = self.Ex ** 2 - self.Ee ** 2 * np.cos(lamb) ** 2
|
||||
|
||||
c1 = x ** 2 + y ** 2 + z ** 2 - (self.ax ** 2 + self.ay ** 2 + self.b ** 2)
|
||||
c0 = (self.ax ** 2 * self.ay ** 2 + self.ax ** 2 * self.b ** 2 + self.ay ** 2 * self.b ** 2 -
|
||||
(self.ay ** 2 + self.b ** 2) * x ** 2 - (self.ax ** 2 + self.b ** 2) * y ** 2 - (
|
||||
self.ax ** 2 + self.ay ** 2) * z ** 2)
|
||||
t2 = (-c1 + np.sqrt(c1 ** 2 - 4 * c0)) / 2
|
||||
t1 = c0 / t2
|
||||
t2e = self.ax ** 2 * np.sin(lamb) ** 2 + self.ay ** 2 * np.cos(lamb) ** 2
|
||||
t1e = self.ay ** 2 * np.sin(beta) ** 2 + self.b ** 2 * np.cos(beta) ** 2
|
||||
|
||||
F = self.Ey ** 2 * np.cos(beta) ** 2 + self.Ee ** 2 * np.sin(lamb) ** 2
|
||||
p1 = -np.sqrt(L / (F * t2)) * self.ax / self.Ex * np.sqrt(B) * np.sin(lamb)
|
||||
p2 = np.sqrt(L / (F * t2)) * self.ay * np.cos(beta) * np.cos(lamb)
|
||||
p3 = 1 / np.sqrt(F * t2) * (self.b * self.Ee ** 2) / (2 * self.Ex) * np.sin(beta) * np.sin(2 * lamb)
|
||||
# p1 = -np.sign(y) * np.sqrt(L / (F * t2)) * self.ax / (self.Ex * self.Ee) * np.sqrt(B) * np.sqrt(t2 - self.ay ** 2)
|
||||
# p2 = np.sign(x) * np.sqrt(L / (F * t2)) * self.ay / (self.Ey * self.Ee) * np.sqrt((ell.ay ** 2 - t1) * (self.ax ** 2 - t2))
|
||||
# p3 = np.sign(x) * np.sign(y) * np.sign(z) * 1 / np.sqrt(F * t2) * self.b / (self.Ex * self.Ey) * np.sqrt(
|
||||
# (t1 - self.b ** 2) * (t2 - self.ay ** 2) * (self.ax ** 2 - t2))
|
||||
p = np.array([p1, p2, p3])
|
||||
q = np.array([n[1] * p[2] - n[2] * p[1],
|
||||
n[2] * p[0] - n[0] * p[2],
|
||||
n[0] * p[1] - n[1] * p[0]])
|
||||
|
||||
return p, q
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
ell = EllipsoidTriaxial.init_name("Eitschberger1978")
|
||||
ell = EllipsoidTriaxial.init_name("BursaSima1980round")
|
||||
diff_list = []
|
||||
for beta_deg in range(-150, 210, 30):
|
||||
for lamb_deg in range(-150, 210, 30):
|
||||
beta = wu.deg2rad(beta_deg)
|
||||
lamb = wu.deg2rad(lamb_deg)
|
||||
point = ell.ell2cart(beta, lamb)
|
||||
diffs_para = []
|
||||
diffs_ell = []
|
||||
diffs_geod = []
|
||||
points = []
|
||||
for v_deg in range(-180, 181, 5):
|
||||
for u_deg in range(-90, 91, 5):
|
||||
v = wu.deg2rad(v_deg)
|
||||
u = wu.deg2rad(u_deg)
|
||||
point = ell.para2cart(u, v)
|
||||
points.append(point)
|
||||
|
||||
elli = ell.cart2ell(point)
|
||||
cart_elli = ell.ell2cart(elli[0], elli[1])
|
||||
diff_ell = np.sum(np.abs(point-cart_elli))
|
||||
diff_ell = np.linalg.norm(point - cart_elli, axis=-1)
|
||||
|
||||
para = ell.cart2para(point)
|
||||
cart_para = ell.para2cart(para[0], para[1])
|
||||
diff_para = np.sum(np.abs(point-cart_para))
|
||||
|
||||
# geod = ell.cart2geod(point, "ligas1")
|
||||
# cart_geod = ell.geod2cart(geod[0], geod[1], geod[2])
|
||||
# diff_geod1 = np.sum(np.abs(point-cart_geod))
|
||||
#
|
||||
# geod = ell.cart2geod(point, "ligas2")
|
||||
# cart_geod = ell.geod2cart(geod[0], geod[1], geod[2])
|
||||
# diff_geod2 = np.sum(np.abs(point-cart_geod))
|
||||
diff_para = np.linalg.norm(point - cart_para, axis=-1)
|
||||
|
||||
geod = ell.cart2geod(point, "ligas3")
|
||||
cart_geod = ell.geod2cart(geod[0], geod[1], geod[2])
|
||||
diff_geod3 = np.sum(np.abs(point-cart_geod))
|
||||
diff_geod3 = np.linalg.norm(point - cart_geod, axis=-1)
|
||||
|
||||
diff_list.append([beta_deg, lamb_deg, diff_ell, diff_para, diff_geod3])
|
||||
diff_list.append([diff_ell])
|
||||
diff_list.append([v_deg, u_deg, diff_ell, diff_para, diff_geod3]) #
|
||||
diffs_ell.append([diff_ell])
|
||||
diffs_para.append([diff_para])
|
||||
diffs_geod.append([diff_geod3])
|
||||
|
||||
diff_list = np.array(diff_list)
|
||||
pass
|
||||
diffs_ell = np.array(diffs_ell)
|
||||
diffs_para = np.array(diffs_para)
|
||||
diffs_geod = np.array(diffs_geod)
|
||||
|
||||
pass
|
||||
points = np.array(points)
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(projection='3d')
|
||||
|
||||
sc = ax.scatter(
|
||||
points[:, 0],
|
||||
points[:, 1],
|
||||
points[:, 2],
|
||||
c=diffs_ell, # Farbcode = diff
|
||||
cmap='viridis', # Colormap
|
||||
s=10 + 20 * diffs_ell, # optional: Größe abhängig vom diff
|
||||
alpha=0.8
|
||||
)
|
||||
|
||||
# Farbskala
|
||||
cbar = plt.colorbar(sc)
|
||||
cbar.set_label("diff")
|
||||
|
||||
ax.set_xlabel("X")
|
||||
ax.set_ylabel("Y")
|
||||
ax.set_zlabel("Z")
|
||||
|
||||
plt.show()
|
||||
Reference in New Issue
Block a user