Allow adding parts to cut via the UI

This commit is contained in:
heyarne 2022-01-01 13:05:25 +01:00
commit 322174c9e7
3 changed files with 88 additions and 17 deletions

View file

@ -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"}}}}}

View file

@ -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;
}

View file

@ -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))
(defn main [] #_(->> (pack-rects-naive (:frame @state) (:rects @state))
(let [{:keys [frame rects]} @state (group-by :size)
sorted (map-indexed vector (pack-rects-naive frame rects))] (into (sorted-map-by geom/height)))
[:main
[:h1 "Visualization"] (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"} [:svg.visualization {:viewBox "-0.5 -0.5 501 501" :xmlns "http://www.w3.org/2000/svg"}
[:rect {:width (geom/width frame) [:rect {:width (geom/width frame)
:height (geom/height frame)}] :height (geom/height frame)}]
(for [[idx rect] sorted] (for [[idx rect] (map-indexed vector packed-rects)
^{:key idx} [:rect {:width (geom/width rect) :height (geom/height rect) :let [[x y] (:p rect)
:x (-> rect :p :x) w (geom/width rect)
:y (-> rect :p :y)}])] 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 []
(let [{:keys [frame rects]} @state
packed (pack-rects-naive frame rects)]
[:main
[:h1 "Visualization"]
[visualization frame packed]
[: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)