This commit is contained in:
2026-02-06 15:49:36 +01:00
parent 0eeb35f173
commit 50326ba246
5 changed files with 2042 additions and 206 deletions

View File

@@ -8,8 +8,7 @@ from GHA_triaxial.gha2_num import gha2_num
from GHA_triaxial.utils import sigma2alpha, pq_ell
P_left: NDArray = None
P_right: NDArray = None
def Sehne(P1: NDArray, P2: NDArray) -> float:
@@ -25,34 +24,10 @@ def Sehne(P1: NDArray, P2: NDArray) -> float:
return s
def midpoint_fitness(x: tuple) -> float:
"""
Fitness für einen Mittelpunkt P_middle zwischen P_left und P_right auf dem triaxialen Ellipsoid:
- Minimiert d(P_left, P_middle) + d(P_middle, P_right)
- Erzwingt d(P_left,P_middle) ≈ d(P_middle,P_right) (echter Mittelpunkt im Sinne der Polygonkette)
:param x: enthält die Startwerte von u und v
:return: Fitnesswert (f)
"""
global P_left, P_right
u, v = x
P_middle = ell.para2cart(u, v)
d1 = Sehne(P_left, P_middle)
d2 = Sehne(P_middle, P_right)
base = d1 + d2
# midpoint penalty (dimensionslos)
# relative Differenz, skaliert über verschiedene Segmentlängen
denom = max(base, 1e-9)
pen_equal = ((d1 - d2) / denom) ** 2
w_equal = 10.0
f = base + denom * w_equal * pen_equal
return f
def gha2_ES(ell: EllipsoidTriaxial, P0: NDArray, Pk: NDArray, maxSegLen: float = None, all_points: bool = True) -> Tuple[float, float, float, NDArray]:
def gha2_ES(ell: EllipsoidTriaxial, P0: NDArray, Pk: NDArray, maxSegLen: float = None, all_points: bool = False) -> Tuple[float, float, float, NDArray] | Tuple[float, float, float]:
"""
Berechnen der 2. GHA mithilfe der CMA-ES.
Die CMA-ES optimiert sukzessive den Mittelpunkt zwischen Start- und Zielpunkt. Der Abbruch der Berechnung erfolgt, wenn alle Segmentlängen <= maxSegLen sind.
@@ -64,6 +39,35 @@ def gha2_ES(ell: EllipsoidTriaxial, P0: NDArray, Pk: NDArray, maxSegLen: float =
:param all_points: Ergebnisliste mit allen Punkte, die wahlweise mit ausgegeben wird
:return: Richtungswinkel in RAD des Start- und Zielpunktes und Gesamtlänge
"""
P_left: NDArray = None
P_right: NDArray = None
def midpoint_fitness(x: tuple) -> float:
"""
Fitness für einen Mittelpunkt P_middle zwischen P_left und P_right auf dem triaxialen Ellipsoid:
- Minimiert d(P_left, P_middle) + d(P_middle, P_right)
- Erzwingt d(P_left,P_middle) ≈ d(P_middle,P_right) (echter Mittelpunkt im Sinne der Polygonkette)
:param x: enthält die Startwerte von u und v
:return: Fitnesswert (f)
"""
nonlocal P_left, P_right, ell
u, v = x
P_middle = ell.para2cart(u, v)
d1 = Sehne(P_left, P_middle)
d2 = Sehne(P_middle, P_right)
base = d1 + d2
# midpoint penalty (dimensionslos)
# relative Differenz, skaliert über verschiedene Segmentlängen
denom = max(base, 1e-9)
pen_equal = ((d1 - d2) / denom) ** 2
w_equal = 10.0
f = base + denom * w_equal * pen_equal
return f
R0 = (ell.ax + ell.ay + ell.b) / 3
if maxSegLen is None:
maxSegLen = R0 * 1 / (637.4*2) # 10km Segment bei mittleren Erdradius
@@ -85,10 +89,10 @@ def gha2_ES(ell: EllipsoidTriaxial, P0: NDArray, Pk: NDArray, maxSegLen: float =
A = points[i]
B = points[i+1]
dAB = Sehne(A, B)
print(dAB)
# print(dAB)
if dAB > maxSegLen:
global P_left, P_right
# global P_left, P_right
P_left, P_right = A, B
Au, Av = ell.cart2para(A)
Bu, Bv = ell.cart2para(B)
@@ -109,7 +113,7 @@ def gha2_ES(ell: EllipsoidTriaxial, P0: NDArray, Pk: NDArray, maxSegLen: float =
new_points.append(B)
points = new_points
print(f"[Level {level}] Punkte: {len(points)} | max Segment: {max_len:.3f} m")
# print(f"[Level {level}] Punkte: {len(points)} | max Segment: {max_len:.3f} m")
P_all = np.vstack(points)
totalLen = float(np.sum(np.linalg.norm(P_all[1:] - P_all[:-1], axis=1)))