// Chaotic Attractor Demo // // Move your mouse around and observe. // // By Aaron Koblin // Based on a Chrome Experiment (http://www.chromeexperiments.com/detail/lorenz-84/) // by Dean McNamee import processing.opengl.*; int numCurves = 2000; float param1 = 1.111f; float param2 = 1.479f; float param3 = 4.494f; float param4 = 0.44f; float dt = 0.136f; float x = 1; float y = 1; float z = 1; Path path; PVector p0; int t =0; boolean fadeOut=false; int restartCounter =0; public void setup(){ size(800,600, OPENGL); noFill(); } void createShape(){ p0 = new PVector(); path = new Path(numCurves); for (int i = 0; i < numCurves; ++i) { path.curves[i] = new Curve(i * 2, i * 2 + 1); PVector p1 = step(); PVector p2 = step(); path.points[i * 2 + 1] = controlFromPoints(p0, p1, p2); path.points[i * 2] = p2; p0 = p2; } } // For 3 points on a curve, calculate a quadratic control point. This means // p0 and p2 are the end points, and we want to find a new point c0, such // that the spline at t = 0.5 evaluates to p1. PVector controlFromPoints(PVector p0, PVector p1,PVector p2) { PVector output = new PVector(); output.x = p1.x + p1.x - 0.5f * p0.x - 0.5f * p2.x; output.y = p1.y + p1.y - 0.5f * p0.y - 0.5f * p2.y; output.z = p1.z + p1.z - 0.5f * p0.z - 0.5f * p2.z; return output; } PVector step() { float dx = (-param1 * x - y * y - z * z + param1 * param3) * dt; float dy = (-y + x * y - param2 * x * z + param4) * dt; float dz = (-z + param2 * x * y + x * z) * dt; x += dx; y += dy; z += dz; PVector output = new PVector(x,y,z); return output; } public void stateZero(){ x = 0; y = 0; z = 0; } public void draw() { stateZero(); if(!mousePressed){ if(param1 > .6) param1 -= .0005f; param2 = t/2000f; if(param2 >1.40f) { fadeOut = true; } t++; } createShape(); pushMatrix(); translate(width/2, height/2); rotateY(mouseX/100f); rotateX(mouseY/100f); scale(90); background(0); drawPath(path); popMatrix(); if(fadeOut){ restartCounter++; println(restartCounter); if(restartCounter>325){ param1 = 1.111f; param2 = 1.479f; t=0; fadeOut = false; restartCounter=0; } } } void drawPath(Path path) { beginShape(); Curve[] curves = path.curves; vertex(0,0,0); for (int j = 0; j < curves.length; j++) { Curve curve = curves[j]; PVector c0 = new PVector(); PVector c1 = new PVector(); c0 = path.points[curve.c0]; c1 = path.points[curve.c0-1]; PVector ep = path.points[curve.ep]; stroke(62,c0.x*30+90,255,150-restartCounter/2); bezierVertex(c0.x, c0.y, c0.z, c1.x, c1.y, c1.z, ep.x, ep.y, ep.z); } endShape(); } public class Curve { int ep,c0; Curve(int ep, int c0) {//quadratic this.ep = ep; // End point. this.c0 = c0; // Control point. } } public class Path { public PVector[] points; public Curve[] curves; Path(int numCurves){ this.points = new PVector[numCurves*2]; this.curves = new Curve[numCurves]; } }