Skip to content

Commit

Permalink
Chapter 0 Exercises 8 and 9
Browse files Browse the repository at this point in the history
  • Loading branch information
Ramblurr committed May 29, 2024
1 parent b52afe9 commit b1d26ff
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 2 deletions.
27 changes: 27 additions & 0 deletions notebooks/chapter_0.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,30 @@ Of course in clojure we can't do that [^um-actually], so I took the approach of
Click that reset button to see it regenerated!

[^um-actually]: Well, technically we can using dynamic vars or an atom, but that's pretty nasty and should only be used as an escape hatch when necessary.


## [Exercise 0.8: A Perlin Noise Technicolor](https://natureofcode.com/random/#exercise-08)

```clojure
^{::clerk/no-cache true ::clerk/viewer clerk/code}
(slurp "src/noc/chapter_0_8e.cljs")
(show-sketch :c0.8e)
```


## [Exercise 0.9: Perlin Noise Animation](https://natureofcode.com/random/#exercise-08)

```clojure
^{::clerk/no-cache true ::clerk/viewer clerk/code}
(slurp "src/noc/chapter_0_9e.cljs")
(show-sketch :c0.9e)
```

Well this one is pretty cool. The sliders control (in order from left to right):

* Perlin noise `octaves`
* Perlin noise octave `fallof`
* Amount `xoff` is incremented by
* Amount `yoff` is incremented by

Finally there is a checkbox to enable animation using the 3rd dimension of the perlin noise.
89 changes: 89 additions & 0 deletions src/noc/chapter_0_8e.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
(ns noc.chapter-0-8e
(:require
[goog.string :as gstring]
[goog.string.format]
[quil.core :as q]))

(def size [640 240])

(defn init-state [_]
{:ui {:octaves {:type :slider
:min 1 :max 20
:step 1 :value 4}
:falloff {:type :slider
:min 0 :max 0.5
:step 0.01
:label "test"
:value 0}
:xoff-incr {:type :slider
:min 0 :max 0.1
:step 0.01
:value 0.01}

:yoff-incr {:type :slider
:min 0 :max 0.1
:step 0.01
:value 0.01}}})

(defn setup! [{:keys [width height]}]
(q/noise-seed (rand-int (-> js/Number (.-MAX_SAFE_INTEGER))))
(q/background 255))

