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 SIZE_SMALLEST_BRANCH = 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 leftBranch, centerBranch, rightBranch; // canvas to draw objects private DrawingCanvas canvas; // size of stem private double stemLength; // angle of stem with positive x-axis private double stemAngle; // Draw broccoli by recursively drawing branches (and flower) public GrowingBroccoli(Location startLocation, double stemLength, double stemAngle, DrawingCanvas canvas) { this.stemLength = stemLength; this.stemAngle = stemAngle; this.canvas = canvas; // draw initial stem (of starting length 1) stem = new AngLine(startLocation, 1, stemAngle, canvas); stem.setColor(BROCCOLI_COLOR); start(); } // recursively draw new BroccoliBranches or flowers according to the length // of the current branch public void run() { // calculate the x and y steps for each step of the animation Location start = stem.getStart(); Location end = stem.getEnd(); double xStep = end.getX() - start.getX(); double yStep = end.getY() - start.getY(); while (start.distanceTo(stem.getEnd()) < stemLength) { // grow the stem Location curEnd = stem.getEnd(); Location newEnd = new Location(curEnd.getX() + xStep, curEnd.getY() + yStep); stem.setEnd(newEnd); pause(PAUSE_TIME); } if (stemLength > SIZE_SMALLEST_BRANCH) { // draw more branches leftBranch = new GrowingBroccoli(stem.getEnd(), stemLength * SHRINK_FACTOR, stemAngle + BRANCH_ANGLE_INC, canvas); centerBranch = new GrowingBroccoli(stem.getEnd(), stemLength * SHRINK_FACTOR, stemAngle, canvas); rightBranch = new GrowingBroccoli(stem.getEnd(), stemLength * SHRINK_FACTOR, stemAngle - BRANCH_ANGLE_INC, canvas); } else { // broccoli 'leaf', draw a yellow bud FilledOval bud = new FilledOval(stem.getEnd(), BUD_SIZE, BUD_SIZE, canvas); bud.setColor(Color.YELLOW); } } }