Skip to content

Commit

Permalink
Chapter 0 Exercise 10
Browse files Browse the repository at this point in the history
  • Loading branch information
Ramblurr committed Jun 3, 2024
1 parent b1d26ff commit b70a08e
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 22 deletions.
14 changes: 14 additions & 0 deletions notebooks/chapter_0.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,17 @@ Well this one is pretty cool. The sliders control (in order from left to right):
* Amount `yoff` is incremented by

Finally there is a checkbox to enable animation using the 3rd dimension of the perlin noise.


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

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

The performance for this one is pretty bad here in the notebook. I'm not 100%
sure why. I switched from a naive nested 2-d vector to using transients, but
that didn't have much of an effect. Some day I'll come back and investigate
more.
84 changes: 84 additions & 0 deletions src/noc/chapter_0_10e.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
(ns noc.chapter-0-10e
(:require
[quil.sketch :as ap :include-macros true]
[quil.core :as q]))

(def size [640 240])

(defn init-terrain [cell-size width height]
(let [cols (quot width cell-size)
rows (quot height cell-size)]
{:cell-size cell-size
:w width
:h height
:cols cols
:rows rows
:zoff 0.0
:cells []}))

;; My initial naive impl
#_(defn tick-terrain [{:keys [cols rows zoff] :as terrain}]
(let [updated-cells (vec (map-indexed
(fn [i _]
(vec (map-indexed
(fn [j _]
(q/map-range (q/noise (+ (* i 0.1) zoff) (+ (* j 0.1) zoff) zoff) 0 1 -120 120))
(range rows))))
(range cols)))
new-zoff (+ zoff 0.01)]
(assoc terrain :cells updated-cells :zoff new-zoff)))

;; Using transients to try and speed it up
(defn tick-terrain [{:keys [cols rows zoff] :as terrain}]
(let [updated-cells (persistent!
(reduce
(fn [acc i]
(assoc! acc i
(persistent!
(reduce
(fn [inner-acc j]
(assoc! inner-acc j
(q/map-range (q/noise (+ (* i 0.1) zoff) (+ (* j 0.1) zoff) zoff) 0 1 -120 120)))
(transient []) (range rows)))))
(transient []) (range cols)))
new-zoff (+ zoff 0.01)]
(assoc terrain :cells updated-cells :zoff new-zoff)))

(defn init-state [{:keys [width height]}]
{:terrain
(tick-terrain (init-terrain 20 800 400))
:theta 0.0})

(defn setup! [{:keys [width height terrain]}]
(q/background 255))

(defn tick [state]
(-> state
(update :terrain tick-terrain)
(update :theta #(+ % 0.0025))))

(defn draw-terrain! [{:keys [cells cell-size cols rows w h]}]
(doseq [x (range (dec cols))]
;; Quil bug https://github.com/quil/quil/issues/415
(.beginShape (ap/current-applet) (aget js/p5.prototype "QUAD_STRIP"))
(doseq [y (range rows)]
(q/stroke 0)
(let [current-elevation (get-in cells [x y])
current-shade (q/map-range current-elevation -120 120 0 255)
x-coordinate (- (* x cell-size) (/ w 2))
y-coordinate (- (* y cell-size) (/ h 2))]
(q/fill current-shade 255)
(q/vertex x-coordinate y-coordinate current-elevation)
(q/vertex (+ x-coordinate cell-size) y-coordinate (get-in cells [(inc x) y]))))
(q/end-shape)))

(defn draw! [{:keys [terrain theta] :as state}]
(q/background 255)
(q/push-style)
(q/push-matrix)
(q/translate 0 20 -200)
(q/rotate-x (/ q/PI 3))
(q/rotate-z theta)
(draw-terrain! terrain)
(q/pop-matrix)
(q/pop-style))
8 changes: 8 additions & 0 deletions src/noc/sketch.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,11 @@
:tick ~(symbol (str chapter "/tick"))
:draw ~(symbol (str chapter "/draw!"))
:size ~(symbol (str chapter "/size"))})

(defmacro sketch-3d-> [chapter]
`{:init ~(symbol (str chapter "/init-state"))
:setup ~(symbol (str chapter "/setup!"))
:tick ~(symbol (str chapter "/tick"))
:draw ~(symbol (str chapter "/draw!"))
:size ~(symbol (str chapter "/size"))
:renderer :p3d})
49 changes: 27 additions & 22 deletions src/noc/sketch.cljs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(ns noc.sketch
(:require-macros [noc.sketch :refer [sketch->]])
(:require-macros [noc.sketch :refer [sketch-> sketch-3d->]])
(:require [quil.core :as q]
[quil.middleware :as m]
[quil.sketch :as ap :include-macros true]
Expand All @@ -17,22 +17,25 @@
[noc.chapter-0-7e :as c0.7e]
[noc.chapter-0-7 :as c0.7]
[noc.chapter-0-8e :as c0.8e]
[noc.chapter-0-9e :as c0.9e]))
[noc.chapter-0-9e :as c0.9e]
[noc.chapter-0-10e :as c0.10e]))

(def sketches {:walker (sketch-> c0.1)
:rand-dist (sketch-> c0.2)
:walker-right (sketch-> c0.3)
:walker-dynamic (sketch-> c0.3e)
:random-gaussian (sketch-> c0.4)
:c0.4e (sketch-> c0.4e)
:c0.5e (sketch-> c0.5e)
:c0.5 (sketch-> c0.5)
:c0.6e (sketch-> c0.6e)
:c0.6 (sketch-> c0.6)
:c0.7e (sketch-> c0.7e)
:c0.7 (sketch-> c0.7)
:c0.8e (sketch-> c0.8e)
:c0.9e (sketch-> c0.9e)})
(def sketches
{:walker (sketch-> c0.1)
:rand-dist (sketch-> c0.2)
:walker-right (sketch-> c0.3)
:walker-dynamic (sketch-> c0.3e)
:random-gaussian (sketch-> c0.4)
:c0.4e (sketch-> c0.4e)
:c0.5e (sketch-> c0.5e)
:c0.5 (sketch-> c0.5)
:c0.6e (sketch-> c0.6e)
:c0.6 (sketch-> c0.6)
:c0.7e (sketch-> c0.7e)
:c0.7 (sketch-> c0.7)
:c0.8e (sketch-> c0.8e)
:c0.9e (sketch-> c0.9e)
:c0.10e (sketch-3d-> c0.10e)})

(defn load-sketch [s]
(when-let [sk (get sketches s)]
Expand Down Expand Up @@ -141,12 +144,14 @@

(defn show-sketch [adjust-frame {:keys [init setup tick draw size] :as opts} el]
{:applet (apply q/sketch (apply concat
(-> opts
(assoc :middleware [m/fun-mode])
(assoc :host el)
(assoc :update (partial tick-wrapper tick))
(assoc :setup (partial setup-wrapper (partial adjust-frame el) init setup))
(assoc :draw (partial draw-wrapper draw)))))
(doto
(-> opts
(assoc :middleware [m/fun-mode])
(assoc :host el)
(assoc :update (partial tick-wrapper tick))
(assoc :setup (partial setup-wrapper (partial adjust-frame el) init setup))
(assoc :draw (partial draw-wrapper draw)))
prn)))
:sketch-name (:sketch-name opts)
:opts opts
:el el})

0 comments on commit b70a08e

Please sign in to comment.