我有一个Java程序,它将基于递归方法绘制分形树,我想让它看起来平滑增长,我不知道如何做到这一点。
以下是我的代码。这是一个学校作业,只是为了让它成为现实,但基本的任务只是绘制一个分形树,我已经完成了,动画是次要的,更多的是我希望完成的个人目标。
package Question4;
import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
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 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);
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, 11);
}
public void drawFractalTree(Graphics g, int x1, int y1, double angle, int depth) {
if (depth == 0) {
} else {
int x2 = x1 + (int) (Math.cos(Math.toRadians(angle)) * depth * 10.0);
int y2 = y1 + (int) (Math.sin(Math.toRadians(angle)) * depth * 10.0);
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 + 30, depth - 1);
drawFractalTree(g, x2, y2, angle - 30, depth - 1);
}
}
}
EDIT 现在作为一个跟进...当我向它添加Thread.sleep()时,它会尴尬地看起来就像递归绘制它一样。是否可以强制它从" trunk"因此,它模拟了一棵真正的树"成长"?
答案 0 :(得分:1)
要实现这一点,您可能需要使用double buffering。基本上,你绘制一个离屏缓冲区,并在绘图完成后将其刷新到屏幕上。
在drawFractalTree()方法中,您必须添加Thread.sleep()调用以延迟绘图。在g2d.drawLine(x1,y1,x2,y2)之后直接添加;应该做的伎俩。它最终可能会非常缓慢。为了抑制这种情况,您可以使用计数器并在每10次通话后休眠1ms。
答案 1 :(得分:0)
要开始看一些动画,请在drawFractalTree()的开头添加一个Thread.sleep(100)调用。
答案 2 :(得分:0)
Thread.sleep(100);
如果您使用图像从图形中进行绘制而不是直接绘制,则效果非常好。因此,每次绘制图像像素的颜色都不会改变。
package Question4;
import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
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 JFrame frame;
private final int WINDOW_WIDTH = 1280;
private final int WINDOW_HEIGHT = 720;
private Image buffer = createImage(WINDOW_WIDTH,WINDOW_HEIGHT);
private Graphics bufferg = buffer.getGraphics();
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);
frame.add(this);
frame.setVisible(true);
}
public static void main(String[] args) {
FractalTree1 ft = new FractalTree1();
ft.setVisible(true);
ft.setBackground(Color.black);
bufferg.setColor(Color.green);
}
@Override
public void paint(Graphics g) {
g.drawImage(buffer,0,0,null);
drawFractalTree(g, WINDOW_WIDTH / 2, WINDOW_HEIGHT - 75, -90, 11);
}
public void drawFractalTree(Graphics g, int x1, int y1, double angle, int depth) {
if (depth == 0) {
} else {
Thread.sleep(100);//It has a catch exception here;
int x2 = x1 + (int) (Math.cos(Math.toRadians(angle)) * depth * 10.0);
int y2 = y1 + (int) (Math.sin(Math.toRadians(angle)) * depth * 10.0);
Graphics2D g2d = (Graphics2D) bufferg;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(0.5f * depth));
g2d.drawLine(x1, y1, x2, y2);
repaint();
drawFractalTree(g, x2, y2, angle + 30, depth - 1);
drawFractalTree(g, x2, y2, angle - 30, depth - 1);
}
}
}