fix(viewer): remove diagonal control-net fan lines from body plan

_draw_cnet_bodyplan: eliminated the longitudinal edges (same WL index
across all stations) — in the body plan all sections are overlaid in
the same y-z plane so those connections produce confusing diagonal
spoke patterns radiating from bow/stern.  Now only transverse section
polylines are drawn as the muted control-net underlay.

_draw_cnet_planview: likewise removed the redundant longitudinal layer
(waterline contours) because layer-3 already draws them bold on top.
Only the transverse station-direction edges are kept, which are the
genuinely new information in plan view.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 17:47:46 -04:00
parent a4b8b03a59
commit eac3a3c965
+17 -54
View File
@@ -307,18 +307,17 @@ class _BaseViewer(QWidget):
def _draw_cnet_bodyplan(p: QPainter, ot, w2s_fn) -> None:
"""Dibuja la malla de control en el Body Plan.
Capa visual entre la grilla de referencia y las curvas del casco:
• Aristas transversales — polilínea de control de cada sección
(equal to the section control polyline, muted, drawn BEFORE the
actual hull-curve so the colored curve reads on top of it).
• Aristas longitudinales — segmentos horizontales a la altura de cada
línea de agua, conectando todos los nodos de esa LdA en ambas bandas.
Permiten ver cómo varía la manga de proa a popa en cada calado.
En el body plan TODAS las secciones se superponen en el mismo plano
y-z, por lo que las aristas longitudinales (mismo índice de LdA a
través de todas las estaciones) producen líneas diagonales en abanico
que carecen de sentido visual. Aquí solo se dibujan las aristas
TRANSVERSALES: la polilínea de control de cada sección, idéntica a la
curva del casco pero dibujada en color muted ANTES que la curva bold,
de forma que el ojo ve claramente «control net → curva encima».
"""
n_sta = ot.n_stations
n_wl = ot.n_waterlines
# ── Aristas transversales (a lo largo de cada sección) ────────────
pen_t = QPen(_CNET_TRAN, 0.8, Qt.PenStyle.SolidLine)
p.setPen(pen_t)
p.setBrush(Qt.BrushStyle.NoBrush)
@@ -335,62 +334,26 @@ def _draw_cnet_bodyplan(p: QPainter, ot, w2s_fn) -> None:
path.lineTo(w2s_fn(0.0, 0.0))
p.drawPath(path)
# ── Aristas longitudinales (a lo largo de cada LdA) ───────────────
# Para cada LdA j: una polilínea a través de todas las estaciones, en
# cada banda por separado (proa=+y, popa=y). Se ve como un arco a
# la altura z[j], mostrando la variación de manga longitudinalmente.
pen_l = QPen(_CNET_LONG, 0.7, Qt.PenStyle.SolidLine)
p.setPen(pen_l)
for j in range(n_wl):
z = ot.z_waterlines[j]
# Banda de proa (estribor, sign=+1)
path_fwd = QPainterPath()
path_aft = QPainterPath()
for i in range(n_sta):
sign = 1.0 if i >= n_sta // 2 else -1.0
pt = w2s_fn(sign * ot.data[i, j], z)
if i == 0:
path_aft.moveTo(pt)
elif i == n_sta // 2:
path_fwd.moveTo(pt)
if i < n_sta // 2:
path_aft.lineTo(pt)
else:
path_fwd.lineTo(pt)
p.drawPath(path_fwd)
p.drawPath(path_aft)
def _draw_cnet_planview(p: QPainter, ot, w2s_fn) -> None:
"""Dibuja la malla de control en la Vista de Planta.
• Aristas longitudinales — waterlines (conectan todas las estaciones
en una LdA = las curvas de contorno, dibujadas muted ANTES de las
curvas reales).
• Aristas transversales — polilínea vertical por estación,
conectando los nodos de esa estación a lo largo de todas las LdA.
Muestra cómo cambia la manga con el calado para cada estación.
Solo aristas TRANSVERSALES: por cada estación i, una polilínea
vertical que conecta sus nodos a lo largo de todas las LdA
(x constante, y varía de 0 a manga máxima en esa estación).
Esto muestra claramente «este nodo pertenece a esta estación» y
distingue los nodos longitudinales (en la waterline) de los
transversales (en la estación).
Las aristas longitudinales (waterlines) se omiten aquí porque la
Capa 3 ya las dibuja como las propias curvas del casco, más bold.
"""
n_sta = ot.n_stations
n_wl = ot.n_waterlines
# ── Aristas longitudinales (contornos de LdA) ─────────────────────
pen_l = QPen(_CNET_LONG, 0.7, Qt.PenStyle.SolidLine)
p.setPen(pen_l)
p.setBrush(Qt.BrushStyle.NoBrush)
for j in range(n_wl):
path = QPainterPath()
for i in range(n_sta):
pt = w2s_fn(ot.x_stations[i], ot.data[i, j])
if i == 0:
path.moveTo(pt)
else:
path.lineTo(pt)
p.drawPath(path)
# ── Aristas transversales (polilínea de sección en planta) ─────────
pen_t = QPen(_CNET_TRAN, 0.7, Qt.PenStyle.SolidLine)
p.setPen(pen_t)
p.setBrush(Qt.BrushStyle.NoBrush)
for i in range(n_sta):
path = QPainterPath()
for j in range(n_wl):