> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.jgA6Qwal$9W/rev.447
 * 
 * authors: 
 *   Nuno Lopes

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



// Newton-Raphson fractals.
// Click the mouse in the image to transform the fractal
// mouseX and mouseY will affect the fractal parameters.
// In order to implement:
// a zoomimg effect
// different colors and smoothing effects
// see  "Interactive Mandelbrot" by LUCAS ALBERTO.

// It is slow..

int MaxIter=20;
float rds=0.2;
float smod=0.0;
float zoom=1.0;
float rcenterX=0.0;
float rcenterY=0.0;
float factor=3.;
int calc=1;

// define square operation
float sqr(float x) { 
  return x*x;
}


// Complex number class
class Complex
{
  private float real;
  private float im;

  // Constructor  
  Complex( ) {
    this.real=0.0;
    this.im=0.0;
  }

  public void setvalue(float real, float im) {
    this.real=real;
    this.im=im;
  }


  public float getreal() {
    return this.real;
  } 

  public float getim() {
    return this.im;
  }

  public float modulo() {
    return this.real*this.real+this.im*this.im;
  }
}

// define some complex operations
Complex conjugate(Complex x) {
  Complex z =new Complex();
  z.setvalue(x.getreal(), -x.getim());
  return z;
}

Complex scmult(float s, Complex x) {
  Complex z =new Complex();
  z.setvalue(s*x.getreal(), s*x.getim());
  return z;
}

Complex cmult( Complex x, Complex y) {
  Complex z =new Complex();
  float real;
  float im;
  real=x.getreal()*y.getreal() -x.getim()*y.getim();
  im=x.getim()*y.getreal()+x.getreal()*y.getim();
  z.setvalue(real, im);
  return z;
}

Complex cadd(Complex x, Complex y) {
  Complex z=new Complex();
  float real;
  float im;
  real= x.getreal()+y.getreal();
  im= x.getim()+y.getim();
  z.setvalue(real, im);
  return z;
}

Complex cminus(Complex x, Complex y) {
  Complex z=new Complex();
  float real;
  float im;
  real= x.getreal()-y.getreal();
  im= x.getim()-y.getim();
  z.setvalue(real, im);
  return z;
}


Complex cpower(Complex x, int p) {
  Complex z = new Complex();
  z=x;
  for (int i=1; i<p;i++) {
    z=cmult(z, x);
  }
  return z;
}

Complex cinv(Complex x) {
  Complex z =new Complex();
  return z=scmult(1./x.modulo(), conjugate(x));
}

// Change these functions to obtain different fractals

Complex f2(Complex x, Complex Cp) {
  Complex z = new Complex();
  return cadd(cpower(x, 3), Cp);
}

Complex f1(Complex x, Complex Cp) {
  Complex z = new Complex();
  return scmult(factor, cpower(x, 2));
}


Complex znew=new Complex();
Complex zold=new Complex();
Complex Cp=new Complex();
Complex Caux= new Complex();



void setup()
{
  Cp.setvalue(1., 0.);
  size(300, 300);
  strokeWeight(1);
  background(0);
  smooth();
  colorMode(HSB, 100.);
  frameRate(1);
}

void draw() {
  loadPixels();
  if (calc==1) {
    int iter=0;
    for (int i=0;i <width;i++) {  
      for (int j=0; j<height;j++) {
        zold.setvalue(4.*((float)i/width)-2., 4.*((float)j/height)-2.);  
        iter=0;
        smod=1.0;        
        while ( (smod>rds)&&(iter<MaxIter)) {
          znew=cminus(zold, cmult(f2(zold, Cp), cinv(f1(zold, Cp))));
          Caux=cminus(znew, zold);
          smod=Caux.modulo();
          zold=znew;
          iter++;
        }
        pixels[j*width+i]=color(abs(1.-smod/rds)*100.);
      }
    }
    updatePixels();
  }
  calc=0;
}


void mouseClicked() {
  calc=1;
  rds=(float) mouseX/width*1.0;
  factor=(float) mouseY/height*5.0;
  println(rds);
  println(factor); 
}