From 942ff6510bae3bae9f7e4f5df5df365610396df3 Mon Sep 17 00:00:00 2001 From: heyarne Date: Mon, 12 Apr 2021 00:09:35 +0200 Subject: [PATCH] WIP: Scale and fit mesh into viewport --- src/heyarne/all_my_friends/core.cljc | 65 ++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/src/heyarne/all_my_friends/core.cljc b/src/heyarne/all_my_friends/core.cljc index 007fc67..1384f13 100644 --- a/src/heyarne/all_my_friends/core.cljc +++ b/src/heyarne/all_my_friends/core.cljc @@ -5,6 +5,8 @@ [cheshire.core :as json] [thi.ng.geom.vector :as v] [thi.ng.geom.core :as g] + [thi.ng.geom.matrix :as mat] + [thi.ng.geom.rect :as r] [thi.ng.math.core :as m] [clojure.java.io :as io] [clojure.string :as str])) @@ -33,23 +35,70 @@ ;; "most-recent" now contains a seq of all faces detected in the most recently ;; uploaded picture +;; next we calculate a matrix to fit each point in the mesh into our +;; bounding box. + +(def max-number #?(:clj Float/MAX_VALUE :cljs js/Infinity)) +(def min-number #?(:clj Float/MIN_VALUE :cljs js/-Infinity)) + +(defn points->bounds [pts] + (let [[x1 y1 x2 y2] (reduce (fn [[x1 y1 x2 y2] [x y]] + [(min x x1) (min y y1) + (max x x2) (max y y2)]) + [max-number max-number min-number min-number] pts)] + (r/rect (v/vec2 x1 y1) (v/vec2 x2 y2)))) + +(def face-bounds + (points->bounds (:scaled-mesh (first most-recent))) + #_(let [bbox (:bounding-box (first most-recent))] + (-> (concat (:top-left bbox) (:bottom-right bbox)) + (points->bounds)))) + +(def bounds (r/rect 0 0 500 500)) + +(defn center-matrix [dst-bounds src-bounds] + (let [delta (m/- (m/+ (:p dst-bounds) (m/* (:size dst-bounds) 0.5)) + (m/+ (:p src-bounds) (m/* (:size src-bounds) 0.5)))] + (g/translate (mat/matrix32) delta))) + +(defn fit-matrix + "Returns an affine matrix than can be used to fit and center all points + described by the bounding box `src-bounds` into `dst-bounds`." + [dst-bounds src-bounds] + (let [factor (min (/ (-> dst-bounds :size :x) (-> src-bounds :size :x)) + (/ (-> dst-bounds :size :y) (-> src-bounds :size :y)))] + (mat/matrix32 factor 0 0 + 0 factor 0))) + +;; TODO: Combine matrices +(def transform-matrix (center-matrix bounds face-bounds)) (defn setup [] - (q/frame-rate 60) + (q/frame-rate 1) + (q/ellipse-mode :center) (q/color-mode :hsb)) +(def debug true) + (defn draw [] (q/clear) (q/background 40 80 255) - (q/stroke 240 100 255) - (q/stroke-weight 1) + (q/stroke 4 120 255) (q/no-fill) + (q/stroke-weight 1) + + (when debug + (doseq [[a b] (->> (g/vertices face-bounds) + (cycle) + (partition-all 2 1) + (take 4))] + (q/line (g/transform a transform-matrix) (g/transform b transform-matrix)))) (doseq [face most-recent - :let [mesh (:mesh face)]] - (doseq [[[x1 y1 z1] pt2] (partition 2 mesh)] - (q/line x1 y1 (+ (q/random -2 2) x1) (+ (q/random -2 2) y1)) - #_(apply q/line pt1 pt2)))) + p (:scaled-mesh face) + :let [p (g/transform (v/vec2 p) transform-matrix)]] + (q/ellipse (p :x) (p :y) 6 6) + #_(apply q/line pt1 pt2))) #_:clj-kondo/ignore (q/defsketch all-my-friends @@ -58,4 +107,4 @@ :middleware [pause-on-error] :setup setup :draw draw - :size [500 500]) + :size (:size bounds))