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