Basti's Scratchpad on the Internet

Fractals in Clojure - Sierpinski Triangle

This fractal is called the Sierpinski triangle, after the Polish mathematician Waclaw Sierpinski.

In order to generate it we'll use the following algorithm,

(ns sierpinski
    (:import (java.awt Dimension Polygon Color)
	     (javax.swing JFrame JLabel)
	     (java.awt.image BufferedImage)))

(defstruct point :x :y)
(defstruct triangle :left :rigth :bottom)

We need two structures for representing a point on the canvas and the triangle we are drawing.

(defn midpoints [trig]
  (struct triangle 
	  (struct point
		  (/ (+ (:x (:bottom trig)) (:x (:left trig))) 2)
		  (/ (+ (:y (:bottom trig)) (:y (:left trig))) 2))
	  (struct point
		  (/ (+ (:x (:rigth trig)) (:x (:bottom trig))) 2)
		  (/ (+ (:y (:rigth trig)) (:y (:bottom trig))) 2))
	  (struct point
		  (/ (+ (:x (:left trig)) (:x (:rigth trig))) 2)
		  (/ (+ (:y (:left trig)) (:y (:rigth trig))) 2))))

Given a triangle this function will return a new triangle thats half the original triangle.

(defn paint-triangle [g trig]
  (let  [polygon (new Polygon)]
    (doto polygon
	  (.addPoint  (:x (:left trig))   (:y (:left trig)))
	  (.addPoint  (:x (:rigth trig))  (:y (:rigth trig)))
	  (.addPoint  (:x (:bottom trig)) (:y (:bottom trig))))
    (.drawPolygon g polygon)))

(defn create-triangles [trig step depth g]
  (paint-triangle g trig)
  (let  [points (midpoints trig) 
	 left   (struct 
		 triangle (:left trig) (:left points) (:bottom points))
	 rigth  (struct 
		 triangle (:rigth trig) (:rigth points) (:bottom points))
	 top    (struct 
		 triangle (:bottom trig) (:rigth points) (:left points)) ]
    (if (< step depth )
      (do (create-triangles left  (inc step) depth g)
	  (create-triangles rigth (inc step) depth g)
	  (create-triangles top   (inc step) depth g)))))

create-triangles is a recursive function that will call it self until required depth is reached. It first draws the given triangle then calculate 3 smaller triangles that will be placed inside the parent triangle.

(defn draw [depth width height]
  (let [image  (BufferedImage. width height BufferedImage/TYPE_INT_RGB)
	canvas (proxy [JLabel] []
		 (paint [g] (.drawImage g image 0 0 this)))
	graphics (.createGraphics image)]

    (.setColor graphics Color/white)
    (create-triangles 
     (struct triangle
	     (struct point 0 height)
	     (struct point width height)
	     (struct point (/ width 2) 0)) 
     0 depth graphics)

    (doto (JFrame.)
      (.add canvas)
      (.setSize (Dimension. width height))
      (.show))))
(draw 4 400 400)

Sierpinski Triangle

Sierpinski Triangle

Other posts
comments powered by Disqus