Not logged in.

From instruction: Draw a straight line and follow it

Code: LineFollow3D by djones

For each point in an initially random list, this Processing Sketch draws a straight line to the next one and follows it. The drawing gradually evolves into a simple loop. 3D version.

http://dxjones.com/processing/LineFollow3D/

// LineFollow3D
// dxjones @ gmail.com

class Vector {
  float x, y, z;
  
  Vector(float _x, float _y, float _z) {
    x = _x;
    y = _y;
    z = _z;
  }
  
  void set(float _x, float _y, float _z) {
    x = _x;
    y = _y;
    z = _z;
  }
}

final int N = 120;

Vector[] p = new Vector[N];
Vector[] v = new Vector[N];

void setup() {
  size(600,400,P3D);
  sphereDetail(5);
  frameRate(60);
  
  p = new Vector[N];
  v = new Vector[N];
  initialize();
}

void initialize() {
  int i;
  
  for (i = 0 ; i < N ; ++i) {
    p[i] = new Vector(width*random(-1,1), height*random(-1,1), height*random(-1,1));
    v[i] = new Vector(random(-1,1), random(-1,1), random(-1,1));
  }
}

void randomize() {
  int i;
  
  for (i = 0 ; i < N ; ++i) {
    p[i].set(width*random(-1,1), height*random(-1,1), height*random(-1,1));
    v[i].set(random(-1,1), random(-1,1), random(-1,1));
  }
}

void mousePressed() {
  randomize();
}

void normalize() {
  int i;
  float mx, my, mz;
  
  mx = 0;
  my = 0;
  mz = 0;
  for (i = 0 ; i < N ; ++i) {
    mx += p[i].x;
    my += p[i].y;
    mz += p[i].z;
  }
  mx /= (float) N;
  my /= (float) N;
  mz /= (float) N;
  for (i = 0 ; i < N ; ++i) {
    p[i].x -= mx;
    p[i].y -= my;
    p[i].z -= mz;
  }
  
  mx = 0;
  my = 0;
  mz = 0;
  for (i = 0 ; i < N ; ++i) {
    if (abs(p[i].x) > mx) {
      mx = abs(p[i].x);
    }
    if (abs(p[i].y) > my) {
      my = abs(p[i].y);
    }
    if (abs(p[i].z) > mz) {
      mz = abs(p[i].z);
    }
  }
  mx = 0.95 * (width/2) / mx;
  my = 0.95 * (height/2) / my;
  mz = 0.95 * (height/2) / mz;
  for (i = 0 ; i < N ; ++i) {
    p[i].x *= mx;
    p[i].y *= my;
    p[i].z *= mz;
  }
}

void update() {
  int i, j;
  
  for (i = 0 ; i < N ; ++i) {
    j = (i+1) % N;
    v[i].x = 0.83 * v[i].x + 0.0125 * (p[j].x - p[i].x);
    v[i].y = 0.83 * v[i].y + 0.0125 * (p[j].y - p[i].y);
    v[i].z = 0.83 * v[i].z + 0.0125 * (p[j].z - p[i].z);
  }
  for (i = 0 ; i < N ; ++i) {
    j = (i+1) % N;
    p[i].x += v[i].x;
    p[i].y += v[i].y;
    p[i].z += v[i].z;
  }
}


void draw() {
  int i, j;
  
  background(200);
  lights();
   
  camera(2*(mouseX - width/2), 2*(mouseY - height/2), height, // eyeX, eyeY, eyeZ
         0.0, 0.0, 0.0, // centerX, centerY, centerZ
         0.0, 1.0, 0.0); // upX, upY, upZ
  
  normalize();
  
  update();
  
  stroke(0);
  noFill();
  for (i = 0 ; i < N ; ++i) {
    j = (i+1) % N;
    line(p[i].x,p[i].y,p[i].z, p[j].x,p[j].y,p[j].z);
  }
  
  line(-width/2,-height/2,0,  width/2,-height/2,0);
  line( width/2,-height/2,0,  width/2, height/2,0);
  line( width/2, height/2,0, -width/2, height/2,0);
  line(-width/2, height/2,0, -width/2,-height/2,0);
  
  noStroke();
  fill(255,0,0);
  for (i = 0 ; i < N ; ++i) {
    pushMatrix();
    translate(p[i].x,p[i].y,p[i].z);
    sphere(8);
    popMatrix();
  }
}

[download]

Written in Processing. Released under the GPLv3 license