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