Allow adding parts to cut via the UI
This commit is contained in:
parent
90af4814fc
commit
322174c9e7
3 changed files with 88 additions and 17 deletions
1
deps.edn
1
deps.edn
|
|
@ -9,5 +9,6 @@
|
||||||
{:cljs {:extra-deps {thheller/shadow-cljs {:mvn/version "2.8.109"}
|
{:cljs {:extra-deps {thheller/shadow-cljs {:mvn/version "2.8.109"}
|
||||||
appliedscience/js-interop {:mvn/version "0.2.5"}
|
appliedscience/js-interop {:mvn/version "0.2.5"}
|
||||||
reagent/reagent {:mvn/version "1.1.0"}
|
reagent/reagent {:mvn/version "1.1.0"}
|
||||||
|
fipp/fipp {:mvn/version "0.6.25"}
|
||||||
#_#_ refactor-nrepl/refactor-nrepl {:mvn/version "3.1.0"}
|
#_#_ refactor-nrepl/refactor-nrepl {:mvn/version "3.1.0"}
|
||||||
#_#_ cider/cider-nrepl {:mvn/version "0.27.2"}}}}}
|
#_#_ cider/cider-nrepl {:mvn/version "0.27.2"}}}}}
|
||||||
|
|
|
||||||
|
|
@ -33,3 +33,16 @@ rect {
|
||||||
stroke-width: 1;
|
stroke-width: 1;
|
||||||
stroke: coral
|
stroke: coral
|
||||||
}
|
}
|
||||||
|
|
||||||
|
text {
|
||||||
|
fill: coral;
|
||||||
|
font: 12px sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.num-rects {
|
||||||
|
width: 4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rect-dim {
|
||||||
|
width: 6em;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,22 +3,23 @@
|
||||||
[reagent.dom :as dom]
|
[reagent.dom :as dom]
|
||||||
[thi.ng.geom.core :as geom]
|
[thi.ng.geom.core :as geom]
|
||||||
[thi.ng.geom.rect :as rect]
|
[thi.ng.geom.rect :as rect]
|
||||||
[thi.ng.geom.vector :as v]))
|
[thi.ng.geom.vector :as v]
|
||||||
|
[fipp.edn :refer [pprint]]))
|
||||||
|
|
||||||
(defonce state (r/atom {:rects []
|
(defonce state (r/atom {:rects []
|
||||||
:frame (rect/rect 500 500)}))
|
:frame (rect/rect 500 500)}))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
|
|
||||||
(swap! state update :rects empty)
|
(swap! state assoc :rects [])
|
||||||
(swap! state update :rects conj (rect/rect 200 200))
|
(swap! state update :rects conj (rect/rect 200 200))
|
||||||
|
|
||||||
;; fill with random rectangles
|
;; fill with random rectangles
|
||||||
(swap! state assoc :rects
|
(swap! state assoc :rects (repeatedly 100 #(rect/rect 50 50)))
|
||||||
(repeatedly 20 #(rect/rect (+ 50 (rand-int 50)) (+ 50 (rand-int 50)))))
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
(defn pack-rects-naive
|
(defn pack-rects-naive
|
||||||
"Sorts all rectangles by height and places them next to each other into frame,
|
"Sorts all rectangles by height and places them next to each other into frame,
|
||||||
starting at the top left."
|
starting at the top left."
|
||||||
|
|
@ -48,27 +49,83 @@
|
||||||
|
|
||||||
#_(pack-rects-naive (:frame @state) (:rects @state))
|
#_(pack-rects-naive (:frame @state) (:rects @state))
|
||||||
|
|
||||||
|
#_(->> (pack-rects-naive (:frame @state) (:rects @state))
|
||||||
|
(group-by :size)
|
||||||
|
(into (sorted-map-by geom/height)))
|
||||||
|
|
||||||
|
(defn by-size [rects]
|
||||||
|
(->> (group-by (comp reverse :size) rects)
|
||||||
|
(into (sorted-map-by (comp (partial * -1) compare)))))
|
||||||
|
|
||||||
|
(defn add-parts-to-cut! [order]
|
||||||
|
(let [rects (repeatedly (:num order) #(rect/rect (:width order) (:height order)))]
|
||||||
|
(swap! state update :rects (comp vec concat) rects)))
|
||||||
|
|
||||||
|
(defn order []
|
||||||
|
(let [base-order {:num 1
|
||||||
|
:width 100
|
||||||
|
:height 100}
|
||||||
|
addition (r/atom base-order)]
|
||||||
|
(fn []
|
||||||
|
(let [to-add @addition]
|
||||||
|
[:p "Add part to cut: "]
|
||||||
|
[:form {:on-submit (fn [e]
|
||||||
|
(.preventDefault e)
|
||||||
|
(add-parts-to-cut! @addition)
|
||||||
|
(reset! addition base-order))}
|
||||||
|
[:input.num-rects {:type "number"
|
||||||
|
:on-change #(swap! addition assoc :num (js/parseInt (.. % -target -value) 10))
|
||||||
|
:value (:num to-add)}] " × "
|
||||||
|
[:input.rect-dim {:type "number"
|
||||||
|
:on-change #(swap! addition assoc :width (js/parseInt (.. % -target -value) 10))
|
||||||
|
:value (:width to-add)}] " cm by "
|
||||||
|
[:input.rect-dim {:type "number"
|
||||||
|
:on-change #(swap! addition assoc :height (js/parseInt (.. % -target -value) 10))
|
||||||
|
:value (:height to-add)}] " cm "
|
||||||
|
[:button "Add"]]))))
|
||||||
|
|
||||||
|
(defn debug [val]
|
||||||
|
[:pre (with-out-str (pprint val))])
|
||||||
|
|
||||||
|
(defn inventory [rects]
|
||||||
|
(prn "re-rendering inventory with rects" rects)
|
||||||
|
[:<>
|
||||||
|
[order]
|
||||||
|
(when (seq rects)
|
||||||
|
[:<>
|
||||||
|
[:p "List of parts to cut:"]
|
||||||
|
[debug (by-size rects)]
|
||||||
|
#_[:ul
|
||||||
|
(for [[size rects] (by-size rects)
|
||||||
|
:let [k (pr-str size)]]
|
||||||
|
^{:key k}
|
||||||
|
[:li [:input.num-rects {:type "number"
|
||||||
|
#_#_ :on-change #(update-rects! rects size (js/Number. (-> % .-target .-value)))
|
||||||
|
#_#_ :value (str (count rects))}] (str " x " (:x size) "x" (:y size))])]])])
|
||||||
|
|
||||||
|
(defn visualization [frame packed-rects]
|
||||||
|
[:svg.visualization {:viewBox "-0.5 -0.5 501 501" :xmlns "http://www.w3.org/2000/svg"}
|
||||||
|
[:rect {:width (geom/width frame)
|
||||||
|
:height (geom/height frame)}]
|
||||||
|
(for [[idx rect] (map-indexed vector packed-rects)
|
||||||
|
:let [[x y] (:p rect)
|
||||||
|
w (geom/width rect)
|
||||||
|
h (geom/height rect)]]
|
||||||
|
^{:key idx} [:<>
|
||||||
|
[:rect {:width w :height h :x x :y y}]
|
||||||
|
[:text {:x x :y y :dx 4 :dy 14} (str w "x" h)]])])
|
||||||
|
|
||||||
(defn main []
|
(defn main []
|
||||||
(let [{:keys [frame rects]} @state
|
(let [{:keys [frame rects]} @state
|
||||||
sorted (map-indexed vector (pack-rects-naive frame rects))]
|
packed (pack-rects-naive frame rects)]
|
||||||
[:main
|
[:main
|
||||||
[:h1 "Visualization"]
|
[:h1 "Visualization"]
|
||||||
[:svg.visualization {:viewBox "-0.5 -0.5 501 501" :xmlns "http://www.w3.org/2000/svg"}
|
[visualization frame packed]
|
||||||
[:rect {:width (geom/width frame)
|
|
||||||
:height (geom/height frame)}]
|
|
||||||
(for [[idx rect] sorted]
|
|
||||||
^{:key idx} [:rect {:width (geom/width rect) :height (geom/height rect)
|
|
||||||
:x (-> rect :p :x)
|
|
||||||
:y (-> rect :p :y)}])]
|
|
||||||
[:h2 "Rectangles"]
|
[:h2 "Rectangles"]
|
||||||
[:ul
|
[inventory rects]]))
|
||||||
(for [[idx rect] sorted]
|
|
||||||
^{:key idx} [:li [:pre (pr-str rect)]])]]))
|
|
||||||
|
|
||||||
(defn ^:dev/after-load init []
|
(defn ^:dev/after-load init []
|
||||||
(println "Initializing…")
|
(println "Initializing…")
|
||||||
(dom/render [main] (.querySelector js/document "#app")))
|
(dom/render [main] (.querySelector js/document "#app")))
|
||||||
|
|
||||||
(defonce app (init))
|
(defonce app (init))
|
||||||
|
|
||||||
(+ 1 2)
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue