samuel bravo
YaBB Newbies
Offline
Posts: 24
scl
Re: Suggestion: fluid dynamics port
Reply #1 - Jun 14th , 2009, 10:06pm
I guess one important reason why Murphy's code is a little slow is the rendering method. It uses small rectangles to present the fluid, each frame it fills the screen with rectangles. If we replace the rectangles with pixels it runs much faster, try it. int res = 2 ;//1 o 2 int lwidth; int lheight; int pnum = 40000; vsquare[][] v; vbuffer[][] vbuf; particle[] p; int pcount = 0; void setup() { size(200, 200); lwidth = width/res; lheight = height/res; v = new vsquare[lwidth+1][lheight+1]; vbuf = new vbuffer[lwidth+1][lheight+1]; p = new particle[pnum]; noStroke(); for(int i = 0; i < pnum; i++) { p[i] = new particle(random(width/2-20,width/2+20),random(height-20,height)); } for(int i = 0; i <= lwidth; i++) { for(int u = 0; u <= lheight; u++) { v[i][u] = new vsquare(i*res,u*res); vbuf[i][u] = new vbuffer(i*res,u*res); } } } void draw() { smooth(); for(int i = 0; i < lwidth; i++) { for(int u = 0; u < lheight; u++) { vbuf[i][u].updatebuf(i,u); v[i][u].col = 0; } } for(int i = 0; i < pnum-1; i++) { p[i].updatepos(); } loadPixels(); for(int i = 0; i < lwidth; i++) { for(int u = 0; u < lheight; u++) { v[i][u].addbuffer(i, u); v[i][u].updatevels(); v[i][u].display(i, u); } } updatePixels(); //objeto stroke(200,0,0); strokeWeight(60); point(240,300); strokeWeight(20); point(140,100); } class particle { float x; float y; float xvel; float yvel; float temp; int pos; particle(float xIn, float yIn) { x = xIn; y = yIn; } void reposition() { x = width/2+random(-20,20);//fuente de baja presion y = random(height-10,height); xvel = random(-1,1); yvel = random(-1,1); } void updatepos() { int vi = (int)(x/res); int vu = (int)(y/res); if(vi > 0 && vi < lwidth && vu > 0 && vu < lheight) { v[vi][vu].addcolour(2); float ax = (x%res)/res; float ay = (y%res)/res; xvel += (1-ax)*v[vi][vu].xvel*0.05; yvel += (1-ay)*v[vi][vu].yvel*0.05; xvel += ax*v[vi+1][vu].xvel*0.05; yvel += ax*v[vi+1][vu].yvel*0.05; xvel += ay*v[vi][vu+1].xvel*0.05; yvel += ay*v[vi][vu+1].yvel*0.05; v[vi][vu].yvel -= (1-ay)*0.003; v[vi+1][vu].yvel -= ax*0.003; if(v[vi][vu].yvel < 0) v[vi][vu].yvel *= 1.00025; x += xvel; y += yvel; } else { reposition(); } if(random(0,400) < 1) { reposition(); } xvel *= 0.6; yvel *= 0.6; } } class vbuffer { int x; int y; float xvel; float yvel; float pressurex = 0; float pressurey = 0; float pressure = 0; vbuffer(int xIn,int yIn) { x = xIn; y = yIn; pressurex = 0; pressurey = 0; } void updatebuf(int i, int u) { if(i>0 && i<lwidth && u>0 && u<lheight) { pressurex = (v[i-1][u-1].xvel*0.5 + v[i-1][u].xvel + v[i-1][u+1].xvel*0.5 - v[i+1][u-1].xvel*0.5 - v[i+1][u].xvel - v[i+1][u+1].xvel*0.5); pressurey = (v[i-1][u-1].yvel*0.5 + v[i][u-1].yvel + v[i+1][u-1].yvel*0.5 - v[i-1][u+1].yvel*0.5 - v[i][u+1].yvel - v[i+1][u+1].yvel*0.5); pressure = (pressurex + pressurey)*0.25; if (color(get(x,y))==color(200,0,0)) pressure = 3.0*.18;//lee el obstaculo } } } class vsquare { int x; int y; float xvel; float yvel; float col; vsquare(int xIn,int yIn) { x = xIn; y = yIn; } void addbuffer(int i, int u) { if(i>0 && i<lwidth && u>0 && u<lheight) { xvel += (vbuf[i-1][u-1].pressure*0.5 + vbuf[i-1][u].pressure + vbuf[i-1][u+1].pressure*0.5 - vbuf[i+1][u-1].pressure*0.5 - vbuf[i+1][u].pressure - vbuf[i+1][u+1].pressure*0.5)*0.49; yvel += (vbuf[i-1][u-1].pressure*0.5 + vbuf[i][u-1].pressure + vbuf[i+1][u-1].pressure*0.5 - vbuf[i-1][u+1].pressure*0.5 - vbuf[i][u+1].pressure - vbuf[i+1][u+1].pressure*0.5)*0.49; } } void updatevels() { xvel *= 0.99; yvel *= 0.98; } void addcolour(int amt) { col += amt; if(col > 196) col = 196; } void display(int i, int u) { float tcol = 0; if(i>0 && i<lwidth-1 && u>0 && u<lheight-1) { tcol = (+ v[i][u+1].col + v[i+1][u].col + v[i+1][u+1].col*0.5 )*0.3; tcol = (int)(tcol+col*0.5); } pixels[int(x+y*width)]=color(255-tcol,255-tcol,255-tcol); if (res==2){ pixels[int(x+1+y*width)]=color(255-tcol,255-tcol,255-tcol); pixels[int(x+(y+1)*width)]=color(255-tcol,255-tcol,255-tcol); pixels[int(x+1+(y+1)*width)]=color(255-tcol,255-tcol,255-tcol); } // pixels[int(x+y*width)]=color(255-tcol,255-tcol-150,255-tcol-255); /* if (255-tcol<60)pixels[int(x+y*width)]=color (255-tcol,2*(255-tcol)-240,2*(255-tcol)); if (255-tcol>=60)pixels[int(x+y*width)]=color (255-tcol,2*(255-tcol)-240,240-2*(255-tcol));*/ col = 0; } }