-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbouncingball.py
More file actions
64 lines (53 loc) · 1.44 KB
/
Copy pathbouncingball.py
File metadata and controls
64 lines (53 loc) · 1.44 KB
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
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
# Dynamics: y[0] = position, y[1] = velocity
def f(t, y):
return [y[1], -9.8]
# Event: detect when ball hits the ground (height = 0)
def hit_ground(t, y):
return y[0]
hit_ground.terminal = True
hit_ground.direction = -1
# Circle drawing helper
def draw_circle(center, radius,color="red"):
theta = np.linspace(0, 2*np.pi, 100)
x = center[0] + radius * np.cos(theta)
y = center[1] + radius * np.sin(theta)
plt.fill(x, y, color=color)
# Initial conditions
t_start = 0
t_final = 500
y0 = [20, -2]
tout = [t_start]
yout = [y0]
teout, yeout, ieout = [], [], []
plt.figure()
plt.xlim(0, 30)
plt.ylim(0, 25)
plt.box(True)
for i in range(20):
sol = solve_ivp(f, [t_start, t_final], y0, events=hit_ground,
max_step=0.05, rtol=1e-6, atol=1e-9)
t = sol.t
y = sol.y.T
nt = len(t)
tout.extend(t[1:])
yout.extend(y[1:])
if sol.t_events[0].size > 0:
teout.append(sol.t_events[0][0])
yeout.append(sol.y_events[0][0])
ieout.append(1)
# Update initial conditions with bounce
y0 = [0, -0.9 * y[-1][1]]
t_start = t[-1]
# Animate ball
for tt in range(nt):
plt.clf()
draw_circle([10, y[tt][0] + 1], 1)
plt.axis([0, 20, 0, 20])
if tt > 0:
plt.pause(0.0001 * (t[tt] - t[tt - 1]))
plt.ylabel('Height')
plt.title('Ball trajectory')
plt.show()