GHA1 ES mit Linie, Legende

This commit is contained in:
Tammo.Weber
2026-02-06 15:06:48 +01:00
parent 2954c0ee3a
commit 0eeb35f173

View File

@@ -27,7 +27,7 @@ from GHA_triaxial.gha2_approx import gha2_approx
def _no_print(*args, **kwargs): def _no_print(*args, **kwargs):
pass pass
builtins.print = _no_print #builtins.print = _no_print
# Bootstrap (CSS) einbindung # Bootstrap (CSS) einbindung
@@ -290,6 +290,7 @@ pane_gha1 = html.Div(
html.Div(id="tabs-GHA1-out", style={"marginBottom": "10px"}), html.Div(id="tabs-GHA1-out", style={"marginBottom": "10px"}),
html.Div(id="gha1-header"),
dcc.Loading(html.Div(id="output-gha1-ana")), dcc.Loading(html.Div(id="output-gha1-ana")),
dcc.Loading(html.Div(id="output-gha1-num")), dcc.Loading(html.Div(id="output-gha1-num")),
dcc.Loading(html.Div(id="output-gha1-stoch")), dcc.Loading(html.Div(id="output-gha1-stoch")),
@@ -331,6 +332,7 @@ pane_gha2 = html.Div(
html.Div(id="tabs-GHA2-out", style={"marginBottom": "10px"}), html.Div(id="tabs-GHA2-out", style={"marginBottom": "10px"}),
html.Div(id="gha2-header"),
dcc.Loading(html.Div(id="output-gha2-num")), dcc.Loading(html.Div(id="output-gha2-num")),
dcc.Loading(html.Div(id="output-gha2-stoch")), dcc.Loading(html.Div(id="output-gha2-stoch")),
dcc.Loading(html.Div(id="output-gha2-approx")), dcc.Loading(html.Div(id="output-gha2-approx")),
@@ -460,7 +462,6 @@ def fill_inputs_from_dropdown(selected_ell):
if not selected_ell: if not selected_ell:
return None, None, None return None, None, None
ell = EllipsoidTriaxial.init_name(selected_ell) ell = EllipsoidTriaxial.init_name(selected_ell)
ax = ell.ax ax = ell.ax
ay = ell.ay ay = ell.ay
@@ -562,23 +563,17 @@ def gha1_method_hint(n, a, nu, st, ap):
prevent_initial_call=True, prevent_initial_call=True,
) )
def compute_gha1_ana(n1, cb_ana, n_in, beta0, lamb0, s, a0, ax, ay, b): def compute_gha1_ana(n1, cb_ana, n_in, beta0, lamb0, s, a0, ax, ay, b):
out = html.Div([
html.H4("Erste Hauptaufgabe"),
])
n_in = int(n_in) if n_in else 70
if not n1: if not n1:
return no_update, no_update return no_update, no_update
if None in (ax, ay, b): if None in (ax, ay, b):
return html.Span("Bitte Ellipsoid wählen.", style={"color": "red"}), None return html.Span("Bitte Ellipsoid wählen.", style={"color": "red"}), None
if None in (beta0, lamb0, s, a0): if None in (beta0, lamb0, s, a0):
return html.Span("Bitte β₀, λ₀, s und α₀ eingeben.", style={"color": "red"}), None return html.Span("Bitte β₀, λ₀, s und α₀ eingeben.", style={"color": "red"}), None
#if not method1:
#return html.Span("Bitte Berechnungsverfahren wählen.", style={"color": "red"}), None
if "on" not in (cb_ana or []): if "on" not in (cb_ana or []):
return "", None return "", None
n_in = int(n_in) if n_in else 70
ell = EllipsoidTriaxial(ax, ay, b) ell = EllipsoidTriaxial(ax, ay, b)
beta_rad = wu.deg2rad(float(beta0)) beta_rad = wu.deg2rad(float(beta0))
lamb_rad = wu.deg2rad(float(lamb0)) lamb_rad = wu.deg2rad(float(lamb0))
@@ -590,7 +585,6 @@ def compute_gha1_ana(n1, cb_ana, n_in, beta0, lamb0, s, a0, ax, ay, b):
beta2_ana, lamb2_ana = ell.cart2ell(P1_ana) beta2_ana, lamb2_ana = ell.cart2ell(P1_ana)
out = html.Div([ out = html.Div([
html.H4("Erste Hauptaufgabe"),
html.Strong("Analytisch: "), html.Strong("Analytisch: "),
html.Br(), html.Br(),
html.Span(f"kartesisch: x₁={P1_ana[0]:.4f} m, y₁={P1_ana[1]:.4f} m, z₁={P1_ana[2]:.4f} m"), html.Span(f"kartesisch: x₁={P1_ana[0]:.4f} m, y₁={P1_ana[1]:.4f} m, z₁={P1_ana[2]:.4f} m"),
@@ -602,6 +596,7 @@ def compute_gha1_ana(n1, cb_ana, n_in, beta0, lamb0, s, a0, ax, ay, b):
store = { store = {
"points": [("P0", P0, "black"), ("P1 (ana)", P1_ana, "red")], "points": [("P0", P0, "black"), ("P1 (ana)", P1_ana, "red")],
"polyline": None, "polyline": None,
"name": "Analytisch",
"color": "red" "color": "red"
} }
return out, store return out, store
@@ -654,6 +649,7 @@ def compute_gha1_num(n1, cb_num, n_in, beta0, lamb0, s, a0, ax, ay, b):
store = { store = {
"points": [("P0", P0, "black"), ("P1 (num)", P1_num, "#ff8c00")], "points": [("P0", P0, "black"), ("P1 (num)", P1_num, "#ff8c00")],
"polyline": polyline, "polyline": polyline,
"name": "Numerisch",
"color": "#ff8c00" "color": "#ff8c00"
} }
return out, store return out, store
@@ -687,7 +683,7 @@ def compute_gha1_stoch(n1, cb_stoch, n_in, beta0, lamb0, s, a0, ax, ay, b):
alpha_rad = wu.deg2rad(float(a0)) alpha_rad = wu.deg2rad(float(a0))
s_val = float(s) s_val = float(s)
P1_stoch, alpha = gha1_ES(ell, beta0=beta_rad, omega0=lamb_rad, alpha0=alpha_rad, s_total=s_val, maxSegLen=n_in) P1_stoch, alpha, points = gha1_ES(ell, beta0=beta_rad, omega0=lamb_rad, alpha0=alpha_rad, s_total=s_val, maxSegLen=n_in)
P0 = ell.ell2cart(beta_rad, lamb_rad) P0 = ell.ell2cart(beta_rad, lamb_rad)
beta1_stoch, lamb1_stoch = ell.cart2ell(P1_stoch) beta1_stoch, lamb1_stoch = ell.cart2ell(P1_stoch)
@@ -701,9 +697,10 @@ def compute_gha1_stoch(n1, cb_stoch, n_in, beta0, lamb0, s, a0, ax, ay, b):
]) ])
store = { store = {
"points": [("P0", P0, "black"), ("P1 (ES)", P1_stoch, "#d62728")], "points": [("P0", P0, "black"), ("P1 (ES)", P1_stoch, "#1fa342")],
"polyline": None, "polyline": points,
"color": "#d62728" "name": "Stochastisch (ES)",
"color": "#1fa342"
} }
return out, store return out, store
@@ -752,6 +749,7 @@ def compute_gha1_approx(n1, cb_approx, ds_in, beta0, lamb0, s, a0, ax, ay, b):
store = { store = {
"points": [("P0", P0, "black"), ("P1 (approx)", P1_app, "#00c2fc")], "points": [("P0", P0, "black"), ("P1 (approx)", P1_app, "#00c2fc")],
"polyline": points, "polyline": points,
"name": "Approximiert",
"color": "#00c2fc" "color": "#00c2fc"
} }
return out, store return out, store
@@ -774,9 +772,6 @@ def compute_gha1_approx(n1, cb_approx, ds_in, beta0, lamb0, s, a0, ax, ay, b):
prevent_initial_call=True, prevent_initial_call=True,
) )
def compute_gha2_num(n2, cb_num, n_in, beta0, lamb0, beta1, lamb1, ax, ay, b): def compute_gha2_num(n2, cb_num, n_in, beta0, lamb0, beta1, lamb1, ax, ay, b):
out = html.Div([
html.H4("Zweite Hauptaufgabe"),
])
if not n2: if not n2:
return no_update, no_update return no_update, no_update
if None in (ax, ay, b): if None in (ax, ay, b):
@@ -806,7 +801,6 @@ def compute_gha2_num(n2, cb_num, n_in, beta0, lamb0, beta1, lamb1, ax, ay, b):
polyline.append([float(x), float(y), float(z)]) polyline.append([float(x), float(y), float(z)])
out = html.Div([ out = html.Div([
html.H4("Zweite Hauptaufgabe"),
html.Strong("Numerisch: "), html.Strong("Numerisch: "),
html.Span(f"{aus.gms('α₀', a0_num, 4)}, {aus.gms('α₁', a1_num, 4)}, s = {s_num:.4f} m"), html.Span(f"{aus.gms('α₀', a0_num, 4)}, {aus.gms('α₁', a1_num, 4)}, s = {s_num:.4f} m"),
]) ])
@@ -814,7 +808,7 @@ def compute_gha2_num(n2, cb_num, n_in, beta0, lamb0, beta1, lamb1, ax, ay, b):
store = { store = {
"points": [("P0", P0, "black"), ("P1", P1, "black")], "points": [("P0", P0, "black"), ("P1", P1, "black")],
"polyline": polyline, "polyline": polyline,
"name": "numerisch", "name": "Numerisch",
"color": "#ff8c00", "color": "#ff8c00",
} }
return out, store return out, store
@@ -852,7 +846,8 @@ def compute_gha2_stoch(n2, cb_stoch, n_in, beta0, lamb0, beta1, lamb1, ax, ay, b
P0 = ell.ell2cart(beta0_rad, lamb0_rad) P0 = ell.ell2cart(beta0_rad, lamb0_rad)
P1 = ell.ell2cart(beta1_rad, lamb1_rad) P1 = ell.ell2cart(beta1_rad, lamb1_rad)
a0_stoch, a1_stoch, s_stoch, points = gha2_ES(ell, P0, P1, maxSegLen=n_in, all_points=True) #a0_stoch, a1_stoch, s_stoch, points = gha2_ES(ell, P0, P1, maxSegLen=n_in, all_points=True)
a0_stoch, a1_stoch, s_stoch, points = gha2_ES(ell, P0, P1)
out = html.Div([ out = html.Div([
html.Strong("Stochastisch (ES): "), html.Strong("Stochastisch (ES): "),
@@ -862,8 +857,8 @@ def compute_gha2_stoch(n2, cb_stoch, n_in, beta0, lamb0, beta1, lamb1, ax, ay, b
store = { store = {
"points": [("P0", P0, "black"), ("P1", P1, "black")], "points": [("P0", P0, "black"), ("P1", P1, "black")],
"polyline": points, "polyline": points,
"name": "stochastisch (ES)", "name": "Stochastisch (ES)",
"color": "#d62728", "color": "#1fa342",
} }
return out, store return out, store
@@ -911,7 +906,7 @@ def compute_gha2_approx(n2, cb_approx, ds_in, beta0, lamb0, beta1, lamb1, ax, ay
store = { store = {
"points": [("P0", P0, "black"), ("P1", P1, "black")], "points": [("P0", P0, "black"), ("P1", P1, "black")],
"polyline": points, "polyline": points,
"name": "approximiert", "name": "Approximiert",
"color": "#00c2fc", "color": "#00c2fc",
} }
@@ -942,29 +937,88 @@ def render_all(ax, ay, b, coords_type, tab, t1, t2,
return go.Figure() return go.Figure()
ell = EllipsoidTriaxial(ax, ay, b) ell = EllipsoidTriaxial(ax, ay, b)
fig = ellipsoid_figure(ell, title="") fig = ellipsoid_figure(ell, title="")
fig = figure_constant_lines(fig, ell, coords_type) fig = figure_constant_lines(fig, ell, coords_type)
legend_added = set()
def add_legend_for_store(store):
nonlocal fig
if not store:
return
name = store.get("name")
color = store.get("color")
if not name or not color:
return
key = (name, color)
if key in legend_added:
return
legend_added.add(key)
has_line = bool(store.get("polyline"))
if has_line:
fig.add_trace(go.Scatter3d(
x=[None], y=[None], z=[None],
mode="lines",
line=dict(width=6, color=color),
name=name,
showlegend=True,
hoverinfo="skip",
))
else:
fig.add_trace(go.Scatter3d(
x=[None], y=[None], z=[None],
mode="markers",
marker=dict(size=8, color=color),
name=name,
showlegend=True,
hoverinfo="skip",
))
def add_from_store(store): def add_from_store(store):
nonlocal fig nonlocal fig
if not store: if not store:
return return
pts = store.get("points") or [] pts = store.get("points") or []
if pts: if pts:
fig = figure_points(fig, pts) fig = figure_points(fig, pts)
line = store.get("polyline") line = store.get("polyline")
if line: if line:
fig = figure_lines(fig, line, store.get("name", ""), store.get("color", "#ff8c00")) fig = figure_lines(
fig,
line,
store.get("name", ""),
store.get("color", "#ff8c00"),
)
if tab == "tab-GHA1": if tab == "tab-GHA1":
for st in (s1a, s1n, s1s, s1p): stores = (s1a, s1n, s1s, s1p)
add_from_store(st)
else: else:
for st in (s2n, s2s, s2p): stores = (s2n, s2s, s2p)
for st in stores:
add_legend_for_store(st)
add_from_store(st) add_from_store(st)
fig.update_layout(
showlegend=True,
legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="left",
x=0.0,
),
)
return fig return fig
# Funktion zum Leeren des Plots bei Änderung des Ellipsoids # Funktion zum Leeren des Plots bei Änderung des Ellipsoids
@app.callback( @app.callback(
Output("store-gha1-ana", "data", allow_duplicate=True), Output("store-gha1-ana", "data", allow_duplicate=True),
@@ -989,6 +1043,7 @@ def clear_all_stores_on_ellipsoid_change(ax, ay, b):
# Funktionen zur separaten Darstellung der Tabs # Funktionen zur separaten Darstellung der Tabs
@app.callback( @app.callback(
Output("calc-token-gha1", "data"), Output("calc-token-gha1", "data"),
Output("gha1-header", "children", allow_duplicate=True),
Output("output-gha1-ana", "children", allow_duplicate=True), Output("output-gha1-ana", "children", allow_duplicate=True),
Output("output-gha1-num", "children", allow_duplicate=True), Output("output-gha1-num", "children", allow_duplicate=True),
Output("output-gha1-stoch", "children", allow_duplicate=True), Output("output-gha1-stoch", "children", allow_duplicate=True),
@@ -1005,11 +1060,11 @@ def start_calc_gha1(n, token):
if not n: if not n:
raise PreventUpdate raise PreventUpdate
token = (token or 0) + 1 token = (token or 0) + 1
return token, "", "", "", "", None, None, None, None return token, "", "", "", "", "", None, None, None, None
@app.callback( @app.callback(
Output("calc-token-gha2", "data"), Output("calc-token-gha2", "data"),
Output("gha2-header", "children", allow_duplicate=True),
Output("output-gha2-num", "children", allow_duplicate=True), Output("output-gha2-num", "children", allow_duplicate=True),
Output("output-gha2-stoch", "children", allow_duplicate=True), Output("output-gha2-stoch", "children", allow_duplicate=True),
Output("output-gha2-approx", "children", allow_duplicate=True), Output("output-gha2-approx", "children", allow_duplicate=True),
@@ -1024,7 +1079,26 @@ def start_calc_gha2(n, token):
if not n: if not n:
raise PreventUpdate raise PreventUpdate
token = (token or 0) + 1 token = (token or 0) + 1
return token, "", "", "", None, None, None return token, "", "", "", "", None, None, None
# Funktionen zur Erzeugung der Überschriften
@app.callback(
Output("gha1-header", "children"),
Input("calc-token-gha1", "data"),
prevent_initial_call=True,
)
def set_gha1_header(_):
return html.H4("Erste Hauptaufgabe")
@app.callback(
Output("gha2-header", "children"),
Input("calc-token-gha2", "data"),
prevent_initial_call=True,
)
def set_gha2_header(_):
return html.H4("Zweite Hauptaufgabe")