Rainbow Arch Grad


  size(400, 200);
  smooth();
  
  color skyBlue = color(0x87, 0xCE, 0xEB); // Equivalent of the CSS color #87CEEB
  color lightSkyBlue = color(0x87, 0xCE, 0xFA);
  color deepSkyBlue = color(0x00, 0xBF, 0xFF);
  color white = color(255, 255, 255);
  
  setGradient(0, 0, width,   height*.333,         deepSkyBlue, skyBlue);
  setGradient(0, height*.333, width, height*.333,  skyBlue, lightSkyBlue);
  setGradient(0, height*.666, width, height*.333,  lightSkyBlue, white);
  
  float cx = width/2;
  float cy = height;
  float rainbowThick = width / 5.0;
  float outerDiam = width * .9;
  
  colorMode(HSB, 1);
  noFill();
  
  for (int i = 0; i < rainbowThick; ++i) {
    float ratio = i/rainbowThick;
    float hue = ratio*ratio;
    float saturation = 1;
    float brightness = 1;
    float alpha = sin( PI*ratio ) * 1.5 / 2;
  
    stroke( hue, saturation, brightness, alpha );
    arc(cx, cy, outerDiam-i, outerDiam-i, PI, PI*2);
  }
  
  // Optimized version of "Simple Linear Gradient" by Ira Greenberg.
  void setGradient(int x, int y, float w, float h, color c1, color c2 ){
    // calculate differences between color components 
    float deltaR = red(c2)-red(c1);
    float deltaG = green(c2)-green(c1);
    float deltaB = blue(c2)-blue(c1);
  
    for (int j = y; j<=(y+h); j++){
      color c = color(
      (red(c1)+(j-y)*(deltaR/h)),
      (green(c1)+(j-y)*(deltaG/h)),
      (blue(c1)+(j-y)*(deltaB/h)) 
        );
      stroke(c);
      line(x, j, x+w, j );
    }
  }