x2XcarleX2x commited on
Commit
09f64ca
·
verified ·
1 Parent(s): f461e9f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -107
app.py CHANGED
@@ -7,12 +7,14 @@ import math
7
  from scipy.special import comb
8
  import random
9
  import json
 
 
10
 
11
  # --- Funções Matemáticas (Inalteradas) ---
12
  def bernstein_poly(i, n, t):
13
  return comb(n, i) * (t**(i)) * ((1 - t)**(n - i))
14
 
15
- def bezier_curve_3d(points, n_times=120): # Fixo em 120 vetores/frames
16
  n_points = len(points)
17
  x_points, y_points, z_points = np.array([p[0] for p in points]), np.array([p[1] for p in points]), np.array([p[2] for p in points])
18
  t = np.linspace(0.0, 1.0, n_times)
@@ -25,113 +27,36 @@ def aprender_com_o_eco_3d(pontos_do_eco: list):
25
  p1, p2 = np.array(pontos_do_eco[0]), np.array(pontos_do_eco[-1])
26
  return {"velocity_vector": p2 - p1}
27
 
28
- # --- Função Principal do Gradio (Gerador de Diagrama Animado) ---
29
 
30
- def gerar_diagrama_animado(estado_anterior_json: str, angulo_camera: int, progress=gr.Progress(track_tqdm=True)):
31
  """
32
- Gera um ciclo da jornada com ambiente estático e movimento discreto da bola.
 
33
  """
34
- progress(0, desc="Decodificando estado anterior...")
35
- # 1. Carrega ou inicializa o estado
36
- if estado_anterior_json:
37
- estado = json.loads(estado_anterior_json)
38
- ponto_a = np.array(estado["ponto_b"])
39
- vetor_inercia_anterior = np.array(estado["vetor_inercia"])
40
- else: # Primeiro ciclo
41
- ponto_a = np.array([-40., 20., 10.])
42
- vetor_inercia_anterior = np.array([30., 10., -20.])
43
-
44
- progress(0.1, desc="Gerando novo checkpoint aleatório...")
45
- # 2. Gera um novo destino (Ponto B)
46
- ponto_b = np.random.rand(3) * 120 - 60
47
-
48
- progress(0.2, desc="Calculando trajetória (120 vetores)...")
49
- # 3. Calcula a nova trajetória
50
- ponto_controle = ponto_a + vetor_inercia_anterior
51
- pontos_curva = [ponto_a, ponto_controle, ponto_b]
52
- x_traj, y_traj, z_traj = bezier_curve_3d(pontos_curva) # Gera 120 vetores
53
- total_frames = len(x_traj)
54
-
55
- # 4. Aprende o "eco" para o próximo ciclo
56
- tamanho_eco = 30
57
- pontos_eco = list(zip(x_traj[-tamanho_eco:], y_traj[-tamanho_eco:], z_traj[-tamanho_eco:]))
58
- vetor_inercia_novo = aprender_com_o_eco_3d(pontos_eco)["velocity_vector"]
59
-
60
- # 5. Salva o novo estado
61
- estado_novo = {"ponto_a": ponto_a.tolist(), "ponto_b": ponto_b.tolist(), "vetor_inercia": vetor_inercia_novo.tolist()}
62
- estado_novo_json = json.dumps(estado_novo)
63
-
64
- # 6. Setup da Animação
65
- fig = plt.figure(figsize=(8, 8)); ax = fig.add_subplot(111, projection='3d')
66
- fig.patch.set_facecolor('#111111'); ax.set_facecolor('#111111')
67
-
68
- # --- A MUDANÇA PRINCIPAL: Ambiente Fixo ---
69
- # Desenha a cena estática UMA VEZ
70
- ax.plot(x_traj, y_traj, z_traj, color='cyan', linewidth=2, alpha=0.4, label='Trajetória (Linhas ABC)')
71
- ax.scatter(*ponto_a, s=400, c='lime', alpha=0.7, label='Checkpoint A (Início)')
72
- ax.scatter(*ponto_b, s=400, c='yellow', marker='X', alpha=0.7, label='Checkpoint B (Destino)')
73
- ax.view_init(elev=30., azim=angulo_camera) # Usa o ângulo da UI
74
- ax.set_xlim(-70, 70); ax.set_ylim(-70, 70); ax.set_zlim(-70, 70)
75
- ax.set_xticklabels([]); ax.set_yticklabels([]); ax.set_zticklabels([])
76
- ax.legend()
77
-
78
- # Inicializa apenas a bola, que é o único elemento que se move
79
- bola, = ax.plot([], [], [], 'o', color='red', markersize=10, markeredgecolor='white')
80
-
81
- def update(frame):
82
- # A bola avança um vetor (frame) de cada vez
83
- bola.set_data_3d([x_traj[frame]], [y_traj[frame]], [z_traj[frame]])
84
- return bola,
85
-
86
- # 7. Renderiza e Salva o Vídeo
87
- progress(0.5, desc="Renderizando animação do ciclo...")
88
- ani = FuncAnimation(fig, update, frames=total_frames, interval=33, blit=True)
89
- output_filename = "diagrama_animado.mp4"
90
- ani.save(output_filename, writer='ffmpeg', fps=30, dpi=100, progress_callback=lambda i, n: progress(0.5 + 0.5 * (i/n), desc=f"Renderizando vetor {i+1}/{n}"))
91
- plt.close(fig)
92
-
93
- info_ciclo = f"Ciclo Concluído.\nInício (A): {np.round(ponto_a, 1)}\nDestino (B): {np.round(ponto_b, 1)}\nInércia Aprendida: {np.round(vetor_inercia_novo, 1)}"
94
-
95
- return output_filename, estado_novo_json, info_ciclo
96
-
97
- # --- Interface Gradio ---
98
-
99
- with gr.Blocks(theme=gr.themes.Base(primary_hue="cyan")) as demo:
100
- gr.Markdown(
101
- """
102
- # 📈 Diagrama 3D Animado de Convergência
103
- Gere um ciclo da simulação. O ambiente (câmera, checkpoints, trajetória ABC) é FIXO.
104
- A animação mostra apenas a **bola vermelha se movendo no tempo**, avançando um vetor a cada frame, sobre o caminho pré-calculado.
105
- """
106
- )
107
-
108
- with gr.Row():
109
- with gr.Column(scale=1):
110
- gr.Markdown("### 🎮 Controles")
111
- estado_oculto = gr.Textbox(label="Estado da Simulação (JSON)", interactive=True, visible=False)
112
- angulo_camera_slider = gr.Slider(-180, 180, value=45, label="Ângulo da Câmera (Azimute)")
113
- info_output = gr.Textbox(label="Dados do Ciclo Atual", lines=4, interactive=False)
114
-
115
- with gr.Row():
116
- start_btn = gr.Button("🚀 Iniciar Simulação", variant="primary")
117
- next_btn = gr.Button("➡️ Gerar Próximo Ciclo", variant="secondary")
118
-
119
- with gr.Column(scale=2):
120
- gr.Markdown("### 📽️ Visualização do Ciclo")
121
- video_output = gr.Video(label="Animação do Ciclo Atual", autoplay=True)
122
-
123
- # Conexões dos botões
124
- start_btn.click(
125
- fn=lambda angulo: gerar_diagrama_animado(None, angulo),
126
- inputs=[angulo_camera_slider],
127
- outputs=[video_output, estado_oculto, info_output]
128
- )
129
 
