Skip to content

Instantly share code, notes, and snippets.

@kernalphage
Created June 15, 2017 23:49
Show Gist options
  • Save kernalphage/97b92f3bc730d0f24b2c4c2b2e93b298 to your computer and use it in GitHub Desktop.
Save kernalphage/97b92f3bc730d0f24b2c4c2b2e93b298 to your computer and use it in GitHub Desktop.
Art generator written in Processing
/**
* 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