Advertisement
here2share

# tk_elastic_collision_by_time.py

Aug 3rd, 2024
263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.56 KB | None | 0 0
  1. # tk_elastic_collision_by_time.py
  2.  
  3. import tkinter as tk
  4. import random
  5. import math
  6. import time
  7.  
  8. WW, HH = 600, 600
  9. BALL_RADIUS = 20
  10. NUM_BALLS = 60
  11.  
  12. root = tk.Tk()
  13. root.geometry(f"{WW}x{HH}+0+0")
  14.  
  15. canvas = tk.Canvas(root, width=WW, height=HH)
  16. canvas.pack()
  17.  
  18. balls = []
  19. for _ in range(NUM_BALLS):
  20.     x = random.randint(BALL_RADIUS, WW - BALL_RADIUS)
  21.     y = random.randint(BALL_RADIUS, HH - BALL_RADIUS)
  22.     angle = random.uniform(0, 2 * math.pi)
  23.     speed = 90
  24.     vx = speed * math.cos(angle)
  25.     vy = speed * math.sin(angle)
  26.     id = canvas.create_oval(x - BALL_RADIUS, y - BALL_RADIUS,
  27.                             x + BALL_RADIUS, y + BALL_RADIUS,
  28.                             fill="#%06x" % random.randint(0, 0xFFFFFF))
  29.     balls.append((x, y, vx, vy, id, time.time()))
  30.  
  31. BALL_RADIUS2 = BALL_RADIUS + 2
  32. while 1:
  33.     current_time = time.time()
  34.     for i, (x, y, vx, vy, id, last_update) in enumerate(balls):
  35.         dt = current_time - last_update
  36.         x += vx * dt
  37.         y += vy * dt
  38.  
  39.         for j, (x2, y2, vx2, vy2, id2, _) in enumerate(balls):
  40.             if i != j:
  41.                 dx = x - x2
  42.                 dy = y - y2
  43.                 distance = math.sqrt(dx ** 2 + dy ** 2)
  44.  
  45.                 if distance < 2 * BALL_RADIUS:
  46.                     # Calculate the normal vector
  47.                     nx = dx / distance
  48.                     ny = dy / distance
  49.  
  50.                     # Calculate the tangent vector
  51.                     tx = -ny
  52.                     ty = nx
  53.  
  54.                     # Project the velocities onto the tangent and normal vectors
  55.                     v1n = vx * nx + vy * ny
  56.                     v1t = vx * tx + vy * ty
  57.                     v2n = vx2 * nx + vy2 * ny
  58.                     v2t = vx2 * tx + vy2 * ty
  59.  
  60.                     # Swap the normal components of the velocities
  61.                     v1n, v2n = v2n, v1n
  62.  
  63.                     # Convert the velocities back to the original coordinate system
  64.                     vx = v1n * nx + v1t * tx
  65.                     vy = v1n * ny + v1t * ty
  66.                     vx2 = v2n * nx + v2t * tx
  67.                     vy2 = v2n * ny + v2t * ty
  68.  
  69.                     # Update the positions to ensure the balls don't overlap
  70.                     x += (2 * BALL_RADIUS2 - distance) * nx / 2
  71.                     y += (2 * BALL_RADIUS2 - distance) * ny / 2
  72.                     x2 -= (2 * BALL_RADIUS2 - distance) * nx / 2
  73.                     y2 -= (2 * BALL_RADIUS2 - distance) * ny / 2
  74.  
  75.                     balls[i] = (x, y, vx, vy, id, current_time)
  76.                     balls[j] = (x2, y2, vx2, vy2, id2, current_time)
  77.  
  78.  
  79.         if x - BALL_RADIUS < 0:
  80.             x = BALL_RADIUS2
  81.             vx *= -1
  82.         elif x + BALL_RADIUS > WW:
  83.             x = WW - BALL_RADIUS2
  84.             vx *= -1
  85.         if y - BALL_RADIUS < 0:
  86.             y = BALL_RADIUS2
  87.             vy *= -1
  88.         elif y + BALL_RADIUS > HH:
  89.             y = HH - BALL_RADIUS2
  90.             vy *= -1
  91.  
  92.         canvas.coords(id, x - BALL_RADIUS, y - BALL_RADIUS,
  93.                       x + BALL_RADIUS, y + BALL_RADIUS)
  94.  
  95.         balls[i] = (x, y, vx, vy, id, current_time)
  96.     root.update()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement