x2XcarleX2x commited on
Commit
9d3fe8b
·
verified ·
1 Parent(s): f32828e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +108 -106
app.py CHANGED
@@ -1,124 +1,122 @@
1
  import gradio as gr
2
  import numpy as np
3
- import matplotlib.pyplot as plt
4
  import math
5
  from scipy.special import comb
6
 
7
- # --- Funções Matemáticas (O Coração do Teorema - sem alterações) ---
8
 
9
  def bernstein_poly(i, n, t):
10
- """ O polinômio de Bernstein, base para as curvas de Bézier. """
11
  return comb(n, i) * (t**(i)) * ((1 - t)**(n - i))
12
 
13
- def bezier_curve(points, n_times=1000):
14
- """ Gera uma curva de Bézier a partir de uma lista de pontos de controle. """
15
  n_points = len(points)
16
  x_points = np.array([p[0] for p in points])
17
  y_points = np.array([p[1] for p in points])
 
18
  t = np.linspace(0.0, 1.0, n_times)
19
- polynomial_array = np.array([bernstein_poly(i, n_points - 1, t) for i in range(0, n_points)])
20
  x_vals = np.dot(x_points, polynomial_array)
21
  y_vals = np.dot(y_points, polynomial_array)
22
- return x_vals, y_vals
 
23
 
24
- def aprender_com_o_eco(pontos_do_eco: list) -> dict:
25
- """ Calcula a essência do movimento (direção e vetor) do eco. """
26
  if len(pontos_do_eco) < 2:
27
- return {"bearing_rad": 0, "velocity_vector": np.array([0, 0])}
28
  p1, p2 = np.array(pontos_do_eco[0]), np.array(pontos_do_eco[-1])
29
  vetor_velocidade = p2 - p1
30
- bearing_radianos = math.atan2(vetor_velocidade[1], vetor_velocidade[0])
31
- return {"bearing_rad": bearing_radianos, "velocity_vector": vetor_velocidade}
32
 
33
- # --- Função Principal do Gradio (A Interface do Laboratório Completo) ---
34
 
35
- def gerar_grafico_dinamico(inflexao1_x, inflexao1_y, inflexao2_x, inflexao2_y, destino_x, destino_y, eco_vetores):
 
 
 
 
36
  """
37
- Gera e plota a jornada com os caminhos da Criança A e B sendo totalmente dinâmicos.
38
  """
39
- # 1. DEFINIÇÃO DOS PONTOS DA JORNADA, AGORA QUASE TODOS DINÂMICOS
40
- p1_inicio = np.array([0, 0])
 
 
 
41
 
42
- # Pontos de inflexão da Criança A (vindo da UI)
43
- p2_inflexao1 = np.array([inflexao1_x, inflexao1_y])
44
- p3_inflexao2 = np.array([inflexao2_x, inflexao2_y])
45
 
46
- # Ponto de encontro é o ponto final da Criança A e o inicial da B.
47
- # Vamos fixá-lo para manter um ponto de referência estável.
48
- p4_encontro = np.array([75, 45])
49
-
50
- # Destino da Criança B (vindo da UI)
51
- p5_destino = np.array([destino_x, destino_y])
52
-
53
- # 2. GERAR A CURVA DINÂMICA DA CRIANÇA A
54
  pontos_curva_a = [p1_inicio, p2_inflexao1, p3_inflexao2, p4_encontro]
55
- x_a, y_a = bezier_curve(pontos_curva_a, n_times=1000)
56
-
57
- # 3. ISOLAR O ECO
58
- NUMERO_DE_VETORES_ECO = int(eco_vetores)
59
- if NUMERO_DE_VETORES_ECO < 2: NUMERO_DE_VETORES_ECO = 2
60
-
61
- x_eco = x_a[-NUMERO_DE_VETORES_ECO:]
62
- y_eco = y_a[-NUMERO_DE_VETORES_ECO:]
63
- pontos_do_eco = list(zip(x_eco, y_eco))
64
-
65
- # 4. CRIANÇA B APRENDE COM O ECO
66
- essencia_movimento = aprender_com_o_eco(pontos_do_eco)
67
- vetor_aprendido = essencia_movimento["velocity_vector"]
68
-
69
- # 5. GERAR A CURVA DINÂMICA DA CRIANÇA B
70
  ponto_controle_b = p4_encontro + vetor_aprendido
71
- pontos_curva_b = [p4_encontro, ponto_controle_b, p5_destino]
72
- x_b, y_b = bezier_curve(pontos_curva_b, n_times=1000)
73
-
74
- # 6. PLOTAGEM COMPLETA
75
- fig, ax = plt.subplots(figsize=(12, 9))
76
- fig.patch.set_facecolor('black')
77
- ax.set_facecolor('black')
78
-
79
- ax.spines['bottom'].set_color('white')
80
- ax.spines['left'].set_color('white')
81
- ax.spines['top'].set_color('black')
82
- ax.spines['right'].set_color('black')
83
- ax.tick_params(axis='x', colors='white')
84
- ax.tick_params(axis='y', colors='white')
85
-
86
- ax.plot(x_a, y_a, label='Caminho da Criança A (Seu Input)', color='cyan', linewidth=2)
87
- ax.plot(x_b, y_b, label='Continuidade da Criança B (Gerado)', color='lime', linewidth=2, linestyle='--')
88
- ax.plot(x_eco, y_eco, label=f'Eco de Memória ({NUMERO_DE_VETORES_ECO} vetores)', color='magenta', linewidth=4)
89
-
90
- pontos_controle_completos = np.array([p1_inicio, p2_inflexao1, p3_inflexao2, p4_encontro, ponto_controle_b, p5_destino])
91
- ax.plot(pontos_controle_completos[:, 0], pontos_controle_completos[:, 1], 'o--', color='lightcoral', markersize=8, alpha=0.6, label='Estrutura de Controle')
92
-
93
- ax.plot(p4_encontro[0], p4_encontro[1], 'o', color='yellow', markersize=12, markeredgecolor='black', label='Ponto de Encontro (Fixo)')
94
- ax.plot(p5_destino[0], p5_destino[1], 'X', color='red', markersize=12, markeredgecolor='white', label='Destino da Criança B')
95
-
96
- ax.set_title('Laboratório de Continuidade Causal', color='white', fontsize=16)
97
- ax.set_xlabel('Eixo X', color='white', fontsize=12)
98
- ax.set_ylabel('Eixo Y', color='white', fontsize=12)
99
- legend = ax.legend(facecolor='#111111', edgecolor='white', framealpha=0.5)
100
- for text in legend.get_texts():
101
- text.set_color('white')
102
-
103
- ax.grid(True, linestyle='--', color='gray', alpha=0.3)
104
- ax.set_aspect('equal', adjustable='box')
 
 
 
 
105
 
106
- caminho_figura = "laboratorio_completo.png"
107
- plt.savefig(caminho_figura, bbox_inches='tight', pad_inches=0.1, dpi=100, transparent=True)
108
- plt.close(fig)
109
 
110
- 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}°"
111
 
112
- return caminho_figura, info_vetor
113
 
114
  # --- Interface Gradio ---
115
 
116
- with gr.Blocks(theme=gr.themes.Base(primary_hue="teal")) as demo:
117
  gr.Markdown(
118
  """
119
- # 🔬 Laboratório de Continuidade Causal (Versão Completa)
120
- 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).
121
- Observe como a inércia é calculada e aplicada para qualquer estilo de movimento.
 
122
  """
123
  )
124
 
@@ -126,34 +124,38 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue="teal")) as demo:
126
  with gr.Column(scale=1):
127
  gr.Markdown("### 🎮 Controles da Simulação")
128
 
