import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# Carregar dados da tabela de cotas
data = [
    (1,     0.0,  845.7, 2008.6, 1465.2, 1640.0, 1686.5, 1691.4),
    (2,  2467.0,  191.6, 1779.2, 1879.5, 2095.2, 2151.0, 2156.6),
    (3,  4933.0,   14.3, 1632.0, 2064.8, 2285.4, 2339.6, 2344.5),
    (4,  7400.0,    0.0, 1585.7, 2171.3, 2394.6, 2447.9, 2452.6),
    (5,  9867.0,   90.9, 1696.8, 1917.4, 2161.0, 2228.8, 2236.4),
    (6, 12333.0,  267.7, 2014.7, 1105.9, 1322.5, 1403.6, 1418.9),
    (7, 14800.0, 2537.1, 2537.1,    0.0,    0.0,    0.0,    0.0)
]

stations = []
for row in data:
    b, x, zk, zd, y25, y50, y75, yd = row
    stations.append({
        'b': int(b), 'x': x/1000.0, 'zk': zk/1000.0, 'zd': zd/1000.0,
        'y25': y25/1000.0, 'y50': y50/1000.0, 'y75': y75/1000.0, 'yd': yd/1000.0
    })

x_orig = np.array([s['x'] for s in stations])
zk_orig = np.array([s['zk'] for s in stations])
zd_orig = np.array([s['zd'] for s in stations])
y25_orig = np.array([s['y25'] for s in stations])
y50_orig = np.array([s['y50'] for s in stations])
y75_orig = np.array([s['y75'] for s in stations])
yd_orig = np.array([s['yd'] for s in stations])

num_x = 50
num_z = 30
x_dense = np.linspace(0.0, 14.800, num_x)

X = np.zeros((num_x, num_z))
Y_be = np.zeros((num_x, num_z))
Z = np.zeros((num_x, num_z))

for i, x in enumerate(x_dense):
    if x >= 14.799:
        zk = zk_orig[-1]
        zd = zd_orig[-1]
        z_vals = np.linspace(zk, zd, num_z)
        y_vals = np.zeros(num_z)
    else:
        zk = max(0.0, float(np.interp(x, x_orig, zk_orig)))
        zd = float(np.interp(x, x_orig, zd_orig))
        y25 = max(0.0, float(np.interp(x, x_orig, y25_orig)))
        y50 = max(0.0, float(np.interp(x, x_orig, y50_orig)))
        y75 = max(0.0, float(np.interp(x, x_orig, y75_orig)))
        yd = max(0.0, float(np.interp(x, x_orig, yd_orig)))
        
        z_ctrl = np.array([zk, zk + 0.25*(zd - zk), zk + 0.50*(zd - zk), zk + 0.75*(zd - zk), zd])
        y_ctrl = np.array([0.0, y25, y50, y75, yd])
        
        z_vals = np.linspace(zk, zd, num_z)
        y_vals = np.interp(z_vals, z_ctrl, y_ctrl)
        y_vals[0] = 0.0
        for k in range(1, num_z - 1):
            y_vals[k] = 0.25 * y_vals[k-1] + 0.5 * y_vals[k] + 0.25 * y_vals[k+1]
        y_vals[0] = 0.0
        
    X[i, :] = x
    Y_be[i, :] = y_vals
    Z[i, :] = z_vals

Y_bb = -Y_be

# Criar Figura com 4 Vistas Técnicas Navais
fig = plt.figure(figsize=(16, 12))
plt.style.use('seaborn-v0_8-whitegrid' if 'seaborn-v0_8-whitegrid' in plt.style.available else 'default')

navy = '#1A365D'
marine = '#2B6CB0'
wood = '#D69E2E'

