import processing.core.*; 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 zoaria_combined extends PApplet {
// Zoaria Combined
// David Montie
// November 27, 2005

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

float x; //Mouse postion translation
float y;

float cervix = 10;
float noder = 6; // node radius
float nodex = 10;// node position (actual) x,y,z
float nodey = 10; 
float nodez;

float rollx = 0;
float rolly = 30;
float rollz = 0;
float slidex;
float slidey = -10;
float zoom = 750; // slidez

float cusp1 = (2*PI)-PI/8;
float cusp2 = PI/2+PI/8;
float cusp3 = PI/2-PI/8;
float cusp4 = PI+PI/8;
float cusp5 = PI-PI/8;
float cusp6 = (3*PI/2)+PI/8;
float cusp7 = (3*PI/2)-PI/8;
float cusp8 = PI/8;

boolean xon = false;
boolean yon = false;
boolean zoomon = false;
boolean rollxon = false;
boolean rollyon = false;
boolean rollzon = false;
boolean slidexon = false;
boolean slideyon = false;
boolean slideon = false;
boolean rotateon = false;
boolean twiston = false;
boolean allon = false;
boolean nodegrab = false;
boolean mesoscale = true;
boolean statered = false;
boolean stateyellow = false;
boolean stateblue = false;
boolean stategreen = false;
boolean meso = true;
boolean micro = false;
boolean macro = false;

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

public void setup()
{
  size (700, 700, P3D);
}

public void draw ()
{

background (255);
lights();
PFont myFont;
myFont = loadFont("ArialMT-16.vlw");

x = mouseX - width/2;
y = mouseY - height/2;

// Menu Box ++++++++++++++++++++++++++++++++++++++
rect (0, 0, width, 43);
    
if (zoomon) {
  yon = true;
  zoom = y * 2; // zoom
  fill (0,250,0);
  rect (502, 2, 98, 18);
  //rect (2, 2, 98, 18);
  fill (0);
  textFont(myFont);
  text ("Zoom: ON", 508, 17, 0);
  noFill();
  } else {
    fill (100);
    rect (502, 2, 98, 18);
    //rect (2, 2, 98, 18);
    fill (0);
    textFont(myFont);
    text ("Zoom: OFF", 508, 17, 0);
    noFill();
    }

if (slidexon) {
  xon = true;
  slidex = x; // side to side
  fill (0,250,0);
  rect (2, 2, 98, 18);
  //rect (102, 2, 98, 18);
  fill (0);
  textFont(myFont);
  text ("Slide X: ON", 7, 17, 0);
  noFill();
  } else {
    fill (100);
    rect (2, 2, 98, 18);
    //rect (102, 2, 98, 18);
    fill (0);
    textFont(myFont);
    text ("Slide X: OFF", 7, 17, 0);
    noFill();
    }
    
if (slideyon) {
  yon = true;
  slidey = y; // up and down
  fill (0,250,0);
  rect (102, 2, 98, 18);
  //rect (202, 2, 98, 18);
  fill (0);
  textFont(myFont);
  text ("Slide Y: ON", 108, 17, 0);
  noFill();
  } else {
    fill (100);
    rect (102, 2, 98, 18);
    //rect (202, 2, 98, 18);
    fill (0);
    textFont(myFont);
    text ("Slide Y: OFF", 108, 17, 0);
    noFill();
    }
    
if (rollxon) {
  xon = true;
  rollx = (x/4); // side to side
  fill (0,250,0);
  rect (202, 2, 98, 18);
  //rect (302, 2, 98, 18);
  fill (0);
  textFont(myFont);
  text ("Roll X: ON", 212, 17, 0);
  noFill();
  } else {
    fill (100);
    rect (202, 2, 98, 18);
    //rect (202, 2, 98, 18);
    fill (0);
    textFont(myFont);
    text ("Roll X: OFF", 212, 17, 0);
    noFill();
    }
       
if (rollyon) {
  yon = true;
  rolly = (y/4); // up and down
  fill (0,250,0);
  rect (302, 2, 98, 18);
  //rect (402, 2, 98, 18);
  fill (0);
  textFont(myFont);
  text ("Roll Y: ON", 312, 17, 0);
  noFill();
  } else {
    fill (100);
    rect (302, 2, 98, 18);
    //rect (402, 2, 98, 18);
    fill (0);
    textFont(myFont);
    text ("Roll Y: OFF", 312, 17, 0);
    noFill();
    }
 
if (rollzon) {
  xon = true;
  rollz = (x/2); // spin around
  fill (0,250,0);
  rect (402, 2, 98, 18);
  //rect (502, 2, 98, 18);
  fill (0);
  textFont(myFont);
  text ("Twist: ON", 412, 17, 0);
  noFill();
  } else {
    fill (100);
    rect (402, 2, 98, 18);
    //rect (502, 2, 98, 18);
    fill (0);
    textFont(myFont);
    text ("Twist: OFF", 412, 17, 0);
    noFill();
    }
    
if (xon) {
  fill (0, 250, 0);
  rect (602, 2, 47, 18);
  fill (0);
  textFont(myFont);
  text ("X", 620, 17, 0);
  noFill();
  } else {
    fill (100);
    rect (602, 2, 47, 18);
    fill (0);
    textFont(myFont);
    text ("X", 620, 17, 0);
    noFill();
    }

if (yon) {
  fill (0, 250, 0);
  rect (651, 2, 47, 18);
  fill (0);
  textFont(myFont);
  text ("Y", 670, 17, 0);
  noFill();
  } else {
    fill (100);
    rect (651, 2, 47, 18);
    fill (0);
    textFont(myFont);
    text ("Y", 670, 17, 0);
    noFill();
    }


// second menu row +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  
// Button 1 - Slide
if (slideon) {
  fill (0, 150, 250);
  } else {
  fill (250);
  }
  rect (2, 23, 198, 18);
  fill (0);
  stroke (0);
  textFont(myFont);
  text ("Slide", 82, 38);
  noFill();
  
// Button 2 - Rotate
if (rotateon) {
  fill (0, 150, 250);  
  } else {
  fill (250);
  }
  rect (202, 23, 198, 18); 
  fill (0);
  stroke (0);
  textFont(myFont);
  text ("Roll", 287, 38);
  noFill();

// Button 3 - Twist
if (twiston) {
  fill (0, 150, 250);
  } else {
  fill (250);
  } 
  rect (402, 23, 198, 18);
  fill (0);
  stroke (0);
  textFont(myFont);
  text ("Twist", 482, 38);
  noFill(); 

// Button 4 - All
if (allon) {
  fill (0, 150, 250);
  } else {
  fill (250);
  }
  rect (602, 23, 96, 18);
  fill (0);
  stroke (0);
  textFont(myFont);
  text ("< All >", 630, 38);
  noFill();
 
   
pushMatrix(); // into active window ++++++++++++++++++++++++++++++++++++++++++++++++
  
  translate (slidex + width/2, slidey + height/2, zoom - height/2);
  rotateZ (PI/2 + radians (rollz));
  rotateX (radians (rollx)); 
  rotateY (radians (rolly) + PI/2); 
  
  
// Cusp Surface ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

if (macro) {// Macro Scale (level = 1)++++++++++++++++++++++++++++++++++++++++++++++++
pushMatrix(); 
translate(0,0,-44);
scale(.5f); 

fill (255);
ellipse (0, 0, cervix, cervix);
noFill();

//Q1 Yellow
pushMatrix();
rotateX(PI/24);
rotateY(-PI/24);  
fill(204,153,0,120);
arc(0,0,120,120,cusp1,cusp2);
noFill ();
popMatrix();

//Q2 Green
pushMatrix();
rotateX(-PI/24);
rotateY(-PI/24); 
fill(0,63,0,120);
arc(0,0,120,120,cusp3,cusp4);
noFill ();
popMatrix();

//Q3 Blue
pushMatrix();
rotateX(-PI/24);
rotateY(PI/24); 
fill(0,0,81,120);
arc(0,0,120,120,cusp5,cusp6);
noFill ();
popMatrix();

//Q4 Red
pushMatrix();
rotateX(PI/24);
rotateY(PI/24); 
fill(153,0,0,120);
arc(0,0,120,120,cusp7,cusp8);
noFill ();
popMatrix();

bezier(55,-24,4, 55,-50,-4, 55,50,4, 55,24,-4);
bezier(-55,-24,-4, -55,-50,4, -55,50,-4, -55,24,4); 
bezier(24,55,-4, 50,55,-4, -50,55,4, -24,55,4); 
bezier(24,-55,4, 50,-55,4, -50,-55,-4, -24,-55,-4); 

popMatrix(); // Macro Scale
}

if (meso) { // Meso Scale (level = 0)++++++++++++++++++++++++++++++++++++++++++++++++++++++++
pushMatrix(); 
translate(0,0,0);
scale(.8f);

fill (255);
ellipse (0, 0, cervix, cervix);
noFill();

//Q1 Yellow
pushMatrix();
rotateX(PI/24);
rotateY(-PI/24);  
fill(204,153,0,120);
arc(0,0,120,120,cusp1,cusp2);
noFill ();
popMatrix();

//Q2 Green 
pushMatrix();
rotateX(-PI/24);
rotateY(-PI/24); 
fill(0,63,0,120);
arc(0,0,120,120,cusp3,cusp4);
noFill ();
popMatrix();

//Q3 Blue
pushMatrix();
rotateX(-PI/24);
rotateY(PI/24); 
fill(0,0,81,120);
arc(0,0,120,120,cusp5,cusp6);
noFill ();
popMatrix();

//Q4 Red
pushMatrix();
rotateX(PI/24);
rotateY(PI/24); 
fill(153,0,0,120);
arc(0,0,120,120,cusp7,cusp8);
noFill ();
popMatrix();

bezier(55,-24,4, 55,-50,-4, 55,50,4, 55,24,-4);
bezier(-55,-24,-4, -55,-50,4, -55,50,-4, -55,24,4); 
bezier(24,55,-4, 50,55,-4, -50,55,4, -24,55,4); 
bezier(24,-55,4, 50,-55,4, -50,-55,-4, -24,-55,-4); 

popMatrix(); // Meso Scale
}

if (micro) {// Micro Scale (level = -1)+++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
pushMatrix(); 
translate(0,0,50);

fill (255);
ellipse (0, 0, cervix, cervix);
noFill();

//Q1 Yellow
pushMatrix();
rotateX(PI/24);
rotateY(-PI/24);  
fill(204,153,0,120);
arc(0,0,120,120,cusp1,cusp2);
popMatrix();

//Q2 Green
pushMatrix();
rotateX(-PI/24);
rotateY(-PI/24); 
fill(0,63,0,120);
arc(0,0,120,120,cusp3,cusp4);
popMatrix();

//Q3 Blue
pushMatrix();
rotateX(-PI/24);
rotateY(PI/24); 
fill(0,0,81,120);
arc(0,0,120,120,cusp5,cusp6);
popMatrix();

//Q4 Red
pushMatrix();
rotateX(PI/24);
rotateY(PI/24); 
fill(153,0,0,120);
arc(0,0,120,120,cusp7,cusp8);
popMatrix();

  bezier(55,-24,4, 55,-50,-4, 55,50,4, 55,24,-4);
  bezier(-55,-24,-4, -55,-50,4, -55,50,-4, -55,24,4); 
  bezier(24,55,-4, 50,55,-4, -50,55,4, -24,55,4); 
  bezier(24,-55,4, 50,-55,4, -50,-55,-4, -24,-55,-4); 

popMatrix(); // Micro Scale
}

// Node +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if (meso) {
  
    if (sq(nodex) + sq(nodey) < (2800) && nodex > nodey / 2.4f && nodey > 0.414f * nodex) { 
    stateyellow = true;
    }
    if (sq(nodex) + sq(nodey) < (2800) && nodex > nodey / -2.4f && nodey < -0.414f * nodex) { 
    statered = true;
    }
    if (sq(nodex) + sq(nodey) < (2800) && nodex < nodey / -2.4f && nodey > -0.414f * nodex) { 
    stategreen = true;
    }
    if (sq(nodex) + sq(nodey) < (2800) && nodex < nodey / 2.4f && nodey < 0.414f * nodex) { 
    stateblue = true;
    }

if (stateyellow) {
    nodez = 0.264f * abs((nodex + nodey)/2);
    pushMatrix ();
    translate (0, 0, nodez);
    stroke (0);
    fill (204,153,0,120);
    ellipse (nodex, nodey, noder, noder);
    noFill ();
    popMatrix (); 
    if (nodex > nodey / -2.4f && nodey > -0.414f * nodex) { 
      stategreen = false;
      statered = false;
      }      
    }
        
  if (stategreen) {
    nodez = -0.264f * abs((nodex - nodey)/2);
    pushMatrix ();
    translate (0, 0, nodez);
    stroke (0);
    fill (0,63,0,120);
    ellipse (nodex, nodey, noder, noder);
    noFill ();
    popMatrix ();
    if (nodex < nodey / 2.4f && nodey > 0.414f * nodex) { 
    stateblue = false;
    stateyellow = false;
    }
  }
               
  if (stateblue) {
    nodez = 0.264f * abs((nodex + nodey)/2);
    pushMatrix ();
    translate (0, 0, nodez);
    stroke (0);
    fill (0,0,81,120);
    ellipse (nodex, nodey, noder, noder);
    noFill ();
    popMatrix ();
    if (nodex < nodey / -2.4f && nodey < -0.414f * nodex) { 
    statered = false;
    stategreen = false;
    } 
  }
    
  if (statered) {
    nodez = -0.264f * abs((nodex - nodey)/2);
    pushMatrix ();
    translate (0, 0, nodez);
    stroke (0);
    fill (153,0,0,120);
    ellipse (nodex, nodey, noder, noder);
    noFill ();
    popMatrix ();
    if (nodex > nodey / 2.4f && nodey < 0.414f * nodex) { 
    stateblue = false;
    stateyellow = false;
    } 
  }
    
   if (sq(nodex) + sq(nodey) > (2800)) { //outer edge - demergence
     micro = true;
     meso = false;
   }
   
   if (sq(nodex) + sq(nodey) <= cervix) { // inner edge - emergence
     meso = false;
     macro = true; 
   }
   
} // end of meso scale
 
   
if (micro) {  
  
    if (nodex > nodey / 2.4f && nodey > 0.414f * nodex) { 
    stateyellow = true;
    }
    if (nodex < nodey / -2.4f && nodey > -0.414f * nodex) { 
    stategreen = true;
    }
    if (nodex < nodey / 2.4f && nodey < 0.414f * nodex) { 
    stateblue = true;
    }
    if (nodex > nodey / -2.4f && nodey < -0.414f * nodex) { 
    statered = true;
    }

  if (stateyellow) {
    nodez = (0.264f * abs((nodex + nodey)/2)) + 50;
    pushMatrix ();
    translate (0, 0, nodez);
    stroke (0);
    fill (204,153,0,120);
    ellipse (nodex, nodey, noder, noder);
    noFill ();
    popMatrix (); 
    if (nodex > nodey / -2.4f && nodey > -0.414f * nodex) { 
      stategreen = false;
      statered = false;
      }      
    }
      
  if (stategreen) {
    nodez = (-0.264f * abs((nodex - nodey)/2)) + 50;
    pushMatrix ();
    translate (0, 0, nodez);
    stroke (0);
    fill (0,63,0,120);
    ellipse (nodex, nodey, noder, noder);
    noFill ();
    popMatrix ();
    if (nodex < nodey / 2.4f && nodey > 0.414f * nodex) { 
    stateblue = false;
    stateyellow = false;
    }
  }
    
  if (stateblue) {
    nodez = (0.264f * abs((nodex + nodey)/2)) + 50;
    pushMatrix ();
    translate (0, 0, nodez);
    stroke (0);
    fill (0,0,81,120);
    ellipse (nodex, nodey, noder, noder);
    noFill ();
    popMatrix ();
    if (nodex < nodey / -2.4f && nodey < -0.414f * nodex) { 
    statered = false;
    stategreen = false;
    } 
  }

  if (statered) {
    nodez = (-0.264f * abs((nodex - nodey)/2)) + 50;
    pushMatrix ();
    translate (0, 0, nodez);
    stroke (0);
    fill (153,0,0,120);
    ellipse (nodex, nodey, noder, noder);
    noFill ();
    popMatrix ();
    if (nodex > nodey / 2.4f && nodey < 0.414f * nodex) { 
    stateblue = false;
    stateyellow = false;
    } 
  }  
  
  if (sq(nodex) + sq(nodey) <= cervix * 2) {
    micro = false;
    meso = true; 
    }
         
} // end of micro scale
      
   
if (macro) {

    if (sq(nodex) + sq(nodey) < (1200) && nodex > nodey / -2.4f && nodey < -0.414f * nodex) { 
    statered = true;
    }
    if (sq(nodex) + sq(nodey) < (1200) && nodex > nodey / 2.4f && nodey > 0.414f * nodex) { 
    stateyellow = true;
    }
    if (sq(nodex) + sq(nodey) < (1200) && nodex < nodey / 2.4f && nodey < 0.414f * nodex) { 
    stateblue = true;
    }
    if (sq(nodex) + sq(nodey) < (1200) && nodex < nodey / -2.4f && nodey > -0.414f * nodex) { 
    stategreen = true;
    }

  if (stateyellow) {
    nodez = (0.264f * abs((nodex + nodey)/2)) - 44;
    pushMatrix ();
    translate (0, 0, nodez);
    stroke (0);
    fill (204,153,0,120);
    ellipse (nodex, nodey, noder, noder);
    noFill ();
    popMatrix (); 
    if (nodex > nodey / -2.4f && nodey > -0.414f * nodex) { 
      stategreen = false;
      statered = false;
      }      
    }
    
  if (stategreen) {
    nodez = (-0.264f * abs((nodex - nodey)/2)) - 44;
    pushMatrix ();
    translate (0, 0, nodez);
    stroke (0);
    fill (0,63,0,120);
    ellipse (nodex, nodey, noder, noder);
    noFill ();
    popMatrix ();
    if (nodex < nodey / 2.4f && nodey > 0.414f * nodex) { 
    stateblue = false;
    stateyellow = false;
    }
  }
      
  if (stateblue) {
    nodez = (0.264f * abs((nodex + nodey)/2)) - 44;
    pushMatrix ();
    translate (0, 0, nodez);
    stroke (0);
    fill (0,0,81,120);
    ellipse (nodex, nodey, noder, noder);
    noFill ();
    popMatrix ();
    if (nodex < nodey / -2.4f && nodey < -0.414f * nodex) { 
    statered = false;
    stategreen = false;
    } 
  }
    
  if (statered) {
    nodez = (-0.264f * abs((nodex - nodey)/2)) - 44;
    pushMatrix ();
    translate (0, 0, nodez);
    stroke (0);
    fill (153,0,0,120);
    ellipse (nodex, nodey, noder, noder);
    noFill ();
    popMatrix ();
    if (nodex > nodey / 2.4f && nodey < 0.414f * nodex) { 
    stateblue = false;
    stateyellow = false;
    } 
  }
  
 if (sq(nodex) + sq(nodey) > 1200) { 
    macro = false;
    meso = true;
    }    
    
} // end of macro scale


// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

popMatrix(); // Out of active window

 } 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

