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 › Mirroring output in realtime
Page Index Toggle Pages: 1
Mirroring output in realtime? (Read 638 times)
Mirroring output in realtime?
Dec 21st, 2008, 8:08pm
 
How do you copy what you've just created and show it on another part of the screen? I've looked into various commands but none of them work. I suspect I should use createGraphics() but it just gives me a black page.

What i want to achieve is to have the output of the left half of the canvas to be duplicated in realtime and mirrored on the right half of the canvas.
Any pointers would be greatly appreciated.

Below is my code for the left half of the piece:

int yPos, xPos;
int startY, startX;
float changeDirection;
int borderChange = 1;
String direction = "";
int myCol = 1;
boolean colourUp;
String atBorder = "";
int i=0;
int cal = 50;
boolean calChange = true;



void setup(){
 size(700,700);
 frameRate(2000);
 yPos = height/2;
 xPos = width/2;
 background(0);
 noFill();


}



void draw(){


 if (myCol == 255){
   colourUp = true;
 }
 else if(myCol == 0){
   colourUp = false;
 }
 if(colourUp == true){
   myCol--;
 }
 if(colourUp == false){
   myCol++;
 }

 strokeWeight(cal);
 stroke(myCol);

 int changeDirection=int(random(5));

 if ((changeDirection == 1) && (direction != "Down") && (direction != "Up") && (xPos%50 == 0)) {
   direction = "Up";
 }
 if ((changeDirection == 2) && (direction != "Up") && (direction != "Down") && (xPos%50 == 0)) {
   direction = "Down";
 }
 if ((changeDirection == 3) && (direction != "Left") && (direction != "Right") && (yPos%50 == 0)) {
   direction = "Right";
 }
 if ((changeDirection == 4) && (direction != "Right") && (direction != "Left") && (yPos%50 == 0)) {
   direction = "Left";
 }    



 if (yPos == height-50){
   i++;
   direction = "Right";
   if (i==51){
     i=0;
     direction = "Up";

   }
 }
 if (yPos == 50){
   i++;
   direction = "Left";
   if (i==51){
     i=0;
     direction = "Down";

   }
 }
 if (xPos == width/2){
   i++;
   direction = "Up";
   if (i==51){
     i=0;
     direction = "Left";

   }
 }
 if (xPos == 50){
   i++;
   direction = "Down";
   if (i==51){
     i=0;
     direction = "Right";
   }
 }

 // top left corner  
 if ( (xPos == 50) && (yPos == 50) && (direction.equals("Left")) ) {
   direction = "Down";
 }
 if ( (xPos == 50) && (yPos == 50) && (direction.equals("Up")) ) {
   direction = "Right";
 }
 // top right corner  
 if ( (xPos == width/2) && (yPos == 50) && (direction.equals("Right")) ) {
   direction = "Down";
 }
 if ( (xPos == width/2) && (yPos == 50) && (direction.equals("Up")) ) {
   direction = "Left";
 }
 // bottom left corner  
 if ( (xPos == width/2) && (yPos == height - 50) && (direction.equals("Down")) ) {
   direction = "Left";
 }
 if ( (xPos == width/2) && (yPos == height - 50) && (direction.equals("Right")) ) {
   direction = "Up";
 }
 // bottom right corner  
 if ( (xPos == 50) && (yPos == height - 50) && (direction.equals("Left")) ) {
   direction = "Up";
 }
 if ( (xPos == 50) && (yPos == height - 50) && (direction.equals("Down")) ) {
   direction = "Right";
 }

 if (direction.equals("Right") ){
   line(xPos, yPos, xPos++, yPos);
 }  
 if (direction.equals("Left") ){
   line(xPos--, yPos, xPos, yPos);
 }
 if (direction.equals("Up") ){
   line(xPos, yPos, xPos, yPos--);
 }
 if (direction.equals("Down") ){
   line(xPos, yPos++, xPos, yPos);
 }


}
Re: Mirroring output in realtime?
Reply #1 - Dec 21st, 2008, 8:24pm
 
If you are going to use PGraphics, don't forget this:
Code:

PGraphics pg;
pg.beginDraw();
...
pg.endDraw();
image(pg, 0, 0);


But now for a quickest, laziest fix.  Slow, but a start:

Code:

int yPos, xPos;
int startY, startX;
float changeDirection;
int borderChange = 1;
String direction = "";
int myCol = 1;
boolean colourUp;
String atBorder = "";
int i=0;
int cal = 50;
boolean calChange = true;



void setup(){
 size(700,700);
 frameRate(2000);
 yPos = height/2;
 xPos = width/2;
 background(0);
 noFill();


}


PImage img;  


