/** * PushPop Cubes * by Ira Greenberg. * * Array of rotating cubes creates * dynamic field patterns. Color * controlled by light sources. Example * of pushMatrix() and popMatrix(). */ // Cube class required float ang; int rows = 21; int cols = 21; int cubeCount = rows*cols; int colSpan, rowSpan; float rotspd = 2.0; Cube[] cubes = new Cube[cubeCount]; float[] angs = new float[cubeCount]; float[] rotvals = new float[cubeCount]; void setup(){ size(640, 360, P3D); colSpan = width/(cols-1); rowSpan = height/(rows-1); noStroke(); // instantiate cubes for (int i = 0; i < cubeCount; i++){ cubes[i] = new Cube(12, 12, 6, 0, 0, 0); /* 3 different rotation options - 1st option: cubes each rotate uniformly - 2nd option: cubes each rotate randomly - 3rd option: cube columns rotate as waves To try the different rotations, leave one of the rotVals[i] lines uncommented below and the other 2 commented out. */ //rotvals[i] = rotspd; //rotvals[i] = random(-rotspd * 2, rotspd * 2); rotvals[i] = rotspd += .01; } } void draw(){ int cubeCounter = 0; background(0); fill(200); // Set up some different colored lights pointLight(51, 102, 255, width/3, height/2, 100); pointLight(200, 40, 60, width/1.5, height/2, -150); // Raise overall light in scene ambientLight(170, 170, 100); // Translate, rotate and draw cubes for (int i = 0; i < cols; i++){ for (int j = 0; j < rows; j++){ pushMatrix(); /* Translate each block. pushmatix and popmatrix add each cube translation to matrix, but restore original, so each cube rotates around its owns center */ translate(i * colSpan, j * rowSpan, -20); //rotate each cube around y and x axes rotateY(radians(angs[cubeCounter])); rotateX(radians(angs[cubeCounter])); cubes[cubeCounter].drawCube(); popMatrix(); cubeCounter++; } } // Angs used in rotate function calls above for (int i = 0; i < cubeCount; i++){ angs[i] += rotvals[i]; } } // Simple Cube class, based on Quads class Cube { // Properties int w, h, d; int shiftX, shiftY, shiftZ; // Constructor Cube(int w, int h, int d, int shiftX, int shiftY, int shiftZ){ this.w = w; this.h = h; this.d = d; this.shiftX = shiftX; this.shiftY = shiftY; this.shiftZ = shiftZ; } /* Main cube drawing method, which looks more confusing than it really is. It's just a bunch of rectangles drawn for each cube face */ void drawCube(){ // Front face beginShape(QUADS); vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ); vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ); vertex(w + shiftX, h + shiftY, -d/2 + shiftZ); vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ); // Back face vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ); vertex(w + shiftX, -h/2 + shiftY, d + shiftZ); vertex(w + shiftX, h + shiftY, d + shiftZ); vertex(-w/2 + shiftX, h + shiftY, d + shiftZ); // Left face vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ); vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ); vertex(-w/2 + shiftX, h + shiftY, d + shiftZ); vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ); // Right face vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ); vertex(w + shiftX, -h/2 + shiftY, d + shiftZ); vertex(w + shiftX, h + shiftY, d + shiftZ); vertex(w + shiftX, h + shiftY, -d/2 + shiftZ); // Top face vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ); vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ); vertex(w + shiftX, -h/2 + shiftY, d + shiftZ); vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ); // Bottom face vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ); vertex(w + shiftX, h + shiftY, -d/2 + shiftZ); vertex(w + shiftX, h + shiftY, d + shiftZ); vertex(-w/2 + shiftX, h + shiftY, d + shiftZ); endShape(); } }