129
- with gr.Accordion("Definir Caminho da Criança A (O Passado)", open=True):
130
- gr.Markdown("Começa em `[0,0]` e termina no ponto fixo de encontro `[75,45]`.")
131
- inflexao1_x = gr.Slider(-50, 150, value=25, label="Vetor 2 (Inflexão 1) - X", visible=False)
132
- inflexao1_y = gr.Slider(-50, 150, value=15, label="Vetor 2 (Inflexão 1) - Y")
133
- inflexao2_x = gr.Slider(-50, 150, value=50, label="Vetor 3 (Inflexão 2) - X", visible=False)
134
- inflexao2_y = gr.Slider(-50, 150, value=30, label="Vetor 3 (Inflexão 2) - Y")
135
-
136
- with gr.Accordion("Definir Caminho da Criança B (O Futuro)", open=True):
137
- destino_x_input = gr.Slider(-50, 150, value=100, label="Destino Final (X)", visible=False)
138
- destino_y_input = gr.Slider(-50, 150, value=90, label="Destino Final (Y)")
139
-
140
- with gr.Accordion("Configurações do Aprendizado", open=False):
141
- eco_input = gr.Slider(2, 300, value=150, step=1, label="Nº de Vetores no Eco de Memória")
142
 
143
- with gr.Column(scale=2):
144
- gr.Markdown("### 📊 Visualização da Jornada")
145
  info_output = gr.Textbox(label="Dados do Aprendizado (Calculado)", interactive=False)
146
- plot_output = gr.Image(label="Gráfico da Continuidade", type="filepath")
147
 
148
- # Lista completa de componentes de entrada
149
- inputs = [inflexao1_x, inflexao1_y, inflexao2_x, inflexao2_y, destino_x_input, destino_y_input, eco_input]
 
 
 
 
 
 
 
 
150
 
151
  # Conecta todos os sliders à função para atualização em tempo real
152
  for component in inputs:
153
- component.change(fn=gerar_grafico_dinamico, inputs=inputs, outputs=[plot_output, info_output])
154
 
155
  # Carga inicial do aplicativo
156
- demo.load(fn=gerar_grafico_dinamico, inputs=inputs, outputs=[plot_output, info_output])
157
 
158
  if __name__ == "__main__":
159
  demo.launch()
 
1
  import gradio as gr
2
  import numpy as np
3
+ import plotly.graph_objects as go
4
  import math
5
  from scipy.special import comb
6
 
7
+ # --- Funções Matemáticas (Adaptadas para 3D) ---
8
 
9
  def bernstein_poly(i, n, t):
10
+ """ O polinômio de Bernstein (base para Bézier). """
11
  return comb(n, i) * (t**(i)) * ((1 - t)**(n - i))
12
 
13
+ def bezier_curve_3d(points, n_times=100):
14
+ """ Gera uma curva de Bézier 3D a partir de pontos de controle. """
15
  n_points = len(points)
16
  x_points = np.array([p[0] for p in points])
17
  y_points = np.array([p[1] for p in points])
18
+ z_points = np.array([p[2] for p in points])
19
  t = np.linspace(0.0, 1.0, n_times)
20
+ polynomial_array = np.array([bernstein_poly(i, n_points - 1, t) for i in range(n_points)])
21
  x_vals = np.dot(x_points, polynomial_array)
22
  y_vals = np.dot(y_points, polynomial_array)
23
+ z_vals = np.dot(z_points, polynomial_array)
24
+ return x_vals, y_vals, z_vals
25
 
26
+ def aprender_com_o_eco_3d(pontos_do_eco: list) -> dict:
27
+ """ Calcula a essência do movimento 3D (vetor) do eco. """
28
  if len(pontos_do_eco) < 2:
29
+ return {"velocity_vector": np.array([0, 0, 0])}
30
  p1, p2 = np.array(pontos_do_eco[0]), np.array(pontos_do_eco[-1])
31
  vetor_velocidade = p2 - p1
32
+ return {"velocity_vector": vetor_velocidade}
 
33
 
34
+ # --- Função Principal do Gradio (O Laboratório 3D Interativo) ---
35
 