# 1. Vista Perspectiva Isométrica 3D
ax1 = fig.add_subplot(2, 2, 1, projection='3d')
surf_be = ax1.plot_surface(X, Y_be, Z, color='#4299E1', alpha=0.75, edgecolor='#2B6CB0', linewidth=0.3, rstride=2, cstride=2)
surf_bb = ax1.plot_surface(X, Y_bb, Z, color='#4299E1', alpha=0.75, edgecolor='#2B6CB0', linewidth=0.3, rstride=2, cstride=2)
# Linha de centro / Quilha e Borda
ax1.plot(x_orig, np.zeros_like(x_orig), zk_orig, color='#C53030', linewidth=2.5, label='Perfil da Quilha / Roda de Proa')
ax1.plot(x_orig, yd_orig, zd_orig, color=navy, linewidth=2, label='Linha de Borda (Sheer)')
ax1.plot(x_orig, -yd_orig, zd_orig, color=navy, linewidth=2)

ax1.set_title("VISTA ISOMÉTRICA 3D DO CASCO (14,80 m)", fontsize=11, fontweight='bold', color=navy)
ax1.set_xlabel("X (m) [Comprimento]")
ax1.set_ylabel("Y (m) [Boca]")
ax1.set_zlabel("Z (m) [Altura]")
ax1.set_box_aspect([14.8, 4.9, 2.6])
ax1.view_init(elev=22, azim=-55)

# 2. Plano de Balizas (Body Plan / Seções Transversais)
ax2 = fig.add_subplot(2, 2, 2)
# Balizas de Vante (Proa - Estações 4 a 7 à direita/BE)
# Balizas de Ré (Popa - Estações 1 a 4 à esquerda/BB)
colors_stations = ['#E53E3E', '#DD6B20', '#D69E2E', '#38A169', '#319795', '#3182CE', '#805AD5']
for idx, s in enumerate(stations):
    zk = s['zk']
    zd = s['zd']
    z_ctrl = np.array([zk, zk + 0.25*(zd - zk), zk + 0.50*(zd - zk), zk + 0.75*(zd - zk), zd])
    y_ctrl = np.array([0.0, s['y25'], s['y50'], s['y75'], s['yd']])
    z_v = np.linspace(zk, zd, 50)
    y_v = np.interp(z_v, z_ctrl, y_ctrl)
    
    # Desenhar ambos os lados com anotação
    lbl = f"B{s['b']} (x={s['x']:.1f}m)"
    if s['b'] <= 4:
        # Ré (desenhar em -y e +y tracejado)
        ax2.plot(-y_v, z_v, color=colors_stations[idx], linewidth=1.8, label=f"Popa: {lbl}")
        ax2.plot(y_v, z_v, color=colors_stations[idx], linewidth=0.8, linestyle=':')
    else:
        # Vante (desenhar em +y)
        ax2.plot(y_v, z_v, color=colors_stations[idx], linewidth=1.8, label=f"Proa: {lbl}")
        ax2.plot(-y_v, z_v, color=colors_stations[idx], linewidth=0.8, linestyle=':')

ax2.axvline(0, color=navy, linestyle='--', linewidth=1.2, label='Linha de Centro (CL)')
ax2.axhline(0, color='#718096', linestyle='-', linewidth=1, label='Linha de Base (BL)')
ax2.axhline(1.20, color='#3182CE', linestyle='-.', linewidth=1.2, label='Linha d\'Água de Projeto (T=1.20m)')
ax2.set_title("PLANO DO CORPO DE BALIZAS (BODY PLAN)", fontsize=11, fontweight='bold', color=navy)
ax2.set_xlabel("Meia-Boca (m) [Bombordo (-) / Boreste (+)]", fontsize=9, fontweight='bold', color=navy)
ax2.set_ylabel("Altura acima da Linha de Base (m)", fontsize=9, fontweight='bold', color=navy)
ax2.legend(loc='lower center', fontsize=7, ncol=2)
ax2.set_xlim(-2.8, 2.8)
ax2.set_ylim(-0.1, 2.8)

