# \[SOLVED\] Help Updating G4P GUI Mandelbrot Code to Processing 3x

**URL:** <https://discourse.processing.org/t/solved-help-updating-g4p-gui-mandelbrot-code-to-processing-3x/4143>\
**Category:** Libraries\
**Created:** [October 4, 2018, 7:55pm UTC](https://discourse.processing.org/t/solved-help-updating-g4p-gui-mandelbrot-code-to-processing-3x/4143 "2018-10-04T19:55:32Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ProsExplorer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/prosexplorer/32/1649_2.png) [@ProsExplorer](https://discourse.processing.org/u/ProsExplorer)\
**Post date:** [October 4, 2018, 7:55pm UTC](https://discourse.processing.org/t/solved-help-updating-g4p-gui-mandelbrot-code-to-processing-3x/4143/1 "2018-10-04T19:55:32Z")

</div>

In an attempt to better understand Qscript Math in relation to what I’m already familiar with and help develop the other programs I’m working on I found this legacy source code from quarks openprocessing page. I realize that it’s written for processing 1x or 2x and was wondering if I could get some help updating it to run in processing 3x, seeing as I’m totally unfamiliar with the G4P GUI and most all the errors seem to be GUI related.

```auto
/**
 * The most complicated example so far. This will display the Mandelbrot
 * set in a separate window. Draw a rectangle over the image to create 
 * a new Mandelbrot in a new window ...
 *
 * by Peter Lager
 */
 
import g4p_controls.*;

//Believe this is the Previous G4P GUI Library
//import guicomponents.*;

final int MAX_ITERATE = 128;

final int MAX_WIDTH = 300;
final int MAX_HEIGHT = 300;

final int MIN_WIDTH = 30;
final int MIN_HEIGHT = 30;

int[] colors = new int[MAX_ITERATE];

GButton btnStart;

int locX = 100, locY = 100;
ArrayList windows = new ArrayList();

String t0,t1,t2;

class Complex {

  public double real;
  public double img;

  Complex(){
    real = img = 0.0f;
  }

  /**
   * * @param r
   * * @param i
        */
  public Complex(float r, float i) {
    super();
    this.real = r;
    this.img = i;
  }

  public void set(double colX, double rowY){
    real = colX;
    img = rowY;
  }

  public Complex add(Complex c){
    real += c.real;
    img += c.img;
    return this;
  }

  public void mult(Complex c){
    double nReal = real * c.real - img * c.img;
    double nImg = real * c.img + img * c.real;
    real = nReal;
    img = nImg;
  }

  public Complex squared(){
    double nReal = (real - img)*(real + img);
    double nImg = 2 * real * img;
    real = nReal;
    img = nImg;  
    return this;
  }

  public double sizeSquared(){
    return real * real + img * img;
  }
}

/**
 * Simple class that extends GWinData and holds the data that is specific
 * to a particular window.
 */
class MyWinData extends GWinData {

  public int msx,msy,mex,mey;
  public double sx,sy,ex,ey;
  public int w, h;
  public PImage img;
  public boolean imgDone;
}

void setup(){
  size(300,200);
  G4P.setFont(this, "Serif", 14);
  G4P.setColorScheme(this, GCScheme.RED_SCHEME);
  btnStart = new GButton(this, "START", (width - 80)/2,height - 30,80,20);
  t0 = "MANDELBROT GALORE\n";
  t1 = "Click on the START button to see the Mandelbrot set in a separate window. ";
  t2 = " To zoom into the set drag a box on the area you are interested in and ";
  t2 += "he enlarged image will appear in a new window.";

  createColours();
}

public void createColours(){
  colors[MAX_ITERATE-1] = color(0);
  float hue = 0.0f;
  float bright = 1.0f;
  float binc = 0.009f/MAX_ITERATE;
  for(int i = 0; i < MAX_ITERATE - 2; i++){
    colors[i] = Color.HSBtoRGB(hue, 1.0f, bright);
    hue = (hue + 0.1309f) % 1.0f ;
    bright -= binc;
  }
}

/**
 * Create a PImage of the correct size and using the data
 * for a window create the Mandelbrot image. Singnal when
 * complete by setting imgDone = true
 * 
 * @param data
 */
public void calcMandlebrot(MyWinData data){
  double x0,x1,y0,y1, deltaX, deltaY;
  double colX, rowY;
  x0 = data.sx;
  x1 = data.ex;
  y0 = data.sy;
  y1 = data.ey;
  deltaX = (x1 - x0)/data.w;
  deltaY = (y1 - y0)/data.h;
  data.img.loadPixels();
  int count = 0;
  Complex c = new Complex();
  Complex z = new Complex();

  colX = x0;
  rowY = y0;
  int minC = 999, maxC = -999;
  for(int row = 0; row < data.h; row++){
    colX = x0;
    for(int col = 0; col < data.w; col++){
      count = 0;
      c.set(colX, rowY);
      z.set(colX, rowY);
      while(count < MAX_ITERATE-1 && z.sizeSquared() < 4.0){
        z = z.squared().add(c); 
        count++;
      }
      if(count < minC) minC = count;
      if(count > maxC) maxC = count;
      data.img.pixels[col + row * data.w] = colors[count];
      colX += deltaX;
    }
    rowY += deltaY;
  }
  data.img.updatePixels();
  data.imgDone = true;
}

/**
 * Create and display a new Frame for a Mandelbrot
 * make it as big as possible to fit MAX_WIDTH and MAX_HEIGHT
 * but reject if this results in the width or height being less
 * than the minimum vales (MIN_WIDTH, MIN_HEIGHT.
 * 
 * @param nsx
 * @param nex
 * @param nsy
 * @param ney
 * @return
 */
public boolean makeNewBrotWindow(double nsx, double nex, double nsy, double ney){
  MyWinData mydata = new MyWinData();
  GWindow window = null;
  float ratio = (float) ((nex-nsx)/(ney-nsy));
  if(ratio > MAX_WIDTH/MAX_HEIGHT){
    mydata.w = MAX_WIDTH;
    mydata.h = (int)( MAX_HEIGHT / ratio);
  }
  else {
    mydata.h = MAX_HEIGHT;
    mydata.w = (int)( MAX_WIDTH * ratio);
  }
  mydata.sx = nsx;
  mydata.sy = nsy;
  mydata.ex = nex;
  mydata.ey = ney;
  mydata.imgDone = false;

  if(mydata.w >= MIN_WIDTH && mydata.h >= MIN_HEIGHT){
    mydata.img = new PImage(mydata.w, mydata.h);
    window = new GWindow(this,"Main", locX, locY, mydata.w, mydata.h, false, null);
    windows.add(window);
    locX = (locX + mydata.w + 20)%(screen.width - MAX_WIDTH);
    locY = (locY + 20)%(screen.height - MAX_HEIGHT);
    window.addData(mydata);
    window.addDrawHandler(this, "windowDraw");
    window.addMouseHandler(this, "windowMouse");
    calcMandlebrot(mydata);
    return true;
  }
  return false;
}

/**
 * Click the button to create the windows.
 * @param button
 */
public void handleButtonEvents(GButton button){
  if(btnStart == button){
    makeNewBrotWindow(-2.0f,0.5f,-1.25f,1.25f);
    btnStart.setVisible(false);
  }
}

/**
 * Draw for the main window
 */
void draw(){
  background(0,192,0);
  textAlign(CENTER);
  if(windows.isEmpty())
    text(t0+t1+t2,10,10,width - 20,height - 40);
  else {
    text(t0+t2,10,10,width - 20,height - 40);
    noLoop();
  }
}

/**
 * Handles mouse events for ALL GWindow objects
 * 
 * @param appc the PApplet object embeded into the frame
 * @param data the data for the GWindow being used
 * @param event the mouse event
 */
public void windowMouse(GWinApplet appc, GWinData data, MouseEvent event){
  MyWinData d = (MyWinData)data;
  if(d.imgDone == false)
    return;
  switch(event.getID()){
  case MouseEvent.MOUSE_PRESSED:
    d.msx = d.mex = appc.mouseX;
    d.msy = d.mey = appc.mouseY;
    appc.loop();
    appc.frameRate(30);
    break;
  case MouseEvent.MOUSE_RELEASED:
    d.mex = appc.mouseX;
    d.mey = appc.mouseY;
    // Make sure the coordinates are top left / bottom left
    int temp;
    if(d.msx > d.mex){
      temp = d.msx; 
      d.msx = d.mex; 
      d.mex = temp;
    }
    if(d.msy > d.mey){
      temp = d.msy; 
      d.msy = d.mey; 
      d.mey = temp;
    }
    // Calculate the new Mandelbrot plane coordinates
    double nsx,nex,nsy,ney;
    nsx = dmap((double)d.msx, (double)0, (double)d.w, d.sx, d.ex);
    nex = dmap((double)d.mex, (double)0, (double)d.w, d.sx, d.ex);
    nsy = dmap((double)d.msy, (double)0, (double)d.h, d.sy, d.ey);
    ney = dmap((double)d.mey, (double)0, (double)d.h, d.sy, d.ey);
    makeNewBrotWindow(nsx, nex, nsy, ney);
    d.msx = d.mex = d.msy = d.mey = 0;
    appc.noLoop();
    break;
  case MouseEvent.MOUSE_DRAGGED:
    d.mex = appc.mouseX;
    d.mey = appc.mouseY;
    break;      
  }
}

/**
* Copied from PApplet and converted floats to doubles 
* @param value
* @param istart
* @param istop
* @param ostart
* @param ostop
* @return
*/
double dmap(double value, double istart, double istop, double ostart, double ostop) {
  return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
}

/**
 * Handles drawing to the windows PApplet area
 * 
 * @param appc the PApplet object embeded into the frame
 * @param data the data for the GWindow being used
 */
public void windowDraw(GWinApplet appc, GWinData data){
  MyWinData d = (MyWinData)data;
  if(d.imgDone){
    appc.image(d.img,0,0);
    if(d.msx != d.mex || d.msy != d.mey){
      appc.strokeWeight(2);
      appc.stroke(255);
      appc.noFill();
      appc.rectMode(CORNERS);
      appc.rect(d.msx,d.msy,d.mex,d.mey);
    }  
  }
}

```

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [October 5, 2018, 4:10pm UTC](https://discourse.processing.org/t/solved-help-updating-g4p-gui-mandelbrot-code-to-processing-3x/4143/2 "2018-10-05T16:10:20Z")

</div>

This example is included with the all versions of G4P so you can find it in the examples. Select **File \> Examples** from the menus open **Contributed Libraries \> G4P \> G4P\_Mandelbrot**.

Note this example does not use the QScript library it demonstrates using multiple windows.

You can find out more about G4P/multiple windows and QScript on my website [Quark’s Place](http://lagers.org.uk/index.html)

---

<div class="post-metadata">

**Author:** ![ProsExplorer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/prosexplorer/32/1649_2.png) [@ProsExplorer](https://discourse.processing.org/u/ProsExplorer)\
**Post date:** [October 5, 2018, 4:27pm UTC](https://discourse.processing.org/t/solved-help-updating-g4p-gui-mandelbrot-code-to-processing-3x/4143/3 "2018-10-05T16:27:08Z")

</div>

I didn’t realize libraries came with their own examples. Ohh okay it uses it’s own class but not the QScript library. Thank you for letting me know!
