【问题标题】:Draw fractal with recursion algorithm用递归算法绘制分形
【发布时间】:2015-11-26 19:57:43
【问题描述】:

我写下面的代码来绘制像照片一样的分形树。但是我在第二种递归方法中有问题。 (用于中间分支长度控制)。如何改进和纠正它?

我的代码:

import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;

public class FractalTree1 extends Canvas {

// fields for drawing
private final JFrame frame;
private final int WINDOW_WIDTH = 1280;
private final int WINDOW_HEIGHT = 720;

public FractalTree1() {
    frame = new JFrame("Fractal Tree");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
    frame.setLocationRelativeTo(null);
    frame.setResizable(true);
    Component add = frame.add(this);
    frame.setVisible(true);
}

public static void main(String[] args) {
    FractalTree1 ft = new FractalTree1();
    ft.setVisible(true);
    ft.setBackground(Color.black);
}

@Override
public void paint(Graphics g) {
    g.setColor(Color.green);
    drawFractalTree(g, WINDOW_WIDTH / 2, WINDOW_HEIGHT - 75, -90, 2, true);
}

public void drawFractalTree(Graphics g, int x1, int y1, double angle, int depth, boolean value) {
    if (depth == 0) {
    } else {
        int x2, y2;
        if (value) {
            x2 = x1 + (int) (Math.cos(Math.toRadians(angle)) * depth * 100.0);
            y2 = y1 + (int) (Math.sin(Math.toRadians(angle)) * depth * 100.0);
        } else {
            x2 = (int) ((x1 + (int) (Math.cos(Math.toRadians(angle)) * depth * 100.0)) * 0.3);
            y2 = (int) (y1 + (int) (Math.sin(Math.toRadians(angle)) * depth * 100.0) * 0.3);
        }

        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        g2d.setStroke(new BasicStroke(0.5f * depth));
        g2d.drawLine(x1, y1, x2, y2);

        drawFractalTree(g, x2, y2, angle + 10, depth - 1, true);
        drawFractalTree(g, x2, y2, angle - 35, depth - 1, false);
        drawFractalTree(g, x2, y2, angle - 70, depth - 1, true);
    }
}

}

我的目标照片: my target photo

我更新了代码:

import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;

public class FractalTree1 extends Canvas {

// fields for drawing
private final JFrame frame;
private final int WINDOW_WIDTH = 1280;
private final int WINDOW_HEIGHT = 720;

public FractalTree1() {
    frame = new JFrame("Fractal Tree");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
    frame.setLocationRelativeTo(null);
    frame.setResizable(true);
    Component add = frame.add(this);
    frame.setVisible(true);
}

public static void main(String[] args) {
    FractalTree1 ft = new FractalTree1();
    ft.setVisible(true);
    ft.setBackground(Color.black);
}

@Override
public void paint(Graphics g) {
    g.setColor(Color.green);
    drawFractalTree((Graphics2D) g, WINDOW_WIDTH / 2, WINDOW_HEIGHT - 75, -90, 3,100, 1.0);
}

public void drawFractalTree(Graphics2D g, int x1, int y1, double angle, int depth, double size, double factor) {
if (depth > 0) {
    int x2 = x1 + (int) (Math.cos(Math.toRadians(angle)) * depth * size * factor);
    int y2 = y1 + (int) (Math.sin(Math.toRadians(angle)) * depth * size * factor);

    g.setStroke(new BasicStroke(0.5f * depth));
    g.drawLine(x1, y1, x2, y2);

    drawFractalTree(g, x2, y2, angle + 10, depth - 1, size, 1.0);
    drawFractalTree(g, x2, y2, angle - 35, depth - 1, size, 0.3);
    drawFractalTree(g, x2, y2, angle - 70, depth - 1, size, 1.0);
} }}

我在此照片链接中展示了我的新结果: new

但是第二个分支长度已经磨损了。我如何像我的第一张照片一样纠正它(目标链接)

【问题讨论】:

  • @tobias_k 我这段代码的结果是假的 :(
  • 是的,我也猜到了。假如何?顺便说一句,您在 y2 = 行中缺少一对括号,但似乎还有更多...

标签: java swing recursion fractals


【解决方案1】:

您的else 案例中的计算是错误的:

  • y2 = ... 行中缺少一些括号
  • 您将因子0.3 应用于分支的端点,而不是其长度

试试这个:

} else {
    x2 = x1 + (int) (Math.cos(Math.toRadians(angle)) * depth * 100.0 * 0.3);
    y2 = y1 + (int) (Math.sin(Math.toRadians(angle)) * depth * 100.0 * 0.3);
}

不过,我需要对不同的尺寸和角度参数进行更多微调。

此外,您可以通过提供更多参数并将抗锯齿设置移出方法来稍微简化您的方法:

public void drawFractalTree(Graphics2D g, int x1, int y1, double angle, int depth, double size, double factor) {
    if (depth > 0) {
        int x2 = x1 + (int) (Math.cos(Math.toRadians(angle)) * depth * size * factor);
        int y2 = y1 + (int) (Math.sin(Math.toRadians(angle)) * depth * size * factor);

        g.setStroke(new BasicStroke(0.5f * depth));
        g.drawLine(x1, y1, x2, y2);

        drawFractalTree(g, x2, y2, angle + 10, depth - 1, size, 1.0);
        drawFractalTree(g, x2, y2, angle - 35, depth - 1, size, 0.3);
        drawFractalTree(g, x2, y2, angle - 70, depth - 1, size, 1.0);
    }
}

【讨论】:

  • 谢谢 :) 但我也有其他问题。如果您使用 depth=3 或 5 绘制此代码,您会看到中间分支是错误的。因为它的长度不正确(参见我的目标照片:i.stack.imgur.com/Tn2Q7.png
  • 它看起来很适合我。你确定你在括号内移动了因子,所以它只适用于长度吗?也许你应该发布一个屏幕显示它现在的样子。
  • @tobais_k 我更新了我的代码和我的问题。我也上传了新代码的结果。
  • @masoodtav 正如我所说,您必须稍微调整角度、长度和因素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 1970-01-01
  • 2011-07-28
  • 1970-01-01
相关资源
最近更新 更多