/*splat gravity
created with processing 0135
by rce12
- click to generate splatters
- press spacebar to generate gravity
an funky abstraction with irregular moves with circles and
line-following-circles. using pixel-blur by seb [and thanks to
him] for as cool as fadeout and radial-based gravity move.
*/
//init
int nmb=100;
splatter[] sp=new splatter[nmb];
gravity_dive gd;
void setup(){
size(500,500,P3D);
background(0);
for(int a=0;a<nmb;a++){
sp[a]=new splatter();
}
gd=new gravity_dive();
}
void draw(){
//trail gravity
gd.trail();
//create splatters
for(int a=0;a<nmb;a++){
sp[a].trail();
}
blur();
}
void mousePressed(){
//generate splatters
for(int a=0;a<nmb;a++){
sp[a]=new splatter();
}
}
void keyPressed(){
//generate gravity
if(key==' '){
gd=new gravity_dive();
}
}
//thanks to seb for pixel-blurring
void blur() {
int index,R,G,B,left,right,top,bottom;
loadPixels();
for(int j=0;j<width;j++) {
for(int i=0;i<height;i++) {
index=i*width+j;
// Wraparound offsets
if(j>0) left=-1; else left=width-1;
if(j==(width-1)) right=-width+1; else right=1;
if(i>0) top=-width; else top=(height-1)*width;
if(i==(height-1)) bottom=-(height-1)*width; else bottom=width;
// Calculate the sum of n neighbors
R=(pixels[left+index]>>16) & 255; // left middle
R+=(pixels[right+index]>>16) & 255; // right middle
R+=(pixels[index]>>16) & 255; // middle middle
R+=(pixels[index+top]>>16) & 255; // middle top
R+=(pixels[index+bottom]>>16) & 255; // middle bottom
R=(R/5);
G=(pixels[left+index]>>8) & 255; // left middle
G+=(pixels[right+index]>>8) & 255; // right middle
G+=(pixels[index]>>8) & 255; // middle middle
G+=(pixels[index+top]>>8) & 255; // middle top
G+=(pixels[index+bottom]>>8) & 255; // middle bottom
G=(G/5);
B=pixels[left+index] & 255; // left middle
B+=pixels[right+index] & 255; // right middle
B+=(pixels[index] & 255); // middle middle
B+=pixels[index+top] & 255; // middle top
B+=pixels[index+bottom] & 255; // middle bottom
B=(B/5);
pixels[index]=(R<<16)+(G<<8)+B;
}
}
updatePixels();
}
class splatter{
float[] x;
float[] y;
int num_mov=(int)random(2,10);
float zm;
color cval=color(random(255),random(255),random(255));
splatter(){
//constuct this
x=new float[num_mov];
y=new float[num_mov];
}
void trail(){
for(int i=0;i<num_mov;i++){
//move on
x[i]+=gd.x;
y[i]+=gd.y;
zm=sqrt(sq(x[i])+sq(y[i]));
//checkout for collision
if(x[i]<0){
x[i]+=width;
}else if(x[i]>width){
x[i]-=width;
}
if(y[i]<0){
y[i]+=height;
}else if(y[i]>height){
y[i]-=height;
}
//moduled
if(i%2==0){
fill(red(cval),green(cval),blue(cval),24);
noStroke();
}else{
stroke(red(cval),green(cval),blue(cval),24);
noFill();
}
ellipse(x[i]%width,y[i]%height,zm*.1,zm*.1);
}
stroke(255);
for(int i=0;i<num_mov-1;i++){
line(x[i],y[i],x[(i+1)%num_mov]*sin(i),y[(i+1)%num_mov]*sin(i));
}
}
}
class gravity_dive{
float x=random(width);
float y=random(height);
float theta=random(TWO_PI);
float tc=random(-0.01,0.01);
float rad=random(0.5,2);
gravity_dive(){
//nothing
}
void trail(){
if(random(100)>99){
rad+=0.001;
}else{
rad-=0.001;
}
theta+=tc;
x+=rad*cos(theta);
y+=rad*sin(theta);
while (x<0) {
x+=width;
}
while (x>=width) {
x-=width;
}
while (y<0) {
y+=height;
}
while (y>=height) {
y-=height;
}
}
}