x2XcarleX2x commited on
Commit
f4a7c39
·
verified ·
1 Parent(s): f9704b1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +46 -66
app.py CHANGED
@@ -2,9 +2,9 @@ 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.animation import FuncAnimation
6
  import math
7
  from scipy.special import comb
 
8
 
9
  # --- Funções Matemáticas (Inalteradas) ---
10
  def bernstein_poly(i, n, t):
@@ -23,38 +23,27 @@ def aprender_com_o_eco_3d(pontos_do_eco: list):
23
  p1, p2 = np.array(pontos_do_eco[0]), np.array(pontos_do_eco[-1])
24
  return {"velocity_vector": p2 - p1}
25
 
26
- # --- Função Principal do Gradio (O Simulador Inteligente) ---
27
 
28
- def gerar_simulacao_inteligente(angulo_camera: int, progress=gr.Progress(track_tqdm=True)):
29
  """
30
- Gera uma jornada contínua com checkpoints dinâmicos e um loop perfeito.
31
  """
32
  NUM_CICLOS = 10
33
  VETORES_POR_CICLO = 60
34
 
35
- # --- 1. CALCULAR A JORNADA COMPLETA E OS CHECKPOINTS ---
36
- progress(0, desc="Calculando trajetória completa para 10 ciclos...")
37
-
38
  x_jornada_total, y_jornada_total, z_jornada_total = [], [], []
39
  checkpoints = [np.array([-40., 20., 10.])]
40
  vetor_inercia = np.array([30., 10., -20.])
41
 
42
  for i in range(NUM_CICLOS):
43
  ponto_a = checkpoints[-1]
44
-
45
- # --- LÓGICA DO LOOP PERFEITO ---
46
- if i < NUM_CICLOS - 1:
47
- ponto_b = np.random.rand(3) * 120 - 60
48
- else: # Último ciclo
49
- ponto_b = checkpoints[0] # O alvo é o primeiro checkpoint
50
- # -----------------------------
51
-
52
  checkpoints.append(ponto_b)
53
 
54
  ponto_controle = ponto_a + vetor_inercia
55
- # Para o loop final, adicionamos um ponto de controle extra para suavizar a chegada
56
  pontos_curva = [ponto_a, ponto_controle, ponto_b] if i < NUM_CICLOS - 1 else [ponto_a, ponto_controle, checkpoints[1], ponto_b]
57
-
58
  x_ciclo, y_ciclo, z_ciclo = bezier_curve_3d(pontos_curva, n_times=VETORES_POR_CICLO)
59
 
60
  x_jornada_total.extend(x_ciclo); y_jornada_total.extend(y_ciclo); z_jornada_total.extend(z_ciclo)
