Skip to content

Instantly share code, notes, and snippets.

@quephird
Last active December 31, 2015 16:49
Show Gist options
  • Save quephird/8016495 to your computer and use it in GitHub Desktop.
Save quephird/8016495 to your computer and use it in GitHub Desktop.
This is a slight variation of candy.clj; this one generates a rectangular arrangement of spheres and colors them using a gradient starting from one corner to the other with some randomness thrown in.
(ns candy-wallpaper
(:use quil.core))
(def screen-w 1920)
(def screen-h 1080)
(def existing-spheres (atom []))
(defn- rand-color []
(vec (repeatedly 3 (fn [] (rand-int 255)))))
(defn- vary-color [c]
(let [variance 30
delta-c (vec (repeatedly 3 (fn [] (- (rand-int (* 2 variance)) variance))))]
(map + c delta-c)))
(defn- calc-color [x y c1 c2]
(let [delta-x1 x
delta-y1 y
d1-squared (+ (* delta-x1 delta-x1) (* delta-y1 delta-y1))
weighted-c1 (map #(* d1-squared %) c1)
delta-x2 (- screen-w x)
delta-y2 (- screen-h y)
d2-squared (+ (* delta-x2 delta-x2) (* delta-y2 delta-y2))
weighted-c2 (map #(* d2-squared %) c2)
seed-color (map #(/ % (+ d1-squared d2-squared)) (map + weighted-c1 weighted-c2))]
(vary-color seed-color)))
(defn- rand-xy [max-x max-y]
[(rand-int max-x) (rand-int max-y)])
(defn- add-sphere! [x y r]
(swap! existing-spheres conj [x y r]))
(defn- draw-sphere [x y r c]
(push-matrix)
(translate x y)
(apply fill c)
(sphere r)
(pop-matrix))
(defn- spheres-intersect? [[x1 y1 r1] [x2 y2 r2]]
(let [delta-x (- x1 x2)
delta-y (- y1 y2)
sum-of-radii (+ r1 r2)
distance-squared (+ (* delta-x delta-x) (* delta-y delta-y))]
(> (* sum-of-radii sum-of-radii) distance-squared)))
(defn- intersects-any-sphere? [existing-spheres new-sphere]
(if (empty? existing-spheres)
false
(some true? (map (fn [existing-sphere] (spheres-intersect? existing-sphere new-sphere)) existing-spheres))))
(defn setup []
(background 0)
(smooth)
(no-stroke)
(no-loop))
(defn draw []
(directional-light 255 255 225 1000 1000 -500)
(ambient-light 100 100 100)
(ambient 100 100 100)
(shininess 2.0)
; This is to prevent distortion of the spheres.
; (ortho (* screen-w -1.1) (* screen-w 1.1) (* screen-h 1.1) (* screen-h -1.1) 0 1000)
(ortho (* screen-w -0.45) (* screen-w 0.45) (* screen-h 0.45) (* screen-h -0.45) 0 1000)
; (translate (/ screen-w 2) (/ screen-h 2) -1000)
(doseq [_ (range 100000)]
; Randomize x,y coordinates of each sphere
(let [[x y] (rand-xy screen-w screen-h)
; Randomize radius of each candy
r (+ 1 (rand-int 25))
c (calc-color x y [127 0 127] [0 127 0])
]
; This is a fairly hackish approach since I just throw away undesired choices;
; ideally I ought to generate usable coordinates each time but I don't know
; how to implement that at this time.
(if (not (intersects-any-sphere? @existing-spheres [x y r]))
(do
(draw-sphere x y r c)
(add-sphere! x y r)))))
(save "candy-wallpaper.png")
)
(sketch
:title "candy wallpaper"
:setup setup
:draw draw
:size [screen-w screen-h]
:renderer :opengl)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment