Loading...
Logo
Processing Forum
Obviously new to this, and the solution is probably obvious, too, but I've tried every placement of the rotate and translate functions I can think of. 

I'm just trying to make the entire level-2 fractal shape rotate around its own center point in the middle of the screen. As it is, the whole shape rotates around 0, 0, 0, or at least appears to. Code follows below. Thanks for any help.

// level-2 mosely fractal assembler

color c = color (0, 200, 20, 100);
int cubeSize = 40;

float rX;
float rY;

MoselyTwo moselySecond;

void setup () {
  size (1200, 800, OPENGL);
  smooth ();
  
moselySecond = new MoselyTwo (width / 2, height / 2, 0);
}

void draw () {
  background (10);
  pushMatrix ();
  rotateX (rX);
  rotateY (rY);
  moselySecond.displayTwo ();
  popMatrix ();
  
  rX = rX + .005;
  rY = rY + .005;
}


class Cube {  
  int cubeX; // final cube x position relative to sponge center
  int cubeY; // final cute y position relative to sponge center
  int cubeZ; // final cube z position relative to sponge center
  
  int holdTime; // wait time in millis before displaying next cube
  
  Cube (int tempCubeX, int tempCubeY, int tempCubeZ, int tempHoldTime) {
    cubeX = tempCubeX;
    cubeY = tempCubeY;
    cubeZ = tempCubeZ;
    holdTime = tempHoldTime;
  }
  
  void display () {
    pushMatrix ();
    translate (cubeX, cubeY, cubeZ);
    fill (c);
    box (cubeSize);
    popMatrix ();
  }
}

class MoselyOne {
  int spongeOneCenterX;
  int spongeOneCenterY;
  int spongeOneCenterZ;
  
  int cubeID;

  int [] cubeCentersInOne = {-1, 0, 0,   1, 0, 0,   -1, 0, -1,   0, 0, -1,   1, 0, -1, 
                             -1, 0, 1,   0, 0, 1,    1, 0, 1,   -1, 1, 0,    0, 1, 0, 
                              1, 1, 0,  -1, -1, 0,   0, -1, 0,   1, -1, 0,   0, 1, -1, 
                              0, 1, 1,   0, -1, -1,  0, -1, 1};
  
  Cube [] cubesInOne = new Cube [18];
  
  MoselyOne (int tempSpongeOneCenterX, int tempSpongeOneCenterY, int tempSpongeOneCenterZ) {
    spongeOneCenterX = tempSpongeOneCenterX;
    spongeOneCenterY = tempSpongeOneCenterY;
    spongeOneCenterZ = tempSpongeOneCenterZ;
    
    for (int i = 0; i < cubeCentersInOne.length - 1; i = i + 3) {
      cubesInOne [cubeID] = new Cube (spongeOneCenterX + cubeCentersInOne [i] * cubeSize, spongeOneCenterY +             cubeCentersInOne [i + 1] * cubeSize,
      spongeOneCenterZ + cubeCentersInOne [i + 2] * cubeSize, 0);
      cubeID = cubeID + 1;
    }
  }
  
  void displayOne () {
    for (int i = 0; i <= cubesInOne.length - 1; i ++) {
      cubesInOne [i].display ();
    }
  } 
}

class MoselyTwo {
  int spongeTwoCenterX;
  int spongeTwoCenterY;
  int spongeTwoCenterZ;
  
  int oneID;

  int [] oneCentersInTwo = {-1, 0, 0,   1, 0, 0,   -1, 0, -1,   0, 0, -1,   1, 0, -1, 
                             -1, 0, 1,   0, 0, 1,    1, 0, 1,   -1, 1, 0,    0, 1, 0, 
                              1, 1, 0,  -1, -1, 0,   0, -1, 0,   1, -1, 0,   0, 1, -1, 
                              0, 1, 1,   0, -1, -1,  0, -1, 1};
  
  MoselyOne [] spongesInTwo = new MoselyOne [18];
  
  MoselyTwo (int tempSpongeTwoCenterX, int tempSpongeTwoCenterY, int tempSpongeTwoCenterZ) {
    spongeTwoCenterX = tempSpongeTwoCenterX;
    spongeTwoCenterY = tempSpongeTwoCenterY;
    spongeTwoCenterZ = tempSpongeTwoCenterZ;
     
    for (int i = 0; i < oneCentersInTwo.length - 1; i = i + 3) {
      spongesInTwo [oneID] = new MoselyOne (spongeTwoCenterX + oneCentersInTwo [i] * cubeSize * 3,       spongeTwoCenterY + oneCentersInTwo [i + 1] * cubeSize * 3,
      spongeTwoCenterZ + oneCentersInTwo [i + 2] * cubeSize * 3);
      oneID = oneID + 1;
    }
  }
  
  void displayTwo () {
    for (int i = 0; i <= spongesInTwo.length - 1; i ++) {
      spongesInTwo [i].displayOne ();
    }

  } 
}

Replies(4)

Hey,

just translate to the middle of your window, then rotate, then translate back to the origin.
Copy code
  1.   pushMatrix ();
      translate(width/2, height/2);
      rotateX (rX);
      rotateY (rY);
      translate(-width/2, -height/2);
      moselySecond.displayTwo ();
      popMatrix ();
Hello every1! 1st post here!!!

I'm just starting to learn Processing, and in the future some Java and JavaScript.
I've made some mods to the hargsquare's code, and in the end, realized both MoselyOne & MoselyTwo classes are very similar to each other.
I was wondering whether it is possible to synthesize & merge them into 1?
Here's his modified code so far:

Copy code
  1. // Level-2 Mosely Fractal Assembler (modded)
  2. // by hargsquare

  3. // http://forum.processing.org/topic
  4. // /rotating-a-composite-shape-made-of-many-cubes-around-a-single-center-point

  5. import processing.opengl.*;

  6. final int gw = 1280/2, gh = 800/2;
  7. final int depth = 150;

  8. final color c = color(0, 200, 20, 100);
  9. final int cubeSize = 40;
  10. final int cube3Size = cubeSize*3;

  11. float rX = 0, rY = 0;
  12. final float rXInc = .005, rYInc = .005;

  13. final int[][] cubeCenters = {
  14.     {-1,  0,  0}, { 1,  0,  0}, {-1,  0, -1},
  15.     { 0,  0, -1}, { 1,  0, -1}, {-1,  0,  1},
  16.     { 0,  0,  1}, { 1,  0,  1}, {-1,  1,  0},
  17.     { 0,  1,  0}, { 1,  1,  0}, {-1, -1,  0},
  18.     { 0, -1,  0}, { 1, -1,  0}, { 0,  1, -1},
  19.     { 0,  1,  1}, { 0, -1, -1}, { 0, -1,  1}
  20. };

  21. final int cubeCentersLength = cubeCenters.length;

  22. MoselyTwo moselySecond;

  23. void setup() {
  24.     size(1280, 800, OPENGL);
  25.     moselySecond = new MoselyTwo(gw, gh, depth);
  26. }

  27. void draw() {
  28.     background(10);
  29.     pushMatrix();
  30.     translate(gw, gh);
  31.     rotateX(rX); rotateY(rY);
  32.     translate(-gw, -gh);
  33.     moselySecond.displayTwo();
  34.     popMatrix();

  35.     rX += rXInc; rY += rYInc;
  36. }
Copy code
  1. class Cube { 
  2.     int cubeX, cubeY, cubeZ;  // final cube x,y,z positions relative to sponge center

  3.     Cube (int tempCubeX, int tempCubeY, int tempCubeZ) {
  4.         cubeX = tempCubeX; cubeY = tempCubeY; cubeZ = tempCubeZ;
  5.     }

  6.     void display() {
  7.         pushMatrix();
  8.         translate(cubeX, cubeY, cubeZ);
  9.         fill(c);
  10.         box(cubeSize);
  11.         popMatrix();
  12.     }
  13. }

  14. class MoselyOne {
  15.     int spongeOneCenterX, spongeOneCenterY, spongeOneCenterZ;
  16.     int i;

  17.     Cube[] cubesInOne = new Cube[cubeCentersLength];

  18.     MoselyOne(int tempSpongeOneCenterX, int tempSpongeOneCenterY, int tempSpongeOneCenterZ) {
  19.         spongeOneCenterX = tempSpongeOneCenterX;
  20.         spongeOneCenterY = tempSpongeOneCenterY;
  21.         spongeOneCenterZ = tempSpongeOneCenterZ;

  22.         for (i = 0; i < cubeCentersLength; ++i)
  23.             cubesInOne[i] = new Cube(
  24.             spongeOneCenterX + cubeCenters[i][0]*cubeSize,
  25.             spongeOneCenterY + cubeCenters[i][1]*cubeSize,
  26.             spongeOneCenterZ + cubeCenters[i][2]*cubeSize);
  27.     }

  28.     void displayOne() {
  29.         for (i = 0; i < cubeCentersLength; cubesInOne[i++].display());
  30.     }
  31. }

  32. class MoselyTwo {
  33.     int spongeTwoCenterX, spongeTwoCenterY, spongeTwoCenterZ;
  34.     int i;

  35.     MoselyOne[] spongesInTwo = new MoselyOne[cubeCentersLength];

  36.     MoselyTwo(int tempSpongeTwoCenterX, int tempSpongeTwoCenterY, int tempSpongeTwoCenterZ) {
  37.         spongeTwoCenterX = tempSpongeTwoCenterX;
  38.         spongeTwoCenterY = tempSpongeTwoCenterY;
  39.         spongeTwoCenterZ = tempSpongeTwoCenterZ;

  40.         for (i = 0; i < cubeCentersLength; ++i)
  41.             spongesInTwo[i] = new MoselyOne(
  42.             spongeTwoCenterX + cubeCenters[i][0]*cube3Size,
  43.             spongeTwoCenterY + cubeCenters[i][1]*cube3Size,
  44.             spongeTwoCenterZ + cubeCenters[i][2]*cube3Size);
  45.     }

  46.     void displayTwo() {
  47.         for (i = 0; i < cubeCentersLength; spongesInTwo[i++].displayOne());
  48.     }
  49. }