void draw(){
img=get();  
image(img,width/2,0);  
 if (myCol == 255){
   colourUp = true;
 }
 else if(myCol == 0){
   colourUp = false;
 }
 if(colourUp == true){
   myCol--;
 }
 if(colourUp == false){
   myCol++;
 }

 strokeWeight(cal);
 stroke(myCol);

 int changeDirection=int(random(5));

 if ((changeDirection == 1) && (direction != "Down") && (direction != "Up") && (xPos%50 == 0)) {
   direction = "Up";
 }
 if ((changeDirection == 2) && (direction != "Up") && (direction != "Down") && (xPos%50 == 0)) {
   direction = "Down";
 }
 if ((changeDirection == 3) && (direction != "Left") && (direction != "Right") && (yPos%50 == 0)) {
   direction = "Right";
 }
 if ((changeDirection == 4) && (direction != "Right") && (direction != "Left") && (yPos%50 == 0)) {
   direction = "Left";
 }    



 if (yPos == height-50){
   i++;
   direction = "Right";
   if (i==51){
i=0;
direction = "Up";

   }
 }
 if (yPos == 50){
   i++;
   direction = "Left";
   if (i==51){
i=0;
direction = "Down";

   }
 }
 if (xPos == width/2){
   i++;
   direction = "Up";
   if (i==51){
i=0;
direction = "Left";

   }
 }
 if (xPos == 50){
   i++;
   direction = "Down";
   if (i==51){
i=0;
direction = "Right";
   }
 }

 // top left corner  
 if ( (xPos == 50) && (yPos == 50) && (direction.equals("Left")) ) {
   direction = "Down";
 }
 if ( (xPos == 50) && (yPos == 50) && (direction.equals("Up")) ) {
   direction = "Right";
 }
 // top right corner  
 if ( (xPos == width/2) && (yPos == 50) && (direction.equals("Right")) ) {
   direction = "Down";
 }
 if ( (xPos == width/2) && (yPos == 50) && (direction.equals("Up")) ) {
   direction = "Left";
 }
 // bottom left corner  
 if ( (xPos == width/2) && (yPos == height - 50) && (direction.equals("Down")) ) {
   direction = "Left";
 }
 if ( (xPos == width/2) && (yPos == height - 50) && (direction.equals("Right")) ) {
   direction = "Up";
 }
 // bottom right corner  
 if ( (xPos == 50) && (yPos == height - 50) && (direction.equals("Left")) ) {
   direction = "Up";
 }
 if ( (xPos == 50) && (yPos == height - 50) && (direction.equals("Down")) ) {
   direction = "Right";
 }

 if (direction.equals("Right") ){
   line(xPos, yPos, xPos++, yPos);
 }  
 if (direction.equals("Left") ){
   line(xPos--, yPos, xPos, yPos);
 }
 if (direction.equals("Up") ){
   line(xPos, yPos, xPos, yPos--);
 }
 if (direction.equals("Down") ){
   line(xPos, yPos++, xPos, yPos);
 }


}
Re: Mirroring output in realtime?
Reply #2 - Dec 21st, 2008, 8:53pm
 
Thanks sw01,

I guess this method isn't the right way to go, I'm thinking now about creating a line object which I'll then create two instances of and then give them mirrored x and y positions.

I'm surprised by how slow the output can be for creating and copying images, I guess it's really hard work to copy all those pixels continuously.


Re: Mirroring output in realtime?
Reply #3 - Dec 21st, 2008, 8:59pm
 
I totally agree.
Re: Mirroring output in realtime?
Reply #4 - Dec 21st, 2008, 10:15pm
 
I think you could do it quite a lot easier.. something along the lines of the following should do it:

Code:
PImage left=get(0,0,width/2,height);
beginShape();
texture(left);
vertex(width/2,0,left.width,0);
vertex(width,0,0,0);
vertex(width,height,0,left.height);
vertex(width/2,height,left.width,left.height);
endShape();
Re: Mirroring output in realtime?
Reply #5 - Dec 21st, 2008, 10:38pm
 
Oh, right. (smacks forehead)

taking from JohnG,
Code:

img=get(0,0,width/2,height);
image(img,width/2,0);  


Which is still a bit slow, but 2x faster.

or another half-baked solution is to limit the scan range:
Code:
 
img=get(xPos-cal/2,yPos-cal/2,xPos+cal/2,yPos+cal/2);
image(img,width/2+xPos-cal/2 ,0+yPos-cal/2);  

But obviously this requires the knowledge of what is being updated, which kinda defeats the point of "mirroring" the image.



I couldn't get the texture method to work properly.  Am I missing something?  Is it faster than image?
Re: Mirroring output in realtime?
Reply #6 - Dec 21st, 2008, 11:16pm
 
I also couldn't get the vertex trick to work. Those new suggestions do seem snappier but arent fast enough yet.

Ive been looking into creating a class which makes the lines but it seems really hard, with my newbie experience I cant get around how one is supposed to create two lines which do the exact opposite of each other.

