Let PShapes in an array rotate on its own axis in Processing

Viewed 85

I have this code that basically reads each pixel of an image and redraws it with different shapes. All shapes will get faded in using a sin() wave. Now I want to rotate every "Pixelshape" around its own axis (shapeMode(CENTER)) while they are faded in and the translate function gives me a headache in this complex way.

Here is the code so far:

void setup() {
  size(1080, 1350); 
  shapeMode(CENTER);
  img = loadImage("loremipsum.png");
…
}

void draw() {
    background(123);
    for (int gridX = 0; gridX < img.width; gridX++) {
    for (int gridY = 0; gridY < img.height; gridY++) {

      // grid position + tile size
      float tileWidth = width / (float)img.width;
      float tileHeight = height / (float)img.height;
      float posX = tileWidth*gridX;
      float posY = tileHeight*gridY;

      // get current color
      color c = img.pixels[gridY*img.width+gridX];

      // greyscale conversion
      int greyscale = round(red(c)*0.222+green(c)*0.707+blue(c)*0.071);
      int gradientToIndex = round(map(greyscale, 0, 255, 0, shapeCount-1));
    
      //FADEIN
      float wave = map(sin(radians(frameCount*4)), -1, 1, 0, 2);
      //translate(HEADACHE);
      rotate(radians(wave));
      shape(shapes[gradientToIndex], posX, posY, tileWidth * wave, tileHeight * wave);
    }
  }

I have tried many calculations but it just lets my sketch explode. One that worked in another sketch where I tried basically the same but just in loop was (equivalent written):

translate(posX + tileWidth/2, posY + tileHeight/2);

I think I just don't get the matrix right? How can I translate them to its meant place?

2 Answers

rotate defines a rotation matrix and multiplies the current matrix by the rotation matrix. rotate therefore causes a rotation by (0, 0).
You have to center the rectangle around (0, 0), rotate it and move the rotated rectangle to the desired position with translate.

Since translate and rotate multiplies the current matrix by a new matrix, you must store and restore the matrix by pushMatrix() respectively popMatrix().

The center of a tile is (posX + tileWidth/2, posY + tileHeight/2):

pushMatrix();
translate(posX + tileWidth/2, posY + tileHeight/2);
rotate(radians(wave));
shape(shapes[gradientToIndex], 
    -tileWidth*wave/2, -tileHeight*wave/2,
    tileWidth * wave, tileHeight * wave);
popMatrix();

Thank you very much @Rabbid76 – at first I just pasted in your idea and it went of crazy – then I added pushMatrix(); and popMatrix(); – turned out your translate(); code was in fact right! Then I had to change the x and y location where every shape is drawn to 0,0, And this is it! Now it works! See the code here:

   float wave = map(sin(radians(frameCount*4)), -1, 1, 0, 2);
   pushMatrix();
   translate(posX + tileWidth/2, posY + tileHeight/2);
   rotate(radians(wave*180));
   shape(shapes[gradientToIndex], 0, 0, tileWidth*wave , tileHeight*wave );
   popMatrix();

PERFECT! Thank you so much!

Related