Homer_simpson
|
Posted: Thu Jan 01, 2009 9:04 pm Post subject: 2d collisions physics simulation |
|
|
i seem to have a problem with collision when balls are moving in the same general direction
Quote: View.Set ("offscreenonly,graphics:700;350")
function distance (x1, y1, x2, y2 : real) : real
result sqrt (((x2 - x1) ** 2) + ((y2 - y1) ** 2)) %y
end distance
function findangle (x1, y1, x2, y2 : real) : real
var ang, slope : real
if not (x2 = x1) then
slope := (y2 - y1) / (x2 - x1)
else
slope := 999999999
end if
ang := arctand (slope)
if slope > 0 then
if y2 < y1 then
ang := 180 + ang
end if
end if
if slope < 0 then
if x2 < x1 then
ang := 180 + ang
end if
if x2 > x1 then
ang := 360 + ang
end if
end if
if slope = 0 then
if x2 > x1 then
ang := 0
end if
if x2 < x1 then
ang := 180
end if
end if
result ang
end findangle
type Particle_Type :
record
x, y, vx, vy, w : real
ch : boolean
end record
const MaxParticles := 9
var Particles : array 1 .. MaxParticles of Particle_Type
procedure RenewParticle (var p : Particle_Type, x, y : real, a, r, w : real)
p.x := x
p.y := y
p.vx := a
p.vy := r
p.w := w
p.ch := false
end RenewParticle
for i : 1 .. MaxParticles
RenewParticle (Particles (i), Rand.Int (1, 700), Rand.Int (0, 350), .4, .4, Rand.Int (10, 100))
end for
colorback (black)
cls
RenewParticle (Particles (1), 200, 100, .6, .3, Rand.Int (10, 100))
RenewParticle (Particles (2), 400, 200, .4, .2, Rand.Int (10, 100))
var chars : array char of boolean
color (white)
procedure collide (var particles1, particles2 : Particle_Type)
var temp1, temp2, temp3, nvx1, nvy1, nvx2, nvy2, magnitude, dirx, diry, mag1, mag2 : real
dirx := - (abs (particles2.vx) / particles2.vx) * (abs (particles1.vx) / particles1.vx)
diry := - (abs (particles2.vy) / particles2.vy) * (abs (particles1.vy) / particles1.vy)
mag1 := distance (0, 0, particles1.vx, particles1.vy)
mag2 := distance (0, 0, particles2.vx, particles2.vy)
locate (1, 1)
temp1 := findangle (particles1.x, particles1.y, particles2.x, particles2.y)
temp2 := findangle (0, 0, particles2.vx, particles2.vy) - temp1
temp3 := findangle (0, 0, particles1.vx, particles1.vy) - temp1
put temp1
put temp2 + temp1
put temp3 + temp1
temp2 := findangle (0, 0, cosd (temp2), -sind (temp2)) + temp1
temp3 := findangle (0, 0, cosd (temp3), -sind (temp3)) + temp1
put "-----------"
put temp2
put temp3
%put "collision angle = ", temp1
%put "Vellocity angle = ", temp2
%put "relative angle = ", temp2 - temp1
%put "------------"
nvx1 := cosd (temp2) %* distance (0, 0, particles1.vx, particles1.vy)
nvy1 := sind (temp2) %* distance (0, 0, particles1.vx, particles1.vy)
nvx2 := cosd (temp3) %* distance (0, 0, particles2.vx, particles2.vy)
nvy2 := sind (temp3) %* distance (0, 0, particles2.vx, particles2.vy)
/*drawline (round (particles1.x), round (particles1.y), round (particles2.x), round (particles2.y), red)
drawline (round (particles2.x), round (particles2.y), round (particles2.x) + round (particles2.vx * 4), round (particles2.y) + round (particles2.vy * 4),
yellow)
drawline (round (particles2.x), round (particles2.y), round (particles2.x) + round (cosd (temp3) * magnitude * 4), round (particles2.y) + round (sind (temp3) *
magnitude * 4),
11)
drawline (0, round (particles2.y), 700, round (particles2.y), green)%*/
%col := true
drawline (round (particles1.x), round (particles1.y), round (particles1.x + (particles1.vx * 90)), round (particles1.y + (particles1.vy * 90)), white)
drawline (round (particles2.x), round (particles2.y), round (particles2.x + (particles2.vx * 90)), round (particles2.y + (particles2.vy * 90)), white)
particles2.vx := -nvx1 * dirx * mag1
particles2.vy := -nvy1 * diry * mag1
particles1.vx := -nvx2 * mag2
particles1.vy := -nvy2 * mag2
particles1.x += particles1.vx * 4
particles1.y += particles1.vy * 4
particles2.x += particles2.vx * 4
particles2.y += particles2.vy * 4
drawline (round (particles1.x), round (particles1.y), round (particles1.x + (particles1.vx * 90)), round (particles1.y + (particles1.vy * 90)), yellow)
drawline (round (particles2.x), round (particles2.y), round (particles2.x + (particles2.vx * 90)), round (particles2.y + (particles2.vy * 90)), yellow)
View.Update
%delay (300)
%particles1.ch := true
%particles2.ch := true
end collide
loop
Input.KeyDown (chars)
if chars ('+') then
end if
for i : 1 .. MaxParticles
Particles (i).x += Particles (i).vx
Particles (i).y += Particles (i).vy
drawfilloval (round (Particles (i).x), round (Particles (i).y), 10, 10, 30 + i)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%ball collision%%%%%%%%%%%%%%%%%%%%%%%%
for ii : 1 .. MaxParticles
if distance (Particles (i).x, Particles (i).y, Particles (ii).x, Particles (ii).y) <= 20 and i not= ii then
if not Particles (i).ch and not Particles (ii).ch then
%put "cOllIde!"
collide (Particles (i), Particles (ii))
%View.Update
%delay (200)
end if
end if
end for
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%ball collision%%%%%%%%%%%%%%%%%%%%%%%%
% Particles (i).ch := false
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%wall collision%%%%%%%%%%%%%%%
if Particles (i).x >= 690 and Particles (i).vx > 0 then
Particles (i).vx := -Particles (i).vx
end if
if Particles (i).x <= 10 and Particles (i).vx < 0 then
Particles (i).vx := -Particles (i).vx
end if
if Particles (i).y >= 340 and Particles (i).vy > 0 then
Particles (i).vy := -Particles (i).vy
end if
if Particles (i).y <= 10 and Particles (i).vy < 0 then
Particles (i).vy := -Particles (i).vy
end if
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%wall collision%%%%%%%%%%%%%%%
end for
View.Update
cls
end loop
|
|
|