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 & HelpPrograms › scrambled brain (Line Wrapping)
Page Index Toggle Pages: 1
scrambled brain (Line Wrapping) (Read 2136 times)
scrambled brain (Line Wrapping)
Aug 10th, 2005, 10:02am
 
It's too early for all this, I know.

Quite simple really:

I'm drawing a line(x1,y1,x2,y2);

I want to wrap the line around the screen so rather than it just clipping it wraps around the screen meaning that possibly more than 1 line needs to be drawn to take care of the overlaps.

You draw upto the edge and then with the % draw the other bit on which ever side of the screen it needs to be.

Anyone got the brains to do the calculation?

Re: scrambled brain (Line Wrapping)
Reply #1 - Aug 10th, 2005, 4:17pm
 
how about using a short bit of bresenham line drawing code (i think someone just posted something about this) to draw straight into the pixel buffer, which will let you use % for the x coordinate and things will wrap for free?

that way, no need to deal with where lines are at the edge, etc.

unless you want thick, anti-aliased lines, which would require more work.
Re: scrambled brain (Line Wrapping)
Reply #2 - Aug 10th, 2005, 4:23pm
 
I'm ok for the thicker, aliased stuff as I'm dumping to AIEXPORT.

I just posted a bresenham myself, but I don't follow you.

I'm blitting a buffer to the screen each frame from an offset x and y position that wraps the around the % portion.


***Update***

Yeah, you're right! Didn't think of that, I just change my pixel plot to % x and y and it wraps auto.

Nice one Ben.
Re: scrambled brain (Line Wrapping)
Reply #3 - Aug 10th, 2005, 4:56pm
 

Bugger! The only problem now is that the line I'm wanting is ai.ai_line(), as these are the ones I'm writing to AIExport.

Looks like I'll need to calculate the additional lines after all
Re: scrambled brain (Line Wrapping)
Reply #4 - Aug 10th, 2005, 6:18pm
 
you could brute force it by translating the coordinates so that x1 and y1 are definitely inside the viewing window, and then drawing eight more lines:

Code:


float xoffsets[] = { -width, 0, width,
                    -width, 0, width,
                    -width, 0, width };
float yoffsets[] = { -height, -height, -height,
                    0,       0,       0,
                    height,  height,  height };

void wrappedLine(float x1, float y1, float x2, float y2) {
 if (x1 < 0) {
   while (x1 < 0) {
     x1 += width;
     x2 += width;
   }
 }
 else if (x1 > width) {
   while (x1 > width) {
     x1 -= width;
     x2 -= width;
   }
 }
 if (y1 < 0) {
   while (y1 < 0) {
     y1 += height;
     y2 += height;
   }
 }
 else if (y1 > height) {
   while (y1 > height) {
     y1 -= height;
     y2 -= height;
   }
 }
 for (int i = 0; i < xoffsets.length; i++) {
   line(x1+xoffsets[i],y1+yoffsets[i],x2+xoffsets[i],y2+yoffsets[i]);
 }
}



