Skip to content

Instantly share code, notes, and snippets.

@Chouser
Created December 31, 2010 16:01
Show Gist options
  • Save Chouser/761108 to your computer and use it in GitHub Desktop.
Save Chouser/761108 to your computer and use it in GitHub Desktop.
; The New Year in Snowflakes
; A Clojure doodle by Chouser
(import '(java.awt Color Graphics Frame RenderingHints))
(defonce draw-agent (agent nil))
(defonce halt (atom false))
(defmacro ui-thread [& body]
`(javax.swing.SwingUtilities/invokeAndWait (fn [] ~@body)))
(def face {
\0 [[ 0 69] [ 40 0] [120 0] [160 69] [160 138]
[160 207] [120 276] [ 40 276] [ 0 207] [ 0 138]]
\1 [[ 11 40] [ 80 0] [ 80 92] [ 80 184] [ 0 276] [80 276] [160 276]]
\2 [[ 0 69] [ 40 0] [120 0] [160 69] [120 138] [80 207]
[ 30 276] [120 276] [200 276]]})
(defn draw-snow [_ g size]
(ui-thread
(doto g
; clear window
(.setColor Color/BLACK)
(.fillRect 0 0 (.width size) (.height size))
; draw white snowflakes
(.setColor Color/WHITE)
(.setRenderingHint RenderingHints/KEY_ANTIALIASING
RenderingHints/VALUE_ANTIALIAS_ON)
(.setRenderingHint RenderingHints/KEY_RENDERING
RenderingHints/VALUE_RENDER_QUALITY)))
(let [t (.getTransform g)]
(doseq [[digit col] (map vector "2011" (reductions + [0 290 270 270]))
[x y] (face digit)
:let [x (+ 50 x col)
y (+ 80 y)
a4 (* 2 Math/PI (rand))] ; rotate whole snowflake some
:while (not @halt)]
(ui-thread
(dotimes [i (+ 5 (rand 15))]
(let [s (* 20 (rand)) ; length of line
dx (* 30 (rand)) ; distance of line from center of flake
a1 (* 2 Math/PI (rand)) ; angle of line around center
a2 (- (* Math/PI (rand)) (/ Math/PI 2))] ; angle from "spoke"
(doseq [a3 (range 0 6 (/ Math/PI 3)), flip [1 -1]]
(doto g
(.setTransform t)
(.translate x y)
(.rotate (+ a4 a3))
(.scale flip 1)
(.rotate a1)
(.translate dx 0.0)
(.rotate a2)
(.scale s 1.0)
(.fillRect 0 0 1 1)))))))))
(defn paint [g size]
(future
(reset! halt true)
(await draw-agent) ; doesn't guarantee much
(reset! halt false)
(send-off draw-agent draw-snow g size)))
(defonce frame
(doto
(proxy [Frame] ["Happy New Year"]
(paint [_] (paint (.getGraphics this) (.getSize this))))
(.setSize 600 700)
(.setVisible true)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment