/* RUNNING UNDER PROCESSING 0098 A set of Particles move across the screen and leave traces. They have a random speed and direction. When they encounter Attractors, they get targeted to the attractors direction. Press 's' to show the attractors. */ int nrOfParticles=10000; int nrOfAttractors=50; void setup() { size(500,1000); colorMode(RGB,255); initParticles(nrOfParticles,width,height); initAttractors(nrOfAttractors,width,height); background(255); loadPixels(); } void draw() { background(255); updatePixels(); updateParticlePosition(nrOfParticles); drawParticles(nrOfParticles,0.1); loadPixels(); if (showAttractors) {drawAttractors(nrOfAttractors);} } boolean showAttractors=true; void keyPressed() { if (key=='s'||key=='S') {showAttractors=!showAttractors;} } Attractor[] attractor=new Attractor[nrOfAttractors]; void initAttractors(int _n,int _w, int _h) { for (int i=0;i<_n;i++) { attractor[i]=new Attractor(i,_w,_h); } } void drawAttractors(int _n) { for (int i=0;i<_n;i++) { attractor[i].drawMe(); } } class Attractor { int id=0; float sScale=400; float x=0,y=0; float xMax=0,yMax=0; float radius=0; float turn=0; float dir=0; int gravityDirection=1; Attractor(int _id, int _w,int _h) { id=_id; sScale=_w>_h?_w:_h; if (_w>_h) { xMax=1.0; yMax=_h/(float)_w; } else { yMax=1.0; xMax=_w/(float)_h; } radius=0.01+sq(random(1))*(xMax/10.0-0.01); // more small ones turn=radians(random(0,2)); if (random(1)<0.5) {turn=-turn;} dir=random(-PI,PI); gravityDirection=random(1)<0.5?-1:1; // position circles without too much overlapping boolean found=false; while (!found) { x=random(xMax); y=random(yMax); boolean overlap=false; for (int i=0;iattractor[i].radius?radius:attractor[i].radius; if (d_h?_w:_h; if (_w>_h) { xMax=1.0; yMax=_h/(float)_w; } else { yMax=1.0; xMax=_w/(float)_h; } x=random(xMax); y=random(yMax); xm=random(0.0005,0.001); ym=random(0.0005,0.001); if (random(1)<0.5) {xm=-xm;} if (random(1)<0.5) {ym=-ym;} r=sqrt(sq(xm)+sq(ym)); rd=atan2(ym,xm); } // UPDATE POSITION, MOVEMENT OF PARTICLE void update() { // update direction if within attractor boolean withinOneAttractor=false; for (int a=0;a2*attractor[a].radius&&distanceToAttractor[a]<0.2) { float dx=attractor[a].x-x; float dy=attractor[a].y-y; float s=0.0000002/sq(distanceToAttractor[a]); xm+=attractor[a].gravityDirection*s*dx; ym+=attractor[a].gravityDirection*s*dy; } } r=sqrt(sq(xm)+sq(ym)); rd=atan2(ym,xm); // change color whiteness if within any attractor if (withinOneAttractor) { targetIntensity+=0.005; } else { targetIntensity-=0.005; } targetIntensity=constrain(targetIntensity,0,1); intensity=(40*intensity+targetIntensity)/41.0; col=color(255-intensity*baseR,255-intensity*baseG,255-intensity*baseB); // move x+=xm; y+=ym; if (x<0) {x+=xMax;} if (x>=xMax) {x-=xMax;} if (y<0) {y+=yMax;} if (y>=yMax) {y-=yMax;} } // DRAW THE PARTICLE void drawMe(float _p) { // set(int(x*sScale),int(y*sScale),col); // sSet(int(x*sScale),int(y*sScale),col,1); sSet(int(x*sScale),int(y*sScale),col,intensity*_p); // sSet(int(x*sScale),int(y*sScale),col,(1.0-0.5*brightness(col)/255.0)*_p); // sSet(int(x*sScale),int(y*sScale),col,_p); } } // LIBRARY PARTICLE // end // calculate shortest degree from deg1 to deg2 float getTurnDirection(float deg1, float deg2) { float rdeg=(deg1>deg2)?deg2-(deg1-TWO_PI):deg2-deg1; if (rdeg>16&255); } int ch_grn(int c) { return (c>>8&255); } int ch_blu(int c) { return (c&255); }