Created
June 15, 2017 23:49
-
-
Save kernalphage/97b92f3bc730d0f24b2c4c2b2e93b298 to your computer and use it in GitHub Desktop.
Art generator written in Processing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Simple Turbulence + art | |
* By Matt Dobler | |
*/ | |
int _w = 1920; | |
int _h = 1080; | |
PVector dim = new PVector(_w, _h); | |
PVector box; | |
float xpos; | |
float ypos; | |
float drag = 30.0; | |
ArrayList<PVector> points = new ArrayList<PVector>(); | |
/////////////////////////////////////////////////////////////////////////// | |
// Useful functions | |
/////////////////////////////////////////////////////////////////////////// | |
int sgn(float val) { | |
return ((0 < val)?1:0) - ((val < 0)?1:0); | |
} | |
PVector viewCoords(PVector pos) { | |
return new PVector(pos.x-_w/2, pos.y - _h/2); | |
} | |
// Not really sure about this one, but it makes turbulence look better | |
// http://prideout.net/blog/?p=63 | |
PVector ComputeCurl(PVector p) | |
{ | |
float e = 4; | |
PVector dx= new PVector(e, 0, 0); | |
PVector dy= new PVector(0, e, 0); | |
PVector dz= new PVector(0, 0, e); | |
float x = turbulence(PVector.add(p, dy)).z - turbulence(PVector.sub(p, dy)).z | |
- turbulence(PVector.add(p, dz)).y + turbulence(PVector.sub(p, dz)).y; | |
float y = turbulence(PVector.add(p, dz)).x - turbulence(PVector.sub(p, dz)).x | |
- turbulence(PVector.add(p, dx)).z + turbulence(PVector.sub(p, dx)).z; | |
float z = turbulence(PVector.add(p, dx)).y - turbulence(PVector.sub(p, dx)).y | |
- turbulence(PVector.add(p, dy)).x + turbulence(PVector.sub(p, dy)).x; | |
return new PVector(x * 2 * e, y * 2 * e, z * 2 * e); | |
} | |
/////////////////////////////////////////////////////////////////////////////////// | |
// Noise functions. | |
// Usually a stateless (Vector) => (Vector) function | |
/////////////////////////////////////////////////////////////////////////////////// | |
PVector turbulence(PVector pos) { | |
//Noise on top of noise on top of noise | |
PVector xy = PVector.mult(pos, .04); | |
PVector v = new PVector(); | |
float dx = noise(xy.x * .1, xy.y *.2, xy.z * .17 + t); | |
float dy = noise(xy.y * .3, xy.x * .4, xy.z * .14 + t); | |
v.x = noise(dx * 8, dy * 12); | |
v.y = noise(dy * 10 + 3, dx * 7 + 1); | |
v.z = noise(dx, dy); | |
return v; | |
} | |
PVector inwards(PVector part) | |
{ | |
PVector dCenter = viewCoords(part); | |
dCenter.normalize(); | |
//dCenter.y -= 1-abs(dCenter.x); | |
dCenter.mult(-.26); | |
return dCenter; | |
} | |
PVector sideways(PVector part, float strength, float exp) { | |
float dx = part.x / _w; | |
return new PVector( pow(dx, exp) + strength, 0); | |
} | |
PVector spin(PVector part, float power) { | |
PVector bouyancy =viewCoords(part); | |
bouyancy.rotate(HALF_PI); | |
bouyancy.normalize(); | |
bouyancy.mult(.3); | |
return bouyancy; | |
} | |
PVector box_d(PVector pos, float strength, float rotation, float scale) { | |
PVector norm = viewCoords(pos); | |
norm.rotate(rotation); | |
norm.mult(scale); | |
PVector bDist = new PVector(abs(norm.x), abs(norm.y), 0); | |
PVector bDir = bDist.sub(box); | |
bDist.x = max(bDist.x, 0); | |
bDist.y = max(bDist.y, 0); | |
bDist.z = max(bDist.z, 0); | |
bDir.x *= -sgn(norm.x); | |
bDir.y *= -sgn(norm.y); | |
bDir.mult(-strength/(1+bDist.magSq())); | |
return bDir; | |
} | |
PVector mountains(PVector pos, float strength, float scale) | |
{ | |
float h = turbulence(new PVector(pos.x * scale, 0)).y; | |
h = ( 1 - (h * .5) ) * _h; // (0-1) to (_h, 0) | |
float dh = _h / (1 + abs(pos.y - h)); | |
float dir = -sgn(pos.y - h); | |
return new PVector(0, dir ).mult(pow(strength, dh)); | |
} | |
////////////////////////////////////////////////////////////// | |
// Initial locations for the points | |
/////////////////////////////////////////////////////////// | |
void drawMap(int rects) { | |
float dw = _w / rects; | |
float dh = _h / rects; | |
PVector center = new PVector(0, _h/2); | |
for (float x = 0; x < _w; x+=dw ) | |
{ | |
for (float y =0; y < _h; y+= dh) | |
{ | |
//torus | |
//points.add(PVector.add( center, PVector.random2D().normalize().mult(random(_h/34, _h/2.3)))); | |
//grid | |
//points.add(new PVector(x, y)); | |
//From side | |
//points.add(new PVector(random(-10, _w/5), random(-_h/10, _h * 1.1))); | |
// small_3d ball | |
PVector plen = new PVector(randomGaussian(), randomGaussian(), 0); | |
if (plen.mag() < 1) { | |
plen.z = randomGaussian() * .2; | |
plen.mult(_h * .022); | |
plen.add(center); | |
points.add(plen); | |
} | |
} | |
} | |
} | |
// Useful for visualizing the vector field | |
void drawgrid(int rects) { | |
float dw = _w / rects; | |
float dh = _h / rects; | |
for (float x = 0; x < _w; x+=dw ) | |
{ | |
for (float y =0; y < _h; y+= dh) | |
{ | |
PVector c = ComputeCurl( new PVector(x, y, 0) ); | |
c.mult(255); | |
fill(c.x, c.y, c.z); | |
noStroke(); | |
rect(x, y, dw, dh); | |
} | |
} | |
} | |
void keyPressed() { | |
if (key == ' ') { | |
noLoop(); | |
} | |
if (key == ENTER) { | |
saveFrame("turb-" + month() + "_" + day() + "_" + minute() + "_#####.png"); | |
} | |
} | |
void setup() { | |
size(1920, 1080); | |
background(20, 10, 7); | |
frameRate(160); | |
box = PVector.mult(new PVector(_h, _h), .18); | |
drawMap(50); | |
noStroke(); | |
} | |
//////////////////////////////////////////////////////////////////////////////////////////// | |
// The meat of it | |
//////////////////////////////////////////////////////////////////////////////////////////// | |
float t = 0; | |
void draw() { | |
colorMode(HSB, 100); | |
// blendMode(ADD); // Tried playing with this, it WILL make things chug | |
t+=.001; | |
for (int i=0; i < points.size(); i++) { | |
PVector part = points.get(i); | |
PVector v = new PVector(); | |
v.add(PVector.mult(ComputeCurl(part), .15 + 1.56 * t)); | |
PVector bouyancy = PVector.mult( inwards(part), 1.17); | |
bouyancy.x = 0; | |
//mountains(part, .7861, .0310); | |
bouyancy.add(sideways(part, .76, 1)); | |
bouyancy.add(box_d(part, 18, HALF_PI/2, 3.5)); | |
//bouyancy.add(spin(part, .3)); | |
//// Move and update | |
PVector vel = PVector.add(v, bouyancy); | |
points.set(i, PVector.add(part, vel)); | |
float hue = vel.heading(); | |
hue = degrees(abs(hue / 5.4)+ t) ; | |
float sat = 100; | |
float val = 70; | |
float headAngle = abs(PVector.angleBetween(vel, new PVector(-1, 0)))/360.0; | |
//Electricity Coloring | |
hue = 50;// lerp(headAngle, 40, 60); | |
sat = lerp(abs(part.y - _h/2) / (_h/3), 70, 90); | |
val = lerp(turbulence(part).y, 24, 80) + t * 10; | |
// Sunburst coloring | |
//hue = lerp(, 0, 244); | |
//float dh = (part.y / bouyancy.y); | |
//sat = lerp(bouyancy.y, 10, 70); | |
//val = lerp(turbulence(part).z, 24, 80); | |
/// mountains coloring | |
// hue = lerp(abs(degrees(vel.heading()))/360, 200, 244); | |
// float dh = (part.y / bouyancy.y); | |
// sat = lerp(dh, 20, 50); | |
// val = lerp(turbulence(part).z, 44, 80); | |
fill(hue, sat, val, 3); | |
rect(part.x, part.y, 2, 2); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment