import processing.core.*; 
import processing.xml.*; 

import java.applet.*; 
import java.awt.Dimension; 
import java.awt.Frame; 
import java.awt.event.MouseEvent; 
import java.awt.event.KeyEvent; 
import java.awt.event.FocusEvent; 
import java.awt.Image; 
import java.io.*; 
import java.net.*; 
import java.text.*; 
import java.util.*; 
import java.util.zip.*; 
import java.util.regex.*; 

public class sketch_aug27d extends PApplet {


ArrayList<Vertex> myPoints = new ArrayList<Vertex>();
class Vector
{
  public float x,y,z;
  public Vector(float randomRange)
  {
    x = random(-randomRange, randomRange);
    y = random(-randomRange, randomRange);
    z = random(-randomRange, randomRange);
  }
  public Vector(float _x, float _y, float _z)
  {
    x = _x;
    y = _y;
    z = _z;
  }

}

class Vertex
{
  private final float MAX_MOVE_SPEED = 0.5f;
  public float x,y,z;
  private Vector myVector = new Vector(random(MAX_MOVE_SPEED));
    
  public Vertex()
  {
    x=y=z=0;
  }
  public Vertex(float _x, float _y, float _z)
  {
    x = _x;
    y = _y;
    z = _z;
  }
  public void Move()
  {
    x += myVector.x;
    y += myVector.y;
    z += myVector.z;
  }
}

float myAngle = 0.0f;
final float ANGLE_CHANGE = 0.001f;
final int MAX_POINTS = 2000;

public void setup()
{
  size(800,600,P3D);
  noFill();

  background(0);
 
  smooth();
  myPoints.add(new Vertex(width/2,height/2,100));
}

public void draw()
{
  try
  {
    background(0);
    
    //rotateScreen();
    
    if ( myPoints.size() >= 3 )
    {
      beginShape();
      Vertex startVertex = myPoints.get(0);
      Vertex endVertex = myPoints.get(myPoints.size()-1);
      
      curveVertex(startVertex.x, startVertex.y, startVertex.z);
      int C=0;
      for ( int i=0; i < myPoints.size(); i++ )
      {
        C++;
        C %= 255;
        stroke(C);
        Vertex thisPoint = myPoints.get(i);
        curveVertex(thisPoint.x, thisPoint.y, thisPoint.z);
        thisPoint.Move();
      }
      curveVertex(endVertex.x, endVertex.y, endVertex.z);
      endShape();    
    }
    
    if ( myPoints.size() < MAX_POINTS )
      addPoint();
  }
  catch (Exception ex)
  {
  }
}

public void rotateScreen()
{
  myAngle += ANGLE_CHANGE;
  if(myAngle >= TWO_PI || myAngle < 0)
    myAngle = 0.0f;   
  
  translate(width/2, height/2);
  
  //rotateX(myAngle);
  rotateY(myAngle);
  
  translate(width/-2, height/-2);
  
}

public void addPoint()
{
  Vertex lastPoint = myPoints.get((int)random(0,myPoints.size()-1));
  Vertex newPoint = new Vertex(
    lastPoint.x + random(-50,50),
    lastPoint.y + random(-50,50),
    lastPoint.z + random(-50,50)
    );
   myPoints.add(newPoint);
}


  static public void main(String args[]) {
    PApplet.main(new String[] { "--bgcolor=#F0F0F0", "sketch_aug27d" });
  }
}
