Skip to content

Commit

Permalink
Chapter 1 Examples 3 and 4, plus Vector Math table reference
Browse files Browse the repository at this point in the history
  • Loading branch information
Ramblurr committed Jun 4, 2024
1 parent 7d8869e commit ecd9f9b
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 3 deletions.
17 changes: 16 additions & 1 deletion dev/user.clj
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,20 @@
[:_ui]
#(dissoc % :foobar))
(range 10)
;;

()

(require '[thi.ng.math.core :as tm])
(require '[thi.ng.geom.vector :as v])
(require '[thi.ng.geom.core :as g])
(let [v1 (v/vec2 2 2)
v2 (v/vec2 1 1)
v3 (v/vec2 3 4)]
(= v3 (tm/+ v1 v2))
(= (tm/* v1 4) (v/vec2 8.0 8.0))
(= 5.0 (tm/mag (v/vec2 4 3)))
(tm/+ (v/vec2 1 1) (v/vec2 1 1))
(tm/normalize (v/vec2 2 3))
(g/heading-xy (v/vec2 2 3)))
;;
)
81 changes: 81 additions & 0 deletions notebooks/chapter_1.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,84 @@ I am skipping these exercises as they don't add much to what we did in Example 1
```

This was more an exercise in 3d than vectors, haha! I fake the boundary condition for the sphere, but it looks more or less right.


## More Vector Math

This section isn't an example or exercise, but this list of vector math related functions is very useful! The `thi.ng/geom` toolkit is very powerful, but doesn't have an easy to use getting started page.

So I'm reproducing the vector math function table from the book, but with functions from `thi.ng/geom`.

To create a vector use [`thi.ng.geom.vector/vec2`](https://cljdoc.org/d/thi.ng/geom/1.0.1/api/thi.ng.geom.vector#vec2) or [`thi.ng.geom.vector/vec3`](https://cljdoc.org/d/thi.ng/geom/1.0.1/api/thi.ng.geom.vector#vec3).

Example:

```
(clerk/code "
(let [pos (v/vec2 100 100)
[x y] pos]
;; use x y
)
(let [pos (v/vec3 100 100 100)
[x y z] pos]
;; use x y z
)
")
```

In the following table the namespaces referenced are:

* [`[thi.ng.math.core :as tm]`](https://github.com/thi-ng/math/blob/0.3.2/src/core.org)
* [`[thi.ng.geom.core :as g]`](https://cljdoc.org/d/thi.ng/geom/1.0.1/api/thi.ng.geom.core)

| p5.js Method | `thi.ng` Function | Task |
|------------------|--------------------------|----------------------------------------------------------------------------------|
| `add()` | `(tm/+ a b)` | Adds vector `a` to vector `b` |
| `sub()` | `(tm/- a b` | Subtracts vector `a` from vector `b` |
| `mult()` | `(tm/* a b)` | Scales this vector with multiplication |
| `div()` | `(tm/div a b)` | Scales this vector with division |
| `mag()` | `(tm/mag a)` | Returns the magnitude of the vector `a` |
| `setMag()` | `-` | Sets the magnitude of this vector- Not available AFAICT |
| `normalize()` | `(tm/normalize a)` | Normalizes this vector to a unit length of 1 |
| `limit()` | `(tm/limit a)` | Limits the magnitude of this vector |
| `heading()` | `(g/heading-xy a)` | Returns the 2D heading of this vector expressed as an angle |
| `rotate()` | `(g/rotate a angle)` | Rotates this 2D vector by `angle` (in radians) |
| `lerp()` | `(tm/mix a b amt)` | Linear interpolates vector `a` towards vector `b` by `amt` |
| `dist()` | `(g/dist a b)` | Returns the Euclidean distance between vector `a` and `b` (considered as points) |
| `angleBetween()` | `(g/angle-between a b )` | Finds the angle between vector `a` and vector `b` |
| `dot()` | `(tm/dot a b)` | Returns $$\vec{a} \cdot \vec{b} $$ (the dot product) |
| `cross()` | `(tm/cross a b)` | Returns $$\vec{a} \times \vec{b} $$ (the cross product) |
| `random2D()` | `-` | Returns a random 2D vector - Not available AFAICT |
| `random3D()` | `-` | Returns a random 3D vector - Not available AFAICT |

Some extra notes:

Most of the math functions in `thi.ng` tend to convert integers to doubles. For example `(tm/mag (v/vec2 4 3))` produces `5.0` not `5` (that makes sense for magnitude since it is often a fractional number).

But this it may be surprising. `(tm/+ (v/vec2 1 1) (v/vec2 1 1))` produces a vector with `2.0` as the x and y components, not `2`.


## [Example 1.3: Vector Subtraction](https://natureofcode.com/vectors/#example-13-vector-subtraction)

```clojure
^{::clerk/no-cache true ::clerk/viewer clerk/code}
(slurp "src/noc/chapter_1_3.cljs")
(show-sketch :c1.3)
```


## [Example 1.4: Multiplying a Vector](https://natureofcode.com/vectors/#example-14-multiplying-a-vector)


```clojure
^{::clerk/no-cache true ::clerk/viewer clerk/code}
(slurp "src/noc/chapter_1_4.cljs")
(show-sketch :c1.4)
```

Ok, for this one I got tired of destructuring the vectors or using `first` and `second` to yoink out the components to pass to quil's `line` function. A little helper goes a long way.

By the way, Daniel's exposition on the vector math in this chapter is really great. Don't just look at the code, refer to the text and the illustrations to really get an understanding of the vector math.
30 changes: 30 additions & 0 deletions src/noc/chapter_1_3.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
(ns noc.chapter-1-3
(:require

[thi.ng.math.core :as tm]
[thi.ng.geom.vector :as v]
[quil.core :as q]))

(def size [640 240])

(defn init-state [{:keys [width height] :as state}]
{})

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

(defn tick [state]
state)

(defn draw! [{:keys [width height mouse-x mouse-y]}]
(let [mouse (v/vec2 mouse-x mouse-y)
center (v/vec2 (quot width 2) (quot height 2))
subtracted (tm/- mouse center)]
(q/background 255)
(q/stroke-weight 4)
(q/stroke 200)
(q/line 0 0 mouse-x mouse-y)
(q/line 0 0 (first center) (second center))
(q/stroke 0)
(q/translate (quot width 2) (quot height 2))
(q/line 0 0 (first subtracted) (second subtracted))))
35 changes: 35 additions & 0 deletions src/noc/chapter_1_4.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
(ns noc.chapter-1-4
(:require

[thi.ng.math.core :as tm]
[thi.ng.geom.vector :as v]
[quil.core :as q]))

(def size [640 240])

(defn init-state [{:keys [width height] :as state}]
{})

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

(defn tick [state]
state)

(defn line [[x1 y1] [x2 y2]]
(q/line x1 y1 x2 y2))

(defn draw! [{:keys [width height mouse-x mouse-y]}]
(let [zero (v/vec2 0 0)
mouse (v/vec2 mouse-x mouse-y)
center (v/vec2 (quot width 2) (quot height 2))
subtracted (tm/- mouse center)
multed (tm/* subtracted 0.5)]
(q/background 255)
(q/translate (quot width 2) (quot height 2))
(q/stroke-weight 2)
(q/stroke 200)
(line zero subtracted)
(q/stroke 0)
(q/stroke-weight 4)
(line zero multed)))
8 changes: 6 additions & 2 deletions src/noc/sketch.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
[noc.chapter-0-10e :as c0.10e]
[noc.chapter-1-1 :as c1.1]
[noc.chapter-1-2 :as c1.2]
[noc.chapter-1-3e :as c1.3e]))
[noc.chapter-1-3e :as c1.3e]
[noc.chapter-1-3 :as c1.3]
[noc.chapter-1-4 :as c1.4]))

(def sketches
{:walker (sketch-> c0.1)
Expand All @@ -41,7 +43,9 @@
:c0.10e (sketch-3d-> c0.10e)
:c1.1 (sketch-> c1.1)
:c1.2 (sketch-> c1.2)
:c1.3e (sketch-3d-> c1.3e)})
:c1.3e (sketch-3d-> c1.3e)
:c1.3 (sketch-> c1.3)
:c1.4 (sketch-> c1.4)})

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

0 comments on commit ecd9f9b

Please sign in to comment.