Welcome to Fractal Forums

Fractal Software => Help & Support => Topic started by: Iariak on March 13, 2017, 06:30:30 PM




Title: Rendering Buddhabrot in Processing (need help)
Post by: Iariak on March 13, 2017, 06:30:30 PM
Hello everyone. Basically I am trying to recreate my atrociously slow VBA program for rendering the Buddha and Anti-Buddha versions of different fractals in Processing aaaaaand it's not working. This is especially infuriating because I have made it work in significantly inferior environment before but I just can't get it to work here  :sad1: I will attach the image the program is generating and the entirety of the code. If anyone could take a look at it (the code is probably terrible, sorry :D ), I would be extremely grateful. I suspect the error is in the incrementPixels function and in the way I am mapping the values but I have no idea how to do it differently. Thanks!

Code:
float range;
int maxIter;
int[] newPixels;
void setup () {
  size(600, 600);
  range = 2;
  maxIter = 500;
  newPixels = new int[width * height];
}

void draw() {
  render();
  colorPix();
  newPixels = new int[width * height];
  saveFrame("failed-buddha.jpg");
}

void render() {
  // this function just picks numbers and passes them down for iterating and stuff.
  for (float x = -range; x < range; x += 0.001) {
    for ( float y = -range; y < range; y += 0.001) {
      test (x, y);
    }
  }
}

void test(float x, float y) {
  // This function tests if the complex number is part of M-set.
  // If it is not, the number is passed to the incrementPixels function.
  C cNum = new C(x, y);
  for (int i = 0; i < maxIter; i++) {
    cNum.MIter();
    if (cNum.escaped()) {
      incrementPixels(cNum);
      return;
    }
  }
}

void incrementPixels(C cNum) {
  // This function takes values stored in track ArrayList
  // (all the values Z became during iterating)
  // and increment values for according pixels. At least that's what I want it to do.
  // I suspect this is where the error is, but I have no idea what's wrong.
  for (float[] nums : cNum.track) {
    float r = nums[0];
    float i = nums[1];
    float coord =  map(r, -range, range, 0, width) + map(i, -range, range, 0, height) * width;
    if (coord < newPixels.length && coord >= 0) {
      newPixels[int(coord)] += 1;
    }
  }
}

void colorPix() {
  // This just takes the newPixels array and loads it onto the screen.
  loadPixels();
  for (int i = 0; i < pixels.length; i++) {
    pixels[i] = color(newPixels[i]);
  }
  updatePixels();
}

// Following is the code for the C class that represents complex number
// I doubt there is anything wrong here
class C {
  float i;
  float r;
  float iConst;
  float rConst;
  ArrayList<float[]> track;
  C (float real, float imaginary) {
    i = imaginary;
    r = real;
    iConst = i;
    rConst = r;
    track = new ArrayList<float[]>();
  }
  void MIter() {
// fixed this bit, thanks to Claude.
    float br = r;
    r = r * r - i * i + rConst;
    i = 2 * br * i + iConst;
    float[] comp = new float[2];
    comp[0] = r;
    comp[1] = i;
    track.add(comp) ;
    
  }
  
  boolean escaped() {
    if (r * r + i * i > 16) {
      return true;
    } else {
      return false;
    }
  }
}



Title: Re: Rendering Buddhabrot in Processing (need help)
Post by: claude on March 13, 2017, 07:24:11 PM

Code:
  void MIter() {
    float bi = i;
    r = i * i - r * r + rConst;
    i = 2 * bi * r + iConst;
    float[] comp = new float[2];
    comp[0] = r;
    comp[1] = i;
    track.add(comp) ;
   
  }

You should save r instead of i, here you use the new value of r instead of the old one when updating i.  Don't know if this is the only problem...


Title: Re: Rendering Buddhabrot in Processing (need help)
Post by: Iariak on March 13, 2017, 07:49:02 PM
Oh yea, that's a dumb mistake. The result is pretty much the same though, code still doesn't generate what I want. Thank you so much for looking through my code though  :)

* I did some poking around and found out that if I change

float coord =  map(r, -range, range, 0, width) + map(i, -range, range, 0, height) * width;
to
float coord =  map(cNum.iConst, -range, range, 0, width) + map(cNum.rConst, -range, range, 0, height) * width;

Which should just show the fractal rotated, or viewed from a different angle (from this angle, it should be pretty much just a regular Mandelbrot set), it gives me this (attached). It might give you more of an idea of what's happening. I have no clue as to why it's spread out like this.

One last edit...I found the mistake myself, it turned out that the way I was creating the newPixels array and assigning it to the pixels array was completely stupid and nonsensical :D Here is the fixed code
Code:
float range;
int maxIter;
int[][] newPixels;
void setup () {
  size(600, 600);
  range = 2;
  maxIter = 500;
  newPixels = new int[width][height];
}

void draw() {
  render();
  colorPix();
  newPixels = new int[width][height];
  saveFrame("failed-buddha.jpg");
}

void render() {
  // this function just picks numbers and passes them down for iterating and stuff.
  for (float x = -range; x < range; x += 0.001) {
    for ( float y = -range; y < range; y += 0.001) {
      test (x, y);
    }
  }
}

void test(float x, float y) {
  // This function tests if the complex number is part of M-set.
  // If it is not, the number is passed to the incrementPixels function.
  C cNum = new C(x, y);
  for (int i = 0; i < maxIter; i++) {
    cNum.MIter();
    if (cNum.escaped()) {
      incrementPixels(cNum);
      return;
    }
  }
}

void incrementPixels(C cNum) {
  // This function takes values stored in track ArrayList
  // (all the values Z became during iterating)
  // and increment values for according pixels. At least that's what I want it to do.
  // I suspect this is where the error is, but I have no idea what's wrong.
  for (float[] nums : cNum.track) {
    float r = nums[0];
    float i = nums[1];
    float iC = cNum.iConst;
    float rC = cNum.rConst;
    float xcoord = map(r, -range, range, 0, width);
    float ycoord = map(i, -range, range, 0, height);
    if (xcoord >= 0 && xcoord < width && ycoord >= 0 && ycoord < height) {
      newPixels[int(xcoord)][int(ycoord)] += 1;
    }
  }
}


void colorPix() {
  // This just takes the newPixels array and loads it onto the screen.
  loadPixels();
  for (int i = 0; i < width; i++) {
    for (int j = 0; j < height; j++) {
      float val = newPixels[i][j];
      pixels[j + i * width] = color(map(val, 0, 1000, 0, 255));
    }
  }
  updatePixels();
}

// Following is the code for the C class that represents complex number
// I doubt there is anything wrong here
class C {
  float i;
  float r;
  float iConst;
  float rConst;
  ArrayList<float[]> track;
  C (float real, float imaginary) {
    i = imaginary;
    r = real;
    iConst = i;
    rConst = r;
    track = new ArrayList<float[]>();
  }
  void MIter() {
    float br = r;
    r = r * r - i * i + rConst;
    i = 2 * br * i + iConst;
    float[] comp = new float[2];
    comp[0] = r;
    comp[1] = i;
    track.add(comp) ;
   
  }
 
  boolean escaped() {
    if (r * r + i * i > 16) {
      return true;
    } else {
      return false;
    }
  }
}