import java.applet.*; 
import java.awt.*; 
import java.awt.image.*; 
import java.awt.event.*; 
import java.io.*; 
import java.net.*; 
import java.text.*; 
import java.util.*; 
import java.util.zip.*; 

public class udk_final_lang extends BApplet {
void setup() {
  size(300, 300);
  background(0);
  fill(255);
  stroke(255); 
  lights();
  smooth(); 
  }
  
  
float xangle = 0.0f;
float yangle = 0.0f;
float initx, inity, initxangle, inityangle;
float tradius = (150); // radius of trackball
float txpos = (150);  // xpos of trackball
float typos = (150);  // ypos of trackball



void loop() { 
  

  translate(150, 150);
  rotateX(yangle);
  rotateY(xangle); 


  //horizontal  
  fakeLine3D(-75, -25, 75, 25, -25, 75, 2.8f);
  fakeLine3D(-75, 75, 75, 25, 75, 75, 2.8f);
  fakeLine3D(-75, -25, -25, 25, -25, -25, 2.8f);
  fakeLine3D(-75, 75, -25, 25, 75, -25, 2.8f);
  fakeLine3D(-25, 25, 25, 75, 25, 25, 2.8f);
  fakeLine3D(-25, -75, 25, 75, -75, 25, 2.8f);
  fakeLine3D(-25, 25, -75, 75, 25, -75, 2.8f);
  fakeLine3D(-25, -75, -75, 75, -75, -75, 2.8f);
  
  //vertical  
  fakeLine3D(-75, 75, 75, -75, -25, 75, 2.8f);
  fakeLine3D(25, 75, 75, 25, -25, 75, 2.8f);
  fakeLine3D(-75, 75, -25, -75, -25, -25, 2.8f);
  fakeLine3D(25, 75, -25, 25, -25, -25, 2.8f);
  fakeLine3D(-25, 25, 25, -25, -75, 25, 2.8f);
  fakeLine3D(75, 25, 25, 75, -75, 25, 2.8f);
  fakeLine3D(-25, 25, -75, -25, -75, -75, 2.8f);
  fakeLine3D(75, 25, -75, 75, -75, -75, 2.8f);
    
  //depth  
  fakeLine3D(-75, -25, 75, -75, -25, -25, 2.8f);
  fakeLine3D(-75, 75, 75, -75, 75, -25, 2.8f);
  fakeLine3D(25, -25, 75, 25, -25, -25, 2.8f);
  fakeLine3D(25, 75, 75, 25, 75, -25, 2.8f);
  fakeLine3D(-25, 25, 25, -25, 25, -75, 2.8f);
  fakeLine3D(-25, -75, 25, -25, -75, -75, 2.8f);  
  fakeLine3D(75, 25, 25, 75, 25, -75, 2.8f);
  fakeLine3D(75, -75, 25, 75, -75, -75, 2.8f);
  
  //diagonal
  fakeLine3D(-75, -25, 75, -25, -75, 25, 2.8f);
  fakeLine3D(-75, 75, 75, -25, 25, 25, 2.8f);
  fakeLine3D(25, -25, 75, 75, -75, 25, 2.8f);
  fakeLine3D(25, 75, 75, 75, 25, 25, 2.8f);
  fakeLine3D(-75, -25, -25, -25, -75, -75, 2.8f);
  fakeLine3D(-75, 75, -25, -25, 25, -75, 2.8f);
  fakeLine3D(25, -25, -25, 75, -75, -75, 2.8f);
  fakeLine3D(25, 75, -25, 75, 25, -75, 2.8f);
  
  }  


void fakeLine3D (float x1, float y1, float z1, float x2, float y2, float z2, float lineStrength) {
  //points defining a 3d vector
  float px= x2-x1;
  float py= y2-y1;
  float pz= z2-z1;
  //angles for rotation 
  float xy, xz;
  //length of line (needed only for linestrength)
  float length= sqrt(sq(px) + sq(py) + sq(pz));
  
  if(px > 0) {
    xz= atan2(pz, -px);
    xy= -atan2(py, sqrt(sq(px) + sq(pz)));
    }
  else{
   xz= atan2(-pz, px);
   xy= atan2(-py, -sqrt(sq(px) + sq(pz))) ;
   };
  
  
  push();
  translate(x1 + px/2, y1 + py/2, z1 + pz/2);
  rotateY(xz);
  rotateZ(xy);
  scale(length/lineStrength, 1, 1);
  box(lineStrength);
  pop();
  }
  


//virtual trackball

boolean trackball = false;

void mousePressed() {
  initx= mouseX-txpos;
  inity= mouseY-txpos;
  if(-tradius <= initx && initx<= tradius && -tradius <= inity && inity <= tradius) {
    initxangle = xangle;
    inityangle = yangle;
    trackball = true;
    }  
  } 

                                                                                                                                                            
void mouseDragged() {
  
  if(trackball == true){
    float xpos = mouseX-txpos;
    float ypos = mouseY-typos;
    
    float x = xpos%tradius;
    float y = ypos%tradius;
    float xsgn = (xpos-x)/tradius;
    float ysgn = (ypos-y)/tradius;   


    float xz = (sqrt(sq(tradius)-sq(x)));
    xangle = xsgn*PI/2 + (atan2(x-initx, xz))+initxangle; 
//    println ("xangle: " + degrees(xangle));
 
    float yz= (sqrt(sq(tradius)-sq(y))); 
    yangle = -(ysgn*PI/2)-(atan2(y-inity, yz))+inityangle;
//    println ("yangle: " + degrees(yangle));
    }
  }    
  
void mouseReleased() {   
  trackball = false;
  }   

}