Does that work?  I haven't tested it, and I suspect I'm thinking as clearly as you were this morning Smiley  One thing - it will only wrap once, so if you've got lines longer than 2*width or 2* height it'll be no good (and if you haven't, the while loops are overkill)... so more thought needed, I guess.


Re: scrambled brain (Line Wrapping)
Reply #5 - Aug 10th, 2005, 6:36pm
 
Ah, tested it now.  I think it works.  But you'll need...

Code:

float xoffsets[];
float yoffsets[];


Somewhere global, and then...

Code:

xoffsets = new float[] { -width, 0, width,
-width, 0, width,
-width, 0, width };
yoffsets = new float[] { -height, -height, -height,
0, 0, 0,
height, height, height };


in setup after you call size.
Re: scrambled brain (Line Wrapping)
Reply #6 - Aug 10th, 2005, 8:07pm
 

I only popped out for a walk, came back and there it was waiting for me. Probably means I should get out more often!

Seems to do the trick, Tom. Nice one!


I'm not too worried about the optimization at the moment as I'm just hacking something together to AIExport. Time's short and I'm having to plough through loads of sketches to make them reproducible at large scale.

Benjamin was right when he asserted that reproducibility is implicit within the work of art in the age of mechanical reproduction. I know that mine bloody well will be from now on in!
Re: scrambled brain (Line Wrapping)
Reply #7 - Aug 10th, 2005, 8:38pm
 

of course the other problem with this solution apart from optimization is AIExport ends up with all the offscreen draws and it becomes difficult to separate them.

Re: scrambled brain (Line Wrapping)
Reply #8 - Aug 10th, 2005, 9:38pm
 
Here's the whole code including Tom's wrapping line method.

I'm doing a wrap around scrolling number, which works fine. The problem is when writing out to the AIExport.

If anyone can see a solution, I'd appreciate it.

Sorry, but it's in 68 and not beta, due to PGraphics and just not getting around to it, so forgive the smoothLine function(), I'm not too arsed about it myself.

Code:


// Rather than snapshot each frame, just produce a vector with a list of points that can be dumped on exit
// as ai.run and snapshot are killer on the cpu

AIExport ai;

BGraphics buf;
color pen;

int backSize = 20;

void setup() {

 size(400,400);
 buf = new BGraphics(400,400);  // This can be any size screen+
 buf.background(255,255,255);
 
  xoffsets = new float[] { -width, 0, width,  
       -width, 0, width,  
       -width, 0, width };  
  yoffsets = new float[]  { -height, -height, -height,    
         0,  0,  0,  
         height,  height,  height };
         
 ai = new AIExport(this, 1);
 ai.setContinuousRecordingFrameRate(0);
 ai.turnTransparencyOn();

 pen = color(30,30,30,40);

 bx = buf.width/2-width;
 by = buf.height/2-height;

 ellipseMode(CENTER_DIAMETER);
 strokeWeight(2);
 blitX = width/2-backSize/2;
 blitY = height/2-backSize/2;
 
 noSmooth();

 setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}

void loop() {

 ai.takeSnapShot();
 ai.run();
 
 if(pause) {
   drawscn();
   return;
   }
   
 updatePos();
 
 // Blit buffer to screen, draw line and blit back modified section to buffer
 drawscn();
 
 if(mousePressed) {
 smoothLine(g,width/2,height/2,width/2+xmag,height/2+ymag,pen);
 backBlit();
   
 ai.ai_line(bx, by, bx+xmag, by+ymag);
   
 
 }
 stroke(0,255,0);
 ellipse(width/2, height/2, 2,2);
}

int blitX,blitY;

void backBlit() {

 x3=(((int)bx%buf.width)+buf.width+blitX)%buf.width;
 y3=(((int)by%buf.height)+buf.height+blitX)%buf.height;

 x1 = abs(buf.width-x3);
 x2 = abs(x1-backSize);
 y1 = abs(buf.height-y3);
 y2 = abs(y1-backSize);

 // blit X wrap around
 if(x3>=buf.width-backSize) {
   buf.replicate(g,blitX+x1,blitY,blitX+x2+x1,blitY+backSize, 0,y3,x2,y3+backSize);

   // blit X and Y wrap
   if(y3>=buf.height-backSize) {
     buf.replicate(g,blitX+x1,blitY+y1,blitX+x2+x1,blitY+y2+y1, 0,0,x2,y2);
   }
 }

 if(y3>=buf.height-backSize) {
   buf.replicate(g,blitX,blitY+y1,blitX+backSize,blitY+y1+y2, x3,0,x3+backSize,y2);
 }

 buf.replicate(g,blitX,blitY,blitX+backSize,blitY+backSize, x3,y3,x3+backSize,y3+backSize);
}

// draw large Bimage to screen as a continuous surface.
int x1,y1,x2,y2,x3,y3;

void drawscn() {

 x3=(((int)bx%buf.width)+buf.width)%buf.width;
 y3=(((int)by%buf.height)+buf.height)%buf.height;

 x1=abs(buf.width-x3);
 x2=abs(width-x1);
 y1=abs(buf.height-y3);
 y2=abs(height-y1);

 // blit X wrap around
 if(x3>=buf.width-width) {
   replicate(buf,0,y3,x2,y3+y1, x1,0,x1+x2,y1);

   // blit X and Y wrap
   if(y3>=buf.height-height) {
     replicate(buf,0,0,x2,y2,x1, y1,x1+x2,y1+y2);
   }
 }

 if(y3>=buf.height-height) {
   replicate(buf,x3,0,x3+x1,y2, 0,y1,x1,y1+y2);
 }

 replicate(buf,x3,y3,x3+x1,y3+y1, 0,0,x1,y1);
}

float bx,by;
float xmag, ymag = 0;

void updatePos() {
 xmag = (pmouseX-width/2)*0.025;
 ymag = (pmouseY-height/2)*0.025;
 bx = (bx+xmag)%buf.width;
 by = (by+ymag)%buf.height;
}

public void smoothLine(BGraphics g, float x1, float y1, float x2, float y2, color penCol) {
 g.stroke(penCol);      // Stroke on @ set weight
 g.line(x1,y1,x2,y2);     // draw the line

 if(g.strokeWeight>1) {
   g.fill(penCol);
   g.noStroke();  // strokeweight>1 causes strange behaviour, so noStroke to be safe, probably quicker, too.
   g.ellipse(x1, y1, g.strokeWeight*2,g.strokeWeight*2);  // cap previous line with rounded end
 }
}


boolean pause = false;
boolean toggle = false;

int saved;

void keyPressed() {

 if(key == ' ' && !toggle) {pause=!pause; toggle=true;}
 if(key == 's') {
 
   ai.setFileName("perfect.ai");
   ai.dumpSnapShots();
 //  ai.beginWriting();
 }
 }

void keyReleased() {

 if(key == ' ') {toggle=false;}
 if(key == 's') {buf.save("ps-"+saved+++".tga");}
 if(key == 'c') {buf.background(255);}
}




float xoffsets[];
float yoffsets[];


void wrappedLine(float x1, float y1, float x2, float y2) {

  ai.ai_stroke(pen);

  if (x1 < 0) {
    while (x1 < 0) {
      x1 += width;
      x2 += width;
    }
  }
  else if (x1 > width) {
    while (x1 > width) {
      x1 -= width;
      x2 -= width;
    }
  }
  if (y1 < 0) {
    while (y1 < 0) {
      y1 += height;
      y2 += height;
    }
  }
  else if (y1 > height) {
    while (y1 > height) {
      y1 -= height;
      y2 -= height;
    }
  }
  for (int i = 0; i < xoffsets.length; i++) {
    ai.ai_line(x1+xoffsets[i],y1+yoffsets[i],x2+xoffsets[i],y2+yoffsets[i]);
   
  }
}
 

Re: scrambled brain (Line Wrapping)
Reply #9 - Aug 10th, 2005, 10:10pm
 
Well, once you're drawing all the possible starts and ends of the line (as I did above) you just need a clippedLine function to throw away bits of lines outside the viewing window...

* TomC gets a pen.

Code:


void clippedLine(float x1, float y1, float x2, float y2) {

// find u for line (x,y) = (x1,y1) + u(x2-x1,y2-y1)
// such that x: [0,width) and y: [0,height)

float u1 = min( -y1/(y2-y1), -x1/(x2-x1) );
float u2 = max( (height-y1)/(y2-y1), (width-x1)/(x2-x1) );

u1 = constrain(u1,0.0,1.0);
u2 = constrain(u2,0.0,1.0);

line(x1+(u1*(x2-x1)),y1+(u1*(y2-y1)),
x1+(u2*(x2-x1)),y1+(u2*(y2-y1)));

}



I have a page of scribbled notes for why I'm right about this, but there was beer and Big Brother getting in the way so my maths might be off.  Not tested as usual...

You'll need to make sure y2 != y1 and x2 != x1 there otherwise you'll divide by zero...

(on edit: added constraint for u1,u2 to be between 0 and 1)
Re: scrambled brain (Line Wrapping)
Reply #10 - Aug 10th, 2005, 11:58pm
 

I've tried it, but no joy. I can't offer much in the way of reasons either because I haven't a clue what that code is doing, other than the logic of it.

Seems AIExport function is still getting duplicates

Thanks though, Tom.


Re: scrambled brain (Line Wrapping)
Reply #11 - Aug 11th, 2005, 12:43am
 
Oh, you're right.  It only seems to catch about half of the cases Sad

Ah well, back to the drawing board...
Re: scrambled brain (Line Wrapping)
Reply #12 - Aug 12th, 2005, 12:20pm
 

Well, never mind. What I'm doing now is just isolating the buffer/ screen with a rectangle, so when I import it into Illustrator I can clip it there.

It's dirty but it works, and that's the main thing!

Thanks for your help Tom.
Page Index Toggle Pages: 1