Banach分形曲线Java-递归

时间:2018-12-12 11:34:47

标签: java recursion curve fractals

我有以下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() 准则:

  • 仅递归解决方案,不允许循环
  • 没有导入,也没有列表(因此也没有地图),也没有?
  • 我只能使用功能public static void banachCurve(int n)和帮助功能private static void banachCurve(double x, double y, double r, int n)
    • 只能使用StdDraw绘制或调用其他函数,不允许使用其他Std类

我考虑到每次添加圆,因为每次应该在边缘分别有9个,在中心有1个,但是我似乎只能使圆在右边或左边,并且由于某种原因会出现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 Banach曲线的阶段: Stages of Banach Curve

2 个答案:

答案 0 :(得分:2)

每次调用n--时,都是将n传递给该函数,然后将其递减一个,以进行下一次调用。相反,您需要将n - 1传递给每个调用,因为该调用本身将在其自己的递归调用中进一步使n递减,最终如您所愿地在0处停止。

对于四个基点,使用(x + d, y)(x, y + d)(x - d, y)(x, y - d)可以正常工作,但是对于四个对角点,您将需要使用毕达哥拉斯(Pythagoras)方法的平方根(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);的输出:

Banach Curve for recursion depth of 6.

答案 1 :(得分:1)

如果您要将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);的输出

enter image description here

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

enter image description here

尽管我不能说它是对原始设计的改进。尽管有七个周围的圈子,在给出这种代码设计的情况下,仍然是微不足道的测试,却引起了人们的注意:

enter image description here