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