A fractal is a geometrical figure, but unlike triangles , circles, and rectangles, fractals can be divided into parts that are each a reduced- size copy of the whole. There are many interesting examples of fractals. This section introduces a simple fractal, called the Sierpinski triangle , named after a famous Polish mathematician .
A Sierpinski triangle is created as follows :
It begins with an equilateral triangle, which is considered to be a Sierpinski fractal of order (or level) 0, as shown in Figure 19.7(a).
Connect the midpoints of the sides of the triangle of order 0 to create a Sierpinski triangle of order 1, as shown in Figure 19.7(b).
Leave the center triangle intact. Connect the midpoints of the sides of the three other triangles to create a Sierpinski of order 2, as shown in Figure 19.7(c).
You can repeat the same process recursively to create a Sierpinski triangle of order 3, 4, , and so on, as shown in Figure 19.7(d).
The problem is inherently recursive. How do you develop a recursive solution for this problem? Consider the base case when the order is 0. It is easy to draw a Sierpinski triangle of order 0. How do you draw a Sierpinski triangle of order 1? The problem can be reduced by drawing three Sierpinski triangles of order 0. How do you draw a Sierpinski triangle of order 2? The problem can be reduced to drawing three Sierpinski triangles of order 1. So the problem of drawing a Sierpinski triangle of order n can be reduced to drawing three Sierpinski triangles of order n “ 1.
Listing 19.8 gives a Java applet that displays a Sierpinski triangle of any order, as shown in Figure 19.7. You can enter an order in a text field to display a Sierpinski triangle of the specified order.
1 import javax.swing.*; 2 import java.awt.*; 3 import java.awt.event.*; 4 5 public class SierpinskiTriangle extends JApplet { 6 private JTextField jtfOrder = new JTextField( 5 ); // To hold order 7 private SierpinskiTrianglePanel trianglePanel = 8 new SierpinskiTrianglePanel(); // To display the pattern 9 10 public SierpinskiTriangle() { 11 // Panel to hold label, text field, and a button 12 JPanel panel = new JPanel(); 13 panel.add( new JLabel( "Enter an order: " )); 14 panel.add(jtfOrder); 15 jtfOrder.setHorizontalAlignment(SwingConstants.RIGHT); 16 17 // Add a Sierpinski Triangle panel to the applet 18 getContentPane().add(trianglePanel); 19 getContentPane().add(panel, BorderLayout.SOUTH); 20 21 // Register a listener 22 jtfOrder.addActionListener( new ActionListener() { 23 public void actionPerformed(ActionEvent e) { 24 trianglePanel.setOrder(Integer.parseInt(jtfOrder.getText())); 25 } 26 }); 27 } 28 29 static class SierpinskiTrianglePanel extends JPanel { 30 private int order = ; 31 32 /** Set a new order */ 33 public void setOrder( int order) { 34 this .order = order; 35 repaint(); 36 } 37 38 public void paintComponent(Graphics g) { 39 super .paintComponent(g); 40 41 // Select three points in proportion to the panel size 42 Point p1 = new Point(getWidth() / 2 , 10 ); 43 Point p2 = new Point( 10 , getHeight() - 10 ); 44 Point p3 = new Point(getWidth() - 10 , getHeight() - 10 ); 45 46 displayTriangles(g, order, p1, p2, p3); 47 } 48 49 private static void displayTriangles(Graphics g, int order, 50 Point p1, Point p2, Point p3) { 51 if (order >= ) { 52 // Draw a triangle to connect three points 53 g.drawLine(p1.x, p1.y, p2.x, p2.y); 54 g.drawLine(p1.x, p1.y, p3.x, p3.y); 55 g.drawLine(p2.x, p2.y, p3.x, p3.y); 56 57 // Get three midpints in the triangle 58 Point midBetweenP1P2 = midpoint(p1, p2); 59 Point midBetweenP2P3 = midpoint(p2, p3); 60 Point midBetweenP3P1 = midpoint (p3, p1); 61 62 // Recursively display three triangles 63 displayTriangles(g, order - 1 , 64 p1, midBetweenP1P2, midBetweenP3P1); 65 displayTriangles(g, order - 1 , 66 midBetweenP1P2, p2, midBetweenP2P3); 67 displayTriangles(g, order - 1 , 68 midBetweenP3P1, midBetweenP2P3, p3); 69 } 70 } 71 72 private static Point midpoint(Point p1, Point p2) { 73 return new Point((p1.x + p2.x) / 2 , (p1.y + p2.y) / 2 ); 74 } 75 } 76 } |
The initial triangle has three points set in proportion to the panel size (lines 42 “44). The displayTriangles(g, order, p1, p2, p3) method performs the following tasks if order >= 0 :
Display a triangle to connect three points p1 , p2 , and p3 in lines 53 “55.
Obtain a midpoint between p1 and p2 (line 58), a midpoint between p2 and p3 (line 59), and a midpoint between p3 and p1 (line 60).
Recursively invoke displayTriangles with a reduced order to display three smaller triangles (lines 63 “68).
A Sierpinski triangle is displayed in a SierpinskiTrianglePanel . The order property in the inner class SierpinskiTrianglePanel specifies the order for the Sierpinski triangle. The Point class, introduced in §14.4, "Mouse Events," represents a point on a component. The midpoint(Point p1, Point p2) method returns the midpoint between p1 and p2 (lines 72 “74).