HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Mandelbrot Streams

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
streamsmandelbrotstackoverflow

Problem

A recent Mandelbrot question (Hi @EBrown) in C# inspired me to build my own using the Java 8 parallel streams to implement the parallelism that's useful for computing each pixel value.

The intention is to incorporate this in to a graphical interface that allows you to navigate and zoom in on the Mandelbrot set.

To do this, I separated the functionality in to three components:

  • a GUI for presenting the results



  • an engine for computing the limits for each pixel's computation



  • a tool that applies color to the results and produces an Image that the GUI can present.



In this question I have only part 2 and part 3 for review.

Note that the limit is used to limit both the number of iterations per pixel, and also to determine the number of colours used for the presentation.

When computing a view in to the set, the code works at a given zoom level, and then maps that zoomed information in to a matrix that represents the pixels in the display that show the zoomed data. This mapping is performed using a "window" that has a center, and a zoom degree. The entire Mandelbrot set is contained in the rectangle bounded by -2.5 and 1.0 on the x axis, and between -1.0 and 1.0 on the y axis.

A parallel stream is used to compute one row of pixels in each thread.

I am looking for ways to optimize this further, and identify other ways it can be improved, styled, or conform better to industry best practices.

```
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.stream.IntStream;

import javax.imageio.ImageIO;

@SuppressWarnings("javadoc")
public class Mandelbrot {

public static final class Window {
private final double centerX, centerY, zoom;

/**
* Create a window centered at the given logical location and zoom
* level.
*
* @param centerX
* The X location
* @param centerY
*

Solution

Say what you mean and mean what you say

You named your class "Window" when it should really be something more like "Viewport". There are no "Windows" (in the GUI sense) in your code. If you decide to incorporate this into an application that does contain Windows in the GUI sense, this will be hopelessly confusing.

Don't omit essential documentation from the code

Above the code, you've posted an explanation, but that isn't present in the code. If you felt the need to write it in order to explain the code to us, shouldn't it also be part of the code?

Use more descriptive comments

The algorithm for computing a point in the Mandelbrot set is ubitiquous and easily comprehensible to anybody skimming the Wikipedia page, but once you get into hard stuff (like zooming) better comments are required. Compare Ebrown's comments with yours:

// Next, consider `xCenter` and `yCenter` which represent what pixel 
// is `(0,0)` in the specified image size.
Point center = new Point(imageSize.Width / 2, imageSize.Height / 2);

// And we'll scale the size so the brot sits within [-2,2], 
SizeF scaleSize = new SizeF(center.X / 2, center.Y);


Yours:

/**
 * Create a window centered at the given logical location and zoom
 * level.
 * 
 * @param centerX
 *            The X location
 * @param centerY
 *            The Y location
 * @param zoom
 *            The zoom degree (1.0 to 1.79e308 or so)
 */


Which do you think is more indicative of what the code is actually doing?

Here's another example, you describe "limit" as the following:


Note that the limit is used to limit both the number of iterations
per pixel, and also to determine the number of colours used for the
presentation.

Then in the code:

/**
 * Compute a matrix of iterations representing a window in to the Mandelbrot set.
 * 
 * @param pixWidth The width of the matrix to compute
 * @param pixHeight The height of the matrix to compute
 * @param limit The limit at which computations assume the coordinate is included in the set.
 * @param window The definition of the location and zoom degree in to the set.
 * @return A matrix containing the computational iterations
 */


Limits, computations, Mandelbrot... we're doing something math related so you're going to confuse people into thinking you mean limit in the mathematical sense. Maybe MaxIterations is a better name.

Magic numbers

What is 1.79e308, why does it matter?

Why -2.5 + 3.5 / 2?

Why getAppropriateHeight() etc. (similarly you use 3.5 and 2.0 in mandelbrot without explanation)

Are these pixels? Complex numbers?

All Mandelbrot viewers handle zooming a different way. Don't assume yours is intuitive just because you start off with a nice number (1.0).

Code Snippets

// Next, consider `xCenter` and `yCenter` which represent what pixel 
// is `(0,0)` in the specified image size.
Point center = new Point(imageSize.Width / 2, imageSize.Height / 2);

// And we'll scale the size so the brot sits within [-2,2], 
SizeF scaleSize = new SizeF(center.X / 2, center.Y);
/**
 * Create a window centered at the given logical location and zoom
 * level.
 * 
 * @param centerX
 *            The X location
 * @param centerY
 *            The Y location
 * @param zoom
 *            The zoom degree (1.0 to 1.79e308 or so)
 */
/**
 * Compute a matrix of iterations representing a window in to the Mandelbrot set.
 * 
 * @param pixWidth The width of the matrix to compute
 * @param pixHeight The height of the matrix to compute
 * @param limit The limit at which computations assume the coordinate is included in the set.
 * @param window The definition of the location and zoom degree in to the set.
 * @return A matrix containing the computational iterations
 */

Context

StackExchange Code Review Q#104249, answer score: 12

Revisions (0)

No revisions yet.