> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.nlWsCCqj3Wh/rev.175
 * 
 * authors: 
 *   
 *   
 *   
 *   Lucas Alberto
 *   
 *   
 *   
 *   

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 





var colpal = {
    { {0, 10, 20}, {50, 100, 240}, {20, 3, 26}, {230, 60, 20},
      {25, 10, 9}, {230, 170, 0}, {20, 40, 10}, {0, 100, 0},
      {5, 10, 10}, {210, 70, 30}, {90, 0, 50}, {180, 90, 120},
      {0, 20, 40}, {30, 70, 200} },
    { {70, 0, 20}, {100, 0, 100}, {255, 0, 0}, {255, 200, 0} },
    { {40, 70, 10}, {40, 170, 10}, {100, 255, 70}, {255, 255, 255} },
    { {0, 0, 0}, {0, 0, 255}, {0, 255, 255}, {255, 255, 255}, {0, 128, 255} },
    { {0, 0, 0}, {255, 255, 255}, {128, 128, 128} },
  };

// initialize color palettes
var colors = [];
int pallete = 1;

//var sketch = new Processing.Sketch();
// define 3D context
//sketch.use3DContext = true;

// Establish a range of values on the complex plane
// A different range will allow us to "zoom" in or out on the fractal
// float xmin = -1.5; float ymin = -.1; float wh = 0.15;
float xmin = -2.5; 
float ymin = -2; 
float wh = 4;
float z = 0;
double zoom = 1.0;
int maxIterations = 250;
double viewX = 0.0;
double viewY = 0.0;

var fractalPixels = [];

void setup() {
    
    for (int p = 0; p < colpal.length; p++) {
      colors[p] = [];
      for (int i = 0; i < colpal[p].length; i++) {
        int[] c1 = colpal[p][i];
        int[] c2 = colpal[p][(i + 1) % colpal[p].length];
        for (int j = 0; j < 12; j++)
          colors[p][i * 12 + j] = color(
              (c1[0] * (11 - j) + c2[0] * j) / 11,
              (c1[1] * (11 - j) + c2[1] * j) / 11,
              (c1[2] * (11 - j) + c2[2] * j) / 11);
      }
    }
        size(500, 500, P2D);
        noLoop();
        noFill();
//        frameRate(1);
}

void draw() { 
//      colorMode(HSB, 100);   
        
        background(255);
        //camera();
        
        if(fractalPixels.length == 0) {
            calculate();
            loadPixels();
            fractalPixels = clone(pixels);            
        } else {
            loadPixels();
            pixels = fractalPixels;
            updatePixels();
        }
}

void mouseMoved() {        
        pixels = fractalPixels;
        updatePixels();
        stroke(255);
        rect(mouseX-25, mouseY-25, 50, 50);
}
    
void mouseClicked() {
        //pallete += 1;
        //pallete = pallete % colors.length;
        
        int mx = mouseX - 25;
        int my = mouseY - 25;
        viewX += zoom * mx / width;
        viewY += zoom * my / height;
        int w = 50;
        int h = 50;
        double r = w / width;
        zoom *= r;  
        
        calculate();
        loadPixels();
        fractalPixels = clone(pixels);
}

// Computes a value for a given complex number
function mandel(double zRe, double zIm, double pRe, double pIm) {
    double zRe2 = zRe * zRe;
    double zIm2 = zIm * zIm;
    double zM2 = 0.0;
    int count = 0;
    while (zRe2 + zIm2 < 4.0 && count < maxIterations) {
      zM2 = zRe2 + zIm2;
      zIm = 2.0 * zRe * zIm + pIm;
      zRe = zRe2 - zIm2 + pRe;
      zRe2 = zRe * zRe;
      zIm2 = zIm * zIm;
      count++;
    }
    if (count == 0 || count == maxIterations)
      return 0;
    // transition smoothing
    zM2 += 0.000000001;
    int v = log(4 / zM2) / log((zRe2 + zIm2) / zM2);
    return count + v;
}

function calculate() {
    for(int y = 0; y < height; y++) {
        for(int x = 0;  x < width; x++) {
        
            double r = zoom / min(width, height);
            double dx = 2.5 * (x * r + viewX) - 2;
            double dy = 1.25 - 2.5 * (y * r + viewY);
            int n = mandel(0.0, 0.0, dx, dy);

            var pcolor = color(0);          
            // We color each pixel based on how long it takes to get to infinity
            // If we never got there, let's pick the color black
            if (n == maxIterations) {
                // pixels[i+j*width] = 0;
                pcolor = color(0, 0, 0);
            }
            else {
               //pixels[i+j*width] = color(n*16 % 255);  // Gosh, we could make fancy colors here if we wanted
               var palSize = colors[pallete].length;
               var c = int(n % palSize);
               pcolor = colors[pallete][c];
            }

            stroke(pcolor);
            point(x, y);
        }
    }
}



var clone(obj) {
  var newObj = (obj instanceof Array) ? [] : {};
  for (i in obj) {
    if (i == 'clone') continue;
    if (obj[i] && typeof obj[i] == "object") {
      newObj[i] = clone(obj[i]);
    } else newObj[i] = obj[i]
  } return newObj;
}