Please let me know how to speed this up or
how to avoid flickering if ball/sphere gets too fast.
Code: Select all
rem 2D elastic collision with spheres v1
rem based on:
rem http://www.vobarian.com/collisions/2dcollisions2.pdf
rem http://blogs.love2d.org/content/circle-collisions
rem SB 3.4 / iPad mini 1.gen  / iOS 7.0.4 / Operator
graphics
option base 1
draw color 1,1,1
fill color 1,1,1
sch = screen_height()
scw = screen_width()
init_speed = 5
max_balls = 25
dim balls(max_balls,5)
x = 1
y = 2 
vx = 3
vy = 4
m = 5
ball_r = 15
'preload balls array x,y,vx,vy,mass
for i = 1 to max_balls
  balls(i,x) = ball_r + rnd(scw - ball_r)
  balls(i,y) = ball_r + rnd(sch - ball_r)
  balls(i,vx) = (-1 + 2*rnd(2))*rnd(init_speed)
  balls(i,vy) = (-1 + 2*rnd(2))*rnd(init_speed)
  balls(i,m) = 1
next i
do
'timer reset
t = timer()
graphics lock
graphics clear 0,0,0
'draw balls
for i = 1 to max_balls
  'draw balls
   ab_v = sqr(balls(i,vx)^2+balls(i,vy)^2)
   fill color ab_v/8,ab_v/8,ab_v/8
   fill circle balls(i,x),balls(i,y) size ball_r
  'move balls
   balls(i,x) += balls(i,vx)
   balls(i,y) += balls(i,vy)
  'wall (screen margin) collision detect & react
   if balls(i,x) <= ball_r Then
     balls(i,x) = ball_r
     balls(i,vx) = -1 * balls(i,vx)
   end if
   if balls(i,x) >= scw - ball_r Then
     balls(i,x) = scw - ball_r
     balls(i,vx) = -1 * balls(i,vx)
   end if
   if balls(i,y) <= ball_r Then
     balls(i,y) = ball_r
     balls(i,vy) = -1 * balls(i,vy)
   end if
   if balls(i,y) >= sch - ball_r Then
     balls(i,y) = sch - ball_r
     balls(i,vy) = -1 * balls(i,vy)
   end if
  'ball to ball collision detect and react
   for j = i + 1 to max_balls
     
     if (balls(i,x)-balls(j,x))^2 + (balls(i,y)-balls(j,y))^2 <= (2*ball_r)^2 Then
       'col_str$ = "ball "&str$(i)&" colliding ball "&str$(j)
       'draw text col_str$ at 10,10
       
       'resolve collision of ball(i) with ball(j)
       'colission vector = normal vector
       
       'calculate normal vector of collision: _n
        vec_n_x = balls(i,x) - balls(j,x)
        vec_n_y = balls(i,y) - balls(j,y)
       
       'normalize L=1 normal vector of collision
       'distance (vec_n_L) should be 2*ball_r
        vec_n_L = sqr(vec_n_x^2 + vec_n_y^2)
        
       'separate balls penetration along the
       '"line of collision".
        
        midptx = (balls(i,x) + balls(j,x))/2
        midpty = (balls(i,y) + balls(j,y))/2
        balls(i,x) = midptx + ball_r / vec_n_L * (balls(i,x) - balls(j,x))
        balls(i,y) = midpty + ball_r / vec_n_L * (balls(i,y) - balls(j,y))
        balls(j,x) = midptx + ball_r / vec_n_L * (balls(j,x) - balls(i,x))
        balls(j,y) = midpty + ball_r / vec_n_L * (balls(j,y) - balls(i,y))
       '.. continue normalization..
        vec_nn_x = vec_n_x / vec_n_L
        vec_nn_y = vec_n_y / vec_n_L
      
       'calculate normalized tangent vector to
       'normal vector
        vec_tn_x = -vec_nn_y
        vec_tn_y = vec_nn_x
       'resolve the velocity vectors, v1 and v2
       'into normal and tangential components 
       ' --> dot product
        v1_n = vec_nn_x * balls(j,vx) + vec_nn_y * balls(j,vy)
        v2_n = vec_nn_x * balls(i,vx) + vec_nn_y * balls(i,vy)
        v1_t = vec_tn_x * balls(j,vx) + vec_tn_y * balls(j,vy)
        v2_t = vec_tn_x * balls(i,vx) + vec_tn_y * balls(i,vy)
     
       'find the "new" tangential velocities 
       'after the collision (remain the same)
        v1_t_ac = v1_t
        v2_t_ac = v2_t
        
       'find the new normal velocities after
       'collision _ac
        v1_n_ac = (v1_n * (balls(j,m) - balls(i,m)) + 2 * balls(i,m) * v2_n) / (balls(j,m) + balls(i,m))
        v2_n_ac = (v2_n * (balls(i,m) - balls(j,m)) + 2 * balls(j,m) * v1_n) / (balls(j,m) + balls(i,m))
       'convert the scalar normal and tangential 
       'velocities into vectors
        vec_v1_n_ac_x = v1_n_ac * vec_nn_x
        vec_v1_n_ac_y = v1_n_ac * vec_nn_y
        vec_v1_t_ac_x = v1_t_ac * vec_tn_x
        vec_v1_t_ac_y = v1_t_ac * vec_tn_y
        vec_v2_n_ac_x = v2_n_ac * vec_nn_x
        vec_v2_n_ac_y = v2_n_ac * vec_nn_y
        vec_v2_t_ac_x = v2_t_ac * vec_tn_x
        vec_v2_t_ac_y = v2_t_ac * vec_tn_y
       'final velocity vectors by adding the
       'normal and tangential components
        vec_v1_ac_x = vec_v1_n_ac_x + vec_v1_t_ac_x
        vec_v1_ac_y = vec_v1_n_ac_y + vec_v1_t_ac_y
    
        vec_v2_ac_x = vec_v2_n_ac_x + vec_v2_t_ac_x
        vec_v2_ac_y = vec_v2_n_ac_y + vec_v2_t_ac_y
       
        balls(j,vx) = vec_v1_ac_x
        balls(j,vy) = vec_v1_ac_y
   
        balls(i,vx) = vec_v2_ac_x
        balls(i,vy) = vec_v2_ac_y
     end if
   next j
   
next i
draw font name "Chalkduster"
draw font size 50
draw text "Smart Basic" AT scw*.65,sch*.9
draw font size 20
draw text "Frames per Second "&str$(int(1000/(timer()-t))) AT 0,5
graphics unlock
until sch = 0

