Fix plotting closed shapes
This commit is contained in:
parent
a136529e0d
commit
9b18bc507f
1 changed files with 72 additions and 29 deletions
|
|
@ -18,40 +18,56 @@
|
|||
(map (fn [[x y z]]
|
||||
(str "G01 X" x " Y" y " Z" z)) gcode-verts))
|
||||
|
||||
(defn- vertices*
|
||||
"Wrapper around geom.core/vertices that makes sure calls for geometries
|
||||
which don't support the resolution parameter don't fail."
|
||||
[geom {:keys [res]}]
|
||||
(try
|
||||
(if res (g/vertices geom res) (g/vertices geom))
|
||||
(catch clojure.lang.ArityException _
|
||||
(g/vertices geom))))
|
||||
|
||||
(defn- vertices
|
||||
"Return the vertices of the outline of a shape; if a geometry is closed, the
|
||||
first and last vertex will be the same."
|
||||
([geom] (vertices geom {}))
|
||||
([geom opts]
|
||||
(let [last-p (last (g/sample-uniform geom Double/MAX_VALUE true))
|
||||
vertices (vertices* geom opts)]
|
||||
(cond-> vertices
|
||||
(not= last-p (last vertices)) (conj last-p)))))
|
||||
|
||||
(defn- ->gcode-verts
|
||||
([geom]
|
||||
(->gcode-verts geom {}))
|
||||
([geom {:keys [r]}]
|
||||
(vertices->gcode-verts (try
|
||||
(if r (g/vertices geom r) (g/vertices geom))
|
||||
(catch IllegalArgumentException _
|
||||
(g/vertices geom))))))
|
||||
([geom {:keys [res]}]
|
||||
(vertices->gcode-verts (vertices geom res))))
|
||||
|
||||
(def gcode-seq
|
||||
"Convert thi.ng.geom types into a sequence of G-Code to plot them.
|
||||
|
||||
An optional parameter `{:r 10}` can be used to adjust the sampling resolution
|
||||
for the shape."
|
||||
An optional parameter `{:res 10}` can be used to adjust the sampling resolution
|
||||
for the shape, if the shape supports it."
|
||||
(comp gcode-verts->gcode-seq ->gcode-verts))
|
||||
|
||||
(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}"
|
||||
;; (pr-str (c/circle 20)) ;; => "#thi.ng.geom.types.Circle2{:p [0.0 0.0], :res 20.0}"
|
||||
|
||||
(defn scene->gcode-seq
|
||||
"Converts a scene into a sequence of G-Code instructions. A scene is an
|
||||
arbitrarily nested vector of geom instances and hiccup-like in that each
|
||||
object can be followed by a map of attributes. The map is currently ignored."
|
||||
([scene] (scene->gcode-seq scene {}))
|
||||
([scene {:keys [r] :as opts}]
|
||||
([scene {:keys [res] :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
|
||||
(sequential? el) (recur rs (vec (concat result (scene->gcode-seq el opts)))) ;; recursively convert sequences
|
||||
(geom? el) (recur rs (conj result (if res (gcode-seq el res) (gcode-seq el)))) ;; convert geoms
|
||||
(map? el) (recur rs result))))) ;; ignore attribute maps
|
||||
|
||||
(comment
|
||||
;; example usage:
|
||||
|
|
@ -67,70 +83,97 @@
|
|||
;; "G01 X200.0 Y200.0 Z1000")
|
||||
|
||||
;; you can pass a second argument to increase or decrease resolution
|
||||
(gcode-seq (c/circle) {:r 10})
|
||||
(gcode-seq (c/circle) {:res 10})
|
||||
;; => ("G01 X1.0 Y0.0 Z1000"
|
||||
;; "G01 X1.0 Y0.0 Z0"
|
||||
;; "G01 X0.9510565162951535 Y0.3090169943749474 Z0"
|
||||
;; "G01 X0.8090169943749475 Y0.5877852522924731 Z0"
|
||||
;; "G01 X0.5877852522924731 Y0.8090169943749475 Z0"
|
||||
;; "G01 X0.30901699437494745 Y0.9510565162951535 Z0"
|
||||
;; "G01 X6.123233995736766E-17 Y1.0 Z0"
|
||||
;; "G01 X-0.30901699437494734 Y0.9510565162951536 Z0"
|
||||
;; "G01 X-0.587785252292473 Y0.8090169943749475 Z0"
|
||||
;; "G01 X-0.8090169943749473 Y0.5877852522924732 Z0"
|
||||
;; "G01 X-0.9510565162951535 Y0.3090169943749475 Z0"
|
||||
;; "G01 X-1.0 Y1.2246467991473532E-16 Z0"
|
||||
;; "G01 X-0.9510565162951535 Y-0.30901699437494773 Z0"
|
||||
;; "G01 X-0.8090169943749476 Y-0.587785252292473 Z0"
|
||||
;; "G01 X-0.5877852522924732 Y-0.8090169943749473 Z0"
|
||||
;; "G01 X-0.30901699437494756 Y-0.9510565162951535 Z0"
|
||||
;; "G01 X-1.8369701987210297E-16 Y-1.0 Z0"
|
||||
;; "G01 X0.30901699437494723 Y-0.9510565162951536 Z0"
|
||||
;; "G01 X0.5877852522924729 Y-0.8090169943749476 Z0"
|
||||
;; "G01 X0.8090169943749473 Y-0.5877852522924734 Z0"
|
||||
;; "G01 X0.8090169943749473 Y-0.5877852522924734 Z1000")
|
||||
;; "G01 X0.9510565162951535 Y-0.3090169943749476 Z0"
|
||||
;; "G01 X0.9510565162951535 Y-0.3090169943749476 Z1000")
|
||||
;; `scene->gcode-seq` converts a tree of arbitrarily nested 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])
|
||||
[(c/circle [5 5] 10)]
|
||||
(r/rect [20 20] [40 40])]]
|
||||
{:r 10})
|
||||
[[(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])]]
|
||||
{:res 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"
|
||||
;; "G01 X0.0 Y10.0 Z0"
|
||||
;; "G01 X0.0 Y10.0 Z1000")
|
||||
;; "G01 X0.0 Y0.0 Z0"
|
||||
;; "G01 X0.0 Y0.0 Z1000")
|
||||
;; ("G01 X0.0 Y0.0 Z1000"
|
||||
;; "G01 X0.0 Y0.0 Z0"
|
||||
;; "G01 X10.0 Y0.0 Z0"
|
||||
;; "G01 X10.0 Y10.0 Z0"
|
||||
;; "G01 X0.0 Y10.0 Z0"
|
||||
;; "G01 X0.0 Y10.0 Z1000")
|
||||
;; "G01 X0.0 Y0.0 Z0"
|
||||
;; "G01 X0.0 Y0.0 Z1000")
|
||||
;; ("G01 X5.0 Y5.0 Z1000"
|
||||
;; "G01 X5.0 Y5.0 Z0"
|
||||
;; "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 X5.0 Y5.0 Z0"
|
||||
;; "G01 X5.0 Y5.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 X20.0 Y20.0 Z0"
|
||||
;; "G01 X20.0 Y20.0 Z1000")
|
||||
;; ("G01 X15.0 Y5.0 Z1000"
|
||||
;; "G01 X15.0 Y5.0 Z0"
|
||||
;; "G01 X14.510565162951535 Y8.090169943749475 Z0"
|
||||
;; "G01 X13.090169943749475 Y10.877852522924732 Z0"
|
||||
;; "G01 X10.877852522924732 Y13.090169943749475 Z0"
|
||||
;; "G01 X8.090169943749475 Y14.510565162951535 Z0"
|
||||
;; "G01 X5.000000000000001 Y15.0 Z0"
|
||||
;; "G01 X1.9098300562505264 Y14.510565162951536 Z0"
|
||||
;; "G01 X-0.87785252292473 Y13.090169943749475 Z0"
|
||||
;; "G01 X-3.0901699437494727 Y10.877852522924734 Z0"
|
||||
;; "G01 X-4.510565162951535 Y8.090169943749475 Z0"
|
||||
;; "G01 X-5.0 Y5.000000000000001 Z0"
|
||||
;; "G01 X-4.510565162951535 Y1.9098300562505228 Z0"
|
||||
;; "G01 X-3.0901699437494763 Y-0.87785252292473 Z0"
|
||||
;; "G01 X-0.8778525229247327 Y-3.0901699437494727 Z0"
|
||||
;; "G01 X1.9098300562505246 Y-4.510565162951535 Z0"
|
||||
;; "G01 X4.999999999999998 Y-5.0 Z0"
|
||||
;; "G01 X8.090169943749473 Y-4.510565162951536 Z0"
|
||||
;; "G01 X10.87785252292473 Y-3.0901699437494763 Z0"
|
||||
;; "G01 X13.090169943749473 Y-0.8778525229247336 Z0"
|
||||
;; "G01 X13.090169943749473 Y-0.8778525229247336 Z1000")
|
||||
;; "G01 X14.510565162951535 Y1.9098300562505237 Z0"
|
||||
;; "G01 X15.0 Y5.0 Z0"
|
||||
;; "G01 X15.0 Y5.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 X20.0 Y20.0 Z0"
|
||||
;; "G01 X20.0 Y20.0 Z1000")]
|
||||
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue