I have written a Python script which creates a Ball class and then creates instances of it. The balls should bounce off the walls, and later (not implemented yet) off of each other. Note that, instead of just reversing the direction of the ball when it reaches a wall, the wall exerts a force (or acceleration) on the ball.
Unfortunately, after bouncing off of a wall, the balls then enter an oscillatory motion, with the amplitude getting bigger and bigger.
I am very new to Python, but have written various javascript/canvas simulations before.
This particular python script uses Verlet integration to compute the positions and velocities. I am basing the script on this:
http://physics.weber.edu/schroeder/software/demos/MolecularDynamics.html
Can anybody suggest how I should modify the code so that it is "stable" with the balls bouncing off the walls? Thank you
from Tkinter import *
import random
window = Tk()
canvas = Canvas(window, width = 400, height = 300)
canvas.pack()
wallStiffness=0.05
dt=0.02
class Ball:
def __init__(self):
self.x=0
self.y=0
self.xvel=random.random()*2-1
self.yvel=random.random()*2-1
self.ax=0
self.ay=0
self.rad=20
def computeAccelerations(z):
if z.x<z.rad:
z.ax=wallStiffness*(z.rad-z.x)
else:
if z.x>400-z.rad:
z.ax=wallStiffness*(400-z.rad-z.x)
#only have horizontal bounces so far, and no bounces between balls yet
list=[]
for i in range(100): #0 to 99, make 100 balls
myball=Ball()
list.append(myball)
#script to place in a crystal to begin with
current_x=30
current_y=0
for j in list:
j.x=current_x
current_x+=30
j.y=current_y
if current_x+30>370:
current_x=30
current_y+=30
j.ball=canvas.create_oval(j.x,j.y,j.x+j.rad,j.y+j.rad,fill="blue")
while True:
for i in range(10): #10 steps per frame
for j in list:
j.x+=j.xvel*dt+0.5*j.ax*dt*dt
j.y+=j.yvel*dt+0.5*j.ay*dt*dt
j.xvel+=0.5*j.ax*dt
j.yvel+=0.5*j.ay*dt
computeAccelerations(j)
for j in list:
j.xvel+=0.5*j.ax*dt
j.yvel+=0.5*j.ay*dt
canvas.after(10) #duration of frame in ms
for z in list:
canvas.move(z.ball,z.xvel, z.yvel)
canvas.update()
window.mainloop() #keeps the window open