From 0288ea01a6af2a9ec10f17b9cf5772f025f9ab93 Mon Sep 17 00:00:00 2001 From: arne Date: Thu, 8 Dec 2022 12:20:24 +0100 Subject: [PATCH] Add resolution parameter to `scene->gcode-seq` --- src/heyarne/line_us/gcode.clj | 83 ++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/src/heyarne/line_us/gcode.clj b/src/heyarne/line_us/gcode.clj index f083ffe..a6b7b00 100644 --- a/src/heyarne/line_us/gcode.clj +++ b/src/heyarne/line_us/gcode.clj @@ -2,7 +2,9 @@ "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] - [clojure.string :as str])) + [clojure.string :as str] + [thi.ng.geom.circle :as c] + [thi.ng.geom.rect :as r])) ;; scroll down for a rich comment with usage examples @@ -20,9 +22,12 @@ (defn- ->gcode-verts ([geom] - (vertices->gcode-verts (g/vertices geom))) - ([geom r] - (vertices->gcode-verts (g/vertices geom r)))) + (->gcode-verts geom {})) + ([geom {:keys [r]}] + (vertices->gcode-verts (try + (g/vertices geom r) + (catch IllegalArgumentException _ + (g/vertices geom)))))) (def gcode-seq "Convert thi.ng.geom types into a sequence of G-Code to plot them. The G-Code @@ -34,7 +39,7 @@ parameter `r` can be used to adjust the resolution." (comp gcode-verts->gcode-seq ->gcode-verts)) -(defn geom? [x] +(defn- geom? [x] (str/starts-with? (pr-str x) "#thi.ng.geom.")) ;; (pr-str (c/circle 20)) ;; => "#thi.ng.geom.types.Circle2{:p [0.0 0.0], :r 20.0}" @@ -46,17 +51,15 @@ 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 - result []] - (cond - (nil? el) result - (sequential? el) (recur rs (concat result (scene->gcode-seq el))) ;; recursively convert sequences - (geom? el) (recur rs (conj result (gcode-seq el))) ;; convert geoms - (map? el) (recur rs result)))) ;; ignore attribute maps - -;; TODO: Resolution for scenes? -;; `g/vertices` fails when called with a second arg for `r/rect` + ([scene] (scene->gcode-seq scene {})) + ([scene {:keys [r] :as opts}] + (loop [[el & rs] scene + result []] + (cond + (nil? el) result + (sequential? el) (recur rs (vec (concat result (scene->gcode-seq el opts)))) ;; recursively convert sequences + (geom? el) (recur rs (conj result (if r (gcode-seq el r) (gcode-seq el)))) ;; convert geoms + (map? el) (recur rs result))))) ;; ignore attribute maps (comment ;; example usage: @@ -72,7 +75,7 @@ ;; "G01 X200.0 Y200.0 Z1000") ;; you can pass a second argument to increase or decrease resolution - (gcode-seq (c/circle) 10) + (gcode-seq (c/circle) {:r 10}) ;; => ("G01 X1.0 Y0.0 Z1000" ;; "G01 X1.0 Y0.0 Z0" ;; "G01 X0.8090169943749475 Y0.5877852522924731 Z0" @@ -86,15 +89,17 @@ ;; "G01 X0.8090169943749473 Y-0.5877852522924734 Z0" ;; "G01 X0.8090169943749473 Y-0.5877852522924734 Z1000") - ;; `scene->gcode-seq` converts a tree of elements into a sequence of gcode drawing instructions + ;; `scene->gcode-seq` converts a tree of arbitrarily nested elements into a + ;; sequence of gcode drawing instructions (scene->gcode-seq - [[(r/rect [0 0] [10 10]) {:attributes/ignored? true}] - (r/rect [0 0] [10 10]) - [(r/rect [5 5] [15 15]) - (r/rect [20 20] [40 40]) - [(r/rect [5 5] [15 15])] - (r/rect [20 20] [40 40])]]) - ;; => (("G01 X0.0 Y0.0 Z1000" + [[(r/rect [0 0] [10 10]) {:attributes/ignored? true}] + (r/rect [0 0] [10 10]) + [(r/rect [5 5] [15 15]) + (r/rect [20 20] [40 40]) + [(c/circle [5 5] 10)] + (r/rect [20 20] [40 40])]] + {:r 10}) + ;; => [("G01 X0.0 Y0.0 Z1000" ;; "G01 X0.0 Y0.0 Z0" ;; "G01 X10.0 Y0.0 Z0" ;; "G01 X10.0 Y10.0 Z0" @@ -106,12 +111,6 @@ ;; "G01 X10.0 Y10.0 Z0" ;; "G01 X0.0 Y10.0 Z0" ;; "G01 X0.0 Y10.0 Z1000") - ;; ("G01 X20.0 Y20.0 Z1000" - ;; "G01 X20.0 Y20.0 Z0" - ;; "G01 X40.0 Y20.0 Z0" - ;; "G01 X40.0 Y40.0 Z0" - ;; "G01 X20.0 Y40.0 Z0" - ;; "G01 X20.0 Y40.0 Z1000") ;; ("G01 X5.0 Y5.0 Z1000" ;; "G01 X5.0 Y5.0 Z0" ;; "G01 X15.0 Y5.0 Z0" @@ -124,10 +123,22 @@ ;; "G01 X40.0 Y40.0 Z0" ;; "G01 X20.0 Y40.0 Z0" ;; "G01 X20.0 Y40.0 Z1000") - ;; ("G01 X5.0 Y5.0 Z1000" - ;; "G01 X5.0 Y5.0 Z0" + ;; ("G01 X15.0 Y5.0 Z1000" ;; "G01 X15.0 Y5.0 Z0" - ;; "G01 X15.0 Y15.0 Z0" - ;; "G01 X5.0 Y15.0 Z0" - ;; "G01 X5.0 Y15.0 Z1000")) + ;; "G01 X13.090169943749475 Y10.877852522924732 Z0" + ;; "G01 X8.090169943749475 Y14.510565162951535 Z0" + ;; "G01 X1.9098300562505264 Y14.510565162951536 Z0" + ;; "G01 X-3.0901699437494727 Y10.877852522924734 Z0" + ;; "G01 X-5.0 Y5.000000000000001 Z0" + ;; "G01 X-3.0901699437494763 Y-0.87785252292473 Z0" + ;; "G01 X1.9098300562505246 Y-4.510565162951535 Z0" + ;; "G01 X8.090169943749473 Y-4.510565162951536 Z0" + ;; "G01 X13.090169943749473 Y-0.8778525229247336 Z0" + ;; "G01 X13.090169943749473 Y-0.8778525229247336 Z1000") + ;; ("G01 X20.0 Y20.0 Z1000" + ;; "G01 X20.0 Y20.0 Z0" + ;; "G01 X40.0 Y20.0 Z0" + ;; "G01 X40.0 Y40.0 Z0" + ;; "G01 X20.0 Y40.0 Z0" + ;; "G01 X20.0 Y40.0 Z1000")] )