## Mandelbrot Set in Java with Iceberg Charts

The Mandelbrot Set is one of the most famous images in all of mathematics. It is a set of complex numbers which do not escape when applied to a simple methematical formula. You can read more about it on Wikipedia.

To write this in Java it is basically the algorithm, where each x and y value is checked against the simple formula **x^2 + y^2 < c**. (where c in our case is 5) .

while (x * x + y * y < 5 && iterations < max) {

double x_new = x * x – y * y + c_re;

y = 2 * x * y + c_im;

x = x_new;

iterations++;

}

We have a max iteration, where we consider that if the equation still hasn’t been fulfilled at the max iteration then the point will remain bounded. If it stays bounded then we consider it part of the set, and we add it to our chart set :

1 2 |
XYDataSeries series = new XYDataSeries( new UIPointSquare(Color.GRAY, 1), null, ""); |

Out XYDataSeries is just a an XY series of one pixel square, with no line connectors. All we are doing is plotting out all these values once we have finished going through the iteration.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
ArrayList values = new ArrayList(); int width = 1000, height = 1000, max = 1000; double factor = 5.0; for (int y_pos = 0; y_pos < height; y_pos++) { for (int x_pos = 0; x_pos < width; x_pos++) { double c_re = (x_pos - width / 2) * factor/ width; double c_im = (y_pos - height / 2) * factor / width; double x = 0; double y = 0; int iterations = 0; /** * Check how far x_pos, y_pos, whether it escapes, or is bounded to some degree */ while (x * x + y * y < factor && iterations < max) { double x_new = x * x - y * y + c_re; y = 2 * x * y + c_im; x = x_new; iterations++; } if (iterations < max) values.add(new DataPoint(x_pos, y_pos)); } } XYDataSeries series = new XYDataSeries( new UIPointSquare(Color.GRAY, 1), null, ""); series.dataPoints = values; XYChart chart = new XYChart("", "", "", series); chart.setSize(1000, 500); chart.rightOffset = 200; chart.setTitleFont(new Font("Ariel", Font.PLAIN, 24)); chart.setTitle("Maths"); |

This creates a chart that looks like this :

That looks pretty simple and straight forward. What if we want to do colors as well? If we assign a different color to an iteration that escapes after a particular number of iterations we can get some pretty cool shading. Eg. if our iteration escapes after only 5 iterations we could have a light red, and if it escapes after 999 iterations then we could use a dark red.

The following code creates a number of XY data series based on the number of possible iterations. For each iterations a different color is used.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
int max = 100; int height = 1000; int width = 1000; int[] colors = new int[max]; HashMap<Integer, XYDataSeries> map = new HashMap<Integer, XYDataSeries>(); for (int i = 0; i < max; i++) { Color color = new Color(Color.HSBtoRGB(i / 256f, 1, i / (i + 8f))); XYDataSeries series = new XYDataSeries(new UIPointSquare(color, 1), null, ""); series.dataPoints = new ArrayList(); map.put(i, series); } XYDataSeries series = new XYDataSeries( new UIPointSquare(Color.BLACK, 1), null, ""); series.dataPoints = new ArrayList(); map.put(0, series); ArrayList values = new ArrayList(); /** * Analyse every pixel along X and Y */ for (int y_pos = 0; y_pos < height; y_pos++) { for (int x_pos = 0; x_pos < width; x_pos++) { double c_re = (x_pos - width / 2) * 5.0 / width; double c_im = (y_pos - height / 2) * 5.0 / width; double x = 0, y = 0; int iterations = 0; /** * Check how far x_pos, y_pos, whether it escapes, or is bounded to some degree */ while (x * x + y * y < 5 && iterations < max) { double x_new = x * x - y * y + c_re; y = 2 * x * y + c_im; x = x_new; iterations++; } if (iterations < max) { XYDataSeries ser = map.get(iterations); ser.dataPoints.add(new DataPoint(x_pos, y_pos)); } } } for (int i = 0; i < max; i++) { XYDataSeries d = map.get(i); if (d.dataPoints.size() == 0) { map.remove(i); } } ArrayList al = new ArrayList(map.values()); XYChart chart = new XYChart("Maths is Fun!!", "Real Axis", "Complex Axis", al); System.out.println("point number " + values.size()); chart.setSize(1000, 500); chart.rightOffset = 200; chart.setTitleFont(new Font("Ariel", Font.PLAIN, 24)); chart.setTitle("Maths is Fun!"); |

This produces a colorful and beautiful chart that looks like this :

Pretty cool, huh?

These two examples can be found in the Iceberg Charts Project as TestDataXY_Mandelbrot1.java and TestDataXY_Mandelbrot2.java.