Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # tk_text2physics.py
- import tkinter as tk
- import random
- import math
- root = tk.Tk()
- root.title("# tk_text2physics")
- canvas = tk.Canvas(root, width=600, height=600, bg='#333333')
- canvas.pack()
- letters_x = []
- letters_y = []
- letters_vx = []
- letters_vy = []
- letters_angle = []
- letters_av = []
- letters_char = []
- letter_chars = list("QWERTYUIOPASDFGHJKLZXCVBNM1234567890")
- def apply_force(i, fx, fy):
- letters_vx[i] += fx
- letters_vy[i] += fy
- def update_letter(i):
- letters_vy[i] += 0.5
- letters_x[i] += letters_vx[i]
- letters_y[i] += letters_vy[i]
- letters_angle[i] += letters_av[i]
- letters_vx[i] *= 0.98
- letters_vy[i] *= 0.98
- letters_av[i] *= 0.92
- if abs(letters_vx[i]) < 0.01:
- letters_vx[i] = 0
- if abs(letters_vy[i]) < 0.01:
- letters_vy[i] = 0
- if abs(letters_av[i]) < 0.001:
- letters_av[i] = 0
- if letters_y[i] > 570:
- letters_y[i] = 570
- if abs(letters_vy[i]) < 0.5:
- letters_vy[i] = 0
- else:
- letters_vy[i] *= -0.4
- letters_av[i] = letters_av[i] * 0.4 + letters_vx[i] * 0.05
- if letters_x[i] < 30:
- letters_x[i] = 30
- letters_vx[i] *= -0.4
- letters_av[i] *= 0.6
- if letters_x[i] > 570:
- letters_x[i] = 570
- letters_vx[i] *= -0.4
- letters_av[i] *= 0.6
- def check_collision(i, j):
- dx = letters_x[j] - letters_x[i]
- dy = letters_y[j] - letters_y[i]
- dist = math.sqrt(dx*dx + dy*dy)
- if dist < 40 and dist > 0:
- nx = dx / dist
- ny = dy / dist
- dvx = letters_vx[j] - letters_vx[i]
- dvy = letters_vy[j] - letters_vy[i]
- dot = dvx * nx + dvy * ny
- if dot < 0:
- impulse = -1.2 * dot / 2
- letters_vx[i] -= impulse * nx
- letters_vy[i] -= impulse * ny
- letters_vx[j] += impulse * nx
- letters_vy[j] += impulse * ny
- tangent_vel_i = -ny * letters_vx[i] + nx * letters_vy[i]
- tangent_vel_j = -ny * letters_vx[j] + nx * letters_vy[j]
- torque_i = tangent_vel_j * 0.015
- torque_j = tangent_vel_i * 0.015
- letters_av[i] += torque_i
- letters_av[j] += torque_j
- letters_av[i] *= 0.7
- letters_av[j] *= 0.7
- overlap = 40 - dist
- if letters_y[i] < letters_y[j]:
- letters_y[i] -= 3
- else:
- letters_y[j] -= 3
- letters_x[i] -= nx * overlap * 0.5
- letters_y[i] -= ny * overlap * 0.5
- letters_x[j] += nx * overlap * 0.5
- letters_y[j] += ny * overlap * 0.5
- def attract_letters():
- for i in range(len(letters_x)):
- for j in range(i+1, len(letters_x)):
- dx = letters_x[j] - letters_x[i]
- dy = letters_y[j] - letters_y[i]
- dist = math.sqrt(dx*dx + dy*dy)
- if dist > 0 and dist < 150:
- force = 0.02 / (dist * dist + 1)
- fx = (dx / dist) * force
- fy = (dy / dist) * force
- apply_force(i, fx, fy)
- apply_force(j, -fx, -fy)
- def update():
- canvas.delete('all')
- attract_letters()
- for i in range(len(letters_x)):
- update_letter(i)
- for i in range(len(letters_x)):
- for j in range(i+1, len(letters_x)):
- check_collision(i, j)
- for i in range(len(letters_x)):
- canvas.create_text(letters_x[i], letters_y[i], text=letters_char[i],
- font=('Arial', 50, 'bold'),
- fill='white', angle=math.degrees(letters_angle[i]))
- root.after(16, update)
- def spawn_letter():
- if len(letters_x) < len(letter_chars):
- letters_x.append(random.randint(50, 550))
- letters_y.append(-20)
- letters_vx.append(0)
- letters_vy.append(0)
- letters_angle.append(0)
- letters_av.append(0)
- letters_char.append(letter_chars[len(letters_x) - 1])
- root.after(500, spawn_letter)
- def reset(event):
- letters_x.clear()
- letters_y.clear()
- letters_vx.clear()
- letters_vy.clear()
- letters_angle.clear()
- letters_av.clear()
- letters_char.clear()
- spawn_letter()
- update()
- root.bind('<space>', reset)
- spawn_letter()
- update()
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment