1.The particles seems to have an excess y-direction movement, but i didn't add a background gravity for them.
2.The particles seems to move too fast when they're getting closer and closer, (because I don't know how to handle the issue of collision?)
I calculate the location by adding the corresponding force it experienced , how can i know if they collided with other? for example:
stage 1
particle1 [1,1]
particle2 [1,9]
stage 2
particle1 [9,9]
particle2 [1,9]
If I plot a graph of the path belonging to each particle, I can see if the graph of paths intercept with other, but the path intercept doesn't 100% means they'll collide, as they can have different speed.
I've tried to debug but just cannot find out where is going wrong.
in version 0 they tend to fail down (not my wish)
in version 1 they tend to fail to the right (i swap the x y) (simplified version)
here is the url of the bin and source (in pascal): stack_exchange_particle_gravity_collision.zip
here is the source code of version 0 in case you do not want to download the zip:
program ParticlesV0; uses graph; const pi=3.14159265358979; n=500; defaultSpeed=1; defaultRadius=2; defaultDensity=1e4; energyLoss=0.50; dotStyle=1; backGroundLevel=0; type ParticleType=record x,y,dr,dd,dx,dy,dfr,dfd:real; color:word; radius,mass:real; end; var gd,gm:smallint; PathToDriver:string; l:longint; particle:array[1..n]of ParticleType; //////////////////////////////////////////////////////////////// procedure backGround(i:smallint); var y:smallint; s,t:string; w,ori:word; begin ori:=GetColor; SetColor(10); while i>0 do begin for y:=0 to (GetMaxY div 10) do begin s:=''; for w:=0 to 255 do begin str(random(10),t); s:=s+t; end; OutTextXY(5,y*10,s); end; dec(i); end; SetColor(ori); end; procedure line(x1,y1,x2,y2:smallint); var x,y:smallint; begin x:=getx; y:=gety; moveto(x1,y1); lineto(x2,y2); moveto(x,y); end; function rx(x:real):real; begin rx:=x+(GetMaxX div 2); end; function ry(y:real):real; begin ry:=y+(GetMaxY div 2); end; function s(r:real):smallint; begin s:=round(r); end; function distance(p1,p2:ParticleType):real; var x,y:real; begin x:=p1.x-p2.x; y:=p1.y-p2.y; distance:=sqrt(x*x+y*y); end; function degree(p1,p2:ParticleType):real; var x,y,d:real; begin x:=p2.x-p1.x; y:=p2.y-p1.y; if x0 then d:=arctan(y/x) else if (yGetMaxX) then begin dx:=-dx; x:=GetMaxX-(x-GetMaxX); end; if (xGetMaxY) then begin dy:=-dy; y:=GetMaxY-(y-GetMaxY); end; if (y0) then begin tfr:=G*p.mass*particle[l].mass/sqr(r); tfd:=degree(p,particle[l]); tdx:=tfr*cos(tfd); tdy:=tfr*sin(tfd); dx:=dx+tdx; dy:=dy+tdy; // tdx:= end; p.dx:=p.dx+dx; p.dy:=p.dy+dy; end; end; //++++++++++++++++++++++++++++++// //////////////////////////////////////////////////////////////// begin gd:=detect; { highest possible resolution } gm:=0; { not needed, auto detection } PathToDriver:=' '; { path to BGI fonts, drivers aren't needed } InitGraph(gd,gm,PathToDriver); if (GraphResult=grok) then begin writeln('gd ',gd); writeln('GetMaxX ',GetMaxX); writeln('GetMaxY ',GetMaxY); writeln('GetMaxColor ',GetMaxColor); backGround(backGroundLevel); line(0, 0, GetMaxX, GetMaxY); SetFillStyle(HatchFill,13); FillEllipse(s(rx(0)),s(ry(0)),10,10); for l:=1 to n do initp(particle[l]); repeat for l:=1 to n do begin calp(particle[l]); movep(particle[l]); end; until false; readln; CloseGraph; { restores the old graphics mode } end else writeln('Graphic not supported.'); readln; end.
sorry for the poor formatting