Банах Фрактальная кривая Ява - Рекурсивный - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть следующая проблема Банаховых фракталов: Так называемая Банахова кривая может быть сгенерирована с использованием следующего правила фрактала:

  1. Нарисуйте круг.каждый с радиусом ⅓ первоначального круга.Один из меньших кругов должен иметь тот же центр, что и исходный круг.Центры оставшихся 8 меньших кругов должны быть равномерно распределены по окружности исходного круга.
  2. Повторите шаг b для каждого из меньших кругов.

Примечание: круградиус r с центром в точке (x, y) - это множество всех точек (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 этапов кривой Банаха: Stages of Banach Curve

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Если вы собираетесь перетащить 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

0 голосов
/ 12 декабря 2018

Каждый раз, когда вы вызываете n--, вы передаете n функции и затем уменьшаете ее на единицу для следующего вызова.Вместо этого вам нужно передать n - 1 каждому вызову, так как сам вызов будет уменьшаться на n дальше в своем собственном рекурсивном вызове, в конечном итоге останавливаясь на 0, как вы правильно сделали.

Для четырех кардиналовТочки, используя (x + d, y), (x, y + d), (x - d, y) и (x, y - d), работают правильно, но для четырех диагональных точек вам нужно будет использовать либо квадратный корень (Math.sqrt) для метода Пифагора, либо синуси косинус (Math.sin и Math.cos) для тригонометрического метода.Использование (x + d, y + d) и т. П. Вместо этого поместит их в квадрат.

Если предположить, что x и y отмечают центр вашего круга, ваша функция станет:

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.

...