@@ -64,72 +53,63 @@ def gerar_simulacao_inteligente(angulo_camera: int, progress=gr.Progress(track_t
64
  vetor_inercia = aprender_com_o_eco_3d(pontos_eco)["velocity_vector"]
65
 
66
  total_frames = len(x_jornada_total)
67
- progress(0.2, desc=f"Trajetória de {total_frames} vetores calculada. Iniciando renderização...")
68
 
69
- # --- 2. RENDERIZAÇÃO INTELIGENTE ---
70
  fig = plt.figure(figsize=(8, 8)); ax = fig.add_subplot(111, projection='3d')
71
  cor_fundo = '#0a0a0a'; fig.patch.set_facecolor(cor_fundo); ax.set_facecolor(cor_fundo)
72
- ax.xaxis.pane.fill = False; ax.yaxis.pane.fill = False; ax.zaxis.pane.fill = False
73
- ax.grid(color='#222222', linestyle='--')
74
- ax.view_init(elev=30., azim=angulo_camera)
75
- ax.set_xlim(-70, 70); ax.set_ylim(-70, 70); ax.set_zlim(-70, 70)
76
- ax.set_xticklabels([]); ax.set_yticklabels([]); ax.set_zticklabels([])
77
 
78
- # Inicializa os elementos animados
79
- bola, = ax.plot([], [], [], 'o', color='#ff4500', markersize=8, markeredgecolor='white')
80
- rastro, = ax.plot([], [], [], '-', color='#ff4500', linewidth=4, alpha=0.6)
81
- checkpoints_passados_scatter = ax.scatter([], [], [], s=150, c='lime', alpha=0.7)
82
- proximo_checkpoint_scatter = ax.scatter([], [], [], s=150, c='red', marker='X', alpha=0.9)
83
- tamanho_rastro = 40
84
-
85
- def update(frame):
86
- # Atualiza a bola e o rastro
87
- bola.set_data_3d([x_jornada_total[frame]], [y_jornada_total[frame]], [z_jornada_total[frame]])
88
- start_index = max(0, frame - tamanho_rastro)
89
- rastro.set_data_3d(x_jornada_total[start_index:frame+1], y_jornada_total[start_index:frame+1], z_jornada_total[start_index:frame+1])
90
-
91
- # --- LÓGICA DOS CHECKPOINTS DINÂMICOS ---
92
- ciclo_atual = frame // VETORES_POR_CICLO
93
 
94
- # Mostra todos os checkpoints que já foram visitados (em verde)
 
 
 
 
 
 
 
 
95
  pontos_passados = np.array(checkpoints[:ciclo_atual + 1])
96
- checkpoints_passados_scatter._offsets3d = (pontos_passados[:,0], pontos_passados[:,1], pontos_passados[:,2])
97
-
98
- # Mostra o próximo alvo (em vermelho), mas apenas se não for o último
99
  if ciclo_atual + 1 < len(checkpoints):
100
  proximo_ponto = checkpoints[ciclo_atual + 1]
101
- proximo_checkpoint_scatter._offsets3d = ([proximo_ponto[0]], [proximo_ponto[1]], [proximo_ponto[2]])
102
- else: # Se chegou no final, esconde o marcador de alvo
103
- proximo_checkpoint_scatter._offsets3d = ([], [], [])
104
-
105
- return bola, rastro, checkpoints_passados_scatter, proximo_checkpoint_scatter
106
 
107
- # --- 3. UMA ÚNICA ANIMAÇÃO E UM ÚNICO VÍDEO ---
108
- ani = FuncAnimation(fig, update, frames=total_frames, interval=33, blit=False) # blit=False é mais robusto para 3D
109
- video_final = "simulacao_inteligente.mp4"
110
- ani.save(video_final, writer='ffmpeg', fps=30, dpi=120, progress_callback=lambda i, n: progress(0.2 + 0.8 * (i/n), desc=f"Renderizando vetor {i+1}/{n}"))
111
- plt.close(fig)
112
-
113
- return video_final
 
 
 
 
 
114
 
115
- # --- Interface Gradio (Inalterada) ---
116
- with gr.Blocks(theme=gr.themes.Base(primary_hue="purple")) as demo:
117
  gr.Markdown(
118
  """
119
- # 🧠 Simulador de Jornada Inteligente 3D
120
- Gere uma jornada contínua de **10 ciclos**. Os checkpoints (alvos em vermelho) aparecem quando a bola se aproxima.
121
- Checkpoints visitados se tornam verdes. A trajetória final é calculada para criar um **loop perfeito**.
122
  """
123
  )
124
  with gr.Row():
125
  with gr.Column(scale=1):
126
- gr.Markdown("### 🎮 Controles")
127
- angulo_camera_slider = gr.Slider(-180, 180, value=30, label="Ângulo da Câmera (Fixo)")
128
- generate_btn = gr.Button("🚀 Gerar Jornada Inteligente", variant="primary")
129
  with gr.Column(scale=2):
130
- gr.Markdown("### 📽️ Vídeo Final")
131
- video_output = gr.Video(label="Animação da Jornada Contínua", autoplay=True)
132
- generate_btn.click(fn=gerar_simulacao_inteligente, inputs=[angulo_camera_slider], outputs=[video_output])
 
 
 
 
 
133
 
134
  if __name__ == "__main__":
135
  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 (Inalteradas) ---
10
  def bernstein_poly(i, n, t):
 
23
  p1, p2 = np.array(pontos_do_eco[0]), np.array(pontos_do_eco[-1])
24
  return {"velocity_vector": p2 - p1}
25
 
26
+ # --- Função Principal do Gradio (Renderização em Tempo Real) ---
27
 
28
+ def gerar_simulacao_em_tempo_real(angulo_camera: int):
29
  """
30
+ Gera a jornada completa e a 'yielda' frame a frame para a UI do Gradio.
31
  """
32
  NUM_CICLOS = 10
33
  VETORES_POR_CICLO = 60
34
 
35
+ # 1. Calcula a jornada completa
 
 
36
  x_jornada_total, y_jornada_total, z_jornada_total = [], [], []
37
  checkpoints = [np.array([-40., 20., 10.])]
38
  vetor_inercia = np.array([30., 10., -20.])
39
 
40
  for i in range(NUM_CICLOS):
41
  ponto_a = checkpoints[-1]
42
+ ponto_b = np.random.rand(3) * 120 - 60 if i < NUM_CICLOS - 1 else checkpoints[0]
 
 
 
 
 
 
 
43
  checkpoints.append(ponto_b)
44
 
45
  ponto_controle = ponto_a + vetor_inercia
 
46
  pontos_curva = [ponto_a, ponto_controle, ponto_b] if i < NUM_CICLOS - 1 else [ponto_a, ponto_controle, checkpoints[1], ponto_b]
 
47
  x_ciclo, y_ciclo, z_ciclo = bezier_curve_3d(pontos_curva, n_times=VETORES_POR_CICLO)
48
 
49
  x_jornada_total.extend(x_ciclo); y_jornada_total.extend(y_ciclo); z_jornada_total.extend(z_ciclo)
 
53
  vetor_inercia = aprender_com_o_eco_3d(pontos_eco)["velocity_vector"]
54
 
55
  total_frames = len(x_jornada_total)
 
56
 
57
+ # 2. Setup do Gráfico (será reutilizado no loop)
58
  fig = plt.figure(figsize=(8, 8)); ax = fig.add_subplot(111, projection='3d')
59
  cor_fundo = '#0a0a0a'; fig.patch.set_facecolor(cor_fundo); ax.set_facecolor(cor_fundo)
 
 
 
 
 
60
 
61
+ # --- 3. LOOP DE RENDERIZAÇÃO E YIELD ---
62
+ for frame in range(total_frames):
63
+ ax.cla() # Limpa o gráfico para o próximo frame
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
+ # Configurações do ambiente fixo
66
+ ax.xaxis.pane.fill = False; ax.yaxis.pane.fill = False; ax.zaxis.pane.fill = False
67
+ ax.grid(color='#222222', linestyle='--')
68
+ ax.view_init(elev=30., azim=angulo_camera)
69
+ ax.set_xlim(-70, 70); ax.set_ylim(-70, 70); ax.set_zlim(-70, 70)
70
+ ax.set_xticklabels([]); ax.set_yticklabels([]); ax.set_zticklabels([])
71
+
72
+ # Lógica dos checkpoints dinâmicos
73
+ ciclo_atual = frame // VETORES_POR_CICLO
74
  pontos_passados = np.array(checkpoints[:ciclo_atual + 1])
75
+ ax.scatter(pontos_passados[:,0], pontos_passados[:,1], pontos_passados[:,2], s=150, c='lime', alpha=0.7)
 
 
76
  if ciclo_atual + 1 < len(checkpoints):
77
  proximo_ponto = checkpoints[ciclo_atual + 1]
78
+ ax.scatter(proximo_ponto[0], proximo_ponto[1], proximo_ponto[2], s=150, c='red', marker='X', alpha=0.9)
 
 
 
 
79
 
80
+ # Desenha a bola e o rastro
81
+ tamanho_rastro = 40
82
+ start_index = max(0, frame - tamanho_rastro)
83
+ ax.plot(x_jornada_total[start_index:frame+1], y_jornada_total[start_index:frame+1], z_jornada_total[start_index:frame+1], '-', color='#ff4500', linewidth=4, alpha=0.6)
84
+ ax.plot([x_jornada_total[frame]], [y_jornada_total[frame]], [z_jornada_total[frame]], 'o', color='#ff4500', markersize=8, markeredgecolor='white')
85
+
86
+ # O comando mágico: envia o gráfico atual para a UI
87
+ yield fig
88
+
89
+ plt.close(fig) # Libera a memória no final
90
+
91
+ # --- Interface Gradio ---
92
 
93
+ with gr.Blocks(theme=gr.themes.Base(primary_hue="red")) as demo:
 
94
  gr.Markdown(
95
  """
96
+ # 🧠 Simulador de Jornada Inteligente 3D (Tempo Real)
97
+ Clique em "Gerar" para iniciar a simulação. O gráfico será renderizado frame a frame diretamente na UI.
 
98
  """
99
  )
100
  with gr.Row():
101
  with gr.Column(scale=1):
102
+ angulo_camera_slider = gr.Slider(-180, 180, value=45, label="Ângulo da Câmera (Azimute)")
103
+ generate_btn = gr.Button("🚀 Gerar Simulação em Tempo Real", variant="primary")
 
104
  with gr.Column(scale=2):
105
+ # Usamos gr.Plot para exibir os gráficos do Matplotlib
106
+ plot_output = gr.Plot(label="Visualização da Simulação")
107
+
108
+ generate_btn.click(
109
+ fn=gerar_simulacao_em_tempo_real,
110
+ inputs=[angulo_camera_slider],
111
+ outputs=[plot_output]
112
+ )
113
 
114
  if __name__ == "__main__":
115
  demo.launch()