Source of OneFern.java


  1: 
  2: import java.util.Scanner;
  3: import java.awt.*;
  4: import javax.swing.*;
  5: 
  6: /**
  7:  * A collection of methods for drawing ferns.
  8:  *
  9:  * @author Mark Young
 10:  * @version 1.0
 11:  */
 12: public class OneFern extends JFrame {
 13: 
 14:     // ---------- Here is the program part -------------------------------- //
 15: 
 16:     // here is the program -- the class is below
 17:     public static void main(String[] args) {
 18:         OneFern win = new OneFern(600, 600, 300, 600, 180, 600);
 19:         win.setVisible(true);
 20:     }
 21: 
 22:     // ---------- below is the class -------------------------------------- //
 23: 
 24:     /** the part of the window we draw in */
 25:     private Graphics canvas;
 26:     /** the x-coordinate of the fern's root */
 27:     private double rootX;
 28:     /** the y-coordinate of the fern's root */
 29:     private double rootY;
 30:     /** the angle the fern grows away from its root (180 = straight up) */
 31:     private double rootAngle;
 32:     /** the root-to-tip length of the fern (it'll actually be a bit shorter) */
 33:     private double fullSize;
 34: 
 35:     /**
 36:      * Create a window for a fern to be drawn in.
 37:      *
 38:      * @param w     the outer width of the window
 39:      * @param h     the outer height of the window
 40:      * @param x     the x-coordinate of the fern's root
 41:      * @param y     the y-coordinate of the fern's root
 42:      * @param a     the angle the fern grows from its root
 43:      * @param s     the nominal size of the fern
 44:      */
 45:     public OneFern(int w, int h, double x, double y, double a, double s) {
 46:         super("A Fern by MYoung");
 47:         setSize(w, h);
 48:         setBackground(Color.BLACK);
 49:         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 50:         rootX = x;
 51:         rootY = y;
 52:         rootAngle = a;
 53:         fullSize = s;
 54:     }
 55: 
 56:     /**
 57:      * Respond to the computer's request to paint the window.
 58:      * This method called by the computer when the window gets shown.
 59:      *
 60:      * @param g     the canvas to draw on -- provided by the computer.
 61:      */
 62:     public void paint(Graphics g) {
 63:         // use the canvas the computer provides
 64:         canvas = g;
 65: 
 66:         // choose a darkish green pen
 67:         canvas.setColor(new Color(0, 127, 0));
 68: 
 69:         // draw the fern
 70:         drawFern(rootX, rootY, rootAngle, fullSize);
 71:     }
 72: 
 73:     /**
 74:      * Draw a fern on my own canvas.
 75:      * This is a recursive method. You should understand how it works.
 76:      *
 77:      * @param x     the x-coordinate of the fern's root
 78:      * @param y     the y-coordinate of the fern's root
 79:      * @param angle the angle the fern grows from its root
 80:      * @param size  the nominal size of the fern
 81:      */
 82:     public void drawFern(double x, double y, double angle, double size) {
 83:         // draw the stem and note where it ends
 84:         double length = size * 0.5;
 85:         double[] end = drawStem(x, y, angle, length);
 86: 
 87:         // if the fern is big...
 88:         if (size > 1.0) {
 89:             // ...draw smaller ferns for the fronds
 90:             double smaller = size * 0.4;
 91:             drawFern(end[0], end[1], angle+60, smaller);
 92:             drawFern(end[0], end[1], angle, smaller);
 93:             drawFern(end[0], end[1], angle-60, smaller);
 94:         }
 95:     }
 96: 
 97:     /**
 98:      * Draw the stem of a fern, returning the coordinates of its upper end.
 99:      * (You do not need to understand how this method works.)
100:      *
101:      * @param x         the x-coordinate of the stem's root
102:      * @param y         the y-coordinate of the stem's root
103:      * @param angle     the angle the stem grows from its root
104:      * @param length    the length of the stem
105:      * @return  an array with the x and y coordinates of the stem's top
106:      *          in its two cells
107:      */
108:     public double[] drawStem(double x, double y, double angle, double length) {
109:         // convert from degrees to radians for the sin & cos functions
110:         double radians = Math.toRadians(angle);
111: 
112:         // figure out (and remember) where the line should end
113:         double[] end = new double[2];
114:         end[0] = x + Math.sin(radians) * length;
115:         end[1] = y + Math.cos(radians) * length;
116: 
117:         // draw the line
118:         drawLine(x, y, end[0], end[1]);
119: 
120:         // return the end-point
121:         return end;
122:     }
123: 
124:     /**
125:      * Draw a line on my convas.
126:      * (You do not need to understand how this method works.)
127:      *
128:      * @param x1    the x-coordinate of the start of the line
129:      * @param y1    the y-coordinate of the start of the line
130:      * @param x2    the x-coordinate of the end of the line
131:      * @param y2    the y-coordinate of the end of the line
132:      */
133:     public void drawLine(double x1, double y1, double x2, double y2) {
134:         // round off the start/end coordinates...
135:         int startX = (int)Math.round(x1);
136:         int startY = (int)Math.round(y1);
137:         int endX = (int)Math.round(x2);
138:         int endY = (int)Math.round(y2);
139: 
140:         // ... because the canvas expects to be given integer coordinates
141:         canvas.drawLine(startX, startY,  endX, endY);
142:     }
143: 
144: }
145: