Skip to content

Instantly share code, notes, and snippets.

@Ming-Tang
Last active September 25, 2015 11:08
Show Gist options
  • Save Ming-Tang/912040 to your computer and use it in GitHub Desktop.
Save Ming-Tang/912040 to your computer and use it in GitHub Desktop.
Lorenz attractor
final int[][] D1 = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
final boolean[][] D2 = { { false, false, false }, { false, false, false }, { true, false, false }, { true, true, false },
{ false, false, true }, { false, false, true }, { true, false, true }, { true, true, true },
{ false, false, false }, { false, true, false }, { true, false, false }, { true, true, false } };
final boolean[][] D3 = { { true, false, false }, { false, true, false }, { true, true, false }, { false, true, false },
{ true, false, true }, { false, true, true }, { true, true, true }, { false, true, true },
{ false, false, true }, { false, true, true }, { true, false, true }, { true, true, true } };
float o = 10, b = 8 / 3, p = 28;
float ra = 0.1, rb = 0.1, rc = 18;
float dt = 0.005;
float r = 90;
int n = 50000;
float axesLength = 15;
float t = 0;
int mode = 0;
PVector[] points;
PVector min = new PVector(-25, -25, 0);
PVector max = new PVector(25, 25, 50);
PVector randV() {
float rmax = PVector.sub(max, min).mag() / 2;
float r = random(rmax);
float theta = random(PI);
float phi = random(TWO_PI);
float sintheta = sin(theta);
float costheta = cos(theta);
float sinphi = sin(phi);
float cosphi = cos(phi);
PVector mid = PVector.div(PVector.add(min, max), 2);
return PVector.add(mid, new PVector(r * sintheta * cosphi, r * sintheta * sinphi, r * costheta));
//return new PVector(random(min.x, max.x), random(min.y, max.y), random(min.z, max.z));
}
void reset() {
points = new PVector[n];
for (int i = 0; i < n; i ++) {
points[i] = randV();
}
frameRate(1 / dt);
}
void axes() {
for (int i = 0; i < 3; i ++) {
stroke(D1[i][0] * 255, D1[i][1] * 255, D1[i][2] * 255);
beginShape(LINES);
vertex(0, 0, 0);
vertex(D1[i][0] * axesLength, D1[i][1] * axesLength, D1[i][2] * axesLength);
endShape();
}
stroke(0xAAFFFFFF);
for (int i = 0; i < D2.length; i ++) {
float x1 = (D2[i][0] ? min : max).x;
float y1 = (D2[i][1] ? min : max).y;
float z1 = (D2[i][2] ? min : max).z;
float x2 = (D3[i][0] ? min : max).x;
float y2 = (D3[i][1] ? min : max).y;
float z2 = (D3[i][2] ? min : max).z;
beginShape(LINES);
vertex(x1, y1, z1);
vertex(x2, y2, z2);
endShape();
}
}
void setup() {
size(1920, 1200, OPENGL);
textMode(SHAPE);
reset();
}
void draw() {
background(0);
float phi = float(mouseX) / float(width) * TWO_PI;
float theta = float(mouseY) / float(height) * PI;
PVector mid = PVector.add(min, PVector.mult(PVector.sub(max, min), 0.5));
PVector cam = PVector.add(mid, new PVector(
r * sin(theta) * cos(phi),
r * sin(theta) * sin(phi),
r * cos(theta)));
float fov = PI/3.0;
float cameraZ = (height/2.0) / tan(fov/2.0);
perspective(fov, float(width)/float(height),
0.1, cameraZ*10.0);
camera(cam.x, cam.y, cam.z, mid.x, mid.y, mid.z, 0, 0, -1);
stroke(255);
noFill();
for (int i = 0; i < n && points[i] != null; i ++) {
PVector v = points[i];
if (Float.isNaN(v.mag())) {
points[i] = randV();
}
PVector dv = mode == 0 ? new PVector(
o * (v.y - v.x),
v.x * (p - v.z) - v.y,
v.x * v.y - b * v.z) : new PVector(
-v.y - v.z,
v.x + ra * v.y,
rb + v.z * (v.x - rc));
dv.mult(dt);
dv.limit(10);
stroke(0x4422CCFF);
points[i] = PVector.add(v, dv);
line(v.x, v.y, v.z, points[i].x, points[i].y, points[i].z);
}
t += dt;
axes();
if (keyPressed)
if (key == 'o') { p = 28; min = new PVector(-25, -25, 0); max = new PVector(25, 25, 50); r = PVector.sub(max, min).mag(); }
else if (key == 'p') { p = 99.96; min = new PVector(-75, -75, 50); max = new PVector(75, 75, 175); r = PVector.sub(max, min).mag(); }
else if (key == '[') smooth();
else if (key == ']') noSmooth();
else if (key == '\\') reset();
else if (key == '\'') { if (mode == 0) mode = 1; else mode = 0; }
p = constrain(p, 1, 200);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment