speed
in
Programming Questions
•
1 year ago
Hi, Im working on a sketch that have a lot of particles moving at the same time. Im trying to simulate water flow on a pipe. The sketch was OK till I started to draw the limit of the pipe. Then the sketch start to be too slow.
I´ve solve the problem changing the way I draw the borders, but I dont understand why my skectch was so slow, and I want to know about it to select in the future faster solutions. The instructions that draw the borders are few compared with the ones that draw the particles.
This is the code as it is now. The lines that draw the borders the slow way are writen at the end as comentaries:
float count;
int width=800;
int height=600;
float g=2;
ArrayList balls= new ArrayList();
float k=1;//factor to increment distance between balls
float c= 4;//maximun penetrance in walls
float vlim=10;//maximum speed
float population=1000;//population limit
float suck = 20;// distance of influence
float leftborder;
float rightborder;
float visc;
float pipediam = 600;
float middle;
float repulsion = 0.1;
float reslenght = 100;
float respoint;
int width=800;
int height=600;
float g=2;
ArrayList balls= new ArrayList();
float k=1;//factor to increment distance between balls
float c= 4;//maximun penetrance in walls
float vlim=10;//maximum speed
float population=1000;//population limit
float suck = 20;// distance of influence
float leftborder;
float rightborder;
float visc;
float pipediam = 600;
float middle;
float repulsion = 0.1;
float reslenght = 100;
float respoint;
void setup(){
noStroke();
size(800,600);
leftborder = width/2-pipediam/2;
rightborder = width/2 + pipediam/2;
middle =(leftborder + rightborder)/2;
respoint = height/2;
for (int i = 0; i < population; i++){
balls.add(new ball(int(random(leftborder,rightborder)), int(random(0,height))));
}
}
noStroke();
size(800,600);
leftborder = width/2-pipediam/2;
rightborder = width/2 + pipediam/2;
middle =(leftborder + rightborder)/2;
respoint = height/2;
for (int i = 0; i < population; i++){
balls.add(new ball(int(random(leftborder,rightborder)), int(random(0,height))));
}
}
void draw(){
fill (250,150);
rect(0,0,width, height);
for(int i=0;i<balls.size();i++){
ball b = (ball) balls.get(i);
//separate from walls
if(b.pos.x>rightborder-b.r+c){b.pos.x=rightborder;}
if(b.pos.x<leftborder + b.r-c){b.pos.x=leftborder;}
if(b.pos.y>height-b.r+c){b.pos.y-=5;}
//repulsion between balls
for(int j=i+1;j<balls.size();j++){
ball b2 = (ball) balls.get(j);
PVector dx=PVector.sub(b2.pos,b.pos);
if (dx.mag() < suck){
dx.normalize();
dx.mult(repulsion);
b2.force.add( dx);
dx.mult(-1);
b.force.add( dx);
}
}
//repulsion to walls
if (b.pos.x < suck + leftborder){
b.force.x = b.force.x + repulsion;
}
if (b.pos.x > rightborder - suck){
b.force.x = b.force.x - repulsion;
}
b.update();
// corrections
if (b.v.y < 0){b.v.y = 0;}
b.render();
if (b.pos.y > height){
b.pos.y = 0;
}
}
fill (250,150);
rect(0,0,width, height);
for(int i=0;i<balls.size();i++){
ball b = (ball) balls.get(i);
//separate from walls
if(b.pos.x>rightborder-b.r+c){b.pos.x=rightborder;}
if(b.pos.x<leftborder + b.r-c){b.pos.x=leftborder;}
if(b.pos.y>height-b.r+c){b.pos.y-=5;}
//repulsion between balls
for(int j=i+1;j<balls.size();j++){
ball b2 = (ball) balls.get(j);
PVector dx=PVector.sub(b2.pos,b.pos);
if (dx.mag() < suck){
dx.normalize();
dx.mult(repulsion);
b2.force.add( dx);
dx.mult(-1);
b.force.add( dx);
}
}
//repulsion to walls
if (b.pos.x < suck + leftborder){
b.force.x = b.force.x + repulsion;
}
if (b.pos.x > rightborder - suck){
b.force.x = b.force.x - repulsion;
}
b.update();
// corrections
if (b.v.y < 0){b.v.y = 0;}
b.render();
if (b.pos.y > height){
b.pos.y = 0;
}
}
}
class ball{
PVector pos;
PVector v;
PVector force;
color c;
int r=3;
float f = 0.1;
float g = 0.1;
float vaverage = 2;
ball(int x0, int y0){
pos=new PVector(x0,y0);
v=new PVector(0,4);
force = new PVector (0,0);
}
void update(){
v.y = vaverage * (0.5 +(1 - sq(pos.x - middle)/sq(pipediam/2)));
v.add (force);
//add some chaos
v.x = v.x + random(-0.3,0.3);
count++;
//v.y = v.y + g ;
pos.add(v);
v.x = v.x*0.5;
force.x = 0;
force.y = 0;
}
void render(){
int pipesize = 60;
float posx;
float posy;
float rightside = middle + pipesize/2;
float leftside = middle - pipesize / 2;
fill(20,20,2000);
rect (leftside - 4, 0, 4 , (height - reslenght)/2);
rect (rightside, 0, 4 , (height - reslenght)/2);
rect (leftside - 4, (height + reslenght)/2, 4 , (height - reslenght)/2);
rect (rightside, (height + reslenght)/2, 4 , (height - reslenght)/2);
line (leftborder, 0, leftborder, height);
if ((pos.y > respoint - reslenght/2)&& (pos.y < respoint + reslenght/2)){
float xini = leftside + 0.25 * pipesize* (1 - abs(pos.y - respoint) /reslenght);
posx = xini + (pipesize - 2 * (xini - leftside)) * (pos.x - leftborder)/pipediam;
}
else
{
posx = leftside + pipesize * (pos.x - leftborder)/pipediam;
}
ellipse(int(posx),int(pos.y),2.5,2.5);
/*for (int i = 0; i < 22;i++){
posy = respoint - i *(reslenght/40);
posx = leftside + 0.25 * pipesize * (1 - sq(i * reslenght/40)/sq(reslenght/2));
ellipse (posx, posy, 5,5);
posy = respoint + i *(reslenght/40);
posx = leftside + 0.25 * pipesize * (1 - sq(i * reslenght/40)/sq(reslenght/2));
ellipse (posx, posy, 5,5);
posy = respoint - i *(reslenght/40);
posx = rightside - 0.25 * pipesize * (1 - sq(i * reslenght/40)/sq(reslenght/2));
ellipse (posx, posy, 5,5);
posy = respoint + i *(reslenght/40);
posx = rightside - 0.25 * pipesize * (1 - sq(i * reslenght/40)/sq(reslenght/2));
ellipse (posx, posy, 5,5);
}*/
ellipse(leftside - 2 , respoint, 0.5* pipesize, reslenght);
ellipse (rightside + 2, respoint, 0.5 * pipesize, reslenght);
fill (255);
ellipse(leftside - 6 , respoint, 0.5* pipesize, reslenght);
ellipse (rightside + 6, respoint, 0.5 * pipesize, reslenght);
//}
}
}
PVector pos;
PVector v;
PVector force;
color c;
int r=3;
float f = 0.1;
float g = 0.1;
float vaverage = 2;
ball(int x0, int y0){
pos=new PVector(x0,y0);
v=new PVector(0,4);
force = new PVector (0,0);
}
void update(){
v.y = vaverage * (0.5 +(1 - sq(pos.x - middle)/sq(pipediam/2)));
v.add (force);
//add some chaos
v.x = v.x + random(-0.3,0.3);
count++;
//v.y = v.y + g ;
pos.add(v);
v.x = v.x*0.5;
force.x = 0;
force.y = 0;
}
void render(){
int pipesize = 60;
float posx;
float posy;
float rightside = middle + pipesize/2;
float leftside = middle - pipesize / 2;
fill(20,20,2000);
rect (leftside - 4, 0, 4 , (height - reslenght)/2);
rect (rightside, 0, 4 , (height - reslenght)/2);
rect (leftside - 4, (height + reslenght)/2, 4 , (height - reslenght)/2);
rect (rightside, (height + reslenght)/2, 4 , (height - reslenght)/2);
line (leftborder, 0, leftborder, height);
if ((pos.y > respoint - reslenght/2)&& (pos.y < respoint + reslenght/2)){
float xini = leftside + 0.25 * pipesize* (1 - abs(pos.y - respoint) /reslenght);
posx = xini + (pipesize - 2 * (xini - leftside)) * (pos.x - leftborder)/pipediam;
}
else
{
posx = leftside + pipesize * (pos.x - leftborder)/pipediam;
}
ellipse(int(posx),int(pos.y),2.5,2.5);
/*for (int i = 0; i < 22;i++){
posy = respoint - i *(reslenght/40);
posx = leftside + 0.25 * pipesize * (1 - sq(i * reslenght/40)/sq(reslenght/2));
ellipse (posx, posy, 5,5);
posy = respoint + i *(reslenght/40);
posx = leftside + 0.25 * pipesize * (1 - sq(i * reslenght/40)/sq(reslenght/2));
ellipse (posx, posy, 5,5);
posy = respoint - i *(reslenght/40);
posx = rightside - 0.25 * pipesize * (1 - sq(i * reslenght/40)/sq(reslenght/2));
ellipse (posx, posy, 5,5);
posy = respoint + i *(reslenght/40);
posx = rightside - 0.25 * pipesize * (1 - sq(i * reslenght/40)/sq(reslenght/2));
ellipse (posx, posy, 5,5);
}*/
ellipse(leftside - 2 , respoint, 0.5* pipesize, reslenght);
ellipse (rightside + 2, respoint, 0.5 * pipesize, reslenght);
fill (255);
ellipse(leftside - 6 , respoint, 0.5* pipesize, reslenght);
ellipse (rightside + 6, respoint, 0.5 * pipesize, reslenght);
//}
}
}
1