caarleexx commited on
Commit
7bf55c6
·
verified ·
1 Parent(s): e5d4f4b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +27 -40
app.py CHANGED
@@ -15,7 +15,7 @@ from PIL import Image
15
  def bernstein_poly(i, n, t):
16
  return comb(n, i) * (t**i) * ((1-t)**(n-i))
17
 
18
- def bezier_curve(points, n_times=20): # original usa 20
19
  points = np.array(points)
20
  t = np.linspace(0, 1, n_times)
21
  n = len(points) - 1
@@ -34,7 +34,7 @@ def learn_from_echo(echo_points):
34
  return p2 - p1
35
 
36
  # ============================================================
37
- # SIMULAÇÃO COM RASTRO IDÊNTICO AO ORIGINAL
38
  # ============================================================
39
 
40
  class CometSimulation:
@@ -69,24 +69,26 @@ class CometSimulation:
69
  dpi = 100
70
  fig = plt.figure(figsize=(12, 8), dpi=dpi)
71
 
72
- # Layout: 3D à esquerda, info à direita
73
  gs = fig.add_gridspec(2, 3, hspace=0.3, wspace=0.3)
74
 
75
  ax_3d = fig.add_subplot(gs[:, 0:2], projection='3d')
76
- ax_info = fig.add_subplot(gs[0, 2])
77
- ax_stats = fig.add_subplot(gs[1, 2])
78
 
79
  bg_color = '#0a0a0a'
80
  fig.patch.set_facecolor(bg_color)
81
  for ax in [ax_3d, ax_info, ax_stats]:
82
  ax.set_facecolor(bg_color)
83
 
84
- # Esfera transparente de referência
 
85
  u = np.linspace(0, 2*np.pi, 20)
86
  v = np.linspace(0, np.pi, 15)
87
  sphere_x = 28 * np.outer(np.cos(u), np.sin(v))
88
  sphere_y = 28 * np.outer(np.sin(u), np.sin(v))
89
  sphere_z = 28 * np.outer(np.ones_like(u), np.cos(v))
 
90
 
91
  cycle = 0
92
  frame_global = 0
@@ -94,7 +96,7 @@ class CometSimulation:
94
  while self.running:
95
  cycle += 1
96
 
97
- # Ângulo da câmera
98
  if auto_rotate:
99
  current_angle = (camera_angle + frame_global * 0.8) % 360
100
  else:
@@ -146,19 +148,17 @@ class CometSimulation:
146
  ax_3d.set_yticklabels([])
147
  ax_3d.set_zticklabels([])
148
 
149
- # Esfera transparente (adicional, não atrapalha)
150
  ax_3d.plot_wireframe(sphere_x, sphere_y, sphere_z,
151
  color='#4488ff', alpha=0.1, linewidth=0.5)
 
152
 
153
  # ===== ELEMENTOS ESTÁTICOS (igual ao original) =====
154
- # Ponto atual (início do ciclo) - verde no original
155
- ax_3d.scatter(*current_point, s=150, c='lime', alpha=0.7)
156
-
157
- # Alvo - X vermelho
158
- ax_3d.scatter(*target, s=150, c='red', marker='X', alpha=0.9)
159
 
160
  # ===== RASTRO IDÊNTICO AO ORIGINAL =====
161
- # Calcula índices do rastro (últimos 12 pontos ANTES do atual)
162
  trail_end = len(history) - len(x_cycle) + frame_idx
163
  trail_start = max(0, trail_end - 12)
164
  trail_segment = history[trail_start:trail_end+1]
@@ -166,7 +166,7 @@ class CometSimulation:
166
  if len(trail_segment) > 1:
167
  for i in range(len(trail_segment) - 1):
168
  p1, p2 = trail_segment[i], trail_segment[i+1]
169
- # Alpha = 0.8 * (i/12) - EXATAMENTE como no original
170
  alpha = 0.8 * (i / 12)
171
  ax_3d.plot([p1[0], p2[0]], [p1[1], p2[1]], [p1[2], p2[2]],
172
  color='#ff4500', linewidth=4, alpha=alpha)
@@ -181,35 +181,28 @@ class CometSimulation:
181
  color='white', fontsize=10,
182
  bbox=dict(boxstyle='round', facecolor='#222222', alpha=0.7))
183
 
184
- # ===== PAINEL INFO =====
185
- ax_info.set_title('📊 ESTATÍSTICAS', color='white', fontsize=11)
186
  ax_info.axis('off')