130
- next_btn.click(
131
- fn=gerar_diagrama_animado,
132
- inputs=[estado_oculto, angulo_camera_slider],
133
- outputs=[video_output, estado_oculto, info_output]
134
- )
135
-
136
- if __name__ == "__main__":
137
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  from scipy.special import comb
8
  import random
9
  import json
10
+ import os
11
+ import subprocess
12
 
13
  # --- Funções Matemáticas (Inalteradas) ---
14
  def bernstein_poly(i, n, t):
15
  return comb(n, i) * (t**(i)) * ((1 - t)**(n - i))
16
 
17
+ def bezier_curve_3d(points, n_times=60): # Fixo em 60 vetores/frames
18
  n_points = len(points)
19
  x_points, y_points, z_points = np.array([p[0] for p in points]), np.array([p[1] for p in points]), np.array([p[2] for p in points])
20
  t = np.linspace(0.0, 1.0, n_times)
 
27
  p1, p2 = np.array(pontos_do_eco[0]), np.array(pontos_do_eco[-1])
28
  return {"velocity_vector": p2 - p1}
29
 
30
+ # --- Função Principal do Gradio (O Estúdio de Animação) ---
31
 
32
+ def gerar_sequencia_completa(angulo_camera: int, progress=gr.Progress(track_tqdm=True)):
33
  """
34
+ Gera uma sequência de 10 ciclos, renderiza cada um como um vídeo
35
+ e os concatena em um resultado final.
36
  """
37
+ NUM_CICLOS = 10
38
+ clipes_de_video = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
+ # Estado inicial da simulação
41
+ estado = {
42
+ "ponto_b": np.array([-40., 20., 10.]),
43
+ "vetor_inercia": np.array([30., 10., -20.])
44
+ }
45
+
46
+ for ciclo_atual in range(NUM_CICLOS):
47
+ progress(ciclo_atual / NUM_CICLOS, desc=f"Processando Ciclo {ciclo_atual + 1}/{NUM_CICLOS}")
48
+
49
+ # 1. Atualiza o estado para o novo ciclo
50
+ ponto_a = estado["ponto_b"]
51
+ vetor_inercia_anterior = estado["vetor_inercia"]
52
+ ponto_b = np.random.rand(3) * 120 - 60
53
+
54
+ # 2. Calcula a trajetória
55
+ ponto_controle = ponto_a + vetor_inercia_anterior
56
+ pontos_curva = [ponto_a, ponto_controle, ponto_b]
57
+ x_traj, y_traj, z_traj = bezier_curve_3d(pontos_curva) # 60 vetores
58
+ total_frames = len(x_traj)
59
+
60
+ # 3. Aprende o eco para o próximo ciclo
61
+ tamanho_eco = 20 # Eco menor para trajetórias mais curtas
62
+ pontos_eco = list(zip(x_traj[-tamanho