Computer Science Canada 2d collisions physics simulation |
Author: | Homer_simpson [ 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 |