Carlexxx commited on
Commit
22c5fe9
·
verified ·
1 Parent(s): 23d6d24

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +166 -0
app.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) ---
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
+
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(0, n_points)])
21
+
22
+ x_vals = np.dot(x_points, polynomial_array)
23
+ y_vals = np.dot(y_points, polynomial_array)
24
+
25
+ return x_vals, y_vals
26
+
27
+ def aprender_com_o_eco(pontos_do_eco: list) -> dict:
28
+ """ Calcula a essência do movimento (direção e vetor) do eco. """
29
+ if len(pontos_do_eco) < 2:
30
+ return {"bearing_rad": 0, "velocity_vector": np.array([0, 0])}
31
+
32
+ p1 = np.array(pontos_do_eco[0])
33
+ p2 = np.array(pontos_do_eco[-1])
34
+ vetor_velocidade = p2 - p1
35
+ delta_x, delta_y = vetor_velocidade
36
+ bearing_radianos = math.atan2(delta_y, delta_x)
37
+
38
+ return {
39
+ "bearing_rad": bearing_radianos,
40
+ "velocity_vector": vetor_velocidade
41
+ }
42
+
43
+ # --- Função Principal do Gradio (A Interface do Oráculo) ---
44
+
45
+ def gerar_grafico_continuidade(p_inflexao_x, p_inflexao_y, p_b_x, p_b_y, tamanho_eco_percent=10):
46
+ """
47
+ Gera e plota a jornada completa das duas crianças.
48
+ """
49
+ PONTO_A = np.array([0, 0])
50
+ PONTO_INFLEXAO = np.array([p_inflexao_x, p_inflexao_y])
51
+ PONTO_B = np.array([p_b_x, p_b_y])
52
+
53
+ # 1. Gerar a curva da Criança A
54
+ pontos_curva_a = [PONTO_A, PONTO_INFLEXAO, PONTO_B]
55
+ x_a, y_a = bezier_curve(pontos_curva_a)
56
+
57
+ # 2. Isolar o Eco
58
+ tamanho_eco_int = int(len(x_a) * (tamanho_eco_percent / 100))
59
+ if tamanho_eco_int < 2: tamanho_eco_int = 2 # Garante um eco mínimo
60
+
61
+ x_eco = x_a[-tamanho_eco_int:]
62
+ y_eco = y_a[-tamanho_eco_int:]
63
+ pontos_do_eco = list(zip(x_eco, y_eco))
64
+
65
+ # 3. 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
+ # 4. Gerar a curva da Criança B
70
+ # O ponto de controle para a curva B é B + vetor_aprendido, para definir a tangente
71
+ ponto_controle_b = PONTO_B + vetor_aprendido
72
+ # O ponto final da Criança B pode ser uma extrapolação
73
+ ponto_final_b = PONTO_B + vetor_aprendido * 3
74
+
75
+ pontos_curva_b = [PONTO_B, ponto_controle_b, ponto_final_b]
76
+ x_b, y_b = bezier_curve(pontos_curva_b)
77
+
78
+ # 5. Plotagem
79
+ plt.style.use('dark_background')
80
+ fig, ax = plt.subplots(figsize=(10, 10))
81
+
82
+ # Curvas
83
+ ax.plot(x_a, y_a, label='Caminho da Criança A', color='cyan', linewidth=2.5)
84
+ ax.plot(x_b, y_b, label='Continuidade da Criança B (Gerado)', color='lime', linewidth=2.5, linestyle='--')
85
+
86
+ # Eco
87
+ ax.plot(x_eco, y_eco, label=f'Eco de Aprendizado ({tamanho_eco_percent}%)', color='magenta', linewidth=5)
88
+
89
+ # Pontos de Controle
90
+ ax.plot(*zip(PONTO_A, PONTO_INFLEXAO, PONTO_B), 'o--', color='lightcoral', markersize=8, label='Pontos de Controle (Input)')
91
+
92
+ # Anotação do Vetor
93
+ ax.annotate(f'Vetor de Inércia\n({vetor_aprendido[0]:.1f}, {vetor_aprendido[1]:.1f})',
94
+ xy=PONTO_B,
95
+ xytext=(PONTO_B[0] + 5, PONTO_B[1] + 5),
96
+ arrowprops=dict(facecolor='yellow', shrink=0.05, width=1.5, headwidth=10),
97
+ fontsize=11, color='yellow',
98
+ bbox=dict(boxstyle="round,pad=0.3", fc="black", ec="yellow", lw=1))
99
+
100
+ # Configurações do Gráfico
101
+ ax.set_title('O Oráculo da Continuidade', fontsize=18, pad=20)
102
+ ax.legend(loc='best')
103
+ ax.grid(True, linestyle='--', alpha=0.2)
104
+ ax.set_aspect('equal', adjustable='box')
105
+ ax.set_xlabel("Eixo X")
106
+ ax.set_ylabel("Eixo Y")
107
+
108
+ # Salvar a figura para o Gradio exibir
109
+ caminho_figura = "continuidade.png"
110
+ plt.savefig(caminho_figura, bbox_inches='tight', pad_inches=0.1, dpi=120)
111
+ plt.close()
112
+
113
+ return caminho_figura
114
+
115
+ # --- Interface Gradio ---
116
+
117
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="teal", secondary_hue="orange")) as demo:
118
+ gr.Markdown(
119
+ """
120
+ # 🔮 O Oráculo da Continuidade
121
+ ### Um laboratório para o Teorema das Crianças
122
+ Defina a trajetória da "Criança A" especificando dois pontos de controle. O Oráculo irá calcular a "inércia" do movimento final
123
+ e gerar a continuação da "Criança B", garantindo uma transição perfeitamente suave.
124
+ """
125
+ )
126
+
127
+ with gr.Row():
128
+ with gr.Column(scale=1):
129
+ gr.Markdown("**1. Defina o Caminho da Criança A**")
130
+ gr.Markdown("O caminho começa em `[0,0]` e termina no `Ponto B`, passando pelo `Ponto de Inflexão`.")
131
+
132
+ p_inflexao_x = gr.Slider(-100, 100, value=25, label="Ponto de Inflexão (X)")
133
+ p_inflexao_y = gr.Slider(-100, 100, value=75, label="Ponto de Inflexão (Y)")
134
+
135
+ p_b_x = gr.Slider(-100, 100, value=50, label="Ponto B (Final da Criança A)")
136
+ p_b_y = gr.Slider(-100, 100, value=50, label="Ponto B (Final da Criança A)")
137
+
138
+ tamanho_eco_percent = gr.Slider(1, 50, value=15, step=1, label="Tamanho do Eco de Aprendizado (%)")
139
+
140
+ run_button = gr.Button("Gerar Continuidade", variant="primary")
141
+
142
+ with gr.Column(scale=2):
143
+ gr.Markdown("**2. Observe a Continuidade Gerada**")
144
+ output_plot = gr.Image(label="Gráfico da Jornada")
145
+
146
+ run_button.click(
147
+ fn=gerar_grafico_continuidade,
148
+ inputs=[p_inflexao_x, p_inflexao_y, p_b_x, p_b_y, tamanho_eco_percent],
149
+ outputs=output_plot
150
+ )
151
+
152
+ gr.Examples(
153
+ examples=[
154
+ [50, 100, 100, 0, 10],
155
+ [-50, 50, 0, 100, 20],
156
+ [80, 20, 40, 90, 5],
157
+ [25, -75, 75, -25, 30]
158
+ ],
159
+ inputs=[p_inflexao_x, p_inflexao_y, p_b_x, p_b_y, tamanho_eco_percent],
160
+ outputs=output_plot,
161
+ fn=gerar_grafico_continuidade,
162
+ cache_examples=True
163
+ )
164
+
165
+ if __name__ == "__main__":
166
+ demo.launch()