-
Notifications
You must be signed in to change notification settings - Fork 4
/
display.py
87 lines (71 loc) · 2.76 KB
/
display.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import Tkinter as tk
import solver
def _create_circle(self, x, y, r, **kwargs):
"""Create a circle
x the abscissa of centre
y the ordinate of centre
r the radius of circle
**kwargs optional arguments
return the drawing of a circle
"""
return self.create_oval(x-r, y-r, x+r, y+r, **kwargs)
tk.Canvas.create_circle = _create_circle
def _coords_circle(self, target, x, y, r, **kwargs):
"""Define a circle
target the circle object
x the abscissa of centre
y the ordinate of centre
r the radius of circle
**kwargs optional arguments
return the circle drawing with updated coordinates
"""
return self.coords(target, x-r, y-r, x+r, y+r, **kwargs)
tk.Canvas.coords_circle = _coords_circle
class Display:
"""Define the window used to display a simulation"""
def __init__(self, balls, step, size):
"""Initialize and launch the display"""
self.balls = balls
self.step = step
self.size = size
self.window = tk.Tk()
self.canvas = tk.Canvas(self.window, width=self.size, height=self.size, bg="black")
self.canvas.pack()
self.canvas.focus_set()
self.drawing = self.create()
self.started = False
start_button = tk.Button(self.window, text="Start", command=self.start)
stop_button = tk.Button(self.window, text="Pause", command=self.stop)
start_button.pack()
stop_button.pack()
self.window.mainloop()
def create(self):
"""Create a drawing item for each solver.Ball object
return a dictionary with solver.Ball objects as keys and their circle drawings as items
"""
return {ball: self.canvas.create_circle(ball.position[0], ball.position[1], ball.radius, fill="white") for ball in self.balls}
def update(self):
"""Update the drawing items for a time step"""
solver.solve_step(self.balls, self.step, self.size)
for ball in self.balls:
self.canvas.coords_circle(self.drawing[ball], ball.position[0], ball.position[1], ball.radius)
self.canvas.update()
def start(self):
"""Start the animation"""
if not self.started:
self.started = True
self.animate()
def animate(self):
"""Animate the drawing items"""
if self.started:
self.update()
self.window.after(0, self.animate)
def stop(self):
"""Stop the animation"""
self.started = False
# Test this module
if __name__ == "__main__":
balls = [solver.Ball(20., 20., [40.,40.], [5.,5.]), solver.Ball(10., 10., [480.,480.], [-15.,-15.]), solver.Ball(15., 15., [30.,470.], [10.,-10.])]
size = 500.
step = 0.01
Display(balls, step, size)