x2XcarleX2x commited on
Commit
af62927
·
verified ·
1 Parent(s): cb02dd8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -91
app.py CHANGED
@@ -2,139 +2,85 @@ import gradio as gr
2
  import numpy as np
3
  import matplotlib.pyplot as plt
4
  from mpl_toolkits.mplot3d import Axes3D
5
- from matplotlib.collections import LineCollection
6
- from matplotlib.colors import LinearSegmentedColormap
7
  import math
8
  from scipy.special import comb
9
  import time
10
 
11
- # --- Funções Matemáticas e Utilitários ---
12
-
13
- def quantizar(valor, multiplo=4):
14
- """Arredonda um valor para o múltiplo mais próximo."""
15
- return multiplo * round(valor / multiplo)
16
-
17
- def bernstein_poly(i, n, t):
18
- return comb(n, i) * (t**(i)) * ((1 - t)**(n - i))
19
-
20
  def bezier_curve_3d(points, n_times=20):
21
- n_points = len(points)
22
- # Quantiza os pontos de controle
23
- points_q = [np.array([quantizar(p[0]), quantizar(p[1]), quantizar(p[2])]) for p in points]
24
  x_points, y_points, z_points = np.array([p[0] for p in points_q]), np.array([p[1] for p in points_q]), np.array([p[2] for p in points_q])
25
  t = np.linspace(0.0, 1.0, n_times)
26
  polynomial_array = np.array([bernstein_poly(i, n_points - 1, t) for i in range(n_points)])
27
- x_vals = np.dot(x_points, polynomial_array)
28
- y_vals = np.dot(y_points, polynomial_array)
29
- z_vals = np.dot(z_points, polynomial_array)
30
  return x_vals, y_vals, z_vals
31
-
32
  def aprender_com_o_eco_3d(pontos_do_eco: list):
33
  if len(pontos_do_eco) < 2: return {"velocity_vector": np.array([0, 0, 0])}
34
  p1, p2 = np.array(pontos_do_eco[0]), np.array(pontos_do_eco[-1])
35
  return {"velocity_vector": p2 - p1}
 
36
 
37
- # --- Função Principal do Gradio (O Motor Elegante) ---
38
-
39
  def motor_da_simulacao_infinita(angulo_camera: int):
40
- ponto_a = np.array([quantizar(v) for v in [-40., 20., 10.]])
41
- vetor_inercia = np.array([quantizar(v) for v in [30., 10., -20.]])
42
  historico_rastro = [ponto_a.tolist()]
43
-
44
  fig = plt.figure(figsize=(8, 8)); ax = fig.add_subplot(111, projection='3d')
45
  cor_fundo = '#0a0a0a'; fig.patch.set_facecolor(cor_fundo); ax.set_facecolor(cor_fundo)
46
-
47
- # --- NOVO: Setup para o Rastro em Degradê ---
48
- cor_rastro = '#ff4500'
49
- cmap = LinearSegmentedColormap.from_list("rastro_cmap", [(0, 0, 0, 0), cor_rastro], N=256)
50
- # ---------------------------------------------
51
-
52
  ciclo_num = 0
53
  while True:
54
- ciclo_num += 1
55
-
56
- ponto_b_raw = np.random.rand(3) * 50 - 25
57
  ponto_b = np.array([quantizar(v) for v in ponto_b_raw])
58
-
59
  ponto_controle = ponto_a + vetor_inercia
60
  pontos_curva = [ponto_a, ponto_controle, ponto_b]
61
  x_ciclo, y_ciclo, z_ciclo = bezier_curve_3d(pontos_curva)
62
-
63
  novos_pontos_rastro = list(zip(x_ciclo, y_ciclo, z_ciclo))
64
  historico_rastro.extend(novos_pontos_rastro)
65
- max_rastro = 150
66
- historico_rastro = historico_rastro[-max_rastro:]
67
-
68
- tamanho_eco = 10
69
- pontos_eco = historico_rastro[-tamanho_eco:]
70
  vetor_inercia = aprender_com_o_eco_3d(pontos_eco)["velocity_vector"]
71
-
72
  for frame in range(len(x_ciclo)):
73
- ax.cla()
74
- ax.xaxis.pane.fill = False; ax.yaxis.pane.fill = False; ax.zaxis.pane.fill = False
75
- ax.grid(color='#222222', linestyle='--')
76
- ax.view_init(elev=30., azim=angulo_camera)
77
  ax.set_xlim(-30, 30); ax.set_ylim(-30, 30); ax.set_zlim(-30, 30)
78
  ax.set_xticklabels([]); ax.set_yticklabels([]); ax.set_zticklabels([])
79
-
80
- ax.scatter(*ponto_a, s=150, c='lime', alpha=0.7)
81
- ax.scatter(*ponto_b, s=150, c='red', marker='X', alpha=0.9)
82
-
83
- # --- LÓGICA DO RASTRO EM DEGRADÊ ---
84
  tamanho_rastro_fixo = 12
