the golden spiral comes to life for a second

Yet another golden mean animation.

This one is really more golden spiral than golden mean. It starts out as just a regular old logarithmic spiral with the angle of curvature gradually growing until it reaches phi and then passes just slightly through it and back again. I love that moment right when it hits phi and it almost seems to come alive, then lose the life again as it recedes back into just a regular shape. Like it’s breathing.

It’s interactive. Move the mouse to control it.

Moving left and right changes the size of the dots
Moving down increases the angle of spiral, Up decreases it.
B toggles between black and white and color modes
P turns on “paint mode” where the animation leaves trails behind it.
G pulses the dot size
1,2,3,4 control how many spirals are in the animation (2 by default).

// Rotation of items at 137.5 degrees
// Golden Rectangle sized canvass naturally.
float phi=1.6180339;
float  dimX=600,dimY=dimX/phi; 
float angle=0;
float lX,lY,nX,nY;
float R,A;  // Constants
int redAmt=int(random(255)),blueAmt=int(random(255)),greenAmt=int(random(255)); 
color[] phicolors = new color[3];
int cnum=0; 
float bigSpin=0; 
color gradient1=color(255,000,000,255); 
color gradient2=color(000,000,255,255); 
float aInc=.01, rInc=5, dInc=.03,angleInc=8;
float diameter=0;
float multiple=.12;  // How large are the dots when we start? 
float dotSize=0; 
float e=2.71828;
float b=.306349;  // (ln phi)/90
float phiPoint=1/b;  // animation gradient cycle length, point where the radian comes alive
int numSpirals=2;
boolean nearPhi=false;
// Defaults are set here
boolean colorAlternate=true,  
        cleared=false, 
        paintMode=false,
        dotAnimate=false,
        angleAnimate=true,
        animate=true,
        BW=false,
        md=true,
        mr=false ,
        gradient=true;
        
void setup(){
  frameRate(20);
  size(int(dimX),int(dimY),JAVA2D);
  //smooth();
  background(255);
  A=2;
  R=dimX;
  lX=R*pow(A*b,radians(angle)) * cos(radians(angle));
  lY=R*pow(A*b,radians(angle)) * sin(radians(angle));
  get3Colors(); 
}

void drawSpiral() {
    for (int $i=0;$i<numSpirals;$i++){
      if (colorAlternate){
        get3Colors();
      }
      rotate(radians(360/numSpirals));
      angle=0;   
      lX=R*pow(A*b,radians(angle)) * cos(radians(angle));
      lY=R*pow(A*b,radians(angle)) * sin(radians(angle));
      while (abs(lX)>4 || abs(lY)>4 && (lX<dimX || lY<dimY)) {
      // if nearPhi go into multicolor mode
        //if (nearPhi){
        //   phicolors[0]=color(200,100,100,100);
        //   phicolors[1]=color(200,100,100,100);
        //   phicolors[2]=color(200,100,100,100);
          //stroke(255,255,255,255*A/b);  
        //}
       // else {
          //stroke(255,255,255,255*A/b);
          stroke(red(phicolors[cnum]),green(phicolors[cnum]),blue(phicolors[cnum]),255);  
        //}
        fill(phicolors[cnum]);

          cnum++;
          if (cnum>2){
             cnum=0;
          }
      angle+=angleInc; 
      nX=R*pow(A*b,radians(angle)) * cos(radians(angle));
      nY=R*pow(A*b,radians(angle)) * sin(radians(angle));
      float dsize=10-(angle/10);
      
      strokeWeight(1); 
      // dots are smaller near the origin larger as they get further away. 
      diameter=pow(nX*nX+nY*nY,.5)*multiple; 
      ellipse(nX,nY,diameter,diameter);
      lX=nX;
      lY=nY;
   }
  }
}


void draw(){
   //if (random(1)>.95){
   // get3Colors(); 
  //}
    if (animate) {
     if (dotAnimate){
      multiple+=dInc;
      if (multiple>1 || multiple<0.1){
        dInc*=-1;
      }
     }
     if (angleAnimate){
       get3Colors(); 
       if (A<1.4){
          if (aInc<0){
            aInc*=-1;
          }
        }
       if (A>(1/b)-.25 && aInc>0){
           nearPhi=true;
          
       }
       if (A>(1/b)-.25 && aInc<0){
           nearPhi=false;
          
       }
       if (A>(1/b)-.05){
         aInc*=-1;
        }
        A+=aInc;
     }
      /*
   if (R<1 || R>dimX){
        rInc*=-1;
      }
      R+=rInc;
  */  
  //drawSpiral();
  if (!paintMode){
    fill(255,255,255,85);
    stroke(255,255,255,255);
    rect(0,0,dimX,dimY);
    
  } 
  translate(dimX/phi,dimY/2);   
  bigSpin+=radians(2);
  if (bigSpin>2*PI){
    bigSpin=0;
    //print("reset");
  }
  rotate(bigSpin);
  drawSpiral();  

}
else {
  translate(dimX/phi,dimY/2);  
}
}

