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();
}