To draw a composite shape it is necessary to nest the translations.

In the code below there is a class called Sponge which is a composite shape of a yellow sphere at its centre and a number of Cubes randomly placed arround the centre.

When the sponge is drawn it
saves the current matrix
translates and rotates the position of the sponge
draws the spere
then for each cube
      save the current matrix
      translate the cube
      draw the cube
      restore the matrix
after last cube restore the matrix


Notice that each cube transformation is compounded with the spaonge transformation.

Copy code
  1. Sponge s;
  2. Cube c;
  3. float rx, ry, rz;

  4. void setup() {
  5.   size(300, 300, P3D);
  6.   float x, y, z, cs;
  7.   int col;
  8.   s = new Sponge(20, 30, 40); // Position of sponge centre in 3D space
  9.   for (int i = 0; i < 6; i++) {
  10.     x = random(-50, 50);
  11.     y = random(-50, 50);
  12.     z = random(-50, 50);
  13.     col = color(random(64, 255), random(64, 255), random(64, 255));
  14.     cs = random(10.0, 18.0);
  15.     c = new Cube(x, y, z, col, cs);
  16.     s.addToBody(c);
  17.   }
  18. }

  19. void draw() {
  20.   background(32);
  21.   lights();
  22.   camera(0, 0, 200, 0, 0, 1, 0, 1, 0);
  23.   s.display();
  24.   rx += 0.01;
  25.   ry += 0.013;
  26.   rz += 0.023;
  27.   s.setRotation(rx, ry, rz);
  28. }

  29. class Sponge {
  30.   float x, y, z ; // position of spogue
  31.   float rotX, rotY, rotZ;
  32.   ArrayList<Cube> body = new ArrayList<Cube>();
  33.   Sponge(float px, float py, float pz) {
  34.     x = px;
  35.     y = py;
  36.     z = pz;
  37.     rotX = rotY = rotZ = 0;
  38.   }

  39.   void setRotation(float rx, float ry, float rz) {
  40.     rotX = rx;
  41.     rotY = ry;
  42.     rotZ = rz;
  43.   }

  44.   void addToBody(Cube c) {
  45.     body.add(c);
  46.   }

  47.   void display() {
  48.     pushMatrix();
  49.     translate(x, y, z);
  50.     rotateX(rotX);
  51.     rotateY(rotY);
  52.     rotateZ(rotZ);
  53.     fill(255, 255, 0);
  54.     noStroke();
  55.     sphere(3); // center of sponge
  56.     for (int i = 0; i < body.size(); i++) {
  57.       body.get(i).display();
  58.     }
  59.     popMatrix();
  60.   }
  61. }

  62. class Cube { 
  63.   float x, y, z; // Position relstive to centre of Sponge
  64.   int col;
  65.   float csize;
  66.   Cube (float px, float py, float pz, int c, float s) {
  67.     x = px;
  68.     y = py;
  69.     z = pz;
  70.     col = c;
  71.     csize = s;
  72.   }

  73.   void display () {
  74.     pushMatrix ();
  75.     translate (x, y, z);
  76.     fill (col);
  77.     box (csize);
  78.     popMatrix ();
  79.   }
  80. }

Hey, thanks, folks. Got it sorted with your help. Much appreciation.