From 9687e576666b94aa6e18386643ae5c3adac5b987 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Wed, 3 Jun 2020 19:12:08 +0100 Subject: [PATCH] Woohoo! Now I can meaningfully search a superstructure! --- project.clj | 1 + src/walkmap/microworld.clj | 4 +++- src/walkmap/polygon.clj | 9 +++++++- src/walkmap/superstructure.clj | 38 ++++++++++++++++++++++++++++++++++ src/walkmap/utils.clj | 10 +++++++++ 5 files changed, 60 insertions(+), 2 deletions(-) diff --git a/project.clj b/project.clj index 4ac438a..577dc87 100644 --- a/project.clj +++ b/project.clj @@ -5,6 +5,7 @@ :output-path "docs/codox" :source-uri "https://github.com/simon-brooke/walkmap/blob/master/{filepath}#L{line}"} :dependencies [[org.clojure/algo.generic "0.1.3"] + [org.clojure/core.memoize "1.0.236"] [org.clojure/clojure "1.8.0"] [org.clojure/data.zip "1.0.0"] [org.clojure/math.numeric-tower "0.0.4"] diff --git a/src/walkmap/microworld.clj b/src/walkmap/microworld.clj index 43d5684..5b88a99 100644 --- a/src/walkmap/microworld.clj +++ b/src/walkmap/microworld.clj @@ -92,4 +92,6 @@ polys) polys)))) -;; (load-microworld-edn "../MicroWorld/mw-cli/isle_of_man.edn" nil {}) + + + diff --git a/src/walkmap/polygon.clj b/src/walkmap/polygon.clj index d5bd83a..2b52167 100644 --- a/src/walkmap/polygon.clj +++ b/src/walkmap/polygon.clj @@ -73,7 +73,14 @@ vse (vertex (:x vne) (:y vsw) (/ (reduce + (map #(or (:z %) 0) [vsw vne])) 2))] - (t/tag (polygon vsw vnw vne vse) :rectangle))) + (t/tag + (assoc + (polygon vsw vnw vne vse) + :centre + (vertex (+ (:x vsw) (/ (- (:x vne) (:x vsw)) 2)) + (+ (:x vsw) (/ (- (:y vne) (:y vsw)) 2)) + (:z vse))) + :rectangle))) ;; (rectangle (vertex 1 2 3) (vertex 7 9 4)) diff --git a/src/walkmap/superstructure.clj b/src/walkmap/superstructure.clj index 50ad5b9..dab1075 100644 --- a/src/walkmap/superstructure.clj +++ b/src/walkmap/superstructure.clj @@ -2,6 +2,7 @@ "single indexing structure for walkmap objects" (:require [clojure.walk :refer [postwalk]] [taoensso.timbre :as l] + [walkmap.edge :refer [edge length]] [walkmap.path :as p] [walkmap.polygon :as q] [walkmap.utils :as u] @@ -180,4 +181,41 @@ #(v/within-box? % minv maxv) (filter #(= (:kind %) :vertex) (vals s)))))) +(defn find-nearest + "Search superstructure `s` for the nearest object matching `filter-fn` to + the `target` vertex. Searches only with `radius` (slight misnomer, area + actually searched is a cube). Returns one object, or `nil` if no matching + object found. + + WARNING: currently only returns objects which have a defined `:centre` + (but most of the significant objects we have do)." + [s target filter-fn radius] + (let [minv (v/vertex + (- (:x (v/check-vertex target)) radius) + (- (:y target) radius) (- (or (:z target) 0) radius)) + maxv (v/vertex + (+ (:x target) 0.5) (+ (:y target) 0.5) + (+ (or (:z target) 0) 0.5))] + ;; filter those objects with the filter function, then sort that list + ;; by the edge distance from the target to the `:centre` of the object + ;; and take the first + (first + (sort-by + #(length (edge target (:centre %))) + (filter + :centre + (map #(retrieve % s) + ;; for each vertex id in vids, get the objects associated with that id + ;; in the vertex index as a single flat list + (reduce + concat + (remove + nil? + (map + #(-> s ::vertex-index % keys) + ;; get all the vertex ids within radius of the target + (set + (map + :walkmap.id/id + (search-vertices s minv maxv)))))))))))) diff --git a/src/walkmap/utils.clj b/src/walkmap/utils.clj index 1295676..427194e 100644 --- a/src/walkmap/utils.clj +++ b/src/walkmap/utils.clj @@ -99,3 +99,13 @@ ")"]))) ~s))) +(defn load-edn + "Load edn from an io/reader source (filename or io/resource)." + [source] + (try + (with-open [r (io/reader source)] + (edn/read (java.io.PushbackReader. r))) + (catch java.io.IOException e + (printf "Couldn't open '%s': %s\n" source (.getMessage e))) + (catch RuntimeException e + (printf "Error parsing edn file '%s': %s\n" source (.getMessage e)))))