I want to do something like this (this is not correct syntax but just to explain:

 if (direction.equals("Right") ){
   line1(xPos, yPos, xPos++, yPos);
   line2(xPos--, yPos, xPos, yPos);
 }  
 if (direction.equals("Left") ){
   line1(xPos--, yPos, xPos, yPos);
   line2(xPos, yPos, xPos++, yPos);
 }
 if (direction.equals("Up") ){
   line1(xPos, yPos, xPos, yPos--);
   line2(xPos, yPos++, xPos, yPos);
 }
 if (direction.equals("Down") ){
   line1(xPos, yPos++, xPos, yPos);
   line2(xPos, yPos, xPos, yPos--);
 }

I cant do that because then the xpos and ypos are nulling each other out.
So i have to double all my variables, this doesnt seem elegant, there's gotta be a way to do this more simply.

I am definitely a newbie as you can tell.

Other things I dont get is if I have on draw():
line(x,y,x,y++);
line(x,y,x++,y);
It makes one line instead of two, and combines the actions (it goes diagonally)

Is there a way of ordering processing to make two separate lines do two different things without creating a class?

Btw even though the image copying thing didn't work out its very good too know for the future, thanks.

Re: Mirroring output in realtime?
Reply #7 - Dec 21st, 2008, 11:44pm
 
Actually, the formula you want to use for mirroring is:

mirrorXPos = width - xPos;


so, barring using class, here is how this can be implemented procedurally with least confusion - replace the part with:

Code:


 int xPos1 = xPos;
 int yPos1 = yPos;
 int xPos2 = xPos;
 int yPos2 = yPos;
 if (direction.equals("Right") ){
   //line(xPos, yPos, xPos++, yPos);
   xPos2++;
   xPos++;
 }  
 if (direction.equals("Left") ){
   //line(xPos--, yPos, xPos, yPos);
   xPos1--;
   xPos--;
 }
 if (direction.equals("Up") ){
   //line(xPos, yPos, xPos, yPos--);
   yPos2--;
   yPos--;
 }
 if (direction.equals("Down") ){
   //line(xPos, yPos++, xPos, yPos);
   yPos1++;
   yPos++;
 }
 line(xPos1, yPos1, xPos2, yPos2);
 
 /* mirror */
 line(width-xPos2, yPos2, width-xPos1, yPos1);


See how the implementation of lines are abstracted to fact that there are two points that needs to be used for lines to be drawn, and expressed that in a mirrored fashion quite literally.

...of course, you will have your head in a tangle if you try to do this with a more complex case, so I recommend learning how to use class in the future Smiley

By the way, it's quite pleasing to the eyes. Nice!
Re: Mirroring output in realtime?
Reply #8 - Dec 22nd, 2008, 12:52am
 
YES!
Thats what i wanted!
Thanks a million sw01.
Bit of a  bumme that i didnt crack the class thing, but this is my first processing piece next time I'll think 'Class" from the beginning.
Thanks again!
Re: Mirroring output in realtime?
Reply #9 - Dec 22nd, 2008, 1:04am
 
Welcome.  I think converting that into a class will be reasonably easy, though.  But it helps to have a working code first.
Re: Mirroring output in realtime?
Reply #10 - Dec 22nd, 2008, 1:10am
 
Thinking of rigging this up to a sound generator now. I'll post the results here when I've got it.
Re: Mirroring output in realtime?
Reply #11 - Dec 22nd, 2008, 10:51pm
 
You guys seem to have it under control but I think you should really consider JohnG's suggestion. I noticed his code snippet is missing a parameter. Each vertex has x, y, and z coordinates and two texture coordinates: u and v.

edit
---
Sorry it does work with just x, y, u, v. It doesn't work with the default renderer though.
---

I would create a quad that is the same size as your sketch window, translate it so it only takes up half the screen, and texture it with a PImage called texture. I would also suggest using something like:

arrayCopy(pixels, texture.pixels);

That would copy whatever you have drawn into the texture for the quad. I believe you could then set the texture coordinates on the quad so that the image would be flipped.

I did something like this to get feedback in a sketch. See my code in this post:
http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Video;action=display;num=1221187582;start=1#1

Maybe I'll try to do a more specific example if I get time.
Re: Mirroring output in realtime?
Reply #12 - Dec 23rd, 2008, 12:16am
 
Yes please! I am definitely curious about that approach especially if it improves on speed.
Re: Mirroring output in realtime?
Reply #13 - Dec 23rd, 2008, 4:01pm
 
I admit I haven't followed closely the thread, but from the subject, maybe these code snippets can help: Re: translate / blend question
If I am off topic, just ignore me! Wink
Re: Mirroring output in realtime?
Reply #14 - Dec 27th, 2008, 7:05pm
 
Here is my solution:
Quote:
PImage b;

void setup() {
 size(400,400,P3D);
 noStroke();
 background(0);
 loadPixels();
 b = new PImage(height,width);
 b.loadPixels();
}

void draw() {
 ellipse(mouseX, mouseY, 50, 50);  
 b.pixels = pixels;
 updatePixels();
 b.updatePixels();
 pushMatrix();
 beginShape(QUADS);
 texture(b);
 vertex(width/2,0,width/2,0);
 vertex(width,0,0,0);
 vertex(width,height,0,height);
 vertex(width/2,height,width/2,height);
 endShape();
 popMatrix();
}


The one with translate and scale in PhiLho's post is probably a little simpler actually. This was (of course) more complicated than I thought as the different renderers handle stuff differently. Also you can't use line() and get round caps in anything but the default renderer but if you just move an circle around without clearing the background you can get the same effect and probably simpler code.
Page Index Toggle Pages: 1