Hi,
I am trying to render the Mandelbrot Set. I have implemented it successfully with this code using doubles:
public class MandelbrotSetDouble {
private int width;
private int height;
private double x, y, xc, yc, tmp;
public MandelbrotSetDouble(int width, int height) {
this.width = width;
this.height = height;
}
public ArrayList<Tuple3Int> loop(double zoom, double offSetX, double offSetY, int maxIter) {
ArrayList<Tuple3Int> list = new ArrayList<Tuple3Int>();
for (int ix = 0; ix < width; ix++) {
for (int iy = 0; iy < height; iy++) {
x = y = 0;
xc = ((ix - (width / 2)) / zoom) + offSetX;
yc = ((iy - (height / 2)) / zoom) + offSetY;
for (int iter = 0; iter < maxIter; iter++) {
if (((x * x) + (y * y)) < 4) {
tmp = x * x - y * y + xc;
y = 2.0 * x * y + yc;
x = tmp;
}else{
list.add(new Tuple3Int(ix, iy, iter));
break;
}
}
}
}
return list;
}
}
Then I converted all the code to using BigDecimal so I could render deeper into the Mandelbrot Set:
public class MandelbrotSetBD {
private int width;
private int height;
private int scale = 32;
private int round = 0;
private BigDecimal x = new BigDecimal("0").setScale(scale, round);
private BigDecimal y = new BigDecimal("0").setScale(scale, round);
private BigDecimal xc = new BigDecimal("0").setScale(scale, round);
private BigDecimal yc = new BigDecimal("0").setScale(scale, round);
private BigDecimal temp1 = new BigDecimal("0").setScale(scale, round);
private BigDecimal temp2 = new BigDecimal("0").setScale(scale, round);
private BigDecimal four = new BigDecimal("4").setScale(scale, round);
private BigDecimal two = new BigDecimal("2").setScale(scale, round);
public MandelbrotSetBD(int width, int height) {
this.width = width;
this.height = height;
}
public ArrayList<Tuple3Int> loop(String zoom, String offSetX, String offSetY, int maxIter) {
System.out.println("Starting generating Mandelbrot Set using BigDecimal with scale=" + scale + "...");
ArrayList<Tuple3Int> list = new ArrayList<Tuple3Int>();
BigDecimal offSetXbd = new BigDecimal(offSetX);
BigDecimal offSetYbd = new BigDecimal(offSetY);
BigDecimal zoombd = new BigDecimal(zoom);
BigDecimal ixbd;
BigDecimal iybd;
BigDecimal widthbd;
BigDecimal heightbd;
for (int ix = 0; ix < width; ix++) {
for (int iy = 0; iy < height; iy++) {
ixbd = new BigDecimal(String.valueOf(ix));
iybd = new BigDecimal(String.valueOf(iy));
widthbd = new BigDecimal(String.valueOf(width));
heightbd = new BigDecimal(String.valueOf(height));
x = new BigDecimal("0").setScale(scale, round);
y = new BigDecimal("0").setScale(scale, round);
xc = ixbd.subtract(widthbd.divide(two));
xc = xc.multiply(zoombd);
xc = xc.add(offSetXbd);
yc = iybd.subtract(heightbd.divide(two));
yc = yc.multiply(zoombd);
yc = yc.add(offSetYbd);
for (int iter = 0; iter < maxIter; iter++) {
temp1 = x.multiply(x).setScale(scale, round);
temp1 = temp1.add(y.multiply(y)).setScale(scale, round);
if (temp1.compareTo(four) == -1) {
temp2 = x.multiply(x).setScale(scale, round).subtract(y.multiply(y).setScale(scale, round)).setScale(scale, round).add(xc).setScale(scale, round);
y = two.multiply(x).setScale(scale, round).multiply(y).setScale(scale, round).add(yc).setScale(scale, round);
x = temp2.setScale(scale, round);
}else{
list.add(new Tuple3Int(ix, iy, iter));
break;
}
}
}
}
System.out.println("Done!");
return list;
}
}
With the scale set to 32 it should be twice as accurate as a double but it pixelates at the EXACT same point. Even when I change the scale to anywhere from 16 to 64 it makes NO DIFFERENCE.
I am completely stumped.
I can't run the code without scaling the BigDecimals because it takes far too long to compute the set.
I think I must have a bottleneck somewhere that is stopping me from seeing the benefits from using BigDeciomal but I can't find it.
Thank you in advance for any of your suggestions,
James
For those who are interested, you can download the latest version of my Mandelbrot Set generator here:
https://mega.co.nz/#!iIVimQaY!KPIMO84fkjWUm8ZLvbNp8lsBd5Mi1B6abo4GKEofooc (https://mega.co.nz/#!iIVimQaY!KPIMO84fkjWUm8ZLvbNp8lsBd5Mi1B6abo4GKEofooc).
Please let me know what you think so far!
(This version is using doubles.)
I honestly have no idea how, but I've fixed it! :D
I was messing around, trying to debug it when it just worked all of a sudden.
I can now render the Mandelbrot Set as deep as I am willing to wait for.
Here is the latest version, if you're interested:
https://mega.co.nz/#!GUNw1RTR!Fa2m2nIFJcBpsW_oUWGRTgtYJD-h1zbYRUOjJGngqew (https://mega.co.nz/#!GUNw1RTR!Fa2m2nIFJcBpsW_oUWGRTgtYJD-h1zbYRUOjJGngqew)
I will leave the thread open, feedback welcome!
James