Banach 分形曲线 Java - 递归

Banach Fractal Curve Java - Recursive

我有以下 Banach 分形问题: 可以使用以下分形规则生成所谓的 Banach 曲线:

  1. 画一个圆。
  2. 绘制 9 个小圆,每个圆的半径为原圆的⅓ 圆圈。其中一个较小的圆圈应与原始圆圈具有相同的中心。其余的中心 8 个较小的圆应沿原圆的圆周等距分布。
  3. 对每个较小的圆圈重复步骤 b。

注:以点(x,y)为圆心的半径为r的圆是所有点的集合 (x + r · cos(t), y + r · sin(t)) 其中 0 ≤ t ≤ 2π ,t 以弧度表示。我可以使用 Math.toRadians() 准则:

我想每次都添加圆圈,因为每次应该在边缘有 9 个,在中心有 1 个,但是我似乎只能在右边或左边得到圆圈,并且由于某种原因运行时错误。

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--);

    }

我的输出: 巴拿赫曲线的阶段:

每次调用 n-- 时,都会将 n 传递给该函数,然后在下次调用时将其递减 1。相反,您需要将 n - 1 传递给每个调用,因为调用本身将在其自己的递归调用中进一步递减 n,最终如您正确的那样停止在 0

对于四个基点,使用(x + d, y)(x, y + d)(x - d, y)(x, y - d)可以正常工作,但是对于四个对角点,您将需要使用毕达哥拉斯方法的平方根 (Math.sqrt) 或三角函数方法的正弦和余弦 (Math.sinMath.cos)。使用 (x + d, y + d) 等会将它们放在正方形上。

假设 xy 标记了你的圆心,那么你的函数将变为:

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
}

这是 banachCurve(0.5, 0.5, 1, 6); 的输出:

如果你要将 Math.cos() 拖到图片中,就像当前接受的答案一样,为什么不全力以赴并使用正弦和余弦绕圆移动:

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);

    banachCurve (x, y, d, n - 1); // center

    for (double angle = 0; angle < 360; angle += 45) {
        double theta = Math.toRadians(angle);
        double dx = x + d * Math.cos(theta);
        double dy = y + d * Math.sin(theta);

        banachCurve (dx, dy, d, n - 1);
    }
}

banachCurve(0.5, 0.5, 1, 3);

的输出

这种方法可以很容易地测试@tucuxi 的建议,即六个而不是八个周围的圆圈。只需将 for 循环中的增量角度从 45 增加到 60:

虽然我不能说这是对原始设计的改进。尽管有七个环绕的圆圈,但鉴于此代码设计,再次测试起来微不足道,但引人注目: