/* Generic interface for a 2D coordinate map * A map takes a 2D Point and generates a new one. */ interface Map{ PVector map(PVector p); PVector map(float x, float y); // the above functions require a new PVector to be declared each time the function is called // A decent image needs 100000+ calls. The variation methods below rely on a result PVector already existing. // This makes the code somwhat more obscure but more efficient. void map(float x, float y,PVector result); void map(PVector p,PVector result); } /* Generic class for a 2D attractor * implements a map and methods for copying and changing. */ class Attractor implements Map{ float[] parameters; int NOP; Attractor(){ NOP=0; } float getParameter(int i){ return parameters[i]; } int getNOP(){ return NOP; } void mutate(float f){ for(int i=0;i0f){ if(i>400){ maxLyapunov+=FastFunctions.log2(d*1000000f); N++; } p2.set(p1.x+0.000001f/d*(p2.x-p1.x),p1.y+0.000001f/d*(p2.y-p1.y),0f); } else{ p2.set(p1.x+0.000001f,p1.y,0f); } } return (N>0)?0.721347f*maxLyapunov/N:0f; } PVector map(float x, float y){ return new PVector(x,y); } PVector map(PVector p){ return map(p.x,p.y); } void map(float x, float y, PVector result){ result.x=x; result.y=y; } void map(PVector p, PVector result){ map(p.x,p.y,result); } } /* / The following consists of a number of different attractor maps. / An AttractorSystem randomly selects one of these cases. */ class TrigAttractor extends Attractor{ TrigAttractor(){ super(); NOP=16; parameters = new float[NOP]; for(int i=0;icumul)&&(selcumul)&&(sel=particles[i].timeOfDeath))||(abs(particles[i].x)+abs(particles[i].y)>1e6)){ // At time of death, reincarnate particle particles[i].dead=true; } } else if(r<1+NofMirror){ float tx=particles[i].x-parameters.centerOfMirror.x; float my=particles[i].y-parameters.centerOfMirror.y; float mx=cosMirrorRot*tx+sinMirrorRot*my; my=cosMirrorRot*my-sinMirrorRot*tx; int mirrorChoice=(int)random(1.999999f)+2; while(parameters.mirror%mirrorChoice>0){ mirrorChoice=(int)random(1.999999f)+2; } switch(mirrorChoice){ case 2: mx*=-1f; break; case 3: my*=-1f; break; } tx=mx; mx=cosMirrorRot*tx-sinMirrorRot*my; my=cosMirrorRot*my+sinMirrorRot*tx; particles[i].setAndKeep(parameters.centerOfMirror.x+mx,parameters.centerOfMirror.y+my); } else{ int s=(int)r-NofMirror; float rx=particles[i].x-parameters.centerOfSymmetry.x; float ry=particles[i].y-parameters.centerOfSymmetry.y; particles[i].setAndKeep(parameters.centerOfSymmetry.x+rx*cosLUT[s]-ry*sinLUT[s],parameters.centerOfSymmetry.y+ry*cosLUT[s]+rx*sinLUT[s]); } } } void update(){ PVector localResult = new PVector(); update(localResult); } }