import objectdraw.*; import java.awt.*; /** * A recursive broccoli object that gradually grows. */ public class GrowingBroccoli extends ActiveObject { // pause between each growth of the broccoli private static final int PAUSE_TIME = 25; // dark green color for broccoli private static final Color BROCCOLI_COLOR = new Color(0, 135, 0); // diameter of broccoli bud private static final int BUD_SIZE = 3; // determines the angle between adjacent branches private static final double BRANCH_ANGLE_INC = Math.PI / 9.0; // Below this size draw flower private static final double SMALLEST_BRANCH_SIZE = 25.0; // How much broccoli shrinks each call private final static double SHRINK_FACTOR = 0.75; // stem of broccoli private AngLine stem; // branches of broccoli private GrowingBroccoli left, center, right; // canvas to draw objects private DrawingCanvas canvas; // size of stem private double size; // angle of stem with positive x-axis private double direction; // the amount of growth at each step of the animation private double xStep, yStep; // Draw broccoli by recursively drawing branches (and flower) public GrowingBroccoli(Location startLocation, double size, double direction, DrawingCanvas canvas) { this.size = size; this.direction = direction; this.canvas = canvas; // draw initial stem (of starting length 1) stem = new AngLine(startLocation, 1, direction, canvas); stem.setColor(BROCCOLI_COLOR); // calculate the x and y steps for each step of the animation Location start = stem.getStart(); Location end = stem.getEnd(); xStep = end.getX() - start.getX(); yStep = end.getY() - start.getY(); start(); } // recursively draw new BroccoliBranches or flowers according to the length // of the current branch public void run() { Location stemStart = stem.getStart(); while (stemStart.distanceTo(stem.getEnd()) < size) { // grow the stem Location curEnd = stem.getEnd(); Location newEnd = new Location(curEnd.getX() + xStep, curEnd.getY() + yStep); stem.setEnd(newEnd); pause(PAUSE_TIME); } Location stemEnd = stem.getEnd(); if (size > SMALLEST_BRANCH_SIZE) { // draw more branches left = new GrowingBroccoli(stemEnd, size * SHRINK_FACTOR, direction + BRANCH_ANGLE_INC, canvas); center = new GrowingBroccoli(stemEnd, size * SHRINK_FACTOR, direction, canvas); right = new GrowingBroccoli(stemEnd, size * SHRINK_FACTOR, direction - BRANCH_ANGLE_INC, canvas); } else { // broccoli 'leaf', draw a yellow bud FilledOval bud = new FilledOval(stemEnd, BUD_SIZE, BUD_SIZE, canvas); bud.setColor(Color.YELLOW); } } }