36
+ def gerar_grafico_3d_dinamico(
37
+ inflexao1_x, inflexao1_y, inflexao1_z,
38
+ inflexao2_x, inflexao2_y, inflexao2_z,
39
+ eco_vetores
40
+ ):
41
  """
42
+ Gera e plota a jornada 3D completa com base nos inputs da UI.
43
  """
44
+ # 1. DEFINIÇÃO DOS PONTOS DA JORNADA
45
+ p1_inicio = np.array([0, 0, 0])
46
+ p2_inflexao1 = np.array([inflexao1_x, inflexao1_y, inflexao1_z])
47
+ p3_inflexao2 = np.array([inflexao2_x, inflexao2_y, inflexao2_z])
48
+ p4_encontro = np.array([75, 45, 10])
49
 
50
+ # Para o loop, o destino final deve ser o ponto de início.
51
+ p5_destino = p1_inicio
 
52
 
53
+ # 2. GERAR A CURVA DA CRIANÇA A
 
 
 
 
 
 
 
54
  pontos_curva_a = [p1_inicio, p2_inflexao1, p3_inflexao2, p4_encontro]
55
+ x_a, y_a, z_a = bezier_curve_3d(pontos_curva_a)
56
+ caminho_a = list(zip(x_a, y_a, z_a))
57
+
58
+ # 3. APRENDER COM O ECO
59
+ num_eco = int(eco_vetores)
60
+ if num_eco < 2: num_eco = 2
61
+ pontos_do_eco = caminho_a[-num_eco:]
62
+ vetor_aprendido = aprender_com_o_eco_3d(pontos_do_eco)["velocity_vector"]
63
+
64
+ # 4. GERAR A CURVA DA CRIANÇA B
 
 
 
 
 
65
  ponto_controle_b = p4_encontro + vetor_aprendido
66
+ ponto_inflexao_retorno = p1_inicio - vetor_aprendido * 0.5
67
+ pontos_curva_b = [p4_encontro, ponto_controle_b, ponto_inflexao_retorno, p5_destino]
68
+ x_b, y_b, z_b = bezier_curve_3d(pontos_curva_b)
69
+
70
+ # 5. PREPARAR DADOS PARA O PLOTLY
71
+
72
+ # Caminho A
73
+ trace_a = go.Scatter3d(x=x_a, y=y_a, z=z_a, mode='lines', line=dict(color='cyan', width=5), name='Caminho A (Passado)')
74
+
75
+ # Caminho B
76
+ trace_b = go.Scatter3d(x=x_b, y=y_b, z=z_b, mode='lines', line=dict(color='lime', width=5, dash='dash'), name='Caminho B (Convergência)')
77
+
78
+ # Eco de Memória
79
+ x_eco, y_eco, z_eco = zip(*pontos_do_eco)
80
+ trace_eco = go.Scatter3d(x=x_eco, y=y_eco, z=z_eco, mode='lines', line=dict(color='magenta', width=10), name=f'Eco de Memória ({num_eco} vetores)')
81
+
82
+ # Pontos de Controle e Waypoints
83
+ pontos_controle = np.array([p1_inicio, p2_inflexao1, p3_inflexao2, p4_encontro, ponto_controle_b, ponto_inflexao_retorno, p5_destino])
84
+ trace_controle = go.Scatter3d(x=pontos_controle[:,0], y=pontos_controle[:,1], z=pontos_controle[:,2], mode='markers', marker=dict(color='lightcoral', size=5), name='Estrutura de Controle')
85
+
86
+ waypoints = np.array([p1_inicio, p4_encontro])
87
+ trace_waypoints = go.Scatter3d(x=waypoints[:,0], y=waypoints[:,1], z=waypoints[:,2], mode='markers', marker=dict(color=['cyan', 'yellow'], size=12, symbol=['circle', 'diamond']), name='Waypoints (Início/Encontro)')
88
+
89
+ # 6. CRIAR A FIGURA PLOTLY
90
+ layout = go.Layout(
91
+ title=dict(text='Laboratório de Continuidade Causal 3D', font=dict(color='white')),
92
+ scene=dict(
93
+ xaxis_title='Eixo X',
94
+ yaxis_title='Eixo Y',
95
+ zaxis_title='Eixo Z',
96
+ xaxis=dict(gridcolor='gray', zerolinecolor='gray', color='white'),
97
+ yaxis=dict(gridcolor='gray', zerolinecolor='gray', color='white'),
98
+ zaxis=dict(gridcolor='gray', zerolinecolor='gray', color='white'),
99
+ bgcolor='#111111'
100
+ ),
101
+ paper_bgcolor='#111111',
102
+ legend=dict(font=dict(color='white'))
103
+ )
104
 
