A surprising glitch(?) in Processing Java

Good morning all,

So I had a simple idea.

  • Make a ball rotate the center of canvas
  • draw a rect over canvas with lots of opacity, so that image fades a bit every time
  • copy a slightly smaller part of canvas and stretch it to fill whole canvas. It creates an effect that you are closing in.

Here’s the p5.js program p5.js Web Editor

I have used this copy screen & stretch method before and noticed it does something funny along x and y axis passing through origo or center of the screen. I thought it’s something to do with web or rounding errors or what not. Previous experiments had shown that Java worked nice and javascript version had these disturbances. So I switched back to Java expecting them to go a way.

Only to find new and honestly very interesting glitches.

Here’s the Java code for if you want to run it on your own computer

color ext = 4;
int rad = 0;

void setup() {
  size(800,800);
  colorMode(HSB, 360, 360, 360, 360);
}

 void draw() {
  copy(ext,ext,width-ext*2,height-ext*2,0,0,width,height);
  fill(0,0,300,3);
  noStroke();
  rect(0,0,width,height);
  translate(width/2, height/2);
  rotate(radians(rad--));
  stroke(0,0,0);
  strokeWeight(10);
  point(0,50);
}

Naturally I’d like to know what happens. Is this a bug in Processing Java or is it just a weird combination of things that causes it.

5 Likes

This gives even weirder results

color ext = 2;
int rad = 0;

void setup() {
  size(800,800);
  colorMode(RGB, 360, 360, 360, 360);
}

 void draw() {
  copy(ext,ext,width-ext*2,height-ext*2,0,0,width,height);
  fill(0,0,300,3);
  noStroke();
  //rect(0,0,width,height);
  translate(width/2, height/2);
  rotate(radians(rad--));
  stroke(0,0,0);
  strokeWeight(10);
  point(0,50);
}
2 Likes

Wow I was just playing with your code and I never thought to use the copy() function to do this, it looks so good :wink:

I think this is just the way the copy() function works

Could be. I’ve used it a couple of times before without problems. I’ll need to try things a bit more. With so few commands it should be easy and quick to go through all combinations.

I found this copy trick from Twitter, so I cannot take credit from inventing it.

Hello,

Thanks for sharing!

I am having fun with this.

I do notice a performance hit when the source to destination is not the same size.

Stats:
size(800, 800) frameRate drops to 30 fps
size(600, 600) frameRate drops to 50 fps
size(500, 500) frameRate almost 60 fps

My exploration of this with a bit of colour and mouse interaction:

Code
color ext = 4;
float rad = 0;
float hue1 = 0;

void setup() 
  {
  size(500, 500);
  colorMode(HSB, 360, 360, 360, 360);
  println(frameRate);
  background(0);
  }

void draw() 
  {
  //copy(sx, sy, sw, sh, dx, dy, dw, dh)
  //copy(ext, ext, width, height, 0, 0, width, height);
  copy(ext, ext, width-ext*2, height-ext*2, 0, 0, width, height);
  //copy(ext, ext, width-ext*2, height-ext*2, 0, 0, width -8, height-8);
    
  fill(300, 0, 0, 3);
  noStroke();
  rect(0,0,width,height);
  
  translate(width/2, height/2);
  
  float den = map(mouseX, 0, width, 1, 90);
  
  rad -= TAU/den; 
  rotate(rad);
  
  hue1 = 360*(0.5*sin(rad)+0.5);
  stroke(hue1, 360, 360);
  strokeWeight(10);
  
  point(0, 50);
  
  if (frameCount%30 == 0)
    println(frameRate);
  }

:)

4 Likes

That makes me happy :grin:

I guess there’s a plenty of calculations with size change. And most likely it’s directly proportional to size of the source and destination. I have used it in slow changes, so drop in the frame rate wasn’t a problem. I need to check what is frameRate with full 1080P.

1 Like

I did a bit more testing. Adding noSmooth();, well removes all white pixels and those wavy stuff. So I think most of the oddness comes from combination of smoothing and usage of copy(). Smoothing, well smoothies color change between (adjacent) pixels to reduce visible pixelation, it takes anti-aliasing off. Then copy picks up those shades in between black and white pixels and because image is enlarged a bit there’s plenty of calculations and rounding of values creates all the weirdness.

I suspect that there’s a lot of interesting and weird stuff to be found.

2 Likes

I think you are right that much of the effect is the propagation of antialiasing artifacts.

That said, this can also propagate noSmooth artifacts from the edges of the circle – sometimes dramatically. Here is a sketch that steps up through different crop margins with each rotation - 3, 4, 5, 6, 7. I’m particularly surprised by the instant changes in the lower half, but the entire geometry being a byproduct of the point interacting with edges is a trip…

color ext = 3;
int rad = 0;
int turn = -1;

void setup() {
  size(800, 800);
  noSmooth();
  colorMode(RGB, 360, 360, 360, 360);
  background(360);
}

void draw() {
  copy(ext, ext, width-ext*2, height-ext*2, 0, 0, width, height);

  fill(0, 0, 300, 3);
  noStroke();
  translate(width/2, height/2);
  rad=rad+turn;
  rotate(radians(rad));
  stroke(0, 0, 0);
  strokeWeight(10);
  point(0, 50);
  if (rad%360==0) {
    println(rad, ext, frameCount);
    ext++;
  }
}

CopyEffects_20200527123959-resize

3 Likes