-
Notifications
You must be signed in to change notification settings - Fork 0
/
view.py
117 lines (105 loc) · 3.88 KB
/
view.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import turtle
class Window:
"""
Window class for handling interactions between the turtle window and the simulator.
"""
def __init__(self, width: int, height: int, drawing_accuracy: int) -> None:
if not all(isinstance(i, int) for i in (width, height, drawing_accuracy)):
raise TypeError("Width, height, and drawing accuracy must be integers")
self.turtle = turtle.Turtle()
self.screen = turtle.Screen()
self.width = width
self.height = height
self.drawing_accuracy = drawing_accuracy
self.__setup_window()
def __setup_window(self) -> None:
"""
Set up the window for the simulator.
:return: None
"""
self.screen.title("Ball Simulator")
self.screen.screensize(self.width, self.height)
self.screen.tracer(0)
self.turtle.speed(0)
self.turtle.hideturtle()
def draw_border(self) -> None:
"""
Draw a border around the window.
:return: None
"""
self.turtle.penup()
self.turtle.goto(self.width, self.height)
self.turtle.pendown()
self.turtle.goto(self.width, -self.height)
self.turtle.goto(-self.width, -self.height)
self.turtle.goto(-self.width, self.height)
self.turtle.goto(self.width, self.height)
self.turtle.penup()
self.turtle.goto(0, 0)
self.turtle.pendown()
def draw_axis(self) -> None:
"""
Draw the x and y axes.
:return: None
"""
self.turtle.penup()
self.turtle.goto(0, self.height)
self.turtle.pendown()
self.turtle.goto(0, -self.height)
self.turtle.penup()
self.turtle.goto(-self.width, 0)
self.turtle.pendown()
self.turtle.goto(self.width, 0)
self.turtle.penup()
self.turtle.goto(0, 0)
self.turtle.pendown()
def sim_info(self, step: int, iteration_time: float) -> None:
"""
Display infomation about the simulation.
:param: step: int
:param: iteration_time: float
:return: None
"""
if not isinstance(step, int):
raise TypeError("Step must be an integer")
if not isinstance(iteration_time, float):
raise TypeError("Iteration time must be a float")
self.turtle.penup()
# put the step count in the top left corner
self.turtle.goto(-self.width + 10, self.height - 20)
self.turtle.write(f"Step: {step}", font=("Arial", 12, "normal"))
# put the iteration time below the step count
self.turtle.goto(-self.width + 10, self.height - 40)
self.turtle.write(
f"Iteration Time: {iteration_time:.2f} ms",
font=("Arial", 12, "normal"),
)
def draw_ball(
self, position: tuple[float, float], ball_diameter: int, color: str
) -> None:
"""
Draw a ball at the specified position with the specified diameter and color.
:param: position: tuple of floats
:param: ball_diameter: int
:param: color: str
:return: None
"""
if not all(isinstance(i, (float, int)) for i in position):
raise TypeError("Position must be a tuple of floats")
if not isinstance(ball_diameter, int):
raise TypeError("Ball diameter must be an integer")
if not isinstance(color, str):
raise TypeError("Color must be a string")
if self.drawing_accuracy != 0:
position = (
round(position[0], self.drawing_accuracy),
round(position[1], self.drawing_accuracy),
)
# Move the turtle to the specified position
self.turtle.penup()
self.turtle.goto(position)
self.turtle.pendown()
# Draw the ball
self.turtle.begin_fill()
self.turtle.dot(ball_diameter, color)
self.turtle.end_fill()