用递归算法画分形
Draw fractal with recursion algorithm
我写了下面的代码来绘制像照片一样的分形树。但是我在第二个递归方法中遇到了问题。 (用于中间分支长度控制)。我该如何改进和纠正它?
我的代码:
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);
} }}
我在这张照片中展示了我的新结果Link:
new
但是第二个分支的长度是worng.how我可以像我的第一张照片一样纠正它(目标link)
你的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);
}
}
我写了下面的代码来绘制像照片一样的分形树。但是我在第二个递归方法中遇到了问题。 (用于中间分支长度控制)。我该如何改进和纠正它?
我的代码:
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);
} }}
我在这张照片中展示了我的新结果Link: new
但是第二个分支的长度是worng.how我可以像我的第一张照片一样纠正它(目标link)
你的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);
}
}