Skip to content

Instantly share code, notes, and snippets.

@dulimarta
Last active October 30, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dulimarta/8ec7c70d1845bde27a8d to your computer and use it in GitHub Desktop.
Save dulimarta/8ec7c70d1845bde27a8d to your computer and use it in GitHub Desktop.
Sierpinski Triangle with animation
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
/**
* Draw a recursive 2D graphics
*
* @version Fall 2015
* @author Hans Dulimarta
*/
public class GUI implements ChangeListener {
private JFrame top;
private JSlider sld;
private SierpinskiTriangle g;
public GUI() {
top = new JFrame();
g = new SierpinskiTriangle();
top.add(g, BorderLayout.CENTER);
sld = new JSlider(1, 7);
sld.setValue(1);
sld.setPaintTicks(true);
sld.setMajorTickSpacing(1);
sld.setSnapToTicks(true);
sld.addChangeListener(this);
g.changeDetails(1);
top.add (sld, BorderLayout.SOUTH);
top.pack();
top.setVisible(true);
top.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
@Override
public void stateChanged(ChangeEvent e) {
g.changeDetails(sld.getValue());
}
public static void main(String[] args) {
new GUI();
}
}
import javax.swing.*;
import javax.swing.Timer;
import javax.swing.border.BevelBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;
/**
* A simple panel for drawing the Sierpinski Triangle
*
* @version Fall 2015
* @author Hans Dulimarta
*/
public class SierpinskiTriangle extends JPanel implements ActionListener {
private static final int SIZE = 500;
private static final int MARGIN = 40;
private int height, side, subdivide;
private Timer ticker;
private ArrayList<int[]> x_coordQueue, y_coordQueue;
private ArrayList<Color> colorQueue;
int x1, y1, x2, y2, x3, y3, lastItemToDraw;
public SierpinskiTriangle() {
setPreferredSize(new Dimension(SIZE, SIZE));
setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
height = SIZE - 2 * MARGIN;
side = (int) (height / Math.sin(Math.toRadians(60.0)));
x1 = SIZE / 2;
y1 = MARGIN;
x2 = (SIZE/2) - (side/2);
y2 = SIZE - MARGIN;
x3 = (SIZE/2) + (side/2);
y3 = SIZE - MARGIN;
subdivide = 1; /* use this variable for recursive subdivision */
ticker = new Timer(200, this);
x_coordQueue = new ArrayList<int[]>();
y_coordQueue = new ArrayList<int[]>();
colorQueue = new ArrayList<Color>();
}
public void changeDetails (int N) {
subdivide = N;
x_coordQueue.clear();
y_coordQueue.clear();
colorQueue.clear();
drawTriangle(x1, y1, x2, y2, x3, y3, Color.ORANGE);
lastItemToDraw = 0;
ticker.setDelay(100/N);
ticker.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (int k = 0; k < lastItemToDraw; k++) {
g.setColor(colorQueue.get(k));
g.fillPolygon(x_coordQueue.get(k), y_coordQueue.get(k), 3);
}
}
private void drawTriangle (int x1, int y1,
int x2, int y2,
int x3, int y3, Color c)
{
/* push the drawing information to a list */
x_coordQueue.add(new int[]{x1, x2, x3});
y_coordQueue.add(new int[]{y1, y2, y3});
colorQueue.add(c);
}
@Override
public void actionPerformed(ActionEvent e) {
if (lastItemToDraw < x_coordQueue.size()) {
repaint(); /* redraw using the new subdivision level */
lastItemToDraw++;
}
else
ticker.stop();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment