Question

I have a Java program that will draw a fractal tree based on a recursive method and I want to make it appear to smoothly grow and I'm not sure how to do this.

The following is my code. This is a school assignment, just to make that known, but the basic assignment was only to draw a fractal tree, which I have already accomplished, the animation is secondary and more of a personal goal that I wish to accomplish.

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 As a follow up now...when I add the Thread.sleep() to it, it draws it awkwardly looking as that's how the recursion draws it. Would it be possible to force it to draw from the "trunk" up so it simulates an actual tree "growing"?

Était-ce utile?

La solution

To get that working, you'll probably need to use double buffering. Essentially you draw on a off-screen buffer and refresh it to the screen when the drawing is done.

In your drawFractalTree() method, you'll have to add a Thread.sleep() call to delay the drawing. Adding this directly after g2d.drawLine(x1, y1, x2, y2); should do the trick. It may end up being very slow. To curb that, you can use a counter and sleep for 1ms after every 10th call.

Autres conseils

To just start seeing some animation, add a Thread.sleep(100) call at the beginning of drawFractalTree().

Thread.sleep(100);

This works excellent if you use an image to draw from its graphics instead of drawing directly.Thus, image pixels' color will not be changed each time you draw sth on it.

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);
    }
   } 
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top