Added koch curve.

This commit is contained in:
Simon Brooke 2025-09-01 21:44:31 +01:00
parent 9ebb2d71bd
commit b0b087dd5e

View file

@ -7,7 +7,7 @@
<body>
<h1>Tittle: Turtles in <a href="https://github.com/babashka/scittle/tree/main">Scittle</a></h1>
<svg id="playing-field"
stype="width: 800; height: 900"
style="width: 100%; height: 900"
version="1.1"
width="800"
height="900"
@ -15,8 +15,9 @@
xmlns:svg="http://www.w3.org/2000/svg">
</svg>
<form><label for="repl">&gt;</label><input type="text" size="80" id="repl"></form>
<script type="application/x-scittle">
(def turtle (atom {:theta 0 :x 0 :y 0 :pen :up :ink "blue"}))
(def turtle (atom {:theta 0 :x 0 :y 0 :pen :up :nib 3 :ink "blue"}))
(defn log-turtle!
[]
@ -71,14 +72,10 @@
(defn turn-to!
"Turn the turtle to face `angle`, expressed in degrees with respect to the
X axis. If `angle` is not a number, throw an exception.
**TODO**: Note that 180&deg; is currently straight up; this is not intended, it
is intended that 0&deg; should be straight up, and this change will be made
before version 1.0."
X axis. If `angle` is not a number, throw an exception."
[angle]
(if (number? angle)
(swap! turtle assoc :theta (sanitise-angle angle))
(swap! turtle assoc :theta (sanitise-angle (+ 180 angle)))
(not-a-number! angle))
(.info js/console (str "(turn-to! " angle
") :: :theta now " (:theta @turtle))))
@ -131,23 +128,29 @@
(.appendChild playing-field elt)))
(swap! turtle assoc :x x :y y))))
(defn centre!
"Move the turtle to the centre of the playing field."
[]
(let [box (.getBoundingClientRect
(.getElementById js/document "playing-field"))
w (.-scrollWidth box)
h (.-scollHeight box)]
(move-to! (/ w 2) (/ h 2))
(turn-to! 0)))
(def ^:const pi 3.141592653589793)
(defn degrees->radians
"Return the equivalent, in radians, of this `angle` espressed in degrees"
[angle]
(let [v (when (number-or-error! angle)
(* angle (/ pi 180)))]
(.log js/console (str "(degrees->radians " angle ") => " v))
v))
(when (number-or-error! angle)
(* angle (/ pi 180))))
(defn radians->degrees
"Return the equivalent, in degrees, of this `angle` espressed in radians"
[angle]
(let [v (when (number-or-error! angle)
(/ (* angle 180) pi))]
(.log js/console (str "(radians->degrees " angle ") => " v))
v))
(when (number-or-error! angle)
(/ (* angle 180) pi)))
(defn sin
"Return the sine of this `angle`, considered to be expressed in degrees."
@ -174,7 +177,6 @@
(when (string? colour)
(swap! turtle assoc :ink colour)))
(defn set-nib!
"Set the nib (width) of the pen to this `n`, which should be a number."
[n]
@ -246,21 +248,40 @@
(when (< side sides)
(recur (inc side))))
(pen-up!))))
(defn koch
[length depth]
(pen-down!)
(.info js/console (str "(koch " length " " depth ")"))
(let [l' (/ length 3)
d' (dec depth)
i (= depth 1)]
(if i (move! l') (koch l' d'))
(turn! -60)
(if i (move! l') (koch l' d'))
(turn! 120)
(if i (move! l') (koch l' d'))
(turn! -60)
(if (= depth 1) (move! l') (koch l' d'))))
(log-turtle!)
(pen-up!)
(log-turtle!)
(move-to! 350 500)
(log-turtle!)
(doall (map #(let [v (* 16 (mod % 16))
c (str "rgb(" v "," 128 "," (- 256 v)")")]
(set-ink! c)
(draw-polygon! % 100))
(range 3 24)))
(turn-to! 180)
(set-ink! "blue")
(set-nib! 2)
(draw-tree! 100 20 16 8 0.2 0.8 9)
(move-to! 400 0)
(set-nib! 1)
(koch 800 5)
;; (doall (map #(let [v (* 16 (mod % 16))
;; c (str "rgb(" v "," 128 "," (- 256 v)")")]
;; (set-ink! c)
;; (draw-polygon! % 100))
;; (range 3 24)))
;; (turn-to! 180)
;; (set-ink! "blue")
;; (set-nib! 2)
;; (draw-tree! 100 20 16 8 0.2 0.8 9)
</script>
</body>
</html>