粒子模拟(重力和碰撞)错误



1.粒子似乎有过多的y方向移动,但我没有为它们添加背景重力。

2.当粒子越来越近时,它们似乎移动得太快了,(因为我不知道如何处理碰撞的问题?)

我通过加上它所经历的相应力来计算位置,我怎么能知道它们是否相互碰撞?例如:

第1阶段

particle1[1,1]

particle2[1,9]

第2阶段

particle1[9,9]

particle2[1,9]

如果我绘制属于每个粒子的路径图,我可以看到路径图是否与其他粒子相交,但路径相交并不100%意味着它们会碰撞,因为它们可能具有不同的速度。

我试过调试,但就是找不到哪里出了问题。

在版本0中,它们往往会出现故障(我不希望)

在版本1中,它们往往会向右失败(我交换x y)(简化版本)

这是bin和源的url(在pascal中):stack_exchange_particle_gravity_collision.zip

以下是版本0的源代码,以防您不想下载zip:

程序ParticlesV0;使用图表constpi=3.14159265358979;n=500;defaultSpeed=1;defaultRadius=2;defaultDensity=1e4;能量损失=0.50;dotStyle=1;backGroundLevel=0;类型ParticleType=记录x、 y,dr,dd,dx,dy,dfr,dfd:real;颜色:单词;半径,质量:真实;终止vargd,gm:smallint;PathToDriver:string;l: 渴望;particle:ParticleType的数组[1.n];////////////////////////////////////////////////////////////////过程背景(i:smallint);vary: smallint;s、 t:字符串;w、 ori:单词;开始ori:=GetColor;SetColor(10);当i>0开始时对于y=0到(GetMaxYdiv 10),请开始s: =";对于w:=0到255,请开始str(随机(10),t);s: =s+t;终止OutTextXY(5,y*10,s);终止dec(i);终止SetColor(ori);终止过程行(x1,y1,x2,y2:smallint);varx、 y:smallint;开始x: =getx;y: =gety;moveto(x1,y1);lineto(x2,y2);moveto(x,y);终止函数rx(x:real):real;开始rx:=x+(GetMaxXdiv 2);终止函数ry(y:实数):实数;开始ry:=y+(GetMaxYdiv 2);终止函数s(r:real):smallint;开始s: =圆形(r);终止函数距离(p1,p2:粒子类型):实数;varx、 y:真实;开始x: =p1.x-p2.x;y: =p1.y-p2.y;距离:=sqrt(x*x+y*y);终止函数度(p1,p2:ParticleType):实数;varx、 y,d:真实;开始x: =p2.x-p1.x;y: =p2.y-p1.y;如果x0,则d:=arctan(y/x)else if(yGetMaxX)然后开始dx:=-dx;x: =GetMaxX-(x-GetMaxX);终止if(xGetMaxY)然后开始dy:=-dy;y: =GetMaxY-(y-GetMaxY);终止if(y0)则开始tfr:=G*p.mass*粒子[l].mass/sqr(r);tfd:=度(p,粒子[l]);tdx:=tfr*cos(tfd);tdy:=tfr*sin(tfd);dx:=dx+tdx;dy:=dy+tdy;//tdx:=终止p.dx:=p.dx+dx;p.dy:=p.dy+dy;终止终止//++++++++++++++++++++++++++++++//////////////////////////////////////////////////////////////////开始gd:=检测;{可能的最高分辨率}gm:=0;{不需要,自动检测}PathToDriver:=";{BGI字体的路径,不需要驱动程序}InitGraph(gd,gm,PathToDriver);如果(GraphResult=grok),则开始writeln('gd',gd);writeln('GetMaxX',GetMaxX);writeln('GetMaxY',GetMaxY);writeln('GetMaxColor',GetMaxColor);backGround(backGroundLevel);行(0,0,GetMaxX,GetMaxY);SetFillStyle(图案填充,13);FillEllipse(s(rx(0)),s(ry(0),10,10);对于l:=1到n do initp(粒子[l]);重复对于l:=1到n,请开始calp(粒子〔l〕);movep(粒子[l]);终止直到错误;readln;CloseGraph;{恢复旧的图形模式}end else writeln('不支持图形。');readln;结束

很抱歉格式不正确

  1. 如果你想在粒子离得太近时移除它,这行应该完成任务:

    procedure calp(var p:ParticleType); ... e:=*put a number here witch scales with mass or something esle, you can even use defaultradius constant*; if (r>e) then begin ... else mass:=0 <- this now means it won't pull others particles, and won't be pulled either, ideally now you need to check everywhere for 0-os, alternatively you can place the particle randomly on the screen again, but it can cause some funny stuff, becouse of leftover vectors.

最新更新