Re-add line-us & gcode utils

This commit is contained in:
arne 2022-11-04 00:33:36 +01:00
commit 37e152bc60
3 changed files with 185 additions and 0 deletions

View file

@ -0,0 +1,76 @@
(ns heyarne.line-us.gcode
"Provides functions to move from geometry types provided by thi.ng to gcode
so you can plot them."
(:require [thi.ng.geom.core :as g]
[thi.ng.geom.types]
[thi.ng.geom.vector :as v]
[thi.ng.geom.circle :as c])
(:import [thi.ng.geom.types Line2 LineStrip2 Circle2]))
(defprotocol GCode
"Convert thi.ng.geom types into sequences of GCode to plot them. The GCode
instructions are given as a sequence of vectors, where each vector is given
as [x y z]."
(->gcode [_] [_ r]
"Returns G01 movements on the x, y, and z axis. Z is constantly 1000 in the
current implementation, but this might change in the future. The optional
parameter `r` can be used to adjust the resolution."))
(defn- point-seq->gcode [pts]
(let [vertices pts
[l-x l-y] (last vertices)]
(conj (mapv (fn [[x y]]
[x y 0]) vertices)
[l-x l-y 1000])))
(defn gcode-seq->str [gcode-seq]
(map (fn [[x y z]]
(str "G01 X" x " Y" y " Z" z)) gcode-seq))
(extend-protocol GCode
Line2
(->gcode
([_] (point-seq->gcode (:points _)))
([_ r] (->gcode _)))
LineStrip2
(->gcode
([_] (point-seq->gcode (:points _)))
([_ r] (->gcode _)))
Circle2
(->gcode
([_] (point-seq->gcode (:points (g/as-polygon _))))
([_ r] (point-seq->gcode (:points (g/as-polygon _ r))))))
(defn scene->gcode
"Converts a scene into a sequence of gcode instructions. A scene is an
arbitrarily nested vector of geom instances.
A scene is hiccup like in that each object can be followed by a map of
attributes, which can provide addition information about the preceding
object."
[scene]
(loop [[el & rs] scene
res []]
(cond
(seq? el) (recur (scene->gcode el) res)
(map? el) (recur rs res)
:else (if (seq rs)
(recur rs (conj res (gcode-seq->str (->gcode el))))
(flatten res)))))
(comment
(require '[thi.ng.geom.circle :as c])
;; convert a single element
(->
(->gcode (c/circle) 10)
(gcode-seq->str))
;; convert a tree of elements
(scene->gcode
[(c/circle 10)
[(c/circle [0 20] 10)
(c/circle [0 40] 10)]])
)