# 3. Plano de Perfil (Sheer Plan / Linhas de Centro e Borda)
ax3 = fig.add_subplot(2, 2, 3)
ax3.plot(x_orig, zk_orig, color='#C53030', linewidth=2.5, marker='o', label='Linha da Quilha e Roda de Proa')
ax3.plot(x_orig, zd_orig, color=navy, linewidth=2.2, marker='s', label='Linha de Borda (Sheer Line)')
ax3.axhline(1.20, color='#3182CE', linestyle='--', linewidth=1.2, label='Linha d\'Água (T=1.20m)')
# Desenhar verticais das balizas
for s in stations:
    ax3.vlines(s['x'], s['zk'], s['zd'], color='#CBD5E0', linestyle=':', linewidth=0.8)
    ax3.text(s['x'], s['zd']+0.08, f"B{s['b']}", ha='center', fontsize=7.5, fontweight='bold', color=navy)

ax3.set_title("PLANO DE PERFIL (SHEER PLAN)", fontsize=11, fontweight='bold', color=navy)
ax3.set_xlabel("Comprimento X (m)", fontsize=9, fontweight='bold', color=navy)
ax3.set_ylabel("Altura Z (m)", fontsize=9, fontweight='bold', color=navy)
ax3.legend(loc='upper left', fontsize=7.5)
ax3.set_xlim(-0.5, 15.5)
ax3.set_ylim(-0.2, 3.0)

# 4. Plano de Meias-Bocas (Half-Breadth Plan / Linhas d'Água)
ax4 = fig.add_subplot(2, 2, 4)
ax4.plot(x_orig, yd_orig, color=navy, linewidth=2.2, marker='s', label='Linha de Borda (Convés)')
ax4.plot(x_orig, y75_orig, color='#2B6CB0', linewidth=1.5, linestyle='--', marker='^', label='Meia-Boca a 75% da altura')
ax4.plot(x_orig, y50_orig, color='#38A169', linewidth=1.5, linestyle='-.', marker='d', label='Meia-Boca a 50% da altura')
ax4.plot(x_orig, y25_orig, color='#D69E2E', linewidth=1.5, linestyle=':', marker='o', label='Meia-Boca a 25% da altura')
ax4.axhline(0, color='#C53030', linewidth=1.5, label='Linha de Centro (CL)')

for s in stations:
    ax4.vlines(s['x'], 0, s['yd'], color='#CBD5E0', linestyle=':', linewidth=0.8)
    ax4.text(s['x'], s['yd']+0.08, f"B{s['b']}", ha='center', fontsize=7.5, fontweight='bold', color=navy)

ax4.set_title("PLANO DE MEIAS-BOCAS (HALF-BREADTH PLAN)", fontsize=11, fontweight='bold', color=navy)
ax4.set_xlabel("Comprimento X (m)", fontsize=9, fontweight='bold', color=navy)
ax4.set_ylabel("Meia-Boca Y (m)", fontsize=9, fontweight='bold', color=navy)
ax4.legend(loc='lower center', fontsize=7.5, ncol=2)
ax4.set_xlim(-0.5, 15.5)
ax4.set_ylim(-0.2, 2.8)

plt.suptitle("PROJETO 3D DO CASCO & PLANO DE LINHAS — SAVEIRO 14,80 m (TABELA DE COTAS)", fontsize=14, fontweight='bold', color=navy, y=0.99)
plt.tight_layout()

img_out1 = '/home/magdalena/eee/grupos/grupo-3/Projeto_3D_Plano_Linhas_Saveiro_14_80m.png'
img_out2 = '/home/magdalena/eee/alunos/rodolfo-g-giordano/Projeto_3D_Plano_Linhas_Saveiro_14_80m.png'
plt.savefig(img_out1, dpi=300)
plt.savefig(img_out2, dpi=300)
print(f"Prancha 3D e Plano de Linhas salva com sucesso em: {img_out1}")
