well... it's easy to do with vector math. Instead of having a vector that you point your object to each time, I'd have a vector that represents velocity: You add that vector to the object's position each frame. The length of this vector would be the velocity of the object!
So here's the above code written in that format.
type vec3
x as float
y as float
z as float
endtype
type particle
pos as vec3
vel as vec3
endtype
dim parts(-1) as vec3
do
for n = 1 to ParticleCount
moveParticle(n)
distsquared(n)
if abs(distance#) > 250000 `if dist^2>500^2
endif
next n
sync
loop
function moveParticle(n as integer)
inc parts(n).pos.x,parts(n).vel.x
inc parts(n).pos.y,parts(n).vel.y
inc parts(n).pos.z,parts(n).vel.z
endfunction
function distsquared(n as integer)
ret#=parts(n).pos.x*parts(n).pos.x+parts(n).pos.y*parts(n).pos.y+parts(n).pos.z*parts(n).pos.z
endfunction ret#
function addParticle(x as float, y as float, z as float)
array insert at bottom parts()
n=array count(parts())
parts(n).pos.x=x
parts(n).pos.y=y
parts(n).pos.z=z
parts(n).vel.x=rnd(100)/1000.0
parts(n).vel.y=rnd(100)/1000.0
parts(n).vel.z=rnd(100)/1000.0
endfunction
The function "distsquared" gets the distance of the particle from the center, squared, and so the if statement checks if the distance is greater than 500 squared.
Okay, so now... The "normal" of a collision is a vector length 1, that is *tangent* to the surface of collision. The great thing with a circle whose center is zero, is that the normal of the collision is just the negative point of collision, normalized! (normalizing a vector is when you divide it by its length, so its length is one.)
So where P is the point of collision (and the position of the particle), the normal, N, =-P/length(P).
If you think about it, what we really want is so that the object's velocity is negated, but in the direction of N. The dot product of a normalized vector (N), and a non-normalized vector (V, velocity), is "The magnitude of V in the direction N", so to zero the object's velocity in the direction of N: V'=V-N*(N.V). To make it so that the object *bounces*, just double the amount you're subtracting! V'=V-N*(2*N.V)
If you're too unfamiliar with vector math, you might want to check out SvenB's tutorials:
http://forum.thegamecreators.com/?m=forum_view&t=180223&b=7
Here's what I came up with for the code:
type vec3
x as float
y as float
z as float
endtype
type particle
pos as vec3
vel as vec3
endtype
dim parts(-1) as particle
sync on
sync rate 0
for n=0 to 100
addParticle(rnd(40)-20,rnd(40)-20,rnd(40)-20)
next
do
for n = 0 to array count(parts())
moveParticle(n)
distance#=distsquared(n)
if abs(distance#) >= 60*60 `if dist^2>500^2
normal as vec3
length#=sqrt(distsquared(n))
normal.x=-parts(n).pos.x/length#
normal.y=-parts(n).pos.y/length#
normal.z=-parts(n).pos.z/length#
bounceParticle(n,normal)
endif
next n
move camera ((mouseclick()=1)-(mouseclick()=2))*.1
rotate camera camera angle x()+mousemovey(),camera angle y()+mousemovex(),0
sync
loop
function bounceParticle(n as integer,normal as vec3)
dotprod#=parts(n).vel.x*normal.x+parts(n).vel.y*normal.y+parts(n).vel.z*normal.z
inc parts(n).vel.x,-2*normal.x*dotprod#
inc parts(n).vel.y,-2*normal.y*dotprod#
inc parts(n).vel.z,-2*normal.z*dotprod#
endfunction
function moveParticle(n as integer)
inc parts(n).pos.x,parts(n).vel.x
inc parts(n).pos.y,parts(n).vel.y
inc parts(n).pos.z,parts(n).vel.z
position object n+1,parts(n).pos.x,parts(n).pos.y,parts(n).pos.z
endfunction
function distsquared(n as integer)
ret#=parts(n).pos.x*parts(n).pos.x+parts(n).pos.y*parts(n).pos.y+parts(n).pos.z*parts(n).pos.z
endfunction ret#
function addParticle(x as float, y as float, z as float)
array insert at bottom parts()
n=array count(parts())
parts(n).pos.x=x
parts(n).pos.y=y
parts(n).pos.z=z
parts(n).vel.x=rnd(100)/10000.0
parts(n).vel.y=rnd(100)/10000.0
parts(n).vel.z=rnd(100)/10000.0
make object sphere n+1,1
endfunction
[edit]
Even better: instead of making spheres, instance planes, and in the move code point them towards the camera! way faster!