public class OneFern extends JFrame
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: