ball in box (version 2)

Download: source archive

Superfically, this program looks about the same. However, wall collisions are explicitly calculated, and the ball position is more accurately determined.

References

VPython

Screenshot

collide2.py


01: from visual import *
02: 
03: side = 40
04: thk = 1
05: 
06: def intersect_window(ball,tstep):
07:   'find nearest wall intersection for times < tstep'
08:   left = -side
09:   right = side
10:   top = side
11:   bottom = -side
12:   tmax = 10.0*tstep;
13:   t = [tmax, tmax, tmax, tmax]
14:   if ball.v.x<0:
15:     t[0] = (ball.x-ball.radius - left)/(-ball.v.x)
16:   if ball.v.x>0:
17:     t[1] = (right-ball.x-ball.radius)/ball.v.x
18:   if ball.v.y<0:
19:     t[2] = (ball.y-ball.radius - bottom)/(-ball.v.y)
20:   if ball.v.y>0:
21:     t[3] = (top - ball.y - ball.radius)/ball.v.y
22:   tx = t[0]
23:   idx = 0
24:   for j in (1,2,3):
25:     if t[j]<tx:
26:       tx = t[j]
27:       idx = j
28:   if tx>tstep: return
29:   return [tx, idx]
30: 
31: def wall_collision(ball,idx):
32:   if idx<2: ball.v.x = -ball.v.x
33:   else: ball.v.y = -ball.v.y
34: 
35: 
36: s2 = 2*side - thk
37: s3 = 2*side + thk
38: gray_red = (1.0,0.7,0.7)
39: gray_blue = (0.7,0.7,1.0)
40: wallR = box (pos=( side, 0, 0), length=thk, height=s2,  width=s3,  color = gray_red )
41: wallL = box (pos=(-side, 0, 0), length=thk, height=s2,  width=s3,  color = gray_red )
42: wallB = box (pos=(0, -side, 0), length=s3,  height=thk, width=s3,  color = gray_blue)
43: wallT = box (pos=(0,  side, 0), length=s3,  height=thk, width=s3,  color = gray_blue)
44: 
45: #scene = display.get_selected()
46: scene.background = (0.5,0.5,0.5)
47: 
48: ball = sphere (color = color.green, radius = 8)
49: ball.mass = 1.0
50: ball.v = vector (-1.5, -2.3, 0.0)
51: ball.z = 30
52: 
53: side = side - thk*0.5 - ball.radius
54: 
55: # Experiment with different values of fps to show sphere penetration of the walls
56: fps = 25
57: dt = 50.0/fps
58: while True:
59:   rate(fps)
60:   tmore = dt
61:   while tmore>0:
62:     c = intersect_window(ball,tmore)
63:     if c:
64:       ball.pos = ball.pos + ball.v * c[0]
65:       wall_collision(ball,c[1])
66:       tmore = tmore - c[0]
67:     else:
68:       ball.pos = ball.pos + ball.v * tmore
69:       tmore = 0.0
70:  


Maintained by John Loomis, updated Sun Apr 06 11:29:23 2008