Computer Science 252
Problem Solving with Java
Spring 2016, The College of Saint Rose
Broccoli BlueJ Project
Click here to download a BlueJ project for Broccoli.
Broccoli Source Code
The Java source code for Broccoli is below. Click on a file name to download it.
/** * Program to create a recursive graphics which looks like broccoli. * Written 11/4/99 by Kim Bruce * Modified 4/20/00 by Andrea Danyluk * * Updated by Jim Teresco for CSC 252, The College of Saint Rose, Fall 2013 * Code cleanup, Spring 2016 * * $Id: Broccoli.java 2924 2016-03-31 00:40:33Z terescoj $ */ import objectdraw.*; import java.awt.*; public class Broccoli extends WindowController { // some named constants for the first broccoli part private static final double STEM_X = 200; private static final double STEM_Y = 350; private static final double STEM_LENGTH = 80; // dragging support private Location lastLocation; private boolean dragging; // Broccoli object to be drawn and moved private BroccoliBranch plant; // In begin, we just create the broccoli public void begin() { plant = new BroccoliBranch(new Location(STEM_X,STEM_Y), STEM_LENGTH, Math.PI/2.0, canvas); } // Get ready to move broccoli public void onMousePress(Location pt) { dragging = plant.contains(pt); lastLocation = pt; } // Drag the broccoli around public void onMouseDrag(Location pt) { if (dragging) { plant.move(pt.getX()-lastLocation.getX(), pt.getY()-lastLocation.getY()); lastLocation = pt; } } }
/* * AngLine.java Jonathan Kallay 7/14/99 * (c) 1999 Williams College */ import java.awt.*; import objectdraw.*; /** * AngLine is an implementation of a drawable line object. * * @author Jonathan Kallay * @version 1.0 last update 8/25/99 * * Updated by Jim Teresco for CSC 252, The College of Saint Rose, Fall 2013 * * $Id: AngLine.java 2244 2013-11-06 04:54:22Z terescoj $ */ public class AngLine extends Line implements LineInterface { private double length; private double angle; /** * Creates a new AngLine object. * @param start the starting point of the line. * @param dest the destination point of the line. * @param c the canvas in which the line is created. */ public AngLine(Location start, double length, double radianAngle, DrawingCanvas canvas){ super(start,new Location(start.getX() + length*Math.cos(radianAngle), start.getY() - length*Math.sin(radianAngle)),canvas); this.length = length; angle = radianAngle; } public Location getDest() { return new Location(start.getX() + length*Math.cos(angle), start.getY() - length*Math.sin(angle)); } }
/* * Class to recursively draw broccoli * * From Williams College, CSC 134 * * Updated by Jim Teresco for CSC 252, The College of Saint Rose, Fall 2013 * Code cleanup, Spring 2016 * * $Id: BroccoliBranch.java 2924 2016-03-31 00:40:33Z terescoj $ */ import objectdraw.*; import java.awt.*; public class BroccoliBranch { // How much broccoli shrinks each call private static final double TOP_FRACT = 0.8; // How little a branch must be before broccoli stops expanding private static final double GROWTH_LIMIT = 20.0; // The size (width and height) of a flower private static final int FLOWER_SIZE = 3; // branches of broccoli: our recursive data structure // note that in this case this not one "next", but three! // these will be null if we are at the base case private BroccoliBranch left, center, right; // stem of broccoli-- every BroccoliBranch has one private AngLine stem; // Flower of broccoli plant, null except in base case (and that's how we'll tell) private FilledOval flower; /** * Draw broccoli by recursively drawing branches (and eventually flower) */ public BroccoliBranch(Location startLocation, double size, double direction, DrawingCanvas canvas) { // Draw stem and color green (we always have this) stem = new AngLine(startLocation,size,direction,canvas); stem.setColor(Color.green); Location destLocation = stem.getDest(); // end of stem if (size > GROWTH_LIMIT) { // we're big enough to keep growing left = new BroccoliBranch(destLocation, size * TOP_FRACT, direction + Math.PI/9.0, canvas); center = new BroccoliBranch(destLocation, size * TOP_FRACT, direction, canvas); right = new BroccoliBranch(destLocation, size * TOP_FRACT, direction - Math.PI/9.0, canvas); } else { // draw flower when small enough -- note this will be null except // in the base case, and will be used to determine the base for // recursive methods flower = new FilledOval(destLocation,FLOWER_SIZE,FLOWER_SIZE,canvas); flower.setColor(Color.yellow); } } // standard move method, but this one's recursive public void move(double x, double y) { stem.move(x,y); // move stem in all cases if (flower == null) { // not the base case, so move rest of broccoli - three branches left.move(x,y); center.move(x,y); right.move(x,y); } else { // move flower only, it's the base case flower.move(x,y); } } // contains, also needs recursion here public boolean contains(Location point) { // first, check stem, since we always know we have one if (stem.contains(point)) return true; // ok, stem didn't contain the point, so we keep checking // do base case next: if flower is not null, it's the only hope we // have to contain the point, so it would be our answer if (flower != null) { return flower.contains(point); } // we must be in a recursive case, so we need to try all three branches return left.contains(point) || center.contains(point) || right.contains(point); } }
import objectdraw.*; /* * Interface for objects that have an endpoint * * Updated by Jim Teresco for CSC 252, The College of Saint Rose, Fall 2013 * * $Id: LineInterface.java 2924 2016-03-31 00:40:33Z terescoj $ */ public interface LineInterface { // Return endpoint public Location getDest(); }