187
-
188
- inertia_text = f"""INÉRCIA:
189
  ({inertia[0]:.1f}, {inertia[1]:.1f}, {inertia[2]:.1f})
190
 
191
- HISTÓRICO: {len(history)} pontos
192
-
193
- ECO: {len(echo_points)} pontos"""
194
-
195
  ax_info.text(0.1, 0.8, inertia_text, transform=ax_info.transAxes,
196
  color='#ffaa00', fontsize=9, verticalalignment='top')
197
 
198
- # ===== PAINEL STATS =====
199
- ax_stats.set_title('📍 POSIÇÃO ATUAL', color='white', fontsize=11)
200
  ax_stats.axis('off')
201
-
202
  pos_text = f"""X: {x_cycle[frame_idx]:.1f}
203
  Y: {y_cycle[frame_idx]:.1f}
204
  Z: {z_cycle[frame_idx]:.1f}"""
205
-
206
  ax_stats.text(0.1, 0.6, pos_text, transform=ax_stats.transAxes,
207
  color='#88ccff', fontsize=12, fontweight='bold')
208
 
209
- # Renderiza
210
  fig.canvas.draw()
211
-
212
- # Converte para array
213
  buf = io.BytesIO()
214
  fig.savefig(buf, format='png', dpi=dpi,
215
  facecolor=bg_color, bbox_inches='tight',
@@ -220,19 +213,18 @@ Z: {z_cycle[frame_idx]:.1f}"""
220
  self.queue.put(buf)
221
 
222
  time.sleep(0.01) # igual ao original
223
-
224
  # Prepara próximo ciclo
225
  pos = target
226
 
227
  # ============================================================
228
- # INTERFACE
229
  # ============================================================
230
 
231
  simulation = CometSimulation()
232
 
233
  def get_frame(camera_angle, auto_rotate):
234
  queue = simulation.start(camera_angle, auto_rotate)
235
-
236
  try:
237
  while True:
238
  buf = queue.get(timeout=1.0)
@@ -243,18 +235,13 @@ def get_frame(camera_angle, auto_rotate):
243
  finally:
244
  simulation.stop()
245
 
246
- # Interface
247
- with gr.Blocks(theme=gr.themes.Base(
248
- primary_hue="purple",
249
- secondary_hue="orange",
250
- )) as demo:
251
-
252
  gr.HTML("""
253
  <div style="text-align: center; margin-bottom: 15px;">
254
  <h1 style="color: #ff4500; font-size: 2.2rem; margin: 0;">
255
  ✨ CAUSAL CONVERGENCE SIMULATOR ✨
256
  </h1>
257
- <p style="color: #cccccc;">rastro idêntico ao original • esfera transparente</p>
258
  </div>
259
  """)
260
 
 
15
  def bernstein_poly(i, n, t):
16
  return comb(n, i) * (t**i) * ((1-t)**(n-i))
17
 
18
+ def bezier_curve(points, n_times=20):
19
  points = np.array(points)
20
  t = np.linspace(0, 1, n_times)
21
  n = len(points) - 1
 
34
  return p2 - p1
35
 
36
  # ============================================================
37
+ # SIMULAÇÃO COM RASTRO IDÊNTICO AO ORIGINAL + ESFERA TRANSPARENTE
38
  # ============================================================
39
 
40
  class CometSimulation:
 
69
  dpi = 100
70
  fig = plt.figure(figsize=(12, 8), dpi=dpi)
71
 
72
+ # Layout: 3D à esquerda (2/3), painéis à direita (1/3)
73
  gs = fig.add_gridspec(2, 3, hspace=0.3, wspace=0.3)
74
 
75
  ax_3d = fig.add_subplot(gs[:, 0:2], projection='3d')
76
+ ax_info = fig.add_subplot(gs[0, 2]) # estatísticas de inércia
77
+ ax_stats = fig.add_subplot(gs[1, 2]) # posição atual
78
 
79
  bg_color = '#0a0a0a'
80
  fig.patch.set_facecolor(bg_color)
81
  for ax in [ax_3d, ax_info, ax_stats]:
82
  ax.set_facecolor(bg_color)
83
 
84
+ # ========== ESFERA TRANSPARENTE (MELHORIA VISUAL) ==========
85
+ # Malha da esfera – referência espacial sem poluir
86
  u = np.linspace(0, 2*np.pi, 20)
87
  v = np.linspace(0, np.pi, 15)
88
  sphere_x = 28 * np.outer(np.cos(u), np.sin(v))
89
  sphere_y = 28 * np.outer(np.sin(u), np.sin(v))
90
  sphere_z = 28 * np.outer(np.ones_like(u), np.cos(v))
91
+ # ============================================================
92
 
93
  cycle = 0
94
  frame_global = 0
 
96
  while self.running:
97
  cycle += 1
98
 
99
+ # Ângulo da câmera (com rotação automática opcional)
100
  if auto_rotate:
101
  current_angle = (camera_angle + frame_global * 0.8) % 360
102
  else:
 
148
  ax_3d.set_yticklabels([])
149
  ax_3d.set_zticklabels([])
150
 
151
+ # ========== DESENHA A ESFERA TRANSPARENTE ==========
152
  ax_3d.plot_wireframe(sphere_x, sphere_y, sphere_z,
153
  color='#4488ff', alpha=0.1, linewidth=0.5)
154
+ # ===================================================
155
 
156
  # ===== ELEMENTOS ESTÁTICOS (igual ao original) =====
157
+ ax_3d.scatter(*current_point, s=150, c='lime', alpha=0.7) # ponto inicial do ciclo
158
+ ax_3d.scatter(*target, s=150, c='red', marker='X', alpha=0.9) # alvo
 
 
 
159
 
160
  # ===== RASTRO IDÊNTICO AO ORIGINAL =====
161
+ # Índices: últimos 12 pontos antes do frame atual
162
  trail_end = len(history) - len(x_cycle) + frame_idx
163
  trail_start = max(0, trail_end - 12)
164
  trail_segment = history[trail_start:trail_end+1]
 
166
  if len(trail_segment) > 1:
167
  for i in range(len(trail_segment) - 1):
168
  p1, p2 = trail_segment[i], trail_segment[i+1]
169
+ # Alpha = 0.8 * (i/12) exatamente como no original
170
  alpha = 0.8 * (i / 12)
171
  ax_3d.plot([p1[0], p2[0]], [p1[1], p2[1]], [p1[2], p2[2]],
172
  color='#ff4500', linewidth=4, alpha=alpha)
 
181
  color='white', fontsize=10,
182
  bbox=dict(boxstyle='round', facecolor='#222222', alpha=0.7))
183
 
184
+ # ===== PAINEL INFO (MELHORIA) =====
185
+ ax_info.set_title('📊 INÉRCIA', color='white', fontsize=11)
186
  ax_info.axis('off')
187
+ inertia_text = f"""Vetor:
 
188
  ({inertia[0]:.1f}, {inertia[1]:.1f}, {inertia[2]:.1f})
189
 
190
+ Histórico: {len(history)} pontos
191
+ Eco: {len(echo_points)} pontos"""
 
 
192
  ax_info.text(0.1, 0.8, inertia_text, transform=ax_info.transAxes,
193
  color='#ffaa00', fontsize=9, verticalalignment='top')
194
 
195
+ # ===== PAINEL STATS (MELHORIA) =====
196
+ ax_stats.set_title('📍 POSIÇÃO', color='white', fontsize=11)
197
  ax_stats.axis('off')
 
198
  pos_text = f"""X: {x_cycle[frame_idx]:.1f}
199
  Y: {y_cycle[frame_idx]:.1f}
200
  Z: {z_cycle[frame_idx]:.1f}"""
 
201
  ax_stats.text(0.1, 0.6, pos_text, transform=ax_stats.transAxes,
202
  color='#88ccff', fontsize=12, fontweight='bold')
203
 
204
+ # Renderiza e envia
205
  fig.canvas.draw()
 
 
206
  buf = io.BytesIO()
207
  fig.savefig(buf, format='png', dpi=dpi,
208
  facecolor=bg_color, bbox_inches='tight',
 
213
  self.queue.put(buf)
214
 
215
  time.sleep(0.01) # igual ao original
216
+
217
  # Prepara próximo ciclo
218
  pos = target
219
 
220
  # ============================================================
221
+ # INTERFACE GRADIO (COM ROTAÇÃO E PAINÉIS)
222
  # ============================================================
223
 
224
  simulation = CometSimulation()
225
 
226
  def get_frame(camera_angle, auto_rotate):
227
  queue = simulation.start(camera_angle, auto_rotate)
 
228
  try:
229
  while True:
230
  buf = queue.get(timeout=1.0)
 
235
  finally:
236
  simulation.stop()
237
 
238
+ with gr.Blocks(theme=gr.themes.Base(primary_hue="purple", secondary_hue="orange")) as demo:
 
 
 
 
 
239
  gr.HTML("""
240
  <div style="text-align: center; margin-bottom: 15px;">
241
  <h1 style="color: #ff4500; font-size: 2.2rem; margin: 0;">
242
  ✨ CAUSAL CONVERGENCE SIMULATOR ✨
243
  </h1>
244
+ <p style="color: #cccccc;">rastro original • esfera transparente • estatísticas</p>
245
  </div>
246
  """)
247