Okey so i was doing a function to handle elastic collision between 2 balls of the same mass, a task which i think i accomplished. (the momentum of the system drops by about 2-5% which it shouldnt, but after that it levels out and stays at aproximately the same momentum after that as it should) I used vector projection as the main part of my function which can be found in the snippet.
okay but as i realised there already was a cool, more realistic, and faster gas simulator here i decided to post a cool "bug" i accidentially stumbled uppon while coding this.
If 2 balls are placed so that they overlap initially, they will now be "entagled" together (its just a name i came up with, not the real thing

) which means that they always stay at the same distance from each other ( it seems actually that they behave like there was a pole between them ). they will then because of the different starting vectors i gave the 2 balls start to move eratically, but not completely randomly. It will appear random at first but it isnt it seems after a while.
check it out:
oh and it uses a2plugin for the graphics (can be replaced with other stuff but wont be even 1% as cool)
oh and you may wonder why i have a for loop for 2 items, well its because i was lazy and just copied the code from my 200 ball version
the lower one is the same but with 25 "ball pairs" and easier graphics. it forms a nice spiderweb if you let it run. For some reason it seems thatsome of the pairs are able to disconnect forming normally beahving balls. press spacekey every now and then to reset tehm back to starting positions.
Rem Project: Dark Basic Pro Project
Rem Created: Monday, April 16, 2012
Rem ***** Main Source File *****
sync on : sync rate 1000
w = screen width() : h = screen height()
r1# = 50
colrad# = (r1#*2)^2
v3 = createvector()
a = 100
dim x#(a)
dim y#(a)
dim v(a)
x#(1) = 100 : y#(1) = 100
x#(2) = 150 : y#(2) = 150
v(1) = createvector()
v(2) = createvector()
set vector2 v(1),rnd(50)/100.0,rnd(50)/100.0
set vector2 v(2),-rnd(50)/100.0,-rnd(50)/100.0
v3 = createvector() : v4 = createvector() : v5 = createvector() : v6 = createvector() : v7 = createvector() : v8 = createvector()
c = 1
t# = 17
det = 100
rad# = 200
do
for i = 1 to 2
for j = det to 1 step -3
a2fillcircle x#(i),y#(i),rad#/j,rgb(j*0.05,j*i*0.05,0)
next
x#(i) = x#(i)+x vector2(v(i)) : y#(i) = y#(i)+y vector2(v(i))
for j = 1 to 2
if squaredist(x#(i),y#(i),x#(j),y#(j)) < colrad# and i<>j
set vector2 v3,x#(i)-x#(j),y#(i)-y#(j)
elastic(x#(i),y#(i),x#(j),y#(j),v(i),v(j),v3,v4,v5,v6,v7,v8)
endif
next
momentum# = momentum#+length vector2(v(i))*1
if x#(i)-r1# < 0 or x#(i)+r1# > w or y#(i)-r1# < 0 or y#(i)+r1# > h then multiply vector2 v(i),-1
next
sync
if timer()/t# = timer()/int(t#)
a2setblendmode 2,2,3
a2fillbox 0,0,w,h,rgb(c,c,c)
a2setblendmode 2,2,1 : a2dot 0,0,0
endif
LOOP
function elastic(x1#,y1#,x2#,y2#,v1,v2,v3,v4,v5,v6,v7,v8)
normalize vector2 v4,v3
scale vector2 v5,v4,dot product vector2(v4,v1)
scale vector2 v6,v4,dot product vector2(v4,v2)
subtract vector2 v7,v1,v5
subtract vector2 v8,v2,v6
subtract vector2 v1,v7,v6
add vector2 v2,v8,v5
ENDFUNCTION
function createvector()
n = find free vector()
a = make vector2(n)
ENDFUNCTION n
function squaredist(x1#,y1#,x2#,y2#)
d# = (x1#-x2#)^2+(y1#-y2#)^2
ENDFUNCTION d#
Rem Project: elastic
Rem Created: Monday, April 16, 2012
Rem ***** Main Source File *****
sync on : sync rate 0
w = screen width() : h = screen height()
r1# = 15
colrad# = (r1#*2)^2
global dim state(300)
v3 = createvector()
a = 50
dim x#(a)
dim y#(a)
dim v(a)
for i = 1 to a step 2
x#(i) = wrap(i,1,10)*70+10 : y#(i) = int(i/10)*50+10
x#(i+1) = wrap(i,1,10)*70+20 : y#(i+1) = int(i/10)*50+20
v(i) = createvector()
v(i+1) = createvector()
set vector2 v(i),rnd(50)/100.0,rnd(50)/100.0
set vector2 v(i+1),rnd(50)/100.0,rnd(50)/100.0
NEXT
v4 = createvector() : v5 = createvector() : v6 = createvector() : v7 = createvector() : v8 = createvector()
c = 1
t# = 80
do
if spacekey() then for i = 1 to a step 2 : x#(i) = wrap(i,1,10)*70+10 : y#(i) = int(i/10)*50+10 : x#(i+1) = wrap(i,1,10)*70+20 : y#(i+1) = int(i/10)*50+20 : next
momentum# = 0
for i = 1 to a
a2dot x#(i),y#(i),rgb(i,255,100-i)
x#(i) = x#(i)+x vector2(v(i)) : y#(i) = y#(i)+y vector2(v(i))
for j = 1 to a
if squaredist(x#(i),y#(i),x#(j),y#(j)) < colrad# and i<>j
set vector2 v3,x#(i)-x#(j),y#(i)-y#(j)
elastic(x#(i),y#(i),x#(j),y#(j),v(i),v(j),v3,v4,v5,v6,v7,v8)
endif
next
momentum# = momentum#+length vector2(v(i))*1
if x#(i) < 0 or x#(i) > w or y#(i) < 0 or y#(i) > h then multiply vector2 v(i),-1
next
sync
if hitimer(10000)/t# = hitimer(10000)/int(t#)
a2setblendmode 2,2,3
a2fillbox 0,0,w,h,rgb(c,c,c)
a2setblendmode 2,2,1 : a2dot 0,0,0
endif
LOOP
function elastic(x1#,y1#,x2#,y2#,v1,v2,v3,v4,v5,v6,v7,v8)
normalize vector2 v4,v3
scale vector2 v5,v4,dot product vector2(v4,v1)
scale vector2 v6,v4,dot product vector2(v4,v2)
subtract vector2 v7,v1,v5
subtract vector2 v8,v2,v6
subtract vector2 v1,v7,v6
add vector2 v2,v8,v5
ENDFUNCTION
function elastico(x1#,y1#,x2#,y2#,v1,v2,m1#,m2#)
xu1# = x vector2(v1) : yu1# = y vector2(v1)
xu2# = x vector2(v2) : yu2# = y vector2(v2)
mtot# = m1#+m2#
v1# = ((m1#-m2#)/mtot#) : v2# = ((2*m2#)/mtot#)
xv1# = v1#*xu1#+v2#*xu2#
yv1# = v1#*yu1#+v2#*yu2#
v3# = ((m2#-m1#)/mtot#) : v4# = ((2*m1#)/mtot#)
xv2# = v3#*xu2#+v4#*xu1#
yv2# = v3#*yu2#+v4#*yu1#
set vector2 v1,xv1#,yv1#
set vector2 v2,xv2#,yv2#
ENDFUNCTION
function createvector()
n = find free vector()
a = make vector2(n)
ENDFUNCTION n
function button(x#,y#,r#)
if mousex() > x#-r# and mousex() < x#+r# and mousey() > y#-r# and mousey() < y#+r#
selected = mouseclick()+1
endif
endfunction selected
function keypress(key)
if keystate(key) = 1
accept = 1
if state(key) = 0
accept = 2
state(key) = 1
endif
ENDIF
if keystate(key) = 0 then state(key) = 0
ENDFUNCTION accept
function squaredist(x1#,y1#,x2#,y2#)
d# = (x1#-x2#)^2+(y1#-y2#)^2
ENDFUNCTION d#
function dist(x1#,y1#,x2#,y2#)
d# = sqrt((x1#-x2#)^2+(y1#-y2#)^2)
ENDFUNCTION d#
function boxdist(x1#,y1#,x2#,y2#)
dx# = abs(x1#-x2#) : dy# = abs(y1#-y2#)
d# = max(dx#,dy#)
ENDFUNCTION d#