Skip to content

Instantly share code, notes, and snippets.

@robbieh
Last active December 24, 2022 16:23
Show Gist options
  • Save robbieh/f4c61a6bd98afc3c25cfe1e3a08dbb55 to your computer and use it in GitHub Desktop.
Save robbieh/f4c61a6bd98afc3c25cfe1e3a08dbb55 to your computer and use it in GitHub Desktop.
Manhattan distance like walk, but across a hex grid
;Named "Babel distance" after the Borges story "The Library of Babel"
(def bearings
{:E [120 240 0 360
:NE [60 180 300]
:NW [120 240 0 360
:W [60 180 300]
:SW [120 240 0 360
:SE [60 180 300]})
(defn babel-distance-lines
"Generate next line segment for a Manhattan-distance like walk but on a hex grid.
width - hex with as 'radius'
bearing - one of [:E :NE :NW :W :SW :SE]
start - [x y] vertex for start point
end - [x y]
kill - max number of iterations allowed"
[width bearing start end & kill]
(loop [start start
end end
bearing bearing
lines []
kill (if kill kill 100)]
(let [[sx sy] start
[ex ey] end
angles (apply merge (map hash-map [:a :b :c] (bearing bearings)))
atan (fm/atan2 (- ey sy)(- ex sx))
degrees (-> atan fm/degrees (mod 360) (Math/round) )
differences (mapv #(vector (first %) (mod (Math/abs (- (second %) degrees)) 360)) angles)
[closestkey
closestbearing] (apply min-key second differences)
angle (get angles closestkey)
theta (fm/radians angle)
nx (-> (fm/cos theta) (* width) (+ sx))
ny (-> (fm/sin theta) (* width) (+ sy))
distance (fm/dist nx ny ex ey)
lines (conj lines [[sx sy] [nx ny]])
newbearing (case angle 0 :W 60 :E 120 :W 180 :E 240 :W 300 :E 360 :W :unk)]
(if (or (= kill 0) (<= distance (* 0.8 width) ))
lines
(recur [nx ny] end newbearing lines (dec kill))) )))
@robbieh
Copy link
Author

robbieh commented Dec 20, 2022

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment