|
3 | 3 | [clojure.core.matrix :as mat]
|
4 | 4 | [kdtree :as kdtree]
|
5 | 5 | [malli.core :as m]
|
6 |
| - [re-frame.core :as rf] |
7 | 6 | [renderer.app.db :refer [App]]
|
| 7 | + [renderer.frame.db :refer [Viewbox]] |
| 8 | + [renderer.frame.handlers :as frame.h] |
8 | 9 | [renderer.snap.db :refer [SnapOption NearestNeighbor]]
|
9 | 10 | [renderer.snap.subs :as-alias snap.s]
|
10 | 11 | [renderer.tool.hierarchy :as tool.hierarchy]
|
|
17 | 18 | (update-in db [:snap :options] disj option)
|
18 | 19 | (update-in db [:snap :options] conj option)))
|
19 | 20 |
|
20 |
| -(m/=> find-nearest-neighbors [:-> App [:sequential NearestNeighbor]]) |
21 |
| -(defn find-nearest-neighbors |
| 21 | +(m/=> in-viewport-tree [:-> any? Viewbox any?]) |
| 22 | +(defn in-viewport-tree |
| 23 | + [tree [x y width height]] |
| 24 | + (->> [[x (+ x width)] [y (+ y height)]] |
| 25 | + (kdtree/interval-search tree) |
| 26 | + (kdtree/build-tree))) |
| 27 | + |
| 28 | +(defn create-tree |
| 29 | + [db] |
| 30 | + (let [zoom (get-in db [:documents (:active-document db) :zoom]) |
| 31 | + pan (get-in db [:documents (:active-document db) :pan]) |
| 32 | + viewbox (frame.h/viewbox zoom pan (:dom-rect db))] |
| 33 | + (-> (tool.hierarchy/snapping-points db) |
| 34 | + (kdtree/build-tree) |
| 35 | + (in-viewport-tree viewbox)))) |
| 36 | + |
| 37 | +(m/=> nearest-neighbors [:-> App [:sequential NearestNeighbor]]) |
| 38 | +(defn nearest-neighbors |
22 | 39 | [db]
|
23 |
| - (let [tree @(rf/subscribe [::snap.s/in-viewport-tree])] ; FIXME: Subscription in event. |
24 |
| - (map #(let [nearest-neighbor (kdtree/nearest-neighbor tree %)] |
25 |
| - (when nearest-neighbor |
26 |
| - (assoc nearest-neighbor :base-point %))) |
27 |
| - (tool.hierarchy/snapping-bases db)))) |
| 40 | + (map #(when-let [nneighbor (kdtree/nearest-neighbor (:kd-tree db) %)] |
| 41 | + (assoc nneighbor :base-point %)) |
| 42 | + (tool.hierarchy/snapping-bases db))) |
28 | 43 |
|
29 |
| -(m/=> find-nearest-neighbor [:-> App [:maybe NearestNeighbor]]) |
30 |
| -(defn find-nearest-neighbor |
| 44 | +(m/=> nearest-neighbor [:-> App [:maybe NearestNeighbor]]) |
| 45 | +(defn nearest-neighbor |
31 | 46 | [db]
|
32 |
| - (let [threshold (-> db :snap :threshold) |
33 |
| - nearest-neighbors (find-nearest-neighbors db) |
34 |
| - threshold (/ threshold (get-in db [:documents (:active-document db) :zoom])) |
35 |
| - nearest-neighbor (reduce |
36 |
| - (fn [nearest-neighbor neighbor] |
37 |
| - (if (< (:dist-squared neighbor) |
38 |
| - (:dist-squared nearest-neighbor)) |
39 |
| - neighbor |
40 |
| - nearest-neighbor)) |
41 |
| - (first nearest-neighbors) |
42 |
| - (rest nearest-neighbors))] |
43 |
| - (when (< (:dist-squared nearest-neighbor) (Math/pow threshold 2)) |
44 |
| - nearest-neighbor))) |
| 47 | + (when (-> db :snap :active) |
| 48 | + (let [threshold (-> db :snap :threshold) |
| 49 | + nneighbors (nearest-neighbors db) |
| 50 | + threshold (/ threshold (get-in db [:documents (:active-document db) :zoom])) |
| 51 | + nneighbor (apply min-key :dist-squared nneighbors)] |
| 52 | + (when (< (:dist-squared nneighbor) (Math/pow threshold 2)) |
| 53 | + nneighbor)))) |
45 | 54 |
|
46 |
| -(m/=> update-nearest-neighbor [:-> App App]) |
47 | 55 | (defn update-nearest-neighbor
|
48 | 56 | [db]
|
49 |
| - (let [nearest-neighbor (find-nearest-neighbor db)] |
50 |
| - (cond-> db |
51 |
| - :always |
52 |
| - (dissoc :nearest-neighbor) |
| 57 | + (assoc db :nearest-neighbor (nearest-neighbor db))) |
53 | 58 |
|
54 |
| - (and (-> db :snap :active) nearest-neighbor) |
55 |
| - (assoc :nearest-neighbor nearest-neighbor)))) |
| 59 | +(defn update-tree |
| 60 | + [db] |
| 61 | + (cond-> db |
| 62 | + (-> db :snap :active) |
| 63 | + (assoc :kd-tree (create-tree db)))) |
56 | 64 |
|
57 | 65 | (m/=> nearest-delta [:-> App Vec2D])
|
58 | 66 | (defn nearest-delta
|
59 | 67 | [db]
|
60 |
| - (let [{:keys [point base-point]} (:nearest-neighbor db)] |
61 |
| - (mat/sub point base-point))) |
| 68 | + (if (:nearest-neighbor db) |
| 69 | + (let [{:keys [point base-point]} (:nearest-neighbor db)] |
| 70 | + (mat/sub point base-point)) |
| 71 | + [0 0])) |
62 | 72 |
|
63 | 73 | (defn snap-with
|
64 | 74 | [db f & more]
|
65 | 75 | (let [db (update-nearest-neighbor db)]
|
66 | 76 | (if (:nearest-neighbor db)
|
67 | 77 | (apply f db (nearest-delta db) more)
|
68 | 78 | db)))
|
| 79 | + |
0 commit comments