Skip to content

Commit b1d26ff

Browse files
committed
Chapter 0 Exercises 8 and 9
1 parent b52afe9 commit b1d26ff

File tree

4 files changed

+217
-2
lines changed

4 files changed

+217
-2
lines changed

notebooks/chapter_0.md

+27
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,30 @@ Of course in clojure we can't do that [^um-actually], so I took the approach of
225225
Click that reset button to see it regenerated!
226226

227227
[^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.
228+
229+
230+
## [Exercise 0.8: A Perlin Noise Technicolor](https://natureofcode.com/random/#exercise-08)
231+
232+
```clojure
233+
^{::clerk/no-cache true ::clerk/viewer clerk/code}
234+
(slurp "src/noc/chapter_0_8e.cljs")
235+
(show-sketch :c0.8e)
236+
```
237+
238+
239+
## [Exercise 0.9: Perlin Noise Animation](https://natureofcode.com/random/#exercise-08)
240+
241+
```clojure
242+
^{::clerk/no-cache true ::clerk/viewer clerk/code}
243+
(slurp "src/noc/chapter_0_9e.cljs")
244+
(show-sketch :c0.9e)
245+
```
246+
247+
Well this one is pretty cool. The sliders control (in order from left to right):
248+
249+
* Perlin noise `octaves`
250+
* Perlin noise octave `fallof`
251+
* Amount `xoff` is incremented by
252+
* Amount `yoff` is incremented by
253+
254+
Finally there is a checkbox to enable animation using the 3rd dimension of the perlin noise.

src/noc/chapter_0_8e.cljs

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
(ns noc.chapter-0-8e
2+
(:require
3+
[goog.string :as gstring]
4+
[goog.string.format]
5+
[quil.core :as q]))
6+
7+
(def size [640 240])
8+
9+
(defn init-state [_]
10+
{:ui {:octaves {:type :slider
11+
:min 1 :max 20
12+
:step 1 :value 4}
13+
:falloff {:type :slider
14+
:min 0 :max 0.5
15+
:step 0.01
16+
:label "test"
17+
:value 0}
18+
:xoff-incr {:type :slider
19+
:min 0 :max 0.1
20+
:step 0.01
21+
:value 0.01}
22+
23+
:yoff-incr {:type :slider
24+
:min 0 :max 0.1
25+
:step 0.01
26+
:value 0.01}}})
27+
28+
(defn setup! [{:keys [width height]}]
29+
(q/noise-seed (rand-int (-> js/Number (.-MAX_SAFE_INTEGER))))
30+
(q/background 255))
31+
32+
(defn gen-noise-image [width height xoff-incr yoff-incr]
33+
(let [rand-color (fn [t1 t2]
34+
(Math/floor (q/map-range (q/noise t1 t2) 0 1 0 255)))
35+
img (q/create-image width height)
36+
roff 0
37+
goff 10000
38+
boff 100000
39+
px (q/pixels img)
40+
xoffs (take width (iterate #(+ % xoff-incr) 0.0))]
41+
(doseq [[x xoff] (map-indexed vector xoffs)]
42+
(let [yoffs (take height (iterate #(+ % yoff-incr) 0.0))]
43+
(doseq [[y yoff] (map-indexed vector yoffs)]
44+
(let [idx (* 4 (+ x (* y width)))
45+
r (rand-color (+ roff xoff) (+ roff yoff))
46+
g (rand-color (+ goff xoff) (+ goff yoff))
47+
b (rand-color (+ boff xoff) (+ boff yoff))]
48+
(aset px idx r)
49+
(aset px (+ 1 idx) g)
50+
(aset px (+ 2 idx) b)
51+
(aset px (+ 3 idx) 255)))))
52+
(q/update-pixels img)
53+
img))
54+
55+
(defn tick [{:keys [old-octaves old-falloff old-yoff-incr old-xoff-incr width height] :as state}]
56+
(let [octaves (-> state :ui :octaves :value)
57+
falloff (-> state :ui :falloff :value)
58+
xoff-incr (-> state :ui :xoff-incr :value)
59+
yoff-incr (-> state :ui :yoff-incr :value)]
60+
(if (or (not= octaves old-octaves)
61+
(not= falloff old-falloff)
62+
(not= yoff-incr old-yoff-incr)
63+
(not= xoff-incr old-xoff-incr))
64+
(do
65+
(q/noise-detail octaves falloff)
66+
(assoc state
67+
:old-octaves octaves
68+
:old-falloff falloff
69+
:old-xoff-incr xoff-incr
70+
:old-yoff-incr yoff-incr
71+
:img (gen-noise-image width height xoff-incr yoff-incr)))
72+
state)))
73+
74+
(defn draw! [{:keys [ui img]}]
75+
(let [octaves (-> ui :octaves :value)
76+
falloff (-> ui :falloff :value)
77+
xoff-incr (-> ui :xoff-incr :value)
78+
yoff-incr (-> ui :yoff-incr :value)]
79+
80+
(when img
81+
(q/image img 0 0))
82+
(q/no-stroke)
83+
(q/fill 255)
84+
(q/rect 0 0 100 55)
85+
(q/fill 0)
86+
(q/text (gstring/format "octaves: %.2f" octaves) 10 20)
87+
(q/text (gstring/format "falloff: %.2f" falloff) 10 30)
88+
(q/text (gstring/format "xoff-incr: %.2f" xoff-incr) 10 40)
89+
(q/text (gstring/format "yoff-incr: %.2f" yoff-incr) 10 50)))

src/noc/chapter_0_9e.cljs

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
(ns noc.chapter-0-9e
2+
(:require
3+
[goog.string :as gstring]
4+
[goog.string.format]
5+
[quil.core :as q]))
6+
7+
(def size [640 240])
8+
9+
(defn init-state [_]
10+
{:z 0.0
11+
:ui {:octaves {:type :slider
12+
:min 1 :max 20
13+
:step 1 :value 4}
14+
:falloff {:type :slider
15+
:min 0 :max 0.5
16+
:step 0.01
17+
:label "test"
18+
:value 0}
19+
:xoff-incr {:type :slider
20+
:min 0 :max 0.1
21+
:step 0.01
22+
:value 0.01}
23+
24+
:yoff-incr {:type :slider
25+
:min 0 :max 0.1
26+
:step 0.01
27+
:value 0.01}
28+
:animate {:type :checkbox :checked? false}}})
29+
30+
(defn setup! [{:keys [width height]}]
31+
(q/noise-seed (rand-int (-> js/Number (.-MAX_SAFE_INTEGER))))
32+
(q/background 255))
33+
34+
(defn gen-noise-image [width height xoff-incr yoff-incr z]
35+
(let [rand-color (fn [t1 t2]
36+
(Math/floor (q/map-range (q/noise t1 t2 z) 0 1 0 255)))
37+
img (q/create-image width height)
38+
roff 0
39+
goff 10000
40+
boff 100000
41+
px (q/pixels img)
42+
xoffs (take width (iterate #(+ % xoff-incr) 0.0))]
43+
(doseq [[x xoff] (map-indexed vector xoffs)]
44+
(let [yoffs (take height (iterate #(+ % yoff-incr) 0.0))]
45+
(doseq [[y yoff] (map-indexed vector yoffs)]
46+
(let [idx (* 4 (+ x (* y width)))
47+
r (rand-color (+ roff xoff) (+ roff yoff))
48+
g (rand-color (+ goff xoff) (+ goff yoff))
49+
b (rand-color (+ boff xoff) (+ boff yoff))]
50+
(aset px idx r)
51+
(aset px (+ 1 idx) g)
52+
(aset px (+ 2 idx) b)
53+
(aset px (+ 3 idx) 255)))))
54+
(q/update-pixels img)
55+
img))
56+
57+
(defn tick [{:keys [old-octaves old-falloff old-yoff-incr old-xoff-incr width height z] :as state}]
58+
(let [octaves (-> state :ui :octaves :value)
59+
falloff (-> state :ui :falloff :value)
60+
xoff-incr (-> state :ui :xoff-incr :value)
61+
yoff-incr (-> state :ui :yoff-incr :value)
62+
animate? (-> state :ui :animate :checked?)
63+
z (+ 0.1 z)]
64+
(if (or animate?
65+
(not= octaves old-octaves)
66+
(not= falloff old-falloff)
67+
(not= yoff-incr old-yoff-incr)
68+
(not= xoff-incr old-xoff-incr))
69+
(do
70+
(q/noise-detail octaves falloff)
71+
(assoc state
72+
:z z
73+
:old-octaves octaves
74+
:old-falloff falloff
75+
:old-xoff-incr xoff-incr
76+
:old-yoff-incr yoff-incr
77+
:img (gen-noise-image width height xoff-incr yoff-incr z)))
78+
state)))
79+
80+
(defn draw! [{:keys [ui img]}]
81+
(let [octaves (-> ui :octaves :value)
82+
falloff (-> ui :falloff :value)
83+
xoff-incr (-> ui :xoff-incr :value)
84+
yoff-incr (-> ui :yoff-incr :value)]
85+
86+
(when img
87+
(q/image img 0 0))
88+
(q/no-stroke)
89+
(q/fill 255)
90+
(q/rect 0 0 100 55)
91+
(q/fill 0)
92+
(q/text (gstring/format "octaves: %.2f" octaves) 10 20)
93+
(q/text (gstring/format "falloff: %.2f" falloff) 10 30)
94+
(q/text (gstring/format "xoff-incr: %.2f" xoff-incr) 10 40)
95+
(q/text (gstring/format "yoff-incr: %.2f" yoff-incr) 10 50)))

src/noc/sketch.cljs

+6-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
[noc.chapter-0-6e :as c0.6e]
1616
[noc.chapter-0-6 :as c0.6]
1717
[noc.chapter-0-7e :as c0.7e]
18-
[noc.chapter-0-7 :as c0.7]))
18+
[noc.chapter-0-7 :as c0.7]
19+
[noc.chapter-0-8e :as c0.8e]
20+
[noc.chapter-0-9e :as c0.9e]))
1921

2022
(def sketches {:walker (sketch-> c0.1)
2123
:rand-dist (sketch-> c0.2)
@@ -28,7 +30,9 @@
2830
:c0.6e (sketch-> c0.6e)
2931
:c0.6 (sketch-> c0.6)
3032
:c0.7e (sketch-> c0.7e)
31-
:c0.7 (sketch-> c0.7)})
33+
:c0.7 (sketch-> c0.7)
34+
:c0.8e (sketch-> c0.8e)
35+
:c0.9e (sketch-> c0.9e)})
3236

3337
(defn load-sketch [s]
3438
(when-let [sk (get sketches s)]

0 commit comments

Comments
 (0)