Oraculo / app.py
Carlexxx's picture
Update app.py
9eaf268 verified
import gradio as gr
import numpy as np
import matplotlib.pyplot as plt
import math
from scipy.special import comb
# --- Funções Matemáticas (O Coração do Teorema - sem alterações) ---
def bernstein_poly(i, n, t):
""" O polinômio de Bernstein, base para as curvas de Bézier. """
return comb(n, i) * (t**(i)) * ((1 - t)**(n - i))
def bezier_curve(points, n_times=1000):
""" Gera uma curva de Bézier a partir de uma lista de pontos de controle. """
n_points = len(points)
x_points = np.array([p[0] for p in points])
y_points = np.array([p[1] for p in points])
t = np.linspace(0.0, 1.0, n_times)
polynomial_array = np.array([bernstein_poly(i, n_points - 1, t) for i in range(0, n_points)])
x_vals = np.dot(x_points, polynomial_array)
y_vals = np.dot(y_points, polynomial_array)
return x_vals, y_vals
def aprender_com_o_eco(pontos_do_eco: list) -> dict:
""" Calcula a essência do movimento (direção e vetor) do eco. """
if len(pontos_do_eco) < 2:
return {"bearing_rad": 0, "velocity_vector": np.array([0, 0])}
p1, p2 = np.array(pontos_do_eco[0]), np.array(pontos_do_eco[-1])
vetor_velocidade = p2 - p1
bearing_radianos = math.atan2(vetor_velocidade[1], vetor_velocidade[0])
return {"bearing_rad": bearing_radianos, "velocity_vector": vetor_velocidade}
# --- Função Principal do Gradio (A Interface do Laboratório Completo) ---
def gerar_grafico_dinamico(inflexao1_x, inflexao1_y, inflexao2_x, inflexao2_y, destino_x, destino_y, eco_vetores):
"""
Gera e plota a jornada com os caminhos da Criança A e B sendo totalmente dinâmicos.
"""
# 1. DEFINIÇÃO DOS PONTOS DA JORNADA, AGORA QUASE TODOS DINÂMICOS
p1_inicio = np.array([0, 0])
# Pontos de inflexão da Criança A (vindo da UI)
p2_inflexao1 = np.array([inflexao1_x, inflexao1_y])
p3_inflexao2 = np.array([inflexao2_x, inflexao2_y])
# Ponto de encontro é o ponto final da Criança A e o inicial da B.
# Vamos fixá-lo para manter um ponto de referência estável.
p4_encontro = np.array([75, 45])
# Destino da Criança B (vindo da UI)
p5_destino = np.array([destino_x, destino_y])
# 2. GERAR A CURVA DINÂMICA DA CRIANÇA A
pontos_curva_a = [p1_inicio, p2_inflexao1, p3_inflexao2, p4_encontro]
x_a, y_a = bezier_curve(pontos_curva_a, n_times=1000)
# 3. ISOLAR O ECO
NUMERO_DE_VETORES_ECO = int(eco_vetores)
if NUMERO_DE_VETORES_ECO < 2: NUMERO_DE_VETORES_ECO = 2
x_eco = x_a[-NUMERO_DE_VETORES_ECO:]
y_eco = y_a[-NUMERO_DE_VETORES_ECO:]
pontos_do_eco = list(zip(x_eco, y_eco))
# 4. CRIANÇA B APRENDE COM O ECO
essencia_movimento = aprender_com_o_eco(pontos_do_eco)
vetor_aprendido = essencia_movimento["velocity_vector"]
# 5. GERAR A CURVA DINÂMICA DA CRIANÇA B
ponto_controle_b = p4_encontro + vetor_aprendido
pontos_curva_b = [p4_encontro, ponto_controle_b, p5_destino]
x_b, y_b = bezier_curve(pontos_curva_b, n_times=1000)
# 6. PLOTAGEM COMPLETA
fig, ax = plt.subplots(figsize=(12, 9))
fig.patch.set_facecolor('black')
ax.set_facecolor('black')
ax.spines['bottom'].set_color('white')
ax.spines['left'].set_color('white')
ax.spines['top'].set_color('black')
ax.spines['right'].set_color('black')
ax.tick_params(axis='x', colors='white')
ax.tick_params(axis='y', colors='white')
ax.plot(x_a, y_a, label='Caminho da Criança A (Seu Input)', color='cyan', linewidth=2)
ax.plot(x_b, y_b, label='Continuidade da Criança B (Gerado)', color='lime', linewidth=2, linestyle='--')
ax.plot(x_eco, y_eco, label=f'Eco de Memória ({NUMERO_DE_VETORES_ECO} vetores)', color='magenta', linewidth=4)
pontos_controle_completos = np.array([p1_inicio, p2_inflexao1, p3_inflexao2, p4_encontro, ponto_controle_b, p5_destino])
ax.plot(pontos_controle_completos[:, 0], pontos_controle_completos[:, 1], 'o--', color='lightcoral', markersize=8, alpha=0.6, label='Estrutura de Controle')
ax.plot(p4_encontro[0], p4_encontro[1], 'o', color='yellow', markersize=12, markeredgecolor='black', label='Ponto de Encontro (Fixo)')
ax.plot(p5_destino[0], p5_destino[1], 'X', color='red', markersize=12, markeredgecolor='white', label='Destino da Criança B')
ax.set_title('Laboratório de Continuidade Causal', color='white', fontsize=16)
ax.set_xlabel('Eixo X', color='white', fontsize=12)
ax.set_ylabel('Eixo Y', color='white', fontsize=12)
legend = ax.legend(facecolor='#111111', edgecolor='white', framealpha=0.5)
for text in legend.get_texts():
text.set_color('white')
ax.grid(True, linestyle='--', color='gray', alpha=0.3)
ax.set_aspect('equal', adjustable='box')
caminho_figura = "laboratorio_completo.png"
plt.savefig(caminho_figura, bbox_inches='tight', pad_inches=0.1, dpi=100, transparent=True)
plt.close(fig)
info_vetor = f"Vetor de Inércia Aprendido: ({vetor_aprendido[0]:.2f}, {vetor_aprendido[1]:.2f}) | Direção: {math.degrees(essencia_movimento['bearing_rad']):.2f}°"
return caminho_figura, info_vetor
# --- Interface Gradio ---
with gr.Blocks(theme=gr.themes.Base(primary_hue="teal")) as demo:
gr.Markdown(
"""
# 🔬 Laboratório de Continuidade Causal (Versão Completa)
Molde a trajetória completa! Use os controles para definir tanto o **caminho da Criança A** (o passado) quanto o **destino da Criança B** (o futuro).
Observe como a inércia é calculada e aplicada para qualquer estilo de movimento.
"""
)
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### 🎮 Controles da Simulação")
with gr.Accordion("Definir Caminho da Criança A (O Passado)", open=True):
gr.Markdown("Começa em `[0,0]` e termina no ponto fixo de encontro `[75,45]`.")
inflexao1_x = gr.Slider(-50, 150, value=25, label="Vetor 2 (Inflexão 1) - X", visible=False)
inflexao1_y = gr.Slider(-50, 150, value=15, label="Vetor 2 (Inflexão 1) - Y")
inflexao2_x = gr.Slider(-50, 150, value=50, label="Vetor 3 (Inflexão 2) - X", visible=False)
inflexao2_y = gr.Slider(-50, 150, value=30, label="Vetor 3 (Inflexão 2) - Y")
with gr.Accordion("Definir Caminho da Criança B (O Futuro)", open=True):
destino_x_input = gr.Slider(-50, 150, value=100, label="Destino Final (X)", visible=False)
destino_y_input = gr.Slider(-50, 150, value=90, label="Destino Final (Y)")
with gr.Accordion("Configurações do Aprendizado", open=False):
eco_input = gr.Slider(2, 300, value=150, step=1, label="Nº de Vetores no Eco de Memória")
with gr.Column(scale=2):
gr.Markdown("### 📊 Visualização da Jornada")
info_output = gr.Textbox(label="Dados do Aprendizado (Calculado)", interactive=False)
plot_output = gr.Image(label="Gráfico da Continuidade", type="filepath")
# Lista completa de componentes de entrada
inputs = [inflexao1_x, inflexao1_y, inflexao2_x, inflexao2_y, destino_x_input, destino_y_input, eco_input]
# Conecta todos os sliders à função para atualização em tempo real
for component in inputs:
component.change(fn=gerar_grafico_dinamico, inputs=inputs, outputs=[plot_output, info_output])
# Carga inicial do aplicativo
demo.load(fn=gerar_grafico_dinamico, inputs=inputs, outputs=[plot_output, info_output])
if __name__ == "__main__":
demo.launch()