Search code examples
javarecursioncurvefractals

Banach Fractal Curve Java - Recursive


I have the following Banach Fractal problem: The so-called Banach Curve can be generated using the following fractal rule:

  1. Draw a circle.
  2. Draw 9 smaller circles, each with a radius ⅓ of the original circle. One of the smaller circles should have the same center as that of the original circle. The centers of the remaining 8 smaller circles should be equally spaced along the circumference of the original circle.
  3. Repeat step b with each of the smaller circles.

Note: The circle of radius r centered at point (x, y) is the set of all the points (x + r · cos(t), y + r · sin(t)) where 0 ≤ t ≤ 2π , and t is given in radians. I can use Math.toRadians() Guidelines:

  • Only recursive solutions, no loops allowed
  • No imports & no lists (so no map or so) & no ?
  • I can only use the functions public static void banachCurve(int n) and help functions private static void banachCurve(double x, double y, double r, int n)
    • Can only use StdDraw to draw or call other functions from it, no other Std classes are allowed

I thought of adding circles each time since there are supposed to be 9 at the edges and 1 in the center each time, however I can only seem to get the circles on the right or left, and for some reason a RuntimeError.

public static void banachCurve(int n) {

        banachCurve (0.5,0.5,1,n);
    }

    private static void banachCurve(double x, double y, double r, int n) {
       if (n == 0) {
           return;
       }
       double d = (r/3);
       StdDraw.circle (x,y,d);
//       StdDraw.ellipse(x, y, r, r);
       banachCurve (x + d, y, d, n - 1); // centre
       banachCurve (x + d+ d, y+d, d, n--); // left
       banachCurve (x , y + d, d, n--); // right
       banachCurve (x+d , y +d+ d, d, n--);
        banachCurve (x+d , y +d, d, n--);

    }

my output: my output stages of Banach Curve: Stages of Banach Curve


Solution

  • Every time you call n--, you are passing n to the function and then decrementing it by one for the next call. Instead, you need to pass n - 1 to each call, as the call itself will decrement n further in its own recursive call, eventually stopping at 0 as you correctly have.

    For the four cardinal points, using (x + d, y), (x, y + d), (x - d, y) and (x, y - d) works correctly, but for the four diagonal points, you will need to use either the square root (Math.sqrt) for the Pythagoras method, or the sine and cosine (Math.sin and Math.cos) for the trigonometric method. Using (x + d, y + d) and the like would place them on a square instead.

    Assuming that x and y mark the centre of your circle, your function will then become:

    private static void banachCurve(final double x, final double y, final double r, final int n) {
        if (n == 0) {
            return;
        }
        final double d = r / 3;
        StdDraw.circle (x, y, d);
        banachCurve (x, y, d, n - 1);     // centre
        banachCurve (x, y + d, d, n - 1); // north
        banachCurve (x + d, y, d, n - 1); // east
        banachCurve (x, y - d, d, n - 1); // south
        banachCurve (x - d, y, d, n - 1); // west
        // Get the diagonal radius for a point at 45 degrees on the circle
        final double diagD = Math.cos(Math.toRadians(45)) * d;
        banachCurve (x + diagD, y + diagD, d, n - 1); // north-east
        banachCurve (x + diagD, y - diagD, d, n - 1); // south-east
        banachCurve (x - diagD, y - diagD, d, n - 1); // south-west
        banachCurve (x - diagD, y + diagD, d, n - 1); // north-west
    }
    

    Here is the output for banachCurve(0.5, 0.5, 1, 6);:

    Banach Curve for recursion depth of 6.