Gasket

What's this? Click the

A **Sierpinsky Gasket** is an equilateral triangle that is composed of smaller
equilateral triangles. Each of these triangles is similarly composed of smaller triangles.
The process goes on indefinitely, and it is this feature — the identical structure
at any magnification — that makes this a *fractal*.

This example is not, in fact, a *true* Sierpinsky Gasket, because it does not use equilateral
triangles. Instead I am taking two right triangles and pasting them together to form a square.
Then I draw two gaskets within those two triangles that are mirror images of each other.

Why? I just thought it was prettier this way.

**Algorithm**

There are different methods for creating these things, but here's the one I use:

Begin with a triangle. It's an imaginary triangle, so there's no need to draw it; just make sure you know the coordinates of the three corners.

Choose one of those three corners at random, and put your finger on it. Then choose a point anywhere in 2-dimensional space (which in this case is limited to the applet window). Put a dot there.

Then figure out the coordinates of the point that is *half-way* between the dot and the
corner your finger is on. Put a dot on *that* point.

Again, choose one of the three corners of the triangle at random. Figure out the coordinates of the point that is half-way between your current point and the corner you just chose. Put a dot there.

Continue on, putting a dot half-way between any corner of the triangle and the dot you just drew.
After doing this a few thousand times, you begin to see the Sierpinsky Gasket.

Top

**Code**

Here, for your interest, is the Java code used to create this applet.

import java.awt.*; import java.applet.*; import java.awt.geom.*; import java.util.Random; /** Display modified Serpinsky Gasket @author Fred Coulson @version June 23, 2002 */ public class chaos extends Applet { boolean isPainted = false; //We retain a copy of the drawing canvas as an instance variable, //so that we can quickly repaint the screen without having to go //through the whole gasket-drawing code every time the screen //gets refreshed. Image imgBuf; public void init(){ imgBuf = createImage(getWidth(),getHeight() ); } public void paint( Graphics g ){ if( !isPainted ){ int count, dotsize; //Die if non-numeric input received try{ count = Integer.parseInt(getParameter("count")); dotsize = Integer.parseInt(getParameter("size")); } catch( RuntimeException e ){ g.drawString( "Error: "+e.getMessage(),10,10); throw e; } Graphics gBuf = imgBuf.getGraphics(); Random generator = new Random(); //Get the width and height of the bounding box: int maxXY = getWidth(); //Define the 4 corners of the box. int x1 = 0; int y1 = 0; int x2 = maxXY; int y2 = maxXY; //pick 2 points at random within the box. int x_last1 = generator.nextInt(maxXY); int y_last1 = generator.nextInt(maxXY); int x_last2 = generator.nextInt(maxXY); int y_last2 = generator.nextInt(maxXY); int red,green,blue; for( int i=0; i<count; i++){ int corner_x1,corner_y1,corner_x2,corner_y2; int pick_point = generator.nextInt(3); switch( pick_point ){ case 0 : corner_x1 = corner_x2 = x1; corner_y1 = corner_y2 = y1; break; case 1 : // 1 is the middle corner. First fill one side of the gasket, // then the other corner_x1 = x2; corner_y1 = y1; corner_x2 = x1; corner_y2 = y2; break; case 2 : corner_x1 = corner_x2 = x2; corner_y1 = corner_y2 = y2; break; default: throw new RuntimeException( "Illegal case branch." ); // This will never happen, but providing a default case // keeps the compiler happy. } int x_point1 = x_last1 - ( (x_last1 - corner_x1) / 2 ); int y_point1 = y_last1 - ( (y_last1 - corner_y1) / 2 ); int x_point2 = x_last2 - ( (x_last2 - corner_x2) / 2 ); int y_point2 = y_last2 - ( (y_last2 - corner_y2) / 2 ); //choose a color at random red = generator.nextInt(256); green = generator.nextInt(256); blue = generator.nextInt(256); //Each triangle gets two calls to drawDot() so that we can save // the dot to the buffer,and watch the dot be drawn on the // screen at the same time. That's why there are four calls // to drawDot() in all. drawDot(x_point1,y_point1,dotsize,red,green,blue,g); drawDot(x_point1,y_point1,dotsize,red,green,blue,gBuf); drawDot(x_point2,y_point2,dotsize,red,green,blue,g); drawDot(x_point2,y_point2,dotsize,red,green,blue,gBuf); // Remember the points we chose, for use in the next loop iteration. x_last1 = x_point1; y_last1 = y_point1; x_last2 = x_point2; y_last2 = y_point2; } isPainted = true; gBuf.dispose(); } else //The screen has already been painted once; no need to go through //all that again. g.drawImage(imgBuf,0,0,null); } public void drawDot( int x, int y, int diameter, int red, int green, int blue, Graphics g ){ Color fillColor = new Color(red,green,blue); Graphics2D g2 = (Graphics2D)g; //We have to "fix" the xy coordinates a little, to make them fall at the center of //the circle defined by "diameter". double xx = x - (diameter/2); double yy = y - (diameter/2); Ellipse2D.Double dot = new Ellipse2D.Double(xx,yy,diameter,diameter); g2.setColor(fillColor); g2.fill(dot); g2.draw(dot); } }Top