import java.awt.geom.GeneralPath; // combinations of lines and curves import java.awt.geom.AffineTransform; // translation, rotation, scale import java.awt.Shape; // general class for shapes // all imports below this line needed if you are implementing Shape import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.Line2D; import java.awt.Rectangle; import java.awt.geom.PathIterator; import java.awt.geom.AffineTransform; /** A House that implements Shape @author Phill Conrad @version for CS10, S09, UCSB, 05/06/2009 */ public class House implements Shape { private GeneralPath house; /** * Constructor for objects of class House. * * @param x upper left x * @param y upper left y * @param width width of house * @param height height of house */ public House(double x, double y, double width, double height) { // Rather than having to scale at the end, we can just // draw things the right way to begin with, using the // x, y, width and height. If you haven't already // hard coded a particular drawing, this may be an easier // way. double firstStoryHeight = .75 * height; double roofHeight = height - firstStoryHeight; double firstStoryUpperLeftY = y + roofHeight; // Make the first story Rectangle2D.Double firstStory = new Rectangle2D.Double(x, firstStoryUpperLeftY , width, firstStoryHeight); // make the roof. Remember that y goes DOWN the page, // so we ADD to y to get a "lower" value on the screen Line2D.Double leftRoof = new Line2D.Double (x, y + roofHeight, x + width/2.0, y); Line2D.Double rightRoof = new Line2D.Double (x + width/2.0, y, x + width, y + roofHeight); // put the whole house together GeneralPath wholeHouse = new GeneralPath (); wholeHouse.append(firstStory, false); wholeHouse.append(leftRoof, false); wholeHouse.append(rightRoof, false); this.house = wholeHouse; } // EVERYTHING BELOW THIS LINE IS JUST A WRAPPER AROUND // THE METHODS OF THE GENERAL PATH OBJECT. SINCE GENERAL PATH IS FINAL, // WE CAN'T INHERIT FROM IT. (OTHERWISE, THIS WOULDN'T BE NECESSARY) /** Tests if the specified coordinates are inside the boundary of the Shape. */ public boolean contains(double x, double y) { return house.contains(x,y); } /** Tests if the interior of the Shape entirely contains the * specified rectangular area. */ public boolean contains(double x, double y, double w, double h) { return house.contains(x,y,w,h); } /** Tests if a specified Point2D is inside the boundary of * the Shape. */ public boolean contains(Point2D p) { return house.contains(p); } /** Tests if the interior of the Shape entirely contains the specified Rectangle2D. */ public boolean contains(Rectangle2D r) { return house.contains(r); } /** Returns an integer Rectangle that completely encloses the * Shape. */ public Rectangle getBounds() { return house.getBounds(); } /** Returns a high precision and more accurate bounding box * of the Shape than the getBounds method. */ public Rectangle2D getBounds2D() { return house.getBounds2D(); } /** Returns an iterator object that iterates along the * Shape boundary and provides access to the geometry of * the Shape outline. */ public PathIterator getPathIterator(AffineTransform at) { return house.getPathIterator( at); } /** Returns an iterator object that iterates along the * Shape boundary and provides access to a flattened view * of the Shape outline geometry. */ public PathIterator getPathIterator(AffineTransform at, double flatness) { return house.getPathIterator( at, flatness); } /** Tests if the interior of the Shape intersects the * interior of a specified rectangular area. */ public boolean intersects(double x, double y, double w, double h) { return house.intersects(x, y, w, h); } /** Tests if the interior of the Shape intersects the interior of * a specified Rectangle2D. */ public boolean intersects(Rectangle2D r) { return intersects(r); } }