// by Kirby Urner, 4D Solutions
// Last modified: Feb 28, 1999

import  java.awt.* ;

public class Cubist extends Artist {
// I'm a Cubist.  I live inside a Studio object as an Artist,
// and I know something about Quaternions (at least I hope I do)


  double cube [ ][ ];
  Quaternion qx, qy, qz, qxinv, qyinv, qzinv;
  boolean xrotor, yrotor, zrotor;

  Cubist(){
    // my Constructor -- I set out these tools as soon as you
    // create me as an object
    noPoints = 8;
    s1 = new int[noPoints][2]; // screen coordinates for cube
    cube = new double[noPoints][3]; // array for cube points
    refcube();  // initialize the cube

    qx = new Quaternion("X",1); // rotate 1 degree around X
    qy = new Quaternion("Y",1); // rotate 1 degree around Y
    qz = new Quaternion("Z",1); // rotate 1 degree around Z

    // I need the inverse of each of the above -- Quaternions
    // know how to return their own inverses
    qxinv = qx.inv();
    qyinv = qy.inv();
    qzinv = qz.inv();

    xrotor = true;
    yrotor = true;
    zrotor = true;
  }

  public void compose(Graphics canvas){
       canvas.setColor(Color.black);
       rotateCube();
       viewcoord(cube,s1)   ;
       drawCube(canvas, s1);
  }

  public void rotateCube() {
      for ( int i=0; i<8; i++ ) {

      // I'm getting the vector part af rotating each
      // cube corner i.e. c = (q c q^-1).vector

        if (xrotor) cube[i] = qx.mult(cube[i]).mult(qxinv).vector;
        if (yrotor) cube[i] = qy.mult(cube[i]).mult(qyinv).vector;
        if (zrotor) cube[i] = qz.mult(cube[i]).mult(qzinv).vector;
      }
  }

  public void refcube () {
      cube[0]   =  new double[]{1,1,1};
      cube[1]   =  new double[]{-1,1,1};
      cube[2]   =  new double[]{-1,1,-1};
      cube[3]   =  new double[]{1,1,-1};
      cube[4]   =  new double[]{1,-1,1};
      cube[5]   =  new double[]{-1,-1,1};
      cube[6]   =  new double[]{-1,-1,-1};
      cube[7]   =  new double[]{1,-1,-1};
  }

  public void drawCube (Graphics g, int coords[][]) {
      for (int i=0; i<3; i++){
         drawLines(g, coords[i][0],coords[i][1],coords[i+1][0],coords[i+1][1]);
      }
      drawLines(g, coords[3][0],coords[3][1],coords[0][0],coords[0][1]);
      for (int i=4; i<noPoints-1; i++){
         drawLines(g, coords[i][0],coords[i][1],coords[i+1][0],coords[i+1][1]);
      }
      drawLines(g, coords[7][0],coords[7][1],coords[4][0],coords[4][1]);
      for (int i=0; i<4; i++){
         drawLines(g, coords[i][0],coords[i][1],coords[i+4][0],coords[i+4][1]);
      }
  }

}
