//Oscillo cube
//By phil
//From tetalab http://www.tetalab.org
//Complex solution to inexistant problems
//R-2R dac
//le code de la genration du cube cf tvout lib: http://code.google.com/p/arduino-tvout/


int rot=0; //0 = x, 1= Y, 2 = z
int incrot = 0;
int zOff = 150;
int xOff = 0;
int yOff = 0;
int cSize = 30;
int view_plane = 60;

float cube3d[8][3] = {
  {xOff - cSize,yOff + cSize,zOff - cSize},
  {xOff + cSize,yOff + cSize,zOff - cSize},
  {xOff - cSize,yOff - cSize,zOff - cSize},
  {xOff + cSize,yOff - cSize,zOff - cSize},
  {xOff - cSize,yOff + cSize,zOff + cSize},
  {xOff + cSize,yOff + cSize,zOff + cSize},
  {xOff - cSize,yOff - cSize,zOff + cSize},
  {xOff + cSize,yOff - cSize,zOff + cSize}
};
unsigned char cube2d[8][2];

void setup() 
{
//  Serial.begin(9600);
  int i =0;
  DDRB = B00111111; //axe x
  DDRD = B11111100; //axe y


  // PORTD = B00000100; //on 2
  // PORTD = B00001000; //on 3
  // PORTD = B00010000; //on 4
  // PORTD = B00100000; //on 5
  // PORTD = B01000000; //on 6
  // PORTD = B10000000; //on 7
  
  // PORTB = B00000001; //on 8
  // PORTB = B00000010; //on 9
  // PORTB = B00000100; //on 10
  // PORTB = B00001000; //on 11
  // PORTB = B00010000; //on 12
  // PORTB = B00100000; //on 13
}


void loop()
{
  
  float inc = 0.1;
  printcube();
  
  switch (rot)
  {
  case 0:
    xrotate(float(inc));
    break; 
  
  case 1:
    yrotate(float(inc));
    break; 
   
  case 2:
    zrotate(float(inc));
    break; 
  }
  
  if (incrot > 126) 
  {
    rot ++;
    if (rot==3) rot = 0;
    incrot = 0;
  }
  incrot++;
 
  
  
  

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
}

  

 void line2(byte x, byte y, byte x2, byte y2)
 {
   int rep = 0;
   
   while (rep < 20)
   {
   point(x,y);
 point(x2,y2);
rep ++; 
   }
 }

void point(byte x,byte y)
{
  delayMicroseconds(40);
  PORTD = y<<2;
  PORTB = x;
}

void printcube() {
  //calculate 2d points
  for(byte i = 0; i < 8; i++) {
   cube2d[i][0] = (unsigned char)((cube3d[i][0] * view_plane / cube3d[i][2]) + (64/2));
   cube2d[i][1] = (unsigned char)((cube3d[i][1] * view_plane / cube3d[i][2]) + (64/2));
  }
  draw_cube();
}




void draw_cube() {

line2(cube2d[0][0],cube2d[0][1],cube2d[1][0],cube2d[1][1]);
line2(cube2d[0][0],cube2d[0][1],cube2d[2][0],cube2d[2][1]);
line2(cube2d[0][0],cube2d[0][1],cube2d[4][0],cube2d[4][1]);
line2(cube2d[1][0],cube2d[1][1],cube2d[5][0],cube2d[5][1]);
line2(cube2d[1][0],cube2d[1][1],cube2d[3][0],cube2d[3][1]);
line2(cube2d[2][0],cube2d[2][1],cube2d[6][0],cube2d[6][1]);
line2(cube2d[2][0],cube2d[2][1],cube2d[3][0],cube2d[3][1]);
line2(cube2d[4][0],cube2d[4][1],cube2d[6][0],cube2d[6][1]);
line2(cube2d[4][0],cube2d[4][1],cube2d[5][0],cube2d[5][1]);
line2(cube2d[7][0],cube2d[7][1],cube2d[6][0],cube2d[6][1]);
line2(cube2d[7][0],cube2d[7][1],cube2d[3][0],cube2d[3][1]);
line2(cube2d[7][0],cube2d[7][1],cube2d[5][0],cube2d[5][1]);

}



void zrotate(float q) {
  float tx,ty,temp;
  for(byte i = 0; i < 8; i++) {
    tx = cube3d[i][0] - xOff;
    ty = cube3d[i][1] - yOff;
    temp = tx * cos(q) - ty * sin(q);
    ty = tx * sin(q) + ty * cos(q);
    tx = temp;
    cube3d[i][0] = tx + xOff;
    cube3d[i][1] = ty + yOff;
  }
}

void yrotate(float q) {
  float tx,tz,temp;
  for(byte i = 0; i < 8; i++) {
    tx = cube3d[i][0] - xOff;
    tz = cube3d[i][2] - zOff;
    temp = tz * cos(q) - tx * sin(q);
    tx = tz * sin(q) + tx * cos(q);
    tz = temp;
    cube3d[i][0] = tx + xOff;
    cube3d[i][2] = tz + zOff;
  }
}

void xrotate(float q) {
  float ty,tz,temp;
  for(byte i = 0; i < 8; i++) {
    ty = cube3d[i][1] - yOff;
    tz = cube3d[i][2] - zOff;
    temp = ty * cos(q) - tz * sin(q);
    tz = ty * sin(q) + tz * cos(q);
    ty = temp;
    cube3d[i][1] = ty + yOff;
    cube3d[i][2] = tz + zOff;
  }
}