105
+ fig = go.Figure(data=[trace_a, trace_b, trace_eco, trace_controle, trace_waypoints], layout=layout)
 
 
106
 
107
+ info_vetor = f"Vetor de Inércia Aprendido: ({vetor_aprendido[0]:.2f}, {vetor_aprendido[1]:.2f}, {vetor_aprendido[2]:.2f})"
108
 
109
+ return fig, info_vetor
110
 
111
  # --- Interface Gradio ---
112
 
113
+ with gr.Blocks(theme=gr.themes.Base(primary_hue="green", secondary_hue="blue")) as demo:
114
  gr.Markdown(
115
  """
116
+ # 🔬 Laboratório de Continuidade Causal 3D Interativo
117
+ Molde a trajetória no espaço! Use os sliders para definir os pontos de inflexão da "Criança A".
118
+ O sistema irá aprender a inércia (vetor de movimento) a partir do "Eco de Memória" (em magenta) e projetar a trajetória contínua da "Criança B" de volta ao início, formando um loop.
119
+ **Use o mouse para girar e dar zoom no gráfico 3D.**
120
  """
121
  )
122
 
 
124
  with gr.Column(scale=1):
125
  gr.Markdown("### 🎮 Controles da Simulação")
126
 
127
+ with gr.Accordion("Definir Ponto de Inflexão 1", open=True):
128
+ inflexao1_x = gr.Slider(-50, 150, value=25, label="Posição X")
129
+ inflexao1_y = gr.Slider(-50, 150, value=60, label="Posição Y")
130
+ inflexao1_z = gr.Slider(-50, 150, value=50, label="Posição Z (Altura)")
131
+
132
+ with gr.Accordion("Definir Ponto de Inflexão 2", open=True):
133
+ inflexao2_x = gr.Slider(-50, 150, value=60, label="Posição X")
134
+ inflexao2_y = gr.Slider(-50, 150, value=20, label="Posição Y")
135
+ inflexao2_z = gr.Slider(-50, 150, value=-30, label="Posição Z (Altura)")
136
+
137
+ with gr.Accordion("Configurações do Aprendizado", open=True):
138
+ eco_input = gr.Slider(2, 100, value=50, step=1, label="Tamanho do Eco de Memória (Nº de Vetores)")
 
139
 
 
 
140
  info_output = gr.Textbox(label="Dados do Aprendizado (Calculado)", interactive=False)
 
141
 
142
+ with gr.Column(scale=3):
143
+ gr.Markdown("### 📊 Visualização da Jornada 3D")
144
+ # Usamos gr.Plot para renderizar a figura do Plotly
145
+ plot_output = gr.Plot()
146
+
147
+ inputs = [
148
+ inflexao1_x, inflexao1_y, inflexao1_z,
149
+ inflexao2_x, inflexao2_y, inflexao2_z,
150
+ eco_input
151
+ ]
152
 
153
  # Conecta todos os sliders à função para atualização em tempo real
154
  for component in inputs:
155
+ component.change(fn=gerar_grafico_3d_dinamico, inputs=inputs, outputs=[plot_output, info_output])
156
 
157
  # Carga inicial do aplicativo
158
+ demo.load(fn=gerar_grafico_3d_dinamico, inputs=inputs, outputs=[plot_output, info_output])
159
 
160
  if __name__ == "__main__":
161
  demo.launch()