85
  indice_global_frame = len(historico_rastro) - len(x_ciclo) + frame
86
  start_index = max(0, indice_global_frame - tamanho_rastro_fixo)
87
-
88
- rastro_atual = np.array(historico_rastro[start_index:indice_global_frame+1])
89
-
90
  if len(rastro_atual) > 1:
91
- pontos = rastro_atual.reshape(-1, 1, 3)
92
- segmentos = np.concatenate([pontos[:-1], pontos[1:]], axis=1)
93
-
94
- # Cria um array de cores com transparência crescente
95
- alphas = np.linspace(0.0, 0.8, len(segmentos))
96
- cores = cmap(np.arange(256))
97
- cores[:,-1] = np.linspace(0, 1, 256)
98
- grad_cmap = LinearSegmentedColormap.from_list('custom_alpha', cores)
99
-
100
- lc = LineCollection(segmentos, cmap=grad_cmap, linewidth=4)
101
- lc.set_array(np.linspace(0, 1, len(segmentos)))
102
- ax.add_collection3d(lc, zs=rastro_atual[:, 2], zdir='z')
103
-
104
  # ------------------------------------
105
 
106
- ax.plot([x_ciclo[frame]], [y_ciclo[frame]], [z_ciclo[frame]], 'o', color=cor_rastro, markersize=8, markeredgecolor='white')
107
-
108
- info_texto = f"Ciclo: {ciclo_num}\nAlvo: {np.round(ponto_b)}"
109
- ax.text2D(0.05, 0.95, info_texto, transform=ax.transAxes, color='white', fontsize=10)
110
-
111
  yield fig
112
  time.sleep(0.01)
113
-
114
  ponto_a = ponto_b
115
-
116
  plt.close(fig)
117
 
118
- # --- Interface Gradio (Inalterada) ---
119
  with gr.Blocks(theme=gr.themes.Base(primary_hue="purple", secondary_hue="orange")) as demo:
120
- gr.Markdown(
121
- """
122
- # Simulador Elegante 3D de Convergência
123
- Uma simulação autônoma com física "quantizada" e um rastro de 12 vetores em degradê.
124
- """
125
- )
126
- with gr.Row():
127
- with gr.Column(scale=1):
128
- angulo_camera_slider = gr.Slider(-180, 180, value=25, label="Ângulo da Câmera (Fixo)")
129
- start_btn = gr.Button("🚀 Iniciar Simulação Elegante", variant="primary")
130
- with gr.Column(scale=2):
131
- plot_output = gr.Plot(label="Visualização em Tempo Real")
132
-
133
- start_btn.click(
134
- fn=motor_da_simulacao_infinita,
135
- inputs=[angulo_camera_slider],
136
- outputs=[plot_output]
137
- )
138
 
139
  if __name__ == "__main__":
140
  demo.launch()
 
2
  import numpy as np
3
  import matplotlib.pyplot as plt
4
  from mpl_toolkits.mplot3d import Axes3D
 
 
5
  import math
6
  from scipy.special import comb
7
  import time
8
 
9
+ # --- Funções Matemáticas ---
10
+ def bernstein_poly(i, n, t): return comb(n, i) * (t**(i)) * ((1 - t)**(n - i))
 
 
 
 
 
 
 
11
  def bezier_curve_3d(points, n_times=20):
12
+ n_points = len(points); points_q = [np.array([quantizar(p[0]), quantizar(p[1]), quantizar(p[2])]) for p in points]
 
 
13
  x_points, y_points, z_points = np.array([p[0] for p in points_q]), np.array([p[1] for p in points_q]), np.array([p[2] for p in points_q])
14
  t = np.linspace(0.0, 1.0, n_times)
15
  polynomial_array = np.array([bernstein_poly(i, n_points - 1, t) for i in range(n_points)])
16
+ x_vals, y_vals, z_vals = np.dot(x_points, polynomial_array), np.dot(y_points, polynomial_array), np.dot(z_points, polynomial_array)
 
 
17
  return x_vals, y_vals, z_vals
 
18
  def aprender_com_o_eco_3d(pontos_do_eco: list):
19
  if len(pontos_do_eco) < 2: return {"velocity_vector": np.array([0, 0, 0])}
20
  p1, p2 = np.array(pontos_do_eco[0]), np.array(pontos_do_eco[-1])
21
  return {"velocity_vector": p2 - p1}
22
+ def quantizar(valor, multiplo=4): return multiplo * round(valor / multiplo)
23
 
24
+ # --- Motor da Simulação ---
 
25
  def motor_da_simulacao_infinita(angulo_camera: int):
26
+ ponto_a = np.array([quantizar(v) for v in [0., 0., 0.]])
27
+ vetor_inercia = np.array([quantizar(v) for v in [10., 10., 10.]])
28
  historico_rastro = [ponto_a.tolist()]
 
29
  fig = plt.figure(figsize=(8, 8)); ax = fig.add_subplot(111, projection='3d')
30
  cor_fundo = '#0a0a0a'; fig.patch.set_facecolor(cor_fundo); ax.set_facecolor(cor_fundo)
 
 
 
 
 
 
31
  ciclo_num = 0
32
  while True:
33
+ ciclo_num += 1; ponto_b_raw = np.random.rand(3) * 50 - 25
 
 
34
  ponto_b = np.array([quantizar(v) for v in ponto_b_raw])
 
35
  ponto_controle = ponto_a + vetor_inercia
36
  pontos_curva = [ponto_a, ponto_controle, ponto_b]
37
  x_ciclo, y_ciclo, z_ciclo = bezier_curve_3d(pontos_curva)
 
38
  novos_pontos_rastro = list(zip(x_ciclo, y_ciclo, z_ciclo))
39
  historico_rastro.extend(novos_pontos_rastro)
40
+ historico_rastro = historico_rastro[-150:]
41
+ pontos_eco = historico_rastro[-10:]
 
 
 
42
  vetor_inercia = aprender_com_o_eco_3d(pontos_eco)["velocity_vector"]
43
+ rastro_np = np.array(historico_rastro)
44
  for frame in range(len(x_ciclo)):
45
+ ax.cla(); ax.xaxis.pane.fill = False; ax.yaxis.pane.fill = False; ax.zaxis.pane.fill = False
46
+ ax.grid(color='#222222', linestyle='--'); ax.view_init(elev=30., azim=angulo_camera)
 
 
47
  ax.set_xlim(-30, 30); ax.set_ylim(-30, 30); ax.set_zlim(-30, 30)
48
  ax.set_xticklabels([]); ax.set_yticklabels([]); ax.set_zticklabels([])
49
+ ax.scatter(*ponto_a, s=150, c='lime', alpha=0.7); ax.scatter(*ponto_b, s=150, c='red', marker='X', alpha=0.9)
50
+
51
+ # --- CORREÇÃO DO RASTRO EM DEGRADÊ ---
 
 
52
  tamanho_rastro_fixo = 12
53
  indice_global_frame = len(historico_rastro) - len(x_ciclo) + frame
54
  start_index = max(0, indice_global_frame - tamanho_rastro_fixo)
55
+ rastro_atual = historico_rastro[start_index:indice_global_frame+1]
 
 
56
  if len(rastro_atual) > 1:
57
+ # Desenha cada segmento do rastro com uma transparência diferente
58
+ for i in range(len(rastro_atual) - 1):
59
+ p1 = rastro_atual[i]; p2 = rastro_atual[i+1]
60
+ alpha = 0.8 * (i / tamanho_rastro_fixo) # Calcula o alfa para o degradê
61
+ ax.plot([p1[0], p2[0]], [p1[1], p2[1]], [p1[2], p2[2]], color='#ff4500', linewidth=4, alpha=alpha)
 
 
 
 
 
 
 
 
62
  # ------------------------------------
63
 
64
+ ax.plot([x_ciclo[frame]], [y_ciclo[frame]], [z_ciclo[frame]], 'o', color='#ff4500', markersize=8, markeredgecolor='white')
65
+ info_texto = f"Ciclo: {ciclo_num}\nAlvo: {np.round(ponto_b)}"; ax.text2D(0.05, 0.95, info_texto, transform=ax.transAxes, color='white')
 
 
 
66
  yield fig
67
  time.sleep(0.01)
 
68
  ponto_a = ponto_b
 
69
  plt.close(fig)
70
 
71
+ # --- Interface Gradio ---
72
  with gr.Blocks(theme=gr.themes.Base(primary_hue="purple", secondary_hue="orange")) as demo:
73
+ gr.Markdown("# ✨ Simulador de Convergência Causal ✨"); gr.Markdown("### A Matemática do Próximo Passo")
74
+ with gr.Tabs():
75
+ with gr.TabItem("🔬 A Simulação"):
76
+ with gr.Row():
77
+ with gr.Column(scale=1):
78
+ gr.Markdown("Controle a perspectiva da câmera e inicie a simulação. O agente (bola) irá navegar autonomamente, gerando novos alvos e deixando um rastro de inércia em degradê."); angulo_camera_slider = gr.Slider(-180, 180, value=25, label="Ângulo da Câmera (Fixo)"); start_btn = gr.Button("🚀 Iniciar Simulação", variant="primary")
79
+ with gr.Column(scale=2):
80
+ plot_output = gr.Plot(label="Visualização em Tempo Real")
81
+ with gr.TabItem("📜 A Teoria"):
82
+ with open("explanation.md", "r", encoding="utf-8") as f: gr.Markdown(f.read())
83
+ start_btn.click(fn=motor_da_simulacao_infinita, inputs=[angulo_camera_slider], outputs=[plot_output])
 
 
 
 
 
 
 
84
 
85
  if __name__ == "__main__":
86
  demo.launch()