(defn gen-noise-image [width height xoff-incr yoff-incr]
(let [rand-color (fn [t1 t2]
(Math/floor (q/map-range (q/noise t1 t2) 0 1 0 255)))
img (q/create-image width height)
roff 0
goff 10000
boff 100000
px (q/pixels img)
xoffs (take width (iterate #(+ % xoff-incr) 0.0))]
(doseq [[x xoff] (map-indexed vector xoffs)]
(let [yoffs (take height (iterate #(+ % yoff-incr) 0.0))]
(doseq [[y yoff] (map-indexed vector yoffs)]
(let [idx (* 4 (+ x (* y width)))
r (rand-color (+ roff xoff) (+ roff yoff))
g (rand-color (+ goff xoff) (+ goff yoff))
b (rand-color (+ boff xoff) (+ boff yoff))]
(aset px idx r)
(aset px (+ 1 idx) g)
(aset px (+ 2 idx) b)
(aset px (+ 3 idx) 255)))))
(q/update-pixels img)
img))

(defn tick [{:keys [old-octaves old-falloff old-yoff-incr old-xoff-incr width height] :as state}]
(let [octaves (-> state :ui :octaves :value)
falloff (-> state :ui :falloff :value)
xoff-incr (-> state :ui :xoff-incr :value)
yoff-incr (-> state :ui :yoff-incr :value)]
(if (or (not= octaves old-octaves)
(not= falloff old-falloff)
(not= yoff-incr old-yoff-incr)
(not= xoff-incr old-xoff-incr))
(do
(q/noise-detail octaves falloff)
(assoc state
:old-octaves octaves
:old-falloff falloff
:old-xoff-incr xoff-incr
:old-yoff-incr yoff-incr
:img (gen-noise-image width height xoff-incr yoff-incr)))
state)))

(defn draw! [{:keys [ui img]}]
(let [octaves (-> ui :octaves :value)
falloff (-> ui :falloff :value)
xoff-incr (-> ui :xoff-incr :value)
yoff-incr (-> ui :yoff-incr :value)]

(when img
(q/image img 0 0))
(q/no-stroke)
(q/fill 255)
(q/rect 0 0 100 55)
(q/fill 0)
(q/text (gstring/format "octaves: %.2f" octaves) 10 20)
(q/text (gstring/format "falloff: %.2f" falloff) 10 30)
(q/text (gstring/format "xoff-incr: %.2f" xoff-incr) 10 40)
(q/text (gstring/format "yoff-incr: %.2f" yoff-incr) 10 50)))
95 changes: 95 additions & 0 deletions src/noc/chapter_0_9e.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
(ns noc.chapter-0-9e
(:require
[goog.string :as gstring]
[goog.string.format]
[quil.core :as q]))

(def size [640 240])

(defn init-state [_]
{:z 0.0
:ui {:octaves {:type :slider
:min 1 :max 20
:step 1 :value 4}
:falloff {:type :slider
:min 0 :max 0.5
:step 0.01
:label "test"
:value 0}
:xoff-incr {:type :slider
:min 0 :max 0.1
:step 0.01
:value 0.01}

:yoff-incr {:type :slider
:min 0 :max 0.1
:step 0.01
:value 0.01}
:animate {:type :checkbox :checked? false}}})

(defn setup! [{:keys [width height]}]
(q/noise-seed (rand-int (-> js/Number (.-MAX_SAFE_INTEGER))))
(q/background 255))

(defn gen-noise-image [width height xoff-incr yoff-incr z]
(let [rand-color (fn [t1 t2]
(Math/floor (q/map-range (q/noise t1 t2 z) 0 1 0 255)))
img (q/create-image width height)
roff 0
goff 10000
boff 100000
px (q/pixels img)
xoffs (take width (iterate #(+ % xoff-incr) 0.0))]
(doseq [[x xoff] (map-indexed vector xoffs)]
(let [yoffs (take height (iterate #(+ % yoff-incr) 0.0))]
(doseq [[y yoff] (map-indexed vector yoffs)]
(let [idx (* 4 (+ x (* y width)))
r (rand-color (+ roff xoff) (+ roff yoff))
g (rand-color (+ goff xoff) (+ goff yoff))
b (rand-color (+ boff xoff) (+ boff yoff))]
(aset px idx r)
(aset px (+ 1 idx) g)
(aset px (+ 2 idx) b)
(aset px (+ 3 idx) 255)))))
(q/update-pixels img)
img))

(defn tick [{:keys [old-octaves old-falloff old-yoff-incr old-xoff-incr width height z] :as state}]
(let [octaves (-> state :ui :octaves :value)
falloff (-> state :ui :falloff :value)
xoff-incr (-> state :ui :xoff-incr :value)
yoff-incr (-> state :ui :yoff-incr :value)
animate? (-> state :ui :animate :checked?)
z (+ 0.1 z)]
(if (or animate?
(not= octaves old-octaves)
(not= falloff old-falloff)
(not= yoff-incr old-yoff-incr)
(not= xoff-incr old-xoff-incr))
(do
(q/noise-detail octaves falloff)
(assoc state
:z z
:old-octaves octaves
:old-falloff falloff
:old-xoff-incr xoff-incr
:old-yoff-incr yoff-incr
:img (gen-noise-image width height xoff-incr yoff-incr z)))
state)))

(defn draw! [{:keys [ui img]}]
(let [octaves (-> ui :octaves :value)
falloff (-> ui :falloff :value)
xoff-incr (-> ui :xoff-incr :value)
yoff-incr (-> ui :yoff-incr :value)]

(when img
(q/image img 0 0))
(q/no-stroke)
(q/fill 255)
(q/rect 0 0 100 55)
(q/fill 0)
(q/text (gstring/format "octaves: %.2f" octaves) 10 20)
(q/text (gstring/format "falloff: %.2f" falloff) 10 30)
(q/text (gstring/format "xoff-incr: %.2f" xoff-incr) 10 40)
(q/text (gstring/format "yoff-incr: %.2f" yoff-incr) 10 50)))
8 changes: 6 additions & 2 deletions src/noc/sketch.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
[noc.chapter-0-6e :as c0.6e]
[noc.chapter-0-6 :as c0.6]
[noc.chapter-0-7e :as c0.7e]
[noc.chapter-0-7 :as c0.7]))
[noc.chapter-0-7 :as c0.7]
[noc.chapter-0-8e :as c0.8e]
[noc.chapter-0-9e :as c0.9e]))

(def sketches {:walker (sketch-> c0.1)
:rand-dist (sketch-> c0.2)
Expand All @@ -28,7 +30,9 @@
:c0.6e (sketch-> c0.6e)
:c0.6 (sketch-> c0.6)
:c0.7e (sketch-> c0.7e)
:c0.7 (sketch-> c0.7)})
:c0.7 (sketch-> c0.7)
:c0.8e (sketch-> c0.8e)
:c0.9e (sketch-> c0.9e)})

(defn load-sketch [s]
(when-let [sk (get sketches s)]
Expand Down

0 comments on commit b1d26ff

Please sign in to comment.