import java.awt.*; import java.applet.*; import java.util.Vector; import java.util.Enumeration; class AboutDialog extends Dialog{ GridBagLayout gridbag; Button buttonOK; CheckboxGroup myGroup; SamplePanel fractal; MyWindow myWindow; /* layout */ public AboutDialog(MyWindow aWindow, boolean modal){ super(aWindow, modal); myWindow = aWindow; /* myWindow.dialogActive = true; */ setTitle("About Fractal"); setResizable(false); GridBagLayout gridbag = new GridBagLayout(); setLayout(gridbag); Panel panel1 = new Panel(); panel1.setLayout(gridbag); constrain(this, panel1, 0, 0, 1, 1, GridBagConstraints.NONE, GridBagConstraints.NORTHWEST, 0.0, 0.0, 10, 10, 5, 5); Panel panel2 = new Panel(); panel2.setLayout(gridbag); constrain(this, panel2, 1, 0, 1, 1, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0, 10, 10, 5, 5); Panel panelOK = new Panel(); panelOK.setLayout(gridbag); constrain(this, panelOK, 0, 1, 2, 1, GridBagConstraints.NONE, GridBagConstraints.NORTHEAST, 0.0, 0.0, 2, 2, 2, 2); buttonOK = new Button("OK"); constrain(panelOK, buttonOK, 0, 0, 1, 1); String sa = "Program by\n Richard Koch\n Mathematics Department\n"; String sb = sa + " University of Oregon\n Eugene, Oregon 97405\n"; String sc = sb + " koch@math.uoregon.edu"; MultiLineLabel line = new MultiLineLabel(sc); constrain(panel1, line, 0, 0, 1, 1); Panel graphs = new Panel(); graphs.setLayout(new BorderLayout()); Panel panelDrawLabel = new Panel(); panelDrawLabel.setLayout(new BorderLayout()); graphs.add("West", panelDrawLabel); Panel panelDraw = new Panel(); panelDraw.setLayout(new BorderLayout()); graphs.add("East", panelDraw); Label generatorLabel = new Label("Generator:"); panelDrawLabel.add("North", generatorLabel); Label fractalLabel = new Label("Fractal:"); panelDrawLabel.add("Center", fractalLabel); SamplePanel generator = new SamplePanel(true, this); panelDraw.add("North", generator); fractal = new SamplePanel(false, this); panelDraw.add("South", fractal); constrain(panel1, graphs, 0, 1, 1, 1); Panel panelCheck = new Panel(); panelCheck.setLayout(gridbag); myGroup = new CheckboxGroup(); Checkbox box1 = new Checkbox("1", myGroup, false); Checkbox box2 = new Checkbox("2", myGroup, true); Checkbox box3 = new Checkbox("3", myGroup, false); constrain(panelCheck, box1, 0, 0, 1, 1); constrain(panelCheck, box2, 1, 0, 1, 1); constrain(panelCheck, box3, 2, 0, 1, 1); constrain(panel1, panelCheck, 0, 2, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, 0.0, 0.0, 0, 0, 0, 0); TextArea infoArea = new TextArea(20, 60); infoArea.setEditable(false); String s1 = " Click on box one at the lower left of the screen, "; String s2 = s1 + "and consider \nthe resulting square. Replace each side of this "; String s3 = s2 + "square by the \n\"generator\" shown just above it. "; String s4 = s3 + "The new object can be seen by \nclicking box "; String s5 = s4 + "two. Now replace each line segment in this object by \n"; String s6 = s5 + "a suitably reduced copy of the generator. Click box three "; String s7 = s6 + "to see \nthe result.\n"; String s8 = s7 + " Imagine this process continued forever. The curve "; String s9 = s8 + "obtained in \nthe limit is called a \"fractal.\" "; String s10 = s9 + "Fractals can be constructed \nstarting with any regular "; String s11 = s10 + "polygon and any generator.\n"; String s13 = s11 + " The computer is only drawing "; String s14 = s13 + "approximations to the ultimate \nfractal. Imagine that each "; String s15 = s14 + "approximation is drawn starting at time \nzero and ending at time one; "; String s16 = s15 + "then the approximations converge \nuniformly and the limit looks "; String s17 = s16 + "almost exactly like the level six \ncurve.\n"; String s18 = s17 + " The first example of a fractal was constructed by Peano in \n1890. "; String s19 = s18 + "He created a continuous curve which passes through every \npoint of a "; String s20 = s19 + "square. Peano's generator is available in the \"choice\" \nmenu.\n"; String s21 = s20 + " Here is a proof for mathematicians that Peano's curve goes \n"; String s22 = s21 + "through every point. The fractal is continuous on [0,1], so its \nimage is "; String s23 = s22 + "compact. But this image contains a dense subset of the \nsquare. "; String s24 = s23 + "Therefore it contains the entire square.\n"; String s = s24 + remainingString(); infoArea.setText(s); constrain(panel2, infoArea, 0, 0, 1, 1, GridBagConstraints.NONE, GridBagConstraints.NORTHWEST, 0.0, 0.0, 0, 0, 0, 0); pack(); move(60, 60); show(); } public String remainingString(){ String s25 = " Many people since Peano have constructed "; String s26 = s25 + "fractals. "; String s27 = s26 + "This \nprogram can be used to construct your own examples.\n"; String s33 = s27 + " In the 1920's, Hausdorff explained how to assign a number to \nany "; String s34 = s33 + "subset A of Euclidean space; this number is now called the \n\"Hausdorff dimension\" "; String s35 = s34 + "of A. Curves have dimension one, surfaces \nhave dimension two, and so forth.\n"; String s36 = s35 + " Some unusual sets have non-integer Hausdorff dimension; they \n"; String s37 = s36 + "are called \"fractals\" by Benoit B. Mandelbrot. Our curves "; String s38 = s37 + "are \nalmost always fractals in this sense.\n"; String s39 = s38 + " In \"The Fractal Geometry of "; String s40 = s39 + "Nature\", Mandelbrot argues that \nfractals are common "; String s41 = s40 + "in nature. From his point of view, the \nobjects constructed here are "; String s42 = s41 + "only the first and most regular \nexamples of fractals.\n"; String s46 = s42 + " You may fill in the interior of a fractal. This program uses "; String s47 = s46 + "a \n\"polygon\" data structure to fill "; String s48 = s47 + "fractals. When the fractal \nbecomes complicated, there isn't room "; String s49 = s48 + "in memory for this \nstructure. That is why the program refuses to fill "; String s50 = s49 + "in some levels \nof fractals.\n"; String s51 = s50 + " According to most graphic packages, a point is outside a curve \nif it is "; String s52 = s51 + "surrounded by the curve an even number of times and \ninside "; String s53 = s52 + "if it is surrounded an odd number of times.\n"; String s54 = s53 + " Click on the fractal to increase its level. Hold down the shift \n"; String s55 = s54 + "key while clicking to decrease the level.\n"; return s55; } public void constrain(Container container, Component component, int grid_x, int grid_y, int grid_width, int grid_height, int fill, int anchor, double weight_x, double weight_y, int top, int left, int bottom, int right){ GridBagConstraints c = new GridBagConstraints(); c.gridx = grid_x; c.gridy = grid_y; c.gridwidth = grid_width; c.gridheight = grid_height; c.fill = fill; c.anchor = anchor; c.weightx = weight_x; c.weighty = weight_y; if (top + bottom + left + right > 0) c.insets = new Insets(top, left, bottom, right); ((GridBagLayout)container.getLayout()).setConstraints(component, c); container.add(component); } public void constrain(Container container, Component component, int grid_x, int grid_y, int grid_width, int grid_height){ constrain(container, component, grid_x, grid_y, grid_width, grid_height, GridBagConstraints.NONE, GridBagConstraints.NORTHWEST, 0.0, 0.0, 0, 0, 0, 0); } public void constrain(Container container, Component component, int grid_x, int grid_y, int grid_width, int grid_height, int top, int left, int bottom, int right){ constrain(container, component, grid_x, grid_y, grid_width, grid_height, GridBagConstraints.NONE, GridBagConstraints.NORTHWEST, 0.0, 0.0, top, left, bottom, right); } /* end layout */ public boolean handleEvent(Event e) { switch (e.id) { case Event.WINDOW_DESTROY: /* myWindow.dialogActive = false; */ dispose(); return true; } return super.handleEvent(e); } public boolean action(Event e, Object arg){ int newsize; if (e.target instanceof Button) { if (e.target == buttonOK) { /* myWindow.dialogActive = false; */ dispose(); } return true; } else if (e.target instanceof Checkbox) { fractal.repaint(); return true; } return false; } } class SamplePanel extends Panel{ boolean generator; AboutDialog parent; int x0, y0; int n, size; double dx, dy; double xpos, ypos; int theturns[] = {0, -90, 90, 90, 0, -90, -90, 90, 0}; public SamplePanel(boolean dogenerator, AboutDialog myparent){ super(); generator = dogenerator; parent = myparent; } public Dimension minimumSize(){ Dimension d = new Dimension(66, 66); return d; } public Dimension preferredSize(){ return minimumSize(); } public void paint(Graphics g){ Dimension r = size(); g.setColor(getBackground()); g.fillRect(0, 0, r.width, r.height); g.setColor(Color.black); if (generator) { moveto(0, 16); thickline(15, 0, g); thickline(0, 15, g); thickline(15, 0, g); thickline(0, - 30, g); thickline(15, 0, g); thickline(0, 15, g); thickline(15, 0, g); } else { xpos = 13; ypos = 53; size = 40; String which = parent.myGroup.getCurrent().getLabel(); if (which.equals("1")) { n = 1; } else if (which.equals("2")) { n = 2; } else { n = 3; } initturtle(); recursion(size,n, g, false); turn(90); recursion(size,n, g, false); turn(90); recursion(size,n, g, false); turn(90); recursion(size,n, g, false); turn(90); if (n == 2) { xpos = 13; ypos = 53; initturtle(); recursion(size, n, g, true); } } } public void moveto(int x, int y){ x0 = x; y0 = y; } public void move(int x, int y){ x0 = x0 + x; y0 = y0 + y; } public void line(int x, int y, Graphics g){ g.drawLine(x0, y0, x0 + x, y0 + y); x0 = x0 + x; y0 = y0 + y; } public void thickline(int x, int y, Graphics g){ if (x > 0) { g.drawLine(x0, y0, x0 + x + 3, y0); g.drawLine(x0, y0 + 1, x0 + x + 3, y0 + 1); g.drawLine(x0, y0 + 2, x0 + x + 3, y0 + 2); g.drawLine(x0, y0 + 3, x0 + x + 3, y0 + 3); } else if (x < 0) { g.drawLine(x0 + 3, y0, x0 + x, y0); g.drawLine(x0 + 3, y0 + 1, x0 + x, y0 + 1); g.drawLine(x0 + 3, y0 + 2, x0 + x, y0 + 2); g.drawLine(x0 + 3, y0 + 3, x0 + x, y0 + 3); } else if (y > 0) { g.drawLine(x0, y0, x0, y0 + y + 3); g.drawLine(x0 + 1, y0, x0 + 1, y0 + y + 3); g.drawLine(x0 + 2, y0, x0 + 2, y0 + y + 3); g.drawLine(x0 + 3, y0, x0 + 3, y0 + y + 3); } else { g.drawLine(x0, y0 + 3, x0, y0 + y); g.drawLine(x0 + 1, y0 + 3, x0 + 1, y0 + y); g.drawLine(x0 + 2, y0 + 3, x0 + 2, y0 + y); g.drawLine(x0 + 3, y0 + 3, x0 + 3, y0 + y); } x0 = x0 + x; y0 = y0 + y; } public void initturtle() { dx = 1; dy = 0; } public void turn(int theta){ double temp; switch(theta) { case 0: break; case 90: temp = dx; dx = dy; dy = -temp; break; case -90: temp = dx; dx = - dy; dy = temp; break; case 180: dx = - dx; dy = - dy; break; } } public void forward(double d, Graphics tempg, boolean fat) { double tempx, tempy; tempx = xpos + d * dx; tempy = ypos + d * dy; if (fat) { if (dx > 0) { tempg.drawLine((int)xpos, (int)ypos, (int)tempx, (int)tempy); tempg.drawLine((int)xpos, (int)ypos - 1, (int)tempx, (int)tempy - 1); tempg.drawLine((int)xpos, (int)ypos - 2, (int)tempx, (int)tempy - 2); } else if (dx < 0) { tempg.drawLine((int)xpos, (int)ypos, (int)tempx, (int)tempy); tempg.drawLine((int)xpos, (int)ypos - 1, (int)tempx, (int)tempy - 1); tempg.drawLine((int)xpos, (int)ypos - 2, (int)tempx, (int)tempy - 2); } else if (dy > 0) { tempg.drawLine((int)xpos, (int)ypos - 2, (int)tempx, (int)tempy); tempg.drawLine((int)xpos + 1, (int)ypos - 2, (int)tempx + 1, (int)tempy); tempg.drawLine((int)xpos + 2, (int)ypos - 2, (int)tempx + 2, (int)tempy); } else { tempg.drawLine((int)xpos, (int)ypos - 2, (int)tempx, (int)tempy); tempg.drawLine((int)xpos + 1, (int)ypos, (int)tempx + 1, (int)tempy - 2); tempg.drawLine((int)xpos + 2, (int)ypos, (int)tempx + 2, (int)tempy - 2); } } else tempg.drawLine((int)xpos, (int)ypos, (int)tempx, (int)tempy); xpos = tempx; ypos = tempy; } public void recursion(double k, int m, Graphics tempg, boolean fat) { if (m == 1) forward(k, tempg, fat); else { for (int i = 1; i <= 8; i++) { turn(theturns[i - 1]); recursion(k / 4, m - 1, tempg, fat); } turn(theturns[8]); } } }