Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # tk_cloth_sim.py ZZZ
- import tkinter as tk
- from random import uniform
- cloth_width = 18
- cloth_height = 12
- cloth_spacing = 30
- cloth_damping = 0.98
- gravity = 0.1
- wind = 0.7
- ww, hh = 600, 600
- root = tk.Tk()
- canvas = tk.Canvas(root, width=ww, height=hh)
- canvas.pack()
- points = []
- constraints = []
- for y in range(cloth_height + 1):
- for x in range(cloth_width + 1):
- point = {
- 'x': x * cloth_spacing,
- 'y': y * cloth_spacing + 20,
- 'old_x': x * cloth_spacing,
- 'old_y': y * cloth_spacing,
- 'pinned': (x == 0 and y == 0) or (x == cloth_width and y == 0),
- }
- points.append(point)
- for x in range(cloth_width):
- a = y * (cloth_width + 1) + x
- b = a + 1
- constraints.append({
- 'point_a': points[a],
- 'point_b': points[b],
- 'length': cloth_spacing,
- })
- for y in range(cloth_height):
- for x in range(cloth_width + 1):
- a = y * (cloth_width + 1) + x
- b = a + cloth_width + 1
- constraints.append({
- 'point_a': points[a],
- 'point_b': points[b],
- 'length': cloth_spacing,
- })
- points[cloth_width]['x'] = ww
- points[cloth_width]['pinned'] = True
- drag_point = None
- def on_mouse_down(event):
- global drag_point
- for point in points:
- if abs(point['x'] - event.x) < cloth_spacing:
- if abs(point['y'] - event.y) < cloth_spacing:
- drag_point = point
- drag_point['xm'] = event.x
- drag_point['ym'] = event.y
- return
- def on_mouse_move(event):
- if drag_point:
- drag_point['x'] = drag_point['xm'] = event.x
- drag_point['y'] = drag_point['ym'] = event.y
- def on_mouse_up(event):
- global drag_point
- drag_point = None
- canvas.bind('<ButtonPress-1>', on_mouse_down)
- canvas.bind('<B1-Motion>', on_mouse_move)
- canvas.bind('<ButtonRelease-1>', on_mouse_up)
- while True:
- for point in points:
- if not point['pinned']:
- velocity_x = (point['x'] - point['old_x']) * cloth_damping
- velocity_y = (point['y'] - point['old_y']) * cloth_damping
- point['old_x'] = point['x']
- point['old_y'] = point['y']
- point['x'] += velocity_x + uniform(-wind, wind)
- point['y'] += velocity_y + gravity + uniform(-wind, wind)
- for constraint in constraints:
- point_a = constraint['point_a']
- point_b = constraint['point_b']
- length = constraint['length']
- dx = point_b['x'] - point_a['x']
- dy = point_b['y'] - point_a['y']
- distance = (dx ** 2 + dy ** 2) ** 0.5
- difference = length - distance
- percentage = difference / distance / 2
- offset_x = dx * percentage
- offset_y = dy * percentage
- if not point_a['pinned']:
- point_a['x'] -= offset_x
- point_a['y'] -= offset_y
- if not point_b['pinned']:
- point_b['x'] += offset_x
- point_b['y'] += offset_y
- if drag_point:
- drag_point['x'] = drag_point['xm']
- drag_point['y'] = drag_point['ym']
- canvas.delete('cloth')
- for y in range(cloth_height + 1):
- point_coords = [(points[y * (cloth_width + 1) + x]['x'], points[y * (cloth_width + 1) + x]['y']) for x in range(cloth_width + 1)]
- canvas.create_line(point_coords, tags='cloth', fill='black')
- for x in range(cloth_width + 1):
- point_coords = [(points[y * (cloth_width + 1) + x]['x'], points[y * (cloth_width + 1) + x]['y']) for y in range(cloth_height + 1)]
- canvas.create_line(point_coords, tags='cloth', fill='black')
- root.update()
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement