views:

73

answers:

2

I wrote an implementation of the Mandelbrot set in Java using a JComponent but I'm getting strange results when I render it. Besides that everything compiles right. I'm just not for sure what I'm doing wrong with it. Any code review also would be appreciated.

My source is posted on pastebin since it would take up too much room here:

JMandelbrot.java Mandelbrat.java

+1  A: 
  • You're drawing the fractal correctly, but it's really small. The entire Mandelbrot set fits in a circle of radius 2, so it barely covers a few pixels in the middle of your 400x500 window.

    You should devise some kind of mapping from the screen window (which goes from (0,0) to (width,height)) to the complex plane, which should have values in the neighborhood of -2-2i to 2+2i or so. A quick fix would be to divide the x-h and k-y expressions by 100 before passing them to renderPoint, and changing the arguments of renderPoint from int to double. Best would be to specify the desired viewing rectangle and use that to determine the mapping.

  • You are computing the fractal image in the GUI thread. This is a no-no, as the application will appear to hang before the window is finished opening. I would change the invocation of render() in the constructor to look like this:

    new Thread() {
      public void run() { render(); }
    }.start();
    
jleedev
+1 for suggesting to use a separate thread. But in this situation, a `repaint()` must be requested after `render()` finishes, or else the computed image is not displayed: `public void run() { render(); repaint(); }`
Christian Semrau
Yes, although I would put the repaint after each row finishes.
jleedev
+3  A: 

Problem:

  • The image is as I expect from the code. The Mandelbrot set has a diameter of 2, so you only see some pixels in the middle.

Solution:

  • Change the renderPoint method to accept double arguments and call it as renderPoint((x - h)/100.0, (k - y)/100.0) to see something more interesting.
  • Change the iteration count and color coding, because now you are computing 255^3 iterations for each inner pixel. I managed to see something nice by changing the return of renderPoint to return (((r << 16) | (g << 8) | b)<<4) and setting MaxColorBit = 16.

A code review:

  • (int)Math.floor(Width / 2) can be replaced by Width / 2, because that is an integer division.
  • You should start your attributes Width and Height with small letters (width and height), because that is a Java convention which helps differentiate classes and attributes.
  • The iterations attribute is not used.
Christian Semrau
Thank you very much. However, can you explain the extra shift by 4 in the return line?
SDLFunTimes
That was my quick-and-dirty color coding hack, because else the image would be too dark to see (try it). The usual color coding is as follows: Compute the iterations until the stop condition holds or a predefined iteration count is reached. You come out with the number of iterations actually performed. That number is used as index into a color table (a "palette"). The palette usually contains one or more smooth gradients of colors. See http://commons.wikimedia.org/wiki/File:Mandelbrot_palette_colour_editing_with_Fractint.png for an example.
Christian Semrau