public void mousePressed() 
{

if (mouseX > 1 && mouseX < 85 && mouseY > 1 && mouseY < 18) { // mouseoverbutton 1
  slidexon = true;
  }
   
if (mouseX > 100 && mouseX < 200 && mouseY > 1 && mouseY < 18) { // mouseoverbutton 2
  slideyon = true;
  }
  
if (mouseX > 200 && mouseX < 300 && mouseY > 1 && mouseY < 18) { // mouseoverbutton 3
  rollxon = true;
  }
  
if (mouseX > 300 && mouseX < 400 && mouseY > 1 && mouseY < 18) { // mouseoverbutton 4
  rollyon = true;
  }
  
if (mouseX > 400 && mouseX < 500 && mouseY > 1 && mouseY < 18) { // mouseoverbutton 5
  rollzon = true;
  }
  
if (mouseX > 500 && mouseX < 600 && mouseY > 1 && mouseY < 18) { // mouseoverbutton 6
  zoomon = true;
  }
  
   
if (mouseX > 1 && mouseX < 200 && mouseY > 19 && mouseY < 43) { // mouseoverbutton 1 - row 3
  slidexon = true;
  slideyon = true;
  slideon = true;
  }
  
if (mouseX > 200 && mouseX < 400 && mouseY > 19 && mouseY < 43) { // mouseoverbutton 2 - row 3
  rollxon = true;
  rollyon = true;
  rotateon = true;
  }
  
if (mouseX > 400 && mouseX < 600 && mouseY > 19 && mouseY < 43) { // mouseoverbutton 3 - row 3
  rollzon = true;
  zoomon = true;
  twiston = true;
  }
   
if (mouseX > 600 && mouseY > 19 && mouseY < 43) { // mouseoverbutton 4 - row 3
  allon = true;
  twiston = true;
  rotateon = true;
  slideon = true;
  slidexon = true;
  slideyon = true;
  rollxon = true;
  rollyon = true;
  rollzon = true;
  zoomon = true;
  }
   
if (mouseY > 44) { // cancel button engagement
  if (yon) {
    yon = false;
    }
  if (xon) {
    xon = false;
    }
  if (zoomon) {
    zoomon = false;
    }
  if (rollxon) {
    rollxon = false;
    }    
  if (rollyon) {
    rollyon = false;
    }
  if (rollzon) {
    rollzon = false;
    }
  if (slidexon) {
    slidexon = false;
    }
  if (slideyon) {
    slideyon = false;
    }
  if (slideon) {
    slideon = false;
    }
  if (rotateon) {
    rotateon = false;
    }
  if (twiston) {
    twiston = false;
    }
  if (allon) {
    allon = false;
    }
  
  }

  nodegrab = true;
//  }    
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

public void mouseDragged() {
  if (nodegrab) {
  
    if (meso) {
    nodex =  -0.34f * (mouseY - screenY (0, slidey + height/2, zoom - 350));
    nodey =  -0.34f * (mouseX - screenX (slidex + width/2, 0, zoom - 350));
    }
    
    if (macro) {
    nodex =  -0.34f * (mouseY - screenY (0, slidey + height/2, zoom - 350));
    nodey =  -0.34f * (mouseX - screenX (slidex + width/2, 0, zoom - 350));
    }
    
    if (micro) {
    nodex =  -0.34f * (mouseY - screenY (0, slidey + height/2, zoom - 350));
    nodey =  -0.34f * (mouseX - screenX (slidex + width/2, 0, zoom - 350));
    }
    
    }
    
  }

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

public void mouseReleased() {
  nodegrab = false;
  }
    
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++     
//void keyPressed ()
 
//void keyReleased ()
   
}