> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.WfYNjd20QYk/rev.4641
 * 
 * authors: 
 *   Ethan May

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



// Pressing Control-R will render this sketch.

double[][][][] cubeList = {genCube(100),genCube(110),genCube(120),genCube(130),genCube(140),genCube(150),genCube(160),genCube(170),genCube(180),genCube(190),genCube(200)};

void setup() {  // this is run once.   
    
    // set the background color
    background(255);
    
    // canvas size (Variable aren't evaluated. Integers only, please.)
    size(500, 500); 
      
    // smooth edges
    smooth();
    noFill();
    
    // limit the number of frames per second
    frameRate(30);
    
    // set the width of the line. 
    strokeWeight(1);
} 

void draw() {  // this is run repeatedly.  
    background(255);  
    //Single Cube
    
    //drawAndRotateCube(cubeList[5],-30);
    //drawAndRotateCube(cubeList[0],30);
    
    //Cube Wave
    
    for (int i = 0; i < cubeList.length; i++)
    {
        drawAndRotateCube(cubeList[i],600/i*.2);
    }
    
}

void drawAndRotateCube(double[][][] cube, int speed) {
    for(int i = 0; i < 4; i++) {
        rQuad(cube[i]);
    }
    
    for(int i = 0; i < 4; i++) {
        cube[i] = rotateX(cube[i], 1/speed);
    }
}

double[][][] genCube(int side) {
    int s = side/2;
    int[][] top = {{s,s,s},{s,s,-s},{-s,s,-s},{-s,s,s}};
    int[][] bot = {{s,-s,s},{s,-s,-s},{-s,-s,-s},{-s,-s,s}};
    int[][] right = {{s,s,s},{s,s,-s},{s,-s,-s},{s,-s,s}};
    int[][] left = {{-s,s,s},{-s,s,-s},{-s,-s,-s},{-s,-s,s}};
    
    double[][][] out = {cubToPolPts(top),cubToPolPts(bot),cubToPolPts(right),cubToPolPts(left)};
    return out;
}

double[][] rotateX(double[][] pts, double rot) {
    for (int i = 0; i < pts.length; i++)
    {
        pts[i][1] += rot
    }
    return pts;
}

//Takes in a polar point and returns its relative cubic coordinates
int[] polToCub(double[] point) {
    r = point[0];
    theta_1 = point[1];
    theta_2 = point[2];
    
    int x = (int)r*cos(theta_2)*cos(theta_1);
    int y = (int)r*sin(theta_2);
    int z = (int)r*cos(theta_2)*sin(theta_1);
    
    int[] out = {x,y,z};
    return out;
}

//Takes a cubic point an returns its relative polar coordinates
double[] cubToPol(int[] point) {
    x = point[0];
    y = point[1];
    z = point[2];
    
    if (x > 0) 
    {
        double r = sqrt(sq(x)+sq(y)+sq(z));
        double theta_2 = asin(((double)(y))/r);
        double theta_1 = atan(z/x);
    }
    else
    {
        double r = sqrt(sq(x)+sq(y)+sq(z));
        double theta_2 = asin(((double)(y))/r);
        double theta_1 = Math.PI + atan(z/x);
    }
    
    double[] out = {r, theta_1, theta_2};
    return out;
}
//Plots a point based upon its polar coordinates
void rplot(double r, double theta_1, double theta_2) {
    int x =  (int)r*cos(theta_2)*cos(theta_1);
    int y = (int)r*sin(theta_2);
    int z = (int)r*cos(theta_2)*sin(theta_1);
    
    plot(x,y,z+250);
}

void rplotPt(double[] point) {
    rplot(point[0],point[1],point[2]);
}

int[][] polToCubPts(double[][] points) {
    int[][] out = new int[points.length][3];
    for (int i = 0; i < points.length; i++)
    {
       out[i] = polToCub(points[i]);
    }
    return out;
}

double[][] cubToPolPts(int[][] points) {
    double[][] out = new double[points.length][3];
    for (int i = 0; i < points.length; i++)
    {
       out[i] = cubToPol(points[i]);
    }
    return out;
}

//Plots a point based on its cubic coordinates
void plot(int x, int y, int d) {
    
    double vSpace = ((double)(y)) / d;
    double hSpace = ((double)(x)) / d;
    
    point((hSpace*250) + 250, (-1*(vSpace*250)+250));
}

void rQuad(double[][] pts) {
    int[][] q = ptl(polToCubPts(pts));
    
    quad(q[0][0],q[0][1],q[1][0],q[1][1],q[2][0],q[2][1],q[3][0],q[3][1]);
}

void plotPt(int[] point) {
    plot(point[0],point[1],point[2]);
}

int[] pt(int x, int y, int d) {
    d+=250;
    double vSpace = ((double)(y)) / d;
    double hSpace = ((double)(x)) / d;
    
    int[] out = {(hSpace*250) + 250, (-1*(vSpace*250)+250)};
    return out;
}

int[][] ptl(int[][] pts) {
    
    for (int i = 0; i < pts.length; i++)
    {
        pts[i] = pt(pts[i][0],pts[i][1],pts[i][2]);      
    }
        
    return pts;           
}