void get3Colors(){
  
  // new seed
  if (BW) {
    redAmt=0;
    greenAmt=redAmt;
    blueAmt=redAmt;
    phicolors[0]=color(redAmt,blueAmt,greenAmt,100);
    phicolors[1]=color(redAmt,blueAmt,greenAmt,100);
    phicolors[2]=color(redAmt,blueAmt,greenAmt,100);
  }
  else {
     // cycle length determines how fast we move from red to blue
     if (gradient) {
       float animDistance=.5/(A/phiPoint); 
       //print("animDiatance:"+animDistance+"\n");
       int redDistance=int(red(gradient2)-red(gradient1)); 
       //print ("redDistance:"+redDistance);
       redAmt=int(red(gradient1)+(redDistance*animDistance));
       //print ("redAmt:"+redAmt);
       
       int greenDistance=int(green(gradient2)-green(gradient1));
       
       greenAmt=int(green(gradient1)+(greenDistance*animDistance));
       
       //print ("greeenAmt:"+greenAmt);
       blueAmt=int(blue(gradient1)+(blue(gradient2)-blue(gradient1))*animDistance);
       
       //print (" blueAmt:"+blueAmt);
       phicolors[0]=color(redAmt,greenAmt,blueAmt,100);
       phicolors[1]=color(redAmt,greenAmt,blueAmt,100);
       phicolors[2]=color(redAmt,greenAmt,blueAmt,100);
     }
     else {
       redAmt=int(random(255));
       greenAmt=int(random(255));
       blueAmt=int(random(255));  
       phicolors[0]=color(redAmt,blueAmt,greenAmt,100);
       phicolors[1]=color(redAmt/phi,blueAmt/phi,greenAmt/phi,100);
       phicolors[2]=color(redAmt*phi,blueAmt*phi,greenAmt*phi,100);
     }
  }
}


void mouseClicked() {
  angleInc=mouseY/20+1;
  print("a"+angleInc+"/n");
}

void mouseMoved(){
  //background(255); 
  if (mr) {
    R=mouseX;
  }
  if (md) {
    multiple=mouseX/dimX;
  }
  A=min((mouseY/(dimY/3))+.5,(1/b)-.2);
  angle=0;
 lX=R*pow(A,radians(angle)) * cos(radians(angle));
  lY=R*pow(A,radians(angle)) * sin(radians(angle));
  //print("R:"+R+"A:"+A+"\n");
  if (!animate) {
    background(255); 
    cleared=true;
  }
  //background(255);
    //translate(dimX/phi,dimY/2);
  //drawSpiral();
}

void keyPressed() {
  if (key == 'a') {
    // pressing s will take a picture.  Won't work on JS version.
    animate=!animate;
    cleared=false;
    print ("animate");
  }
  if (key == 's') {
    // pressing s will take a picture.  Won't work on JS version.
    print("settings:"+"\n");
    print("A:"+A+"\n");
    print("R:"+R+"\n");
    print("multiple:"+multiple+"\n");
    print("numspirals"+numSpirals+"\n");
    //print:("settings:"+"\n");
    saveFrame("output##.png");
  }
   if (key == '1') {
     numSpirals=1;
  }
   if (key == '2') {
    numSpirals=2;
  }
   if (key == '3') {
   numSpirals=3;
 }
   if (key == '4') {
   numSpirals=4;
  }
  if (key == 'r') { // reset
    background(255);
  }
 if (key == 'c') { // reset
    get3Colors();
  }
 if (key == 'b') { // shift to B&W
    BW=!BW;
  }
   if (key == 'p') { // shift to B&W
    paintMode=!paintMode;
  }
  if (key == 'g') { // Animates Dots
    dotAnimate=!dotAnimate;
  }
  if (key == 'G') { // Animates Dots
    gradient=!gradient;
  }
  if (key == 'n') { // Animates Dots
    angleAnimate=!angleAnimate;
  }
  if (key == 'd') { // Mouse moves diameter instead of Radius
    md=!md;
    mr=!mr; 
  }
}

Posted: April 14th, 2011 | Author: Rob | Filed under: Animation, Golden Mean, Processing, Programming | No Comments »

Leave a Reply