<script type="application/processing"> // amoebaAbstract_01_formatik // Copyright 2003 Marius Watz // http://www.evolutionzone.com/ // // Variation on abstract computational animation for the exhibition // "Abstraction Now", K�nstlerhaus Vienna, 29.08-28.09 2003. // // You are allowed to play with this code as much as you like, but // you may not publish pieces based directly on it. The Vec2D class // can be used freely in any context. // int num,cnt,px,py,fadeInterval; Particle[] particles; boolean initialised=false,doClear=false; float lastRelease=-1,scMod,fadeAmount; void setup() { size(500,600); background(255); smooth(); rectMode(CENTER_DIAMETER); ellipseMode(CENTER_DIAMETER); cnt=0; num=150; particles=new Particle[num]; for(int i=0; i<num; i++) particles[i]=new Particle(); reinit(); px=-1; py=-1; } void draw() { if(doClear) { background(255); doClear=false; } noStroke(); if(frameCount%fadeInterval==0) { fill(255,255,255, fadeAmount); rect(width/2,height/2, width,height); } updateAuto(); for(int i=0; i<num; i++) if(particles[i].age>0) particles[i].update(); } void reinit() { doClear=true; scMod=random(1,1.4); fadeInterval=(int)random(220,300); fadeAmount=random(30,60); // println("fadeInterval "+fadeInterval+" scMod "+nf(scMod,0,3)+ // " fadeAmount "+nf(fadeAmount,0,3)); for(int i=0; i<num; i++) particles[i].age=-1; initAuto(); } void mousePressed() { reinit(); } AutoMover auto[]; int autoN; void initAuto() { autoN=(int)random(3,6); // println("initAuto "+autoN); auto=new AutoMover[autoN]; for(int i=0; i<autoN; i++) auto[i]=new AutoMover(); } void updateAuto() { for(int i=0; i<autoN; i++) auto[i].update(); } class AutoMover { Vec2D pos,posOld; float dir,dirD,speed,sc,dirCnt; int type,age,ageGoal,interval; AutoMover() { reinit(); } void reinit() { ageGoal=(int)random(150,350); if(random(100)>95) ageGoal*=1.25; age=-(int)random(50,150); pos=new Vec2D(random(width-100)+50,random(height-100)+50); dir=(int)random(36)*10; type=0; if(random(100)>60) type=1; interval=(int)random(2,5); if(type==1) { interval=1; dir=degrees(atan2(-(pos.y-height/2),pos.x-width/2)); } dirD=random(1,2); if(random(100)<50) dirD=-dirD; speed=random(3,6); sc=random(0.5,1); if(random(100)>90) sc=random(1.2,1.6); dirCnt=random(20,35); if(type==0) { if(random(100)>95) sc=random(1.5,2.25); else sc=random(0.8,1.2); } sc*=scMod; speed*=sc; } void update() { age++; if(age<0) return; else if(age>ageGoal) reinit(); else { if(type==1) { pos.add( cos(radians(dir))*speed,sin(radians(dir))*speed); dir+=dirD; dirD+=random(-0.2,0.2); dirCnt--; if(dirCnt<0) { dirD=random(1,5); if(random(100)<50) dirD=-dirD; dirCnt=random(20,35); } } if(age%interval==0) newParticle(); if(pos.x<-50 || pos.x>width+50 || pos.y<-50 || pos.y>height+50) reinit(); } } void newParticle() { int partNum,i; if(type==0) dir=int(random(36))*10; i=0; while(i<num) { if(particles[i].age<1) { float offs=random(30,90); if(random(100)>50) offs=-offs; particles[i].init(dir+offs,pos.x,pos.y,sc); break; } i++; } px=mouseX; py=mouseY; } } class Particle { Vec2D v,vD; float dir,dirMod,speed,sc; int col,age,stateCnt; int type; Particle() { v=new Vec2D(0,0); vD=new Vec2D(0,0); age=0; } void init(float _dir,float mx,float my,float _sc) { dir=_dir; sc=_sc; float prob=random(100); if(prob<80) age=15+int(random(30)); else if(prob<99) age=45+int(random(50)); else age=100+int(random(100)); if(random(100)<80) speed=random(2)+0.5; else speed=random(2)+2; if(random(100)<80) dirMod=20; else dirMod=60; v.set(mx,my); initMove(); dir=_dir; stateCnt=10; if(random(100)>50) col=0; else col=1; type=(int)random(30000)%2; } void initMove() { if(random(100)>50) dirMod=-dirMod; dir+=dirMod; vD.set(speed,0); vD.rotate(radians(dir+90)); stateCnt=10+int(random(5)); if(random(100)>90) stateCnt+=30; } void update() { age--; if(age>=30) { vD.rotate(radians(1)); vD.mult(1.01f); } v.add(vD); if(col==0) fill(255-age,0,100,150); else fill(100,200-(age/2),255-age,150); if(type==1) { if(col==0) fill(255-age,100,0,150); else fill(255,200-(age/2),0,150); } pushMatrix(); scale(sc); translate(v.x,v.y); rotate(radians(dir)); rect(0,0,1,16); popMatrix(); if(age==0) { if(random(100)>50) fill(200,0,0,200); else fill(00,200,255,200); float size=2+random(4); if(random(100)>95) size+=5; size*=sc; ellipse(v.x*sc,v.y*sc,size,size); } if(v.x<0 || v.x>width || v.y<0 || v.y>height) age=0; if(age<30) { stateCnt--; if(stateCnt==0) { initMove(); } } } } // General vector class for 2D vectors class Vec2D { float x,y; Vec2D(float _x,float _y) { x=_x; y=_y; } Vec2D(Vec2D v) { x=v.x; y=v.y; } void set(float _x,float _y) { x=_x; y=_y; } void set(Vec2D v) { x=v.x; y=v.y; } void add(float _x,float _y) { x+=_x; y+=_y; } void add(Vec2D v) { x+=v.x; y+=v.y; } void sub(float _x,float _y) { x-=_x; y-=_y; } void sub(Vec2D v) { x-=v.x; y-=v.y; } void mult(float m) { x*=m; y*=m; } void div(float m) { x/=m; y/=m; } float length() { return sqrt(x*x+y*y); } float angle() { return atan2(y,x); } void normalise() { float l=length(); if(l!=0) { x/=l; y/=l; } } Vec2D tangent() { return new Vec2D(-y,x); } void rotate(float val) { // Due to float not being precise enough, double is used for the calculations double cosval=Math.cos(val); double sinval=Math.sin(val); double tmpx=x*cosval - y*sinval; double tmpy=x*sinval + y*cosval; x=(float)tmpx; y=(float)tmpy; } } </script> <canvas width="500px" height="600px" id="processing"></canvas>