// Cassini // // Author: Mario Klingemann // mario@quasimondo.com // http://incubator.quasimondo.com // // // // THIS CODE IS PROVIDED UNDER THE TERMS OF THE // CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). // THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER // APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN // AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW // IS PROHIBITED. // // You are free: // // to copy, distribute, display, and perform the work // to make derivative works // to make commercial use of the work // Under the following conditions: // Attribution. You must give the original author credit. // For any reuse or distribution, you must make clear to others the license terms of this work. // Any of these conditions can be waived if you get permission from the copyright holder. // Your fair use and other rights are in no way affected by the above. // // Details: http://creativecommons.org/licenses/by/2.0/legalcode Particle[] dots; int count; int iMax; Gradient grad; int closest; boolean hasClosest=false; void setup(){ size(300,400); int c2=0xfff7f4; int c1=0x505b57; grad=new Gradient(c1,c1); grad.addMarker(0.14,c1); grad.addMarker(0.2,c2); grad.addMarker(0.6,c2); grad.addMarker(0.66,c1); iMax=width*height; count=5; dots=new Particle[count]; for (int i=0;i-1.0;) { for (float x=width;--x>-1.0;) { i--; d=1; for (p=count;--p>-1;) { dx=x-dots[p].ix; dy=y-dots[p].iy; d*=(1+dx*dx+dy*dy)/1000.0; } if (d>70000000.0) d=70000000.0; pixels[i]=grad.getColor((int)(pow(d,0.4))&255); } } } void getClosest(){ int mind=100000; for (int i=count;--i>-1;){ int dx=mouseX+dots[i].ix; int dy=mouseY+dots[i].iy; int d=dx*dx+dy*dy; if (dwidth-BORDER || y>height-BORDER){ targetAngle=atan2(height/2-y,width/2-x); angle=turn(angle,targetAngle,.1); } } void updateDirection() { targetAngle=random(TWO_PI); angle=turn(angle,targetAngle,.01); } void checkTargets() { float dMin=TARGET_ZONE+1; float pointAngle=angle; friendDetected=false; for (int i=0;iAVOID_ZONE){ dMin=d; pointAngle=atan2(dy,dx); } else { speed*=1.02; } fd=i; friendDetected=true; } } dMin=TARGET_ZONE+1; if (friendDetected){ angle=turn(angle,pointAngle,.1); speed*=.99; } else { speed*=1.01; } } void updateSpeed() { speed=min(speed,MAXSPEED); vx=cos(angle)*speed; vy=sin(angle)*speed; } void apply() { x=nx; y=ny; ix=int(x); iy=int(y); ip=ix+iy*width; } float turn(float currentAngle,float targetAngle,float percent) { float aDif=targetAngle-currentAngle; if (aDif>PI){ aDif=-(TWO_PI-aDif); } else if (aDif<-PI){ aDif=TWO_PI+aDif; } return currentAngle+aDif*percent; } } class Gradient { int shift=0; Marker[] markers; color[] palette; Gradient(color c1,color c2){ markers=new Marker[2]; markers[0]=new Marker(0,c1); markers[1]=new Marker(1,c2); palette=new color[256]; this.updatePalette(); } void addMarker(float p,color c) { Marker[] tempMarkers=new Marker[markers.length+1]; int iAdd=0; for (int i=0;i