We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › Improving the efficiency of drawing many lines
Page Index Toggle Pages: 1
Improving the efficiency of drawing many lines? (Read 579 times)
Improving the efficiency of drawing many lines?
May 26th, 2009, 7:32am
 
Hello, i'm attempting to make a simple drawing app similar to the flash one on ratemydrawing.com, but before my app reaches anything near the number of vertices required for a semi-decent drawing, it begins to seriously chug. Is there any way of improving the efficiency of drawing thousands of lines, perhaps by combining each section into a shape? I've attempted to use drawing onto a canvas instead (which meant that the number of lines draw didn't affect the framerate) but to get the canvas size I wanted it had to be huge...and the memory usage was off the charts!

Thanks,
Rob

/*
Buttons:
1 - draw (drag mouse to draw)
2 - move  (drag mouse to move)
*/

PFont font;

int fps=60;
int dX=800;
int dY=800;

ArrayList userPoints=new ArrayList();

boolean mouse=false;
int viewX=0;
int viewY=0;
int dragStartX=0;
int dragStartY=0;
int tool=0;

void setup(){
 size(dX,dY);
 frameRate(fps);
 smooth();
 background(255);
 font=createFont("Arial",12);
 textFont(font,12);
}

void draw(){
 background(255);
 
 if(mousePressed){
   
   //button held
   if(!mouse){
     if(tool==0){
       userPoints.add(new Point(mouseX-viewX,mouseY-viewY));
     }
     if(tool==1){
       dragStartX=mouseX-viewX;
       dragStartY=mouseY-viewY;
     }
   }
     
   
   //add point
   if(tool==0)
   if(!(mouseX==pmouseX && mouseY==pmouseY)|| !mouse){
     userPoints.add(new Point(mouseX-viewX,mouseY-viewY));
   }
    //set drag start pos
   if(tool==1){
     viewX=(mouseX-dragStartX);
     viewY=(mouseY-dragStartY);
   }
   
   mouse=true;
 }
 //released
 else
 if(mouse){
   if(tool==0){
     userPoints.add(new Point());
   }
   mouse=false;
 }
 
 //draw lines
 if(userPoints.size()>0){
   for(int i=0;i<userPoints.size()-1;i++){
     Point p2=(Point)userPoints.get(i+1);
     Point p1=(Point)userPoints.get(i);
     if(!p2.empty && !p1.empty){
       int x2=p2.x+viewX;
       int y2=p2.y+viewY;
       int x1=p1.x+viewX;
       int y1=p1.y+viewY;
       stroke(0);
       strokeWeight(3);
       line(x1,y1,x2,y2);
     }
     noFill();
   }
 }

 fill(0);
 //show view position
 text("("+-viewX+","+-viewY+")",10,20);
 text("Num vertices: "+userPoints.size(),width/2,20);
 text("fps: "+frameRate,width/4,20);
 if(tool==0)text("Drawing",width-50,20);
 if(tool==1)text("Moving",width-50,20);
}

void keyPressed(){
 if(key=='1'){
   tool=0;
 }
 if(key=='2'){
   tool=1;
 }
}

public class Point{
 int x,y;
 boolean empty=false;
 Point(){
   empty=true;
   x=0;
   y=0;
 }
 Point(int x,int y){
   this.x=x;
   this.y=y;
 }
 
 void setPos(int x,int y){
   this.x=x;
   this.y=y;
 }
 
 String toString(){
   if(!empty)return x+" "+y;
   else return "-";
 }
}
Re: Improving the efficiency of drawing many lines?
Reply #1 - May 26th, 2009, 9:05am
 
I suppose you meant Rate My Drawings (plural).

I am not sure what you mean by "chug". Nor what canvas size you aim at, a quick glance at the site didn't show huge drawing sizes.

Just a remark: it might be more efficient and at least more readable to handle mouse events in their respective callback functions instead of stacking everything in draw(). And indeed, you should avoid drawing all lines on each draw() loop, building the finished drawing in an offscreen PGraphics might be a sensible option.
Re: Improving the efficiency of drawing many lines?
Reply #2 - May 27th, 2009, 4:03am
 
Cheers for the swift reply. Sorry, used a bit of welsh lingo there...chug just means to seriously slow down. I've done as you've suggested and seperated the mouse stuff into the callbacks; it looks a lot nicer now.
The canvas size I wanted was infinite! So I was using a set of 4 canvases that scrolled as you moved which eventually looping back to the start and drawing the new content when off screen. So the effect was an infinite canvas. But the there was a serious memory issue because you needed 4 PGraphics each larger than the window size in memory at one time. Any ideas?

Is flash significantly more efficient at drawing than java? Because that ratemydrawings flash applet can handle several times more vertices.

Cheers,
Rob
Re: Improving the efficiency of drawing many lines?
Reply #3 - May 27th, 2009, 6:02am
 
Flash also starts to chug after it has drawn a large number of vertices, so that Flash applet will almost certainly take the same approach suggested by PhiLho - i.e. regularly drawing them to a bitmap.  Certainly that's the approach I've seen suggested when handling this type of application in Flash...
Re: Improving the efficiency of drawing many lines?
Reply #4 - May 27th, 2009, 8:45am
 
Well, the Flash applet doesn't handle infinite canvas, does it?
Beside, if you have an infinite canvas, you would need infinite variables to store the coordinates...
This infinite canvas complicates the problem, because it is harder to put in cache the strokes: if you reveal a portion of canvas, you would need to repaint that part with the strokes there...
Page Index Toggle Pages: 1