0

我有一个 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);
    }
  } 
}

编辑作为现在的后续行动......当我将 Thread.sleep() 添加到它时,它会笨拙地绘制它,因为这就是递归绘制它的方式。是否可以强制它从“树干”向上绘制,以便模拟实际的树“生长”?

4

3 回答 3

1

要使其正常工作,您可能需要使用双缓冲。本质上,您在屏幕外缓冲区上绘制并在绘制完成后将其刷新到屏幕上。

在您的 drawFractalTree() 方法中,您必须添加一个 Thread.sleep() 调用来延迟绘图。在 g2d.drawLine(x1, y1, x2, y2); 之后直接添加这个 应该做的伎俩。它最终可能会非常缓慢。为了抑制这种情况,您可以使用计数器并在每 10 次调用后休眠 1 毫秒。

于 2013-03-28T13:25:12.750 回答
0

要开始看到一些动画,请在 drawFractalTree() 的开头添加一个 Thread.sleep(100) 调用。

于 2013-03-28T13:30:16.510 回答
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);
    }
   } 
}
于 2014-02-10T22:08:56.717 回答