Created
June 26, 2011 21:26
-
-
Save kiras/1047989 to your computer and use it in GitHub Desktop.
Sierpinski Gasket code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns sierpinski.core | |
(:use [penumbra.opengl]) | |
(:require [penumbra.app :as app]) | |
(:require clojure.contrib.math)) | |
(defn make-point [x y z] | |
{:x x :y y :z z}) | |
(defn make-triangle [p1 p2 p3] | |
{:p1 p1 :p2 p2 :p3 p3}) | |
(defn generate-random-point | |
"Generates a random 3D point, with vertex values between 0 (inclusive) and the | |
corresponding n (default 1) (exclusive)." | |
([] | |
(make-point (rand) (rand) (rand))) | |
([x-n, y-n, z-n] | |
(make-point (rand x-n) (rand y-n) (rand z-n)))) | |
(defn generate-random-points | |
"Generates a lazy-seq of n random points. Each point will have vertex values | |
between 0 (inclusive) and the corresponding n (default 1) (exclusive)." | |
([n x-n y-n z-n] | |
(lazy-seq | |
(when (> n 0) | |
(cons (generate-random-point x-n y-n z-n) | |
(generate-random-points (dec n) x-n y-n z-n)))))) | |
(defn sierpinskisize | |
"Chooses a vertex from tri at random, returning the point halfway between | |
p and the vertex." | |
[p tri] | |
(let [v-num (clojure.contrib.math/floor (rand 3)) | |
vertex (cond (= v-num 0) | |
(:p1 tri) | |
(= v-num 1) | |
(:p2 tri) | |
(= v-num 2) | |
(:p3 tri)) | |
halfway-point (fn [p1 p2] | |
[(/ (+ (:x p1) (:x p2)) 2) | |
(/ (+ (:y p1) (:y p2)) 2) | |
(/ (+ (:z p1) (:z p2)) 2)])] | |
(apply make-point (halfway-point vertex p)))) | |
(defn sierpinski-points | |
"Generates a lazy-seq of n points describing a Sierpinski gasket. The gasket | |
will have boundaries set by the vertices of tri." | |
[n tri initial-point] | |
(lazy-seq | |
(let [sierpinski-point (sierpinskisize initial-point tri)] | |
(when (> n 0) | |
(cons (sierpinskisize sierpinski-point tri) | |
(sierpinski-points (dec n) tri sierpinski-point)))))) | |
(defn generate-sierpinski-gasket [n tri initial-point] | |
"Creates and draws a sierpinski gasket with n points, within the bounds | |
specified by tri." | |
(->> (sierpinski-points n tri initial-point) | |
(map #(vertex (% :x) (% :y) (% :z))) | |
(dorun))) | |
;; Callbacks. | |
(defn init [state] | |
(app/title! "Sierpinski Gasket")) | |
(defn reshape [[x y width height] state] | |
(ortho-view 0.0 100.0 100.0 0.0 0.0 -1.0) | |
state) | |
(defn display [[delta time] state] | |
(draw-points | |
(color 1.0 0.0 0.0) | |
(let [tri (make-triangle (make-point 0.0 0.0 0.0) | |
(make-point 25.0 50.0 0.0) | |
(make-point 50.0 0.0 0.0)) | |
initial-point (make-point 10 10 10)] | |
(generate-sierpinski-gasket 10000 tri initial-point)))) | |
(app/start | |
{:init init, :display display, :reshape reshape} | |
{}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment