// Fractals Applet // Algorithms found in: // The Algorithmic Beauty of Plants \ P. Prusinkiewicz and A. Lindenmayer // Implementation: (c) Sigal Blay // Original April 2002. Updated to Java Swing October 2005 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.Stack; public class fractals extends JApplet { public void init() { Container contentPane = getContentPane(); headPane headPanel = new headPane(); contentPane.add(headPanel); } } class headPane extends JPanel implements ActionListener { double distance = 80; // turtle step length double alpha = 90; // initial angle of turtle head double delta = 90; // turning angle of turtle head String initiator = "F-F-F-F"; String generator = "F-F+F+FF-F-F+F"; String generator1, generator2; int no_of_iterations = 1; // number of iterations double x=185, next_x, y=170, next_y=170; JComboBox a_menu, b_menu, c_menu; Dimension d; Stack base_x = new Stack(); Stack base_y = new Stack(); Stack base_alpha = new Stack(); Color pen_color = Color.red; String[] b_list; // [fractal][level] y distance x double size[][][] = new double[][][] { {{180,80},{180,20},{180,5},{180,1.35}}, {{140,80},{140,40},{140,17},{140,6},{140,2}}, {{300,80,100},{320,30,100},{420,10,100},{505,4,80}}, {{160,80,100},{160,40,100},{160,15,100},{160,5,100}}, {{250,40},{250,20},{250,10},{250,5}}, {{160,80,100},{160,40,100},{160,14,100},{160,5,100}}, {{300,80},{300,40},{300,20},{300,10},{300,5}}, {{400,5},{400,5},{400,5},{400,5},{400,5},{400,5},{400,5},{400,5},{400,5},{400,5}}, {{340,10},{340,10},{340,10},{340,10},{340,10},{140,7}}, {{380,80,80},{380,40,80},{380,20,80},{280,10,80}}, {{150,50,50},{100,19,50},{20,5,50}}, {{40,20},{40,20},{40,15},{40,7},{40,2.3}}, {{40,20},{40,20},{40,20},{40,10}}, {{40,20},{40,20},{40,20},{40,17},{40,9}}, {{40,20,280},{40,20,280},{40,20,280},{40,14,280},{40,7,280}}, {{40,20},{40,20},{40,20},{40,15},{40,9},{40,4.5}}, }; // [fractal] initiator generator[1] generator2 String properties[][] = new String[][] { {"F-F-F-F", "F-F+F+FF-F-F+F"}, {"F--F--F", "F+F--F+F"}, {"F-F-F-F","FF-F-F-F-F-F+F"}, {"F-F-F-F","FF-F-F-F-FF"}, {"F-F-F-F","F-F+F-F-F"}, {"F-F-F-F","FF-F--F-F"}, {"+F-F-F-F","F-FF--F-F"}, {"++l","l+r+",""}, {"-r","r+l+r",""}, {"--r","l+r++r-l--ll-r+",""}, {"-r","ll-r-r+l+l-r-rl+r+llr-l+r+ll+r-lr-r-l+l+rr-",""}, {"F","F[+F]F[-F]F"}, {"F","FF-[-F+F+F]+[+F-F-F]"}, {"l","r[+l]r[-l]+l","rr"}, {"l","r-[[l]+l]+r[+rl]-l","rr"}, {"l","r[+l][-l]rl","rr"}, }; double deltas[] = new double[] { 90,60,90,90,90,90,90,90,60,60,90,25.7,22.5,22.5,22.5,22.5 }; public headPane() { setLayout(null); String[] a_list = {"Red","Green","Blue", "Pink", "Yellow"}; a_menu = new JComboBox(a_list); a_menu.addActionListener(this); b_list = new String[]{"Level 1", "Level 2", "Level 3", "Level 4"}; b_menu = new JComboBox(b_list); b_menu.addActionListener(this); String[] c_list = {"Quadratic Koch Island", "Snowflake curve", "Koch curve a.", "Koch curve b.", "Koch curve c.", "Koch curve d.", "Koch curve e.", "the dragon curve", "Sierpinski gasket", "hexagonal Gosper curve", "quadratic Gosper curve", "herb a.","herb b.","herb c.","herb d.","herb e."}; c_menu = new JComboBox(c_list); c_menu.addActionListener(this); Dimension size = c_menu.getPreferredSize(); a_menu.setBounds(570, 26+2*size.height, size.width, size.height); b_menu.setBounds(570, 23+size.height, size.width, size.height); c_menu.setBounds(570, 20, size.width, size.height); add(a_menu); add(b_menu); add(c_menu); } public void actionPerformed(ActionEvent e) { JComboBox cb = (JComboBox)e.getSource(); String label = (String)cb.getSelectedItem(); if (label.equals ("Red")) pen_color = Color.red; else if (label.equals("Blue")) pen_color = Color.blue; else if (label.equals("Green")) pen_color = Color.green; else if (label.equals("Pink")) pen_color = Color.pink; else if (label.equals("Yellow")) pen_color = Color.yellow; // Adjust number of levels for fractal type: if (cb.equals(c_menu)) { b_menu.setSelectedIndex(0); int nlevels = size[c_menu.getSelectedIndex()].length; int menuLevels = b_menu.getItemCount(); if (menuLevels > nlevels) { for(int i= nlevels; i < menuLevels; i++) b_menu.removeItem("Level "+(i+1)); } else if (menuLevels < nlevels) { for (int i= menuLevels; i < nlevels; i++) b_menu.addItem("Level "+(i+1)); } } no_of_iterations = b_menu.getSelectedIndex() + 1; // y = size[c_menu.getSelectedIndex()][b_menu.getSelectedIndex()][0]; distance = size[c_menu.getSelectedIndex()][b_menu.getSelectedIndex()][1]; initiator = properties[c_menu.getSelectedIndex()][0]; delta = deltas[c_menu.getSelectedIndex()]; // if (size[c_menu.getSelectedIndex()][b_menu.getSelectedIndex()].length > 2) // x = size[c_menu.getSelectedIndex()][b_menu.getSelectedIndex()][2]; // else x = 185; if (properties[c_menu.getSelectedIndex()].length ==2) generator = properties[c_menu.getSelectedIndex()][1]; else { generator1 = properties[c_menu.getSelectedIndex()][1]; if (properties[c_menu.getSelectedIndex()][2].equals("")) create_generator2(); else generator2 = properties[c_menu.getSelectedIndex()][2]; } repaint(); } private void create_generator2() { generator2 = new StringBuffer().append(generator1). reverse().toString().replace('+','*'). replace('-', '+').replace('*','-'). replace('l','*').replace('r','l'). replace('*','r'); } public void paintComponent(Graphics g) { Graphics2D gg = (Graphics2D)g; d = new Dimension(500,500); //getSize(); gg.setPaint(Color.black); gg.fill(new Rectangle(0, 0, d.width, d.height)); gg.setColor(Color.red); Font my_font = new Font("Helvetica", Font.BOLD, 40); gg.setFont(my_font); gg.drawString("Fractals", 10, 40); gg.setColor(pen_color); alpha = 90; y = size[c_menu.getSelectedIndex()][b_menu.getSelectedIndex()][0]; if (size[c_menu.getSelectedIndex()][b_menu.getSelectedIndex()].length > 2) x = size[c_menu.getSelectedIndex()][b_menu.getSelectedIndex()][2]; else x = 185; turtle(g, 0, -1, initiator); } // 2D Double recursive function private void turtle(Graphics g, int j, int n, String gen) { if (gen.charAt(j) == '+') alpha += delta; else if (gen.charAt(j) == '-') alpha -= delta; else if (gen.charAt(j) == '[') { base_x.push(x); base_y.push(y); base_alpha.push(alpha); } else if (gen.charAt(j) == ']') { x = base_x.pop(); y = base_y.pop(); alpha = base_alpha.pop(); } else if (n == no_of_iterations - 1) draw_line(g); else if (gen.charAt(j) == 'F') turtle(g, 0, n+1, generator); else if (gen.charAt(j) == 'l') turtle(g, 0, n+1, generator1); else if (gen.charAt(j) == 'r') turtle(g, 0, n+1, generator2); j++; if (j < gen.length()) turtle(g, j, n, gen); } void draw_line(Graphics g) { next_x = x + distance*(Math.cos(alpha*(Math.PI/180))); next_y = y + distance*(Math.sin(alpha*(Math.PI/180))); g.drawLine((int)x , d.height - (int)y, (int)next_x, d.height - (int)next_y); x = next_x; y = next_y; } }