import processing.opengl.*;
//import voltron.dataprole.*;

voltron volt;

final int MINITER = 200;
final int MAXITER = 1000;
final float p=2.0;
final color white = color(255);

float[][] pts = new float[MAXITER+1][3];
int count = 0;
float x,y,z;

PFont font;

boolean needRefresh = false;

void setup() {
  size(1200,800,OPENGL);
  //smooth();
  frameRate(1000);
  background(0);
  translate(width/2, height/2);
  stroke(255);
  font = loadFont("Arial-Black-12.vlw");
  volt = new voltron(this);
}

void draw() {

  compute();

  background(0);
  translate(width/2, height/2);
  
  fill(255, 80);
  textFont(font,12);
  text(" Over " + volt.getArraySize()/1000/3/2 + "K points - FPS : " + frameRate, -(width/2), height-(height/2+15));
  
  pushMatrix();
  rotateY(radians(frameCount*PI/20));
  //rotateZ(radians(frameCount*PI/200));
  pushMatrix();
  
  volt.plotVox("points", 1.0);




  popMatrix();
  popMatrix();
  needRefresh = false;

}  

void compute() {
 
/*  count++;
  if(count > 10000) {
    count=0;
    randomSeed(millis());
  }
  */
  
  while(!needRefresh) {
  x = random(-2.0,2.0);
  y = random(-2.0,2.0);
  z = random(-2.0,2.0);

  int iter = 0;
  float r = 0.0;
  float nx = x;
  float ny = y;
  float nz = z;
  r=sqrt(x*x+y*y+z*z);
  float th=atan(y/x)*p;
  float ph=asin(z/r)*p;
  
  while(iter < MAXITER && r<2.0) {
    float r2p = pow(r,p);
    th=atan(ny/nx)*p;
    ph=asin(nz/r)*p;
    nx=r2p*cos(ph)*cos(th)+x;
    ny=r2p*cos(ph)*sin(th)+y;
    nz=r2p*sin(ph)+z;
    pts[iter][0] = nx;
    pts[iter][1] = ny;
    pts[iter][2] = nz;
    r=sqrt(nx*nx+ny*ny+nz*nz);
    iter++;
  }

  
  if(r>2.0 && iter > MINITER) {
      for(int i = MINITER; i < iter ; i++) {
        //float xd = pts[0][0] - pts[(i)][0];
        //float yd = pts[0][1] - pts[(i)][1];
        //float zd = pts[0][2] - pts[(i)][2];
        //float distance = sqrt(xd*xd + yd*yd + zd*zd);
        //if(abs(distance) < 0.01) { break; }
        if(pts[i][0]*pts[i][0] + pts[i][1]*pts[i][1] + pts[i][2]*pts[i][2] < 2.0) {
          volt.addPoint(pts[i][0]*350.0, pts[i][1]*350.0, pts[i][2]*350.0, abs(pts[i][0]),abs(pts[i][1]),abs(pts[i][2]),0.2);
          volt.addPoint(pts[i][0]*350.0, pts[i][1]*350.0, -pts[i][2]*350.0, abs(pts[i][0]),abs(pts[i][1]),abs(pts[i][2]),0.2);
          volt.addPoint(pts[i][0]*350.0, -pts[i][1]*350.0, pts[i][2]*350.0, abs(pts[i][0]),abs(pts[i][1]),abs(pts[i][2]),0.2);
          volt.addPoint(pts[i][0]*350.0, -pts[i][1]*350.0, -pts[i][2]*350.0, abs(pts[i][0]),abs(pts[i][1]),abs(pts[i][2]),0.2);
          needRefresh = true;
        }
      }      
  }
  }  
  
}
  


