From 777b8bc077e2dd796ab1d4799208674a4808f92e Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Wed, 3 Jun 2020 21:53:27 +0100 Subject: [PATCH] Solid start made on routing. --- docs/cloverage/index.html | 86 ++-- docs/cloverage/walkmap/microworld.clj.html | 10 +- docs/cloverage/walkmap/path.clj.html | 8 +- docs/cloverage/walkmap/polygon.clj.html | 119 +++-- .../cloverage/walkmap/superstructure.clj.html | 480 +++++++++++------- docs/cloverage/walkmap/utils.clj.html | 234 +++++---- docs/cloverage/walkmap/vertex.clj.html | 8 +- docs/codox/dali-performance.html | 2 +- docs/codox/index.html | 2 +- docs/codox/intro.html | 2 +- docs/codox/walkmap.edge.html | 2 +- docs/codox/walkmap.id.html | 2 +- docs/codox/walkmap.microworld.html | 3 + docs/codox/walkmap.ocean.html | 2 +- docs/codox/walkmap.path.html | 2 +- docs/codox/walkmap.polygon.html | 2 +- docs/codox/walkmap.read-svg.html | 2 +- docs/codox/walkmap.routing.html | 2 +- docs/codox/walkmap.stl.html | 2 +- docs/codox/walkmap.superstructure.html | 9 +- docs/codox/walkmap.svg.html | 2 +- docs/codox/walkmap.tag.html | 2 +- docs/codox/walkmap.utils.html | 6 +- docs/codox/walkmap.vertex.html | 8 +- project.clj | 3 - src/walkmap/microworld.clj | 37 +- src/walkmap/routing.clj | 67 ++- src/walkmap/superstructure.clj | 20 +- src/walkmap/utils.clj | 4 +- 29 files changed, 684 insertions(+), 444 deletions(-) create mode 100644 docs/codox/walkmap.microworld.html diff --git a/docs/cloverage/index.html b/docs/cloverage/index.html index 1c568a3..f8390be 100644 --- a/docs/cloverage/index.html +++ b/docs/cloverage/index.html @@ -53,7 +53,7 @@ style="width:92.5%; float:left;"> 37 7.50 % -95840 +971140 walkmap.ocean
16
93.98 %
35
34
3
1
-97.44 % -94939 +97.37 % +94938 walkmap.polygon
338
131
-72.07 % + style="width:33.59528487229863%; + float:left;"> 171 +66.40 %
45
6
7
-87.93 % -1181358 + style="width:19.047619047619047%; + float:left;"> 12 +80.95 % +1251363 walkmap.read-svg
walkmap.superstructure
257
107
-70.60 % + style="width:53.41614906832298%; + float:left;"> 258
225
+53.42 %
62
3
22
-74.71 % -1831887 + style="width:3.669724770642202%; + float:left;"> 4
43
+60.55 % +22119109 walkmap.svg
walkmap.utils
755
1
-99.87 % + style="width:97.04749679075738%; + float:left;"> 756
23
+97.05 %
35
1
-100.00 % -101936 + style="width:85.71428571428571%; + float:left;"> 36
1
5
+88.10 % +113942 walkmap.vertex
Totals: -72.81 % +69.99 % -68.80 % +65.94 % diff --git a/docs/cloverage/walkmap/microworld.clj.html b/docs/cloverage/walkmap/microworld.clj.html index 839c56b..560d445 100644 --- a/docs/cloverage/walkmap/microworld.clj.html +++ b/docs/cloverage/walkmap/microworld.clj.html @@ -286,8 +286,14 @@ 094  
- - 095  ;; (load-microworld-edn "../MicroWorld/mw-cli/isle_of_man.edn" nil {}) + + 095   +
+ + 096   +
+ + 097  
diff --git a/docs/cloverage/walkmap/path.clj.html b/docs/cloverage/walkmap/path.clj.html index 4df3664..be05352 100644 --- a/docs/cloverage/walkmap/path.clj.html +++ b/docs/cloverage/walkmap/path.clj.html @@ -139,13 +139,13 @@ 045    from the calling function."
- + 046    [o]
047    `(check-kind-type-seq ~o path? :path))
- + 048  
@@ -211,13 +211,13 @@ 069    sequence of vertices."
- + 070    [o]
071    (cond
- + 072      (seq? o) (when
diff --git a/docs/cloverage/walkmap/polygon.clj.html b/docs/cloverage/walkmap/polygon.clj.html index a7c5f47..afa6805 100644 --- a/docs/cloverage/walkmap/polygon.clj.html +++ b/docs/cloverage/walkmap/polygon.clj.html @@ -139,13 +139,13 @@ 045  (defmacro check-triangle
- + 046    "If `o` is not a triangle, throw an `IllegalArgumentException` with an
047    appropriate message; otherwise, returns `o`. Macro, so exception is thrown
- + 048    from the calling function."
@@ -211,13 +211,13 @@ 069    ;; corners, but the maths are a bit to advanced for me today. TODO: do it!
- + 070    (let [vnw (vertex (:x (check-vertex vsw))
071                      (:y (check-vertex vne))
- + 072                      (/ (reduce + (map #(or (:z %) 0) [vsw vne])) 2))
@@ -229,134 +229,155 @@ 075                      (/ (reduce + (map #(or (:z %) 0) [vsw vne])) 2))]
- - 076      (t/tag (polygon vsw vnw vne vse) :rectangle))) + + 076      (t/tag
- - 077   + + 077        (assoc +
+ + 078          (polygon vsw vnw vne vse)
- 078  ;; (rectangle (vertex 1 2 3) (vertex 7 9 4)) + 079          :centre +
+ + 080          (vertex (+ (:x vsw) (/ (- (:x vne) (:x vsw)) 2)) +
+ + 081                  (+ (:x vsw) (/ (- (:y vne) (:y vsw)) 2)) +
+ + 082                  (:z vse))) +
+ + 083        :rectangle)))
- 079   + 084   +
+ + 085  ;; (rectangle (vertex 1 2 3) (vertex 7 9 4)) +
+ + 086  
- 080  (defn gradient + 087  (defn gradient
- 081    "Return a polygon like `triangle` but with a key `:gradient` whose value is a + 088    "Return a polygon like `triangle` but with a key `:gradient` whose value is a
- 082    unit vector representing the gradient across `triangle`." + 089    unit vector representing the gradient across `triangle`."
- 083    [triangle] + 090    [triangle]
- 084    (let [order (sort #(max (:z %1) (:z %2)) + 091    (let [order (sort #(max (:z %1) (:z %2))
- 085                      (:vertices (check-triangle triangle))) + 092                      (:vertices (check-triangle triangle)))
- 086          highest (first order) + 093          highest (first order)
- 087          lowest (last order)] + 094          lowest (last order)]
- 088       (assoc triangle :gradient (e/unit-vector (e/edge lowest highest))))) + 095       (assoc triangle :gradient (e/unit-vector (e/edge lowest highest)))))
- 089   + 096  
- 090  (defn triangle-centre + 097  (defn triangle-centre
- 091    "Return a canonicalised `facet` (i.e. a triangular polygon) with an added + 098    "Return a canonicalised `facet` (i.e. a triangular polygon) with an added
- 092    key `:centre` whose value represents the centre of this facet in 3 + 099    key `:centre` whose value represents the centre of this facet in 3
- 093    dimensions. This only works for triangles, so is here not in + 100    dimensions. This only works for triangles, so is here not in
- 094    `walkmap.polygon`. It is an error (although no exception is currently + 101    `walkmap.polygon`. It is an error (although no exception is currently
- 095    thrown) if the object past is not a triangular polygon." + 102    thrown) if the object past is not a triangular polygon."
- 096    [facet] + 103    [facet]
- 097    (let [vs (:vertices (check-triangle facet)) + 104    (let [vs (:vertices (check-triangle facet))
- 098          v1 (first vs) + 105          v1 (first vs)
- 099          opposite (e/edge (nth vs 1) (nth vs 2)) + 106          opposite (e/edge (nth vs 1) (nth vs 2))
- 100          oc (e/centre opposite)] + 107          oc (e/centre opposite)]
- 101        (assoc + 108        (assoc
- 102        facet + 109        facet
- 103        :centre + 110        :centre
- 104        (vertex + 111        (vertex
- 105          (+ (:x v1) (* (- (:x oc) (:x v1)) 2/3)) + 112          (+ (:x v1) (* (- (:x oc) (:x v1)) 2/3))
- 106          (+ (:y v1) (* (- (:y oc) (:y v1)) 2/3)) + 113          (+ (:y v1) (* (- (:y oc) (:y v1)) 2/3))
- 107          (+ (:z v1) (* (- (:z oc) (:z v1)) 2/3)))))) + 114          (+ (:z v1) (* (- (:z oc) (:z v1)) 2/3))))))
- 108   + 115  
- 109  (defn centre + 116  (defn centre
- 110    [poly] + 117    [poly]
- 111    (case (count (:vertices (check-polygon poly))) + 118    (case (count (:vertices (check-polygon poly)))
- 112      3 (triangle-centre poly) + 119      3 (triangle-centre poly)
- 113      ;; else + 120      ;; else
- 114      (throw + 121      (throw
- 115        (UnsupportedOperationException. + 122        (UnsupportedOperationException.
- 116          "The general case of centre for polygons is not yet implemented.")))) + 123          "The general case of centre for polygons is not yet implemented."))))
- 117   + 124  
- 118   + 125  
diff --git a/docs/cloverage/walkmap/superstructure.clj.html b/docs/cloverage/walkmap/superstructure.clj.html index 229b2b9..25e2662 100644 --- a/docs/cloverage/walkmap/superstructure.clj.html +++ b/docs/cloverage/walkmap/superstructure.clj.html @@ -17,541 +17,655 @@ 004              [taoensso.timbre :as l]

- 005              [walkmap.path :as p] + 005              [walkmap.edge :refer [edge length]]
- 006              [walkmap.polygon :as q] + 006              [walkmap.path :as p]
- 007              [walkmap.utils :as u] + 007              [walkmap.polygon :as q]
- 008              [walkmap.vertex :as v])) + 008              [walkmap.utils :as u] +
+ + 009              [walkmap.vertex :as v]))
- 009   + 010  
- 010  ;; TODO: Think about reification/dereification. How can we cull a polygon, if + 011  ;; TODO: Think about reification/dereification. How can we cull a polygon, if
- 011  ;; some vertices still index it? I *think* that what's needed is that when + 012  ;; some vertices still index it? I *think* that what's needed is that when
- 012  ;; we store something in the superstructure, we replace all its vertices (and + 013  ;; we store something in the superstructure, we replace all its vertices (and
- 013  ;; other dependent structures, if any with their ids - as well as, obviously, + 014  ;; other dependent structures, if any with their ids - as well as, obviously,
- 014  ;; adding/merging those vertices/dependent structures into the superstructure + 015  ;; adding/merging those vertices/dependent structures into the superstructure
- 015  ;; as first class objects in themselves. That means, for each identified thing, + 016  ;; as first class objects in themselves. That means, for each identified thing,
- 016  ;; the superstructure only contains one copy of it. + 017  ;; the superstructure only contains one copy of it.
- 017  ;; + 018  ;;
- 018  ;; The question then is, when we want to do things with those objects, do we + 019  ;; The question then is, when we want to do things with those objects, do we
- 019  ;; exteract a copy with its dependent structures fixed back up (reification), + 020  ;; exteract a copy with its dependent structures fixed back up (reification),
- 020  ;; or do we indirect through the superstructure every time we want to access + 021  ;; or do we indirect through the superstructure every time we want to access
- 021  ;; them? In a sense, the copy in the superstructure is the 'one true copy', + 022  ;; them? In a sense, the copy in the superstructure is the 'one true copy',
- 022  ;; but it may become very difficult then to have one true copy of the + 023  ;; but it may become very difficult then to have one true copy of the
- 023  ;; superstructure - unless we replace the superstructure altogether with a + 024  ;; superstructure - unless we replace the superstructure altogether with a
- 024  ;; database, which may be the Right Thing To Do. + 025  ;; database, which may be the Right Thing To Do.
- 025   + 026  
- 026  (def vertex-index ::vertex-index) + 027  (def vertex-index ::vertex-index)
- 027   + 028  
- 028  (defn vertices + 029  (defn vertices
- 029    "If `o` is an object with vertices, return those vertices, else nil." + 030    "If `o` is an object with vertices, return those vertices, else nil."
- 030    [o] + 031    [o]
- 031    (cond + 032    (cond
- 032      (v/vertex? o) (list o) + 033      (v/vertex? o) (list o)
- 033      (q/polygon? o) (:vertices o) + 034      (q/polygon? o) (:vertices o)
- 034      (p/path? o) (:vertices o))) + 035      (p/path? o) (:vertices o)))
- 035   + 036  
- 036  (defn index-vertex + 037  (defn index-vertex
- 037    "Return a superstructure like `s` in which object `o` is indexed by vertex + 038    "Return a superstructure like `s` in which object `o` is indexed by vertex
- 038    `v`. It is an error (and an exception may be thrown) if + 039    `v`. It is an error (and an exception may be thrown) if
- 039   + 040  
- 040    1. `s` is not a map; + 041    1. `s` is not a map;
- 041    2. `o` is not a map; + 042    2. `o` is not a map;
- 042    3. `o` does not have a value for the key `:walkmap.id/id`; + 043    3. `o` does not have a value for the key `:walkmap.id/id`;
- 043    4. `v` is not a vertex." + 044    4. `v` is not a vertex."
- 044    [s o v] + 045    [s o v]
- 045    (if-not (v/vertex? o) + 046    (if-not (v/vertex? o)
- 046      (if (:walkmap.id/id o) + 047      (if (:walkmap.id/id o)
- - 047        (if (v/vertex? v) + + 048        (if (v/vertex? v)
- 048          (let [vi (or (::vertex-index s) {}) + 049          (let [vi (or (::vertex-index s) {})
- 049                current (or (vi (:walkmap.id/id v)) {})] + 050                current (or (vi (:walkmap.id/id v)) {})] +
+ + 051            ;; deep-merge doesn't merge sets, only maps; so at this
- 050            ;; deep-merge doesn't merge sets, only maps; so at this -
- - 051            ;; stage we need to build a map. + 052            ;; stage we need to build a map.
- 052            (assoc vi (:walkmap.id/id v) (assoc current (:walkmap.id/id o) (:walkmap.id/id v)))) + 053            (assoc vi (:walkmap.id/id v) (assoc current (:walkmap.id/id o) (:walkmap.id/id v))))
- 053          (throw (IllegalArgumentException. "Not a vertex: " v))) + 054          (throw (IllegalArgumentException. "Not a vertex: " v)))
- 054        (throw (IllegalArgumentException. (u/truncate (str "No `:walkmap.id/id` value: " o) 80)))) + 055        (throw (IllegalArgumentException. (u/truncate (str "No `:walkmap.id/id` value: " o) 80))))
- 055      ;; it shouldn't actually be an error to try to index a vertex, but it + 056      ;; it shouldn't actually be an error to try to index a vertex, but it
- 056      ;; also isn't useful to do so, so I'd be inclined to ignore it. + 057      ;; also isn't useful to do so, so I'd be inclined to ignore it.
- 057      (::vertex-index s))) + 058      (::vertex-index s)))
- 058   + 059  
- 059  (defn index-vertices + 060  (defn index-vertices
- 060    "Return a superstructure like `s` in which object `o` is indexed by its + 061    "Return a superstructure like `s` in which object `o` is indexed by its
- 061    vertices. It is an error (and an exception may be thrown) if + 062    vertices. It is an error (and an exception may be thrown) if
- 062   + 063  
- 063    1. `s` is not a map; + 064    1. `s` is not a map;
- 064    2. `o` is not a map; + 065    2. `o` is not a map;
- 065    3. `o` does not have a value for the key `:walkmap.id/id`." + 066    3. `o` does not have a value for the key `:walkmap.id/id`."
- 066    [s o] + 067    [s o]
- 067    (u/deep-merge + 068    (u/deep-merge
- 068      s + 069      s
- 069      {::vertex-index + 070      {::vertex-index
- 070       (reduce + 071       (reduce
- 071         u/deep-merge + 072         u/deep-merge
- 072         {} + 073         {}
- 073         (map + 074         (map
- 074           #(index-vertex s o %) + 075           #(index-vertex s o %)
- 075           (:vertices o)))})) + 076           (:vertices o)))}))
- 076   + 077  
- 077  (defn in-retrieve + 078  (defn in-retrieve
- 078    "Internal guts of `retrieve`, q.v. `x` can be anything; `s` must be a + 079    "Internal guts of `retrieve`, q.v. `x` can be anything; `s` must be a
- 079    walkmap superstructure. TODO: recursive, quite likely to blow the fragile + 080    walkmap superstructure. TODO: recursive, quite likely to blow the fragile
- 080    Clojure stack. Probably better to do this with `walk`, but I don't yet + 081    Clojure stack. Probably better to do this with `walk`, but I don't yet
- 081    understand that." + 082    understand that."
- 082    [x s] + 083    [x s]
- 083    (cond + 084    (cond
- 084      ;; if it's a keyword identifying something in s, retrieve that something. + 085      ;; if it's a keyword identifying something in s, retrieve that something.
- 085      (keyword? x) (if (s x) + 086      (keyword? x) (if (s x)
- 086                     (in-retrieve (s x) s) + 087                     (in-retrieve (s x) s)
- 087                     x) + 088                     x)
- 088      ;; if it's a map, for every key which is not `:walkmap.id/id`, recurse. + 089      ;; if it's a map, for every key which is not `:walkmap.id/id`, recurse.
- 089      (map? x) (let [v (reduce + 090      (map? x) (let [v (reduce
- 090                         (fn [m k] + 091                         (fn [m k]
- 091                           (assoc m k (in-retrieve (x k) s))) + 092                           (assoc m k (in-retrieve (x k) s)))
- 092                         {} + 093                         {}
- 093                         (keys (dissoc x :walkmap.id/id))) + 094                         (keys (dissoc x :walkmap.id/id)))
- 094                     id (:walkmap.id/id x)] + 095                     id (:walkmap.id/id x)]
- 095                 ;; if it has an id, bind it to that id in the returned value. + 096                 ;; if it has an id, bind it to that id in the returned value.
- 096                 (if id + 097                 (if id
- 097                   (assoc + 098                   (assoc
- 098                     v + 099                     v
- 099                     :walkmap.id/id + 100                     :walkmap.id/id
- 100                     (:walkmap.id/id x)) + 101                     (:walkmap.id/id x))
- 101                   v)) + 102                   v))
- 102      (set? x) x ;; TODO: should I search in sets for objects when storing? + 103      (set? x) x ;; TODO: should I search in sets for objects when storing?
- 103      (coll? x) (map #(in-retrieve % s) x) + 104      (coll? x) (map #(in-retrieve % s) x)
- 104      :else x)) + 105      :else x))
- 105   + 106  
- 106  (defn retrieve + 107  (defn retrieve
- 107    "Retrieve the canonical representation of the object with this `id` from the + 108    "Retrieve the canonical representation of the object with this `id` from the
- 108    superstructure `s`." + 109    superstructure `s`."
- 109    [id s] + 110    [id s]
- 110    (in-retrieve (id s) s)) + 111    (in-retrieve (id s) s))
- 111   + 112  
- 112  (defn in-store-find-objects + 113  (defn in-store-find-objects
- 113    "Return an id -> object map of every object within `o`. Internal to + 114    "Return an id -> object map of every object within `o`. Internal to
- 114    `in-store`, q.v. Use at your own peril." + 115    `in-store`, q.v. Use at your own peril."
- 115    ([o] + 116    ([o]
- 116     (in-store-find-objects o {})) + 117     (in-store-find-objects o {}))
- 117    ([o s] + 118    ([o s]
- 118     (l/debug "Finding objects in:" o) + 119     (l/debug "Finding objects in:" o)
- 119     (cond + 120     (cond
- 120       (set? o) s ;; TODO: should I search in sets for objects when storing? + 121       (set? o) s ;; TODO: should I search in sets for objects when storing?
- 121       (map? o) (if (:walkmap.id/id o) + 122       (map? o) (if (:walkmap.id/id o)
- 122                  (assoc + 123                  (assoc
- 123                    (in-store-find-objects (vals o) s) + 124                    (in-store-find-objects (vals o) s)
- 124                    (:walkmap.id/id o) + 125                    (:walkmap.id/id o)
- 125                    o) + 126                    o)
- 126                  (in-store-find-objects (vals o) s)) + 127                  (in-store-find-objects (vals o) s))
- 127       (coll? o) (reduce merge s (map #(in-store-find-objects % s) o)) + 128       (coll? o) (reduce merge s (map #(in-store-find-objects % s) o))
- 128       :else s))) + 129       :else s)))
- 129   + 130  
- 130  (defn in-store-replace-with-keys + 131  (defn in-store-replace-with-keys
- 131    "Return a copy of `o` in which each reified walkmap object within `o` has + 132    "Return a copy of `o` in which each reified walkmap object within `o` has
- 132    been replaced with the `:walkmap.id/id` of that object. Internal to + 133    been replaced with the `:walkmap.id/id` of that object. Internal to
- 133    `in-store`, q.v. Use at your own peril." + 134    `in-store`, q.v. Use at your own peril."
- 134    [o] + 135    [o]
- 135    (assoc + 136    (assoc
- 136      (postwalk #(or (:walkmap.id/id %) %) (dissoc o :walkmap.id/id)) + 137      (postwalk #(or (:walkmap.id/id %) %) (dissoc o :walkmap.id/id))
- 137      :walkmap.id/id + 138      :walkmap.id/id
- 138      (:walkmap.id/id o))) + 139      (:walkmap.id/id o)))
- 139   + 140  
- 140  ;; (in-store-replace-with-keys (p/path (v/vertex 0 0 0) (v/vertex 0 1 2) (v/vertex 3 3 3))) + 141  ;; (in-store-replace-with-keys (p/path (v/vertex 0 0 0) (v/vertex 0 1 2) (v/vertex 3 3 3)))
- 141  ;; (in-store-find-objects (p/path (v/vertex 0 0 0) (v/vertex 0 1 2) (v/vertex 3 3 3))) + 142  ;; (in-store-find-objects (p/path (v/vertex 0 0 0) (v/vertex 0 1 2) (v/vertex 3 3 3)))
- 142   + 143  
- 143  (defn store + 144  (defn store
- 144    "Return a superstructure like `s` with object `o` added. If only one + 145    "Return a superstructure like `s` with object `o` added. If only one
- 145    argument is supplied it will be assumed to represent `o` and a new + 146    argument is supplied it will be assumed to represent `o` and a new
- 146    superstructure will be returned. + 147    superstructure will be returned.
- 147   + 148  
- 148    It is an error (and an exception may be thrown) if + 149    It is an error (and an exception may be thrown) if
- 149   + 150  
- 150    1. `s` is not a map; + 151    1. `s` is not a map;
- 151    2. `o` is not a recognisable walkmap object" + 152    2. `o` is not a recognisable walkmap object"
- 152    ([o] + 153    ([o]
- 153     (store o {})) + 154     (store o {}))
- 154    ([o s] + 155    ([o s]
- 155     (when-not (:walkmap.id/id o) + 156     (when-not (:walkmap.id/id o)
- 156       (throw + 157       (throw
- 157         (IllegalArgumentException. + 158         (IllegalArgumentException.
- 158           (str "Not a walkmap object: no value for `:walkmap.id/id`: " + 159           (str "Not a walkmap object: no value for `:walkmap.id/id`: "
- 159                (u/kind-type o))))) + 160                (u/kind-type o)))))
- 160     (when-not (map? s) + 161     (when-not (map? s)
- 161       (throw + 162       (throw
- 162         (IllegalArgumentException. + 163         (IllegalArgumentException.
- 163           (str "Superstructure must be a map: " (u/kind-type s))))) + 164           (str "Superstructure must be a map: " (u/kind-type s)))))
- 164     (assoc + 165     (assoc
- 165       (u/deep-merge s (in-store-find-objects o) (index-vertices s o)) + 166       (u/deep-merge s (in-store-find-objects o) (index-vertices s o))
- 166       (:walkmap.id/id o) + 167       (:walkmap.id/id o)
- 167       (in-store-replace-with-keys o)))) + 168       (in-store-replace-with-keys o))))
- 168   + 169  
- 169  (defn search-vertices + 170  (defn search-vertices
- 170    "Search superstructure `s` for vertices within the box defined by vertices + 171    "Search superstructure `s` for vertices within the box defined by vertices
- 171    `minv` and `maxv`. Every coordinate in `minv` must have a lower value than + 172    `minv` and `maxv`. Every coordinate in `minv` must have a lower value than
- 172    the equivalent coordinate in `maxv`. If `d2?` is supplied and not false, + 173    the equivalent coordinate in `maxv`. If `d2?` is supplied and not false,
- 173    search only in the x,y projection." + 174    search only in the x,y projection."
- 174    ([s minv maxv] + 175    ([s minv maxv]
- 175     (search-vertices s minv maxv false)) + 176     (search-vertices s minv maxv false))
- 176    ([s minv maxv d2?] + 177    ([s minv maxv d2?]
- 177     (let [minv' (if d2? (assoc minv :z Double/NEGATIVE_INFINITY) minv) + 178     (let [minv' (if d2? (assoc minv :z Double/NEGATIVE_INFINITY) minv)
- 178           maxv' (if d2? (assoc maxv :z Double/POSITIVE_INFINITY) maxv)] + 179           maxv' (if d2? (assoc maxv :z Double/POSITIVE_INFINITY) maxv)]
- 179       (filter + 180       (filter
- 180         #(v/within-box? % minv maxv) + 181         #(v/within-box? % minv maxv)
- 181         (filter #(= (:kind %) :vertex) (vals s)))))) -
- - 182   + 182         (filter #(= (:kind %) :vertex) (vals s))))))
183  
+ + 184  (defn find-nearest +
+ + 185    "Search superstructure `s` for the nearest object matching `filter-fn` to +
+ + 186    the `target` vertex. Searches only with `radius` (slight misnomer, area +
+ + 187    actually searched is a cube). Returns one object, or `nil` if no matching +
+ + 188    object found. +
+ + 189   +
+ + 190    WARNING: currently only returns objects which have a defined `:centre` +
+ + 191    (but most of the significant objects we have do)." +
+ + 192    [s target filter-fn radius] +
+ + 193    (let [minv (v/vertex +
+ + 194                 (- (:x (v/check-vertex target)) radius) +
+ + 195                 (- (:y target) radius) (- (or (:z target) 0) radius)) +
+ + 196          maxv (v/vertex +
+ + 197                 (+ (:x target) 0.5) (+ (:y target) 0.5) +
+ + 198                 (+ (or (:z target) 0) 0.5))] +
+ + 199      ;; filter those objects with the filter function, then sort that list +
+ + 200      ;; by the edge distance from the target to the `:centre` of the object +
+ + 201      ;; and take the first +
+ + 202      (first +
+ + 203        (sort-by +
+ + 204          #(length (edge target (:centre %))) +
+ + 205          (filter +
+ + 206            :centre +
+ + 207            (map #(retrieve % s) +
+ + 208                 ;; for each vertex id in vids, get the objects associated with that id +
+ + 209                 ;; in the vertex index as a single flat list +
+ + 210                 (reduce +
+ + 211                   concat +
+ + 212                   (remove +
+ + 213                     nil? +
+ + 214                     (map +
+ + 215                       #(-> s ::vertex-index % keys) +
+ + 216                       ;; get all the vertex ids within radius of the target +
+ + 217                       (set +
+ + 218                         (map +
+ + 219                           :walkmap.id/id +
+ + 220                           (search-vertices s minv maxv)))))))))))) +
+ + 221   +
diff --git a/docs/cloverage/walkmap/utils.clj.html b/docs/cloverage/walkmap/utils.clj.html index 1ed6104..bf4b92c 100644 --- a/docs/cloverage/walkmap/utils.clj.html +++ b/docs/cloverage/walkmap/utils.clj.html @@ -11,301 +11,337 @@ 002    "Miscellaneous utility functions."

- 003    (:require [clojure.math.numeric-tower :as m] + 003    (:require [clojure.edn :as edn :only [read]]
- 004              [clojure.string :as s])) + 004              [clojure.java.io :as io] +
+ + 005              [clojure.math.numeric-tower :as m] +
+ + 006              [clojure.string :as s]))
- 005   + 007  
- 006  (defn deep-merge + 008  (defn deep-merge
- 007    "Recursively merges maps. If vals are not maps, the last value wins." + 009    "Recursively merges maps. If vals are not maps, the last value wins."
- 008    ;; TODO: not my implementation, not sure I entirely trust it. + 010    ;; TODO: not my implementation, not sure I entirely trust it.
- 009    ;; TODO TODO: if we are to successfully merge walkmap objects, we must + 011    ;; TODO TODO: if we are to successfully merge walkmap objects, we must
- 010    ;; return, on each object, the union of its tags if any. + 012    ;; return, on each object, the union of its tags if any.
- 011    [& vals] + 013    [& vals]
- 012    (if (every? map? vals) + 014    (if (every? map? vals)
- 013      (apply merge-with deep-merge vals) + 015      (apply merge-with deep-merge vals)
- 014      (last vals))) + 016      (last vals)))
- 015   + 017  
- 016  (defn truncate + 018  (defn truncate
- 017    "If string `s` is more than `n` characters long, return the first `n` + 019    "If string `s` is more than `n` characters long, return the first `n`
- 018    characters; otherwise, return `s`." + 020    characters; otherwise, return `s`."
- 019    [s n] + 021    [s n]
- 020    (if (and (string? s) (number? n) (> (count s) n)) + 022    (if (and (string? s) (number? n) (> (count s) n))
- 021      (subs s 0 n) + 023      (subs s 0 n)
- 022      s)) + 024      s))
- 023   + 025  
- 024  (defn kind-type + 026  (defn kind-type
- 025    "Identify the type of an `object`, e.g. for logging. If it has a `:kind` key, + 027    "Identify the type of an `object`, e.g. for logging. If it has a `:kind` key,
- 026    it's one of ours, and that's what we want. Otherwise, we want its type; but + 028    it's one of ours, and that's what we want. Otherwise, we want its type; but
- 027    the type of `nil` is `nil`, which doesn't get printed when assembling error + 029    the type of `nil` is `nil`, which doesn't get printed when assembling error
- 028    ,essages, so return \"nil\"." + 030    ,essages, so return \"nil\"."
- 029    [object] + 031    [object]
- 030    (or (:kind object) (type object) "nil")) + 032    (or (:kind object) (type object) "nil"))
- 031   + 033  
- 032  (defn =ish + 034  (defn =ish
- 033    "True if numbers `n1`, `n2` are roughly equal; that is to say, equal to + 035    "True if numbers `n1`, `n2` are roughly equal; that is to say, equal to
- 034    within `tolerance` (defaults to one part in one hundred thousand)." + 036    within `tolerance` (defaults to one part in one hundred thousand)."
- 035    ([n1 n2] + 037    ([n1 n2]
- 036     (if (and (number? n1) (number? n2)) + 038     (if (and (number? n1) (number? n2))
- 037       (let [m (m/abs (min n1 n2)) + 039       (let [m (m/abs (min n1 n2))
- 038             t (if (zero? m) 0.00001 (* 0.00001 m))] + 040             t (if (zero? m) 0.00001 (* 0.00001 m))]
- 039         (=ish n1 n2 t)) + 041         (=ish n1 n2 t))
- 040       (= n1 n2))) + 042       (= n1 n2)))
- 041    ([n1 n2 tolerance] + 043    ([n1 n2 tolerance]
- 042     (if (and (number? n1) (number? n2)) + 044     (if (and (number? n1) (number? n2))
- 043       (< (m/abs (- n1 n2)) tolerance) + 045       (< (m/abs (- n1 n2)) tolerance)
- 044       (= n1 n2)))) + 046       (= n1 n2))))
- 045   + 047  
- 046  (defmacro check-kind-type + 048  (defmacro check-kind-type
- 047    "If `object` is not of kind-type `expected`, throws an + 049    "If `object` is not of kind-type `expected`, throws an
- 048    IllegalArgumentException with an appropriate message; otherwise, returns + 050    IllegalArgumentException with an appropriate message; otherwise, returns
- 049    `object`. If `checkfn` is supplied, it should be a function which tests + 051    `object`. If `checkfn` is supplied, it should be a function which tests
- 050    whether the object is of the expected kind-type. + 052    whether the object is of the expected kind-type.
- 051   + 053  
- 052    Macro, so that the exception is thrown from the calling function." + 054    Macro, so that the exception is thrown from the calling function."
- 053    ([object expected] + 055    ([object expected]
- 054     `(if-not (= (kind-type ~object) ~expected) + 056     `(if-not (= (kind-type ~object) ~expected)
- 055        (throw + 057        (throw
- 056          (IllegalArgumentException. + 058          (IllegalArgumentException.
- 057            (s/join + 059            (s/join
- 058              " " + 060              " "
- 059              ["Expected" ~expected "but found" (kind-type ~object)]))) + 061              ["Expected" ~expected "but found" (kind-type ~object)])))
- 060        ~object)) + 062        ~object))
- 061    ([object checkfn expected] + 063    ([object checkfn expected]
- 062     `(if-not (~checkfn ~object) + 064     `(if-not (~checkfn ~object)
- 063        (throw + 065        (throw
- 064          (IllegalArgumentException. + 066          (IllegalArgumentException.
- 065            (s/join + 067            (s/join
- 066              " " + 068              " "
- 067              ["Expected" ~expected "but found" (kind-type ~object)]))) + 069              ["Expected" ~expected "but found" (kind-type ~object)])))
- 068        ~object))) + 070        ~object)))
- 069   + 071  
- 070  (defmacro check-kind-type-seq + 072  (defmacro check-kind-type-seq
- 071    "If some item on sequence `s` is not of the `expected` kind-type, throws an + 073    "If some item on sequence `s` is not of the `expected` kind-type, throws an
- 072    IllegalArgumentException with an appropriate message; otherwise, returns + 074    IllegalArgumentException with an appropriate message; otherwise, returns
- 073    `object`. If `checkfn` is supplied, it should be a function which tests + 075    `object`. If `checkfn` is supplied, it should be a function which tests
- 074    whether the object is of the expected kind-type. + 076    whether the object is of the expected kind-type.
- 075   + 077  
- 076    Macro, so that the exception is thrown from the calling function." + 078    Macro, so that the exception is thrown from the calling function."
- 077    ([s expected] + 079    ([s expected]
- 078    `(if-not (every? #(= (kind-type %) ~expected) ~s) + 080    `(if-not (every? #(= (kind-type %) ~expected) ~s)
- 079       (throw + 081       (throw
- 080         (IllegalArgumentException. + 082         (IllegalArgumentException.
- 081           (s/join + 083           (s/join
- 082             " " + 084             " "
- 083             ["Expected sequence of" + 085             ["Expected sequence of"
- 084              ~expected + 086              ~expected
- 085              "but found (" + 087              "but found ("
- 086              (s/join ", " (remove #(= ~expected %) (map kind-type ~s))) + 088              (s/join ", " (remove #(= ~expected %) (map kind-type ~s)))
- 087              ")"]))) + 089              ")"])))
- 088       ~s)) + 090       ~s))
- 089    ([s checkfn expected] + 091    ([s checkfn expected]
- 090    `(if-not (every? #(~checkfn %) ~s) + 092    `(if-not (every? #(~checkfn %) ~s)
- 091       (throw + 093       (throw
- 092         (IllegalArgumentException. + 094         (IllegalArgumentException.
- 093           (s/join + 095           (s/join
- 094             " " + 096             " "
- 095             ["Expected sequence of" + 097             ["Expected sequence of"
- 096              ~expected + 098              ~expected
- 097              "but found (" + 099              "but found ("
- 098              (s/join ", " (remove #(= ~expected %) (map kind-type ~s))) + 100              (s/join ", " (remove #(= ~expected %) (map kind-type ~s)))
- 099              ")"]))) + 101              ")"])))
- 100       ~s))) + 102       ~s)))
- 101   + 103   +
+ + 104  (defn load-edn +
+ + 105    "Load edn from an io/reader source (filename or io/resource)." +
+ + 106    [source] +
+ + 107    (try +
+ + 108      (with-open [r (io/reader source)] +
+ + 109        (edn/read (java.io.PushbackReader. r))) +
+ + 110      (catch java.io.IOException e +
+ + 111        (printf "Couldn't open '%s': %s\n" source (.getMessage e))) +
+ + 112      (catch RuntimeException e +
+ + 113        (printf "Error parsing edn file '%s': %s\n" source (.getMessage e)))))
diff --git a/docs/cloverage/walkmap/vertex.clj.html b/docs/cloverage/walkmap/vertex.clj.html index 6495272..54ea011 100644 --- a/docs/cloverage/walkmap/vertex.clj.html +++ b/docs/cloverage/walkmap/vertex.clj.html @@ -139,13 +139,13 @@ 045      (:walkmap.id/id o)
- + 046      (number? (:x o))
047      (number? (:y o))
- + 048      (or (nil? (:z o)) (number? (:z o)))
@@ -211,13 +211,13 @@ 069    (check-vertex v2)
- + 070    (every?
071      #(=ish (% v1) (% v2))
- + 072      [:x :y :z]))
diff --git a/docs/codox/dali-performance.html b/docs/codox/dali-performance.html index 6087c9b..d156cdf 100644 --- a/docs/codox/dali-performance.html +++ b/docs/codox/dali-performance.html @@ -1,6 +1,6 @@ -Dali performance

Dali performance

+Dali performance

Dali performance

Notes written while trying to characterise the performance problem in Dali.

Hypothesis one: it’s the way I format the polygons that’s the issue

Firstly, with both versions of stl->svg using the same version of facet->svg-poly, i.e. this one:

diff --git a/docs/codox/index.html b/docs/codox/index.html index faeaa60..819e75e 100644 --- a/docs/codox/index.html +++ b/docs/codox/index.html @@ -1,3 +1,3 @@ -Walkmap 0.1.0-SNAPSHOT

Walkmap 0.1.0-SNAPSHOT

Released under the EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0

A Clojure library designed to assist in computing walkmaps for games.

Installation

To install, add the following dependency to your project or build file:

[journeyman-cc/walkmap "0.1.0-SNAPSHOT"]

Topics

Namespaces

walkmap.edge

Essentially the specification for things we shall consider to be an edge. An edge is a line segment having just a start and an end, with no intervening nodes.

walkmap.id

The namespace within which the privileged keyword :walkmap.id/id is defined.

Public variables and functions:

walkmap.ocean

Deal with (specifically, at this stage, cull) ocean areas

Public variables and functions:

walkmap.path

Essentially the specification for things we shall consider to be path. Note that for these purposes path means any continuous linear feature, where such features specifically include watercourses.

walkmap.polygon

Essentially the specification for things we shall consider to be polygons.

walkmap.read-svg

Utility functions for scalable vector graphics (SVG) into walkmap structures.

walkmap.routing

Finding optimal routes to traverse a map.

Public variables and functions:

    walkmap.stl

    Utility functions dealing with stereolithography (STL) files. Not a stable API yet!

    walkmap.svg

    Utility functions for writing stereolithography (STL) files (and possibly, later, other geometry files of interest to us) as scalable vector graphics (SVG).

    walkmap.tag

    Code for tagging, untagging, and finding tags on objects. Note the use of the namespaced keyword, :walkmap.tag/tags, denoted in this file ::tags. This is in an attempt to avoid name clashes with other uses of this key.

    Public variables and functions:

    walkmap.utils

    Miscellaneous utility functions.

    walkmap.vertex

    Essentially the specification for things we shall consider to be vertices.

    \ No newline at end of file +Walkmap 0.1.0-SNAPSHOT

    Walkmap 0.1.0-SNAPSHOT

    Released under the EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0

    A Clojure library designed to assist in computing walkmaps for games.

    Installation

    To install, add the following dependency to your project or build file:

    [journeyman-cc/walkmap "0.1.0-SNAPSHOT"]

    Topics

    Namespaces

    walkmap.edge

    Essentially the specification for things we shall consider to be an edge. An edge is a line segment having just a start and an end, with no intervening nodes.

    walkmap.id

    The namespace within which the privileged keyword :walkmap.id/id is defined.

    Public variables and functions:

    walkmap.microworld

    An interface between walkmap and microworld, to allow use of microworld functionality to model things like rainfall, soil fertility, settlement and so on.

    Public variables and functions:

    walkmap.ocean

    Deal with (specifically, at this stage, cull) ocean areas

    Public variables and functions:

    walkmap.path

    Essentially the specification for things we shall consider to be path. Note that for these purposes path means any continuous linear feature, where such features specifically include watercourses.

    walkmap.polygon

    Essentially the specification for things we shall consider to be polygons.

    walkmap.read-svg

    Utility functions for scalable vector graphics (SVG) into walkmap structures.

    walkmap.routing

    Finding optimal routes to traverse a map.

    Public variables and functions:

      walkmap.stl

      Utility functions dealing with stereolithography (STL) files. Not a stable API yet!

      walkmap.svg

      Utility functions for writing stereolithography (STL) files (and possibly, later, other geometry files of interest to us) as scalable vector graphics (SVG).

      walkmap.tag

      Code for tagging, untagging, and finding tags on objects. Note the use of the namespaced keyword, :walkmap.tag/tags, denoted in this file ::tags. This is in an attempt to avoid name clashes with other uses of this key.

      Public variables and functions:

      walkmap.utils

      Miscellaneous utility functions.

      walkmap.vertex

      Essentially the specification for things we shall consider to be vertices.

      \ No newline at end of file diff --git a/docs/codox/intro.html b/docs/codox/intro.html index 8eadcd4..2cb458e 100644 --- a/docs/codox/intro.html +++ b/docs/codox/intro.html @@ -1,6 +1,6 @@ -Introduction to walkmap

      Introduction to walkmap

      +Introduction to walkmap

      Introduction to walkmap

      This library is written in support of work on The Great Game, but is separate because it may be of some use in other settings.

      Usage

      What works:

      diff --git a/docs/codox/walkmap.edge.html b/docs/codox/walkmap.edge.html index 5dd5e9e..3f44988 100644 --- a/docs/codox/walkmap.edge.html +++ b/docs/codox/walkmap.edge.html @@ -1,6 +1,6 @@ -walkmap.edge documentation

      walkmap.edge

      Essentially the specification for things we shall consider to be an edge. An edge is a line segment having just a start and an end, with no intervening nodes.

      centre

      (centre edge)

      Return the vertex that represents the centre of this edge.

      collinear2d?

      (collinear2d? e1 e2)

      True if the projections of edges e1, e2 onto the x, y plane are collinear.

      collinear?

      (collinear? e1 e2)

      True if edges e1 and e2 are collinear with one another.

      edge

      (edge v1 v2)

      Return an edge between vertices v1 and v2.

      edge?

      (edge? o)

      True if o satisfies the conditions for a edge. An edge shall be a map having the keys :start and :end, such that the values of each of those keys shall be a vertex.

      intersection2d

      (intersection2d e1 e2)

      The probability of two lines intersecting in 3d space is low, and actually that is mostly not something we’re interested in. We’re interested in intersection in the x,y plane. This function returns a vertex representing a point vertically over the intersection of edges e1, e2 in the x,y plane, whose z coordinate is

      +walkmap.edge documentation

      walkmap.edge

      Essentially the specification for things we shall consider to be an edge. An edge is a line segment having just a start and an end, with no intervening nodes.

      centre

      (centre edge)

      Return the vertex that represents the centre of this edge.

      collinear2d?

      (collinear2d? e1 e2)

      True if the projections of edges e1, e2 onto the x, y plane are collinear.

      collinear?

      (collinear? e1 e2)

      True if edges e1 and e2 are collinear with one another.

      edge

      (edge v1 v2)

      Return an edge between vertices v1 and v2.

      edge?

      (edge? o)

      True if o satisfies the conditions for a edge. An edge shall be a map having the keys :start and :end, such that the values of each of those keys shall be a vertex.

      intersection2d

      (intersection2d e1 e2)

      The probability of two lines intersecting in 3d space is low, and actually that is mostly not something we’re interested in. We’re interested in intersection in the x,y plane. This function returns a vertex representing a point vertically over the intersection of edges e1, e2 in the x,y plane, whose z coordinate is

      • 0 if both edges are 2d (i.e. have missing or zero z coordinates);
      • if one edge is 2d, then the point on the other edge over the intersection;
      • diff --git a/docs/codox/walkmap.id.html b/docs/codox/walkmap.id.html index cd607e5..8d37cbf 100644 --- a/docs/codox/walkmap.id.html +++ b/docs/codox/walkmap.id.html @@ -1,3 +1,3 @@ -walkmap.id documentation

        walkmap.id

        The namespace within which the privileged keyword :walkmap.id/id is defined.

        id

        The magic id key walkmap uses, to distinguish it from all other uses of the unprotected keyword.

        \ No newline at end of file +walkmap.id documentation

        walkmap.id

        The namespace within which the privileged keyword :walkmap.id/id is defined.

        id

        The magic id key walkmap uses, to distinguish it from all other uses of the unprotected keyword.

        \ No newline at end of file diff --git a/docs/codox/walkmap.microworld.html b/docs/codox/walkmap.microworld.html new file mode 100644 index 0000000..f69ee8b --- /dev/null +++ b/docs/codox/walkmap.microworld.html @@ -0,0 +1,3 @@ + +walkmap.microworld documentation

        walkmap.microworld

        An interface between walkmap and microworld, to allow use of microworld functionality to model things like rainfall, soil fertility, settlement and so on.

        cell->polygon

        (cell->polygon cell)(cell->polygon cell scale-vector)

        TODO: write docs

        load-microworld-edn

        (load-microworld-edn filename)(load-microworld-edn filename map-kind)(load-microworld-edn filename mapkind superstucture)(load-microworld-edn filename map-kind superstructure scale-vertex)

        While it would be possible to call MicroWorld functions directly from Walkmap, the fact is that running MicroWorld is so phenomenally compute-heavy that it’s much more sensible to do it in batch mode. So the better plan is to be able to pull the output from MicroWorld - as an EDN structure - into a walkmap superstructure.

        \ No newline at end of file diff --git a/docs/codox/walkmap.ocean.html b/docs/codox/walkmap.ocean.html index f59e609..4009a9b 100644 --- a/docs/codox/walkmap.ocean.html +++ b/docs/codox/walkmap.ocean.html @@ -1,4 +1,4 @@ -walkmap.ocean documentation

        walkmap.ocean

        Deal with (specifically, at this stage, cull) ocean areas

        *sea-level*

        dynamic

        The sea level on heightmaps we’re currently handling. If characters are to be able to swin in the sea, we must model the sea bottom, so we need heightmaps which cover at least the continental shelf. However, the sea bottom is not walkable territory and can be culled from walkmaps.

        +walkmap.ocean documentation

        walkmap.ocean

        Deal with (specifically, at this stage, cull) ocean areas

        *sea-level*

        dynamic

        The sea level on heightmaps we’re currently handling. If characters are to be able to swin in the sea, we must model the sea bottom, so we need heightmaps which cover at least the continental shelf. However, the sea bottom is not walkable territory and can be culled from walkmaps.

        Note must be a floating point number. (= 0 0.0) returns false!

        cull-ocean-facets

        (cull-ocean-facets stl)

        Ye cannae walk on water. Remove all facets from this stl structure which are at sea level.

        ocean?

        (ocean? facet)

        Of a facet, is the altitude of every vertice equal to *sea-level*?

        \ No newline at end of file diff --git a/docs/codox/walkmap.path.html b/docs/codox/walkmap.path.html index 1c18dac..33c8a59 100644 --- a/docs/codox/walkmap.path.html +++ b/docs/codox/walkmap.path.html @@ -1,5 +1,5 @@ -walkmap.path documentation

        walkmap.path

        Essentially the specification for things we shall consider to be path. Note that for these purposes path means any continuous linear feature, where such features specifically include watercourses.

        check-path

        macro

        (check-path o)

        If o is not a path, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

        check-paths

        macro

        (check-paths o)

        If o is not a sequence of paths, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

        length

        (length path)

        Return the length of this path, in metres. Note that 1. This is not the same as the distance from the start to the end of the path, which, except for absolutely straight paths, will be shorter; 2. It is not even quite the same as the length of the path as rendered, since paths will generally be rendered as spline curves.

        path

        (path & vertices)

        Return a path constructed from these vertices.

        path->edges

        (path->edges o)

        if o is a path, a polygon, or a sequence of vertices, return a sequence of edges representing that path, polygon or sequence.

        +walkmap.path documentation

        walkmap.path

        Essentially the specification for things we shall consider to be path. Note that for these purposes path means any continuous linear feature, where such features specifically include watercourses.

        check-path

        macro

        (check-path o)

        If o is not a path, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

        check-paths

        macro

        (check-paths o)

        If o is not a sequence of paths, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

        length

        (length path)

        Return the length of this path, in metres. Note that 1. This is not the same as the distance from the start to the end of the path, which, except for absolutely straight paths, will be shorter; 2. It is not even quite the same as the length of the path as rendered, since paths will generally be rendered as spline curves.

        path

        (path & vertices)

        Return a path constructed from these vertices.

        path->edges

        (path->edges o)

        if o is a path, a polygon, or a sequence of vertices, return a sequence of edges representing that path, polygon or sequence.

        Throws IllegalArgumentException if o is not a path, a polygon, or sequence of vertices.

        path?

        (path? o)

        True if o satisfies the conditions for a path. A path shall be a map having the key :vertices, whose value shall be a sequence of vertices as defined in walkmap.vertex.

        polygon->path

        (polygon->path o)

        If o is a polygon, return an equivalent path. What’s different about a path is that in polygons there is an implicit edge between the first vertex and the last. In paths, there isn’t, so we need to add that edge explicitly.

        If o is not a polygon, will throw an exception.

        \ No newline at end of file diff --git a/docs/codox/walkmap.polygon.html b/docs/codox/walkmap.polygon.html index c181388..f2b0b3e 100644 --- a/docs/codox/walkmap.polygon.html +++ b/docs/codox/walkmap.polygon.html @@ -1,3 +1,3 @@ -walkmap.polygon documentation

        walkmap.polygon

        Essentially the specification for things we shall consider to be polygons.

        centre

        (centre poly)

        TODO: write docs

        check-polygon

        macro

        (check-polygon o)

        If o is not a polygon, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

        check-polygons

        macro

        (check-polygons o)

        If o is not a sequence of polygons, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

        check-triangle

        macro

        (check-triangle o)

        If o is not a triangle, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

        gradient

        (gradient triangle)

        Return a polygon like triangle but with a key :gradient whose value is a unit vector representing the gradient across triangle.

        polygon

        (polygon & vertices)

        Return a polygon constructed from these vertices.

        polygon?

        (polygon? o)

        True if o satisfies the conditions for a polygon. A polygon shall be a map which has a value for the key :vertices, where that value is a sequence of vertices.

        triangle-centre

        (triangle-centre facet)

        Return a canonicalised facet (i.e. a triangular polygon) with an added key :centre whose value represents the centre of this facet in 3 dimensions. This only works for triangles, so is here not in walkmap.polygon. It is an error (although no exception is currently thrown) if the object past is not a triangular polygon.

        triangle?

        (triangle? o)

        True if o satisfies the conditions for a triangle. A triangle shall be a polygon with exactly three vertices.

        \ No newline at end of file +walkmap.polygon documentation

        walkmap.polygon

        Essentially the specification for things we shall consider to be polygons.

        centre

        (centre poly)

        TODO: write docs

        check-polygon

        macro

        (check-polygon o)

        If o is not a polygon, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

        check-polygons

        macro

        (check-polygons o)

        If o is not a sequence of polygons, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

        check-triangle

        macro

        (check-triangle o)

        If o is not a triangle, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

        gradient

        (gradient triangle)

        Return a polygon like triangle but with a key :gradient whose value is a unit vector representing the gradient across triangle.

        polygon

        (polygon & vertices)

        Return a polygon constructed from these vertices.

        polygon?

        (polygon? o)

        True if o satisfies the conditions for a polygon. A polygon shall be a map which has a value for the key :vertices, where that value is a sequence of vertices.

        rectangle

        (rectangle vsw vne)

        Return a rectangle, with edges aligned east-west and north-south, whose south-west corner is the vertex vsw and whose north-east corner is the vertex vne.

        triangle-centre

        (triangle-centre facet)

        Return a canonicalised facet (i.e. a triangular polygon) with an added key :centre whose value represents the centre of this facet in 3 dimensions. This only works for triangles, so is here not in walkmap.polygon. It is an error (although no exception is currently thrown) if the object past is not a triangular polygon.

        triangle?

        (triangle? o)

        True if o satisfies the conditions for a triangle. A triangle shall be a polygon with exactly three vertices.

        \ No newline at end of file diff --git a/docs/codox/walkmap.read-svg.html b/docs/codox/walkmap.read-svg.html index 2a2fb55..3b40905 100644 --- a/docs/codox/walkmap.read-svg.html +++ b/docs/codox/walkmap.read-svg.html @@ -1,3 +1,3 @@ -walkmap.read-svg documentation

        walkmap.read-svg

        Utility functions for scalable vector graphics (SVG) into walkmap structures.

        command-string->vertices

        (command-string->vertices s)

        Return the destination of each successive line (l, L) and move (m, M) command in this string s, expected to be an SVG path command string.

        match->vertex

        (match->vertex match-vector x y)

        TODO: write docs

        path-elt->path

        (path-elt->path elt)

        Given the SVG path element elt, return a walkmap path structure representing the line (l, L) and move (m, M) commands in that path.

        progeny

        (progeny elt predicate)

        Return all the nodes in the XML structure below this elt which match this predicate.

        read-svg

        (read-svg file-name)(read-svg file-name map-kind)

        TODO: write docs

        upper-case?

        (upper-case? s)

        TODO: write docs

        \ No newline at end of file +walkmap.read-svg documentation

        walkmap.read-svg

        Utility functions for scalable vector graphics (SVG) into walkmap structures.

        command-string->vertices

        (command-string->vertices s)

        Return the destination of each successive line (l, L) and move (m, M) command in this string s, expected to be an SVG path command string.

        match->vertex

        (match->vertex match-vector x y)

        TODO: write docs

        path-elt->path

        (path-elt->path elt)

        Given the SVG path element elt, return a walkmap path structure representing the line (l, L) and move (m, M) commands in that path.

        progeny

        (progeny elt predicate)

        Return all the nodes in the XML structure below this elt which match this predicate.

        read-svg

        (read-svg file-name)(read-svg file-name map-kind)

        TODO: write docs

        upper-case?

        (upper-case? s)

        TODO: write docs

        \ No newline at end of file diff --git a/docs/codox/walkmap.routing.html b/docs/codox/walkmap.routing.html index 45e5507..f8bb0e0 100644 --- a/docs/codox/walkmap.routing.html +++ b/docs/codox/walkmap.routing.html @@ -1,3 +1,3 @@ -walkmap.routing documentation

        walkmap.routing

        Finding optimal routes to traverse a map.

        \ No newline at end of file +walkmap.routing documentation

        walkmap.routing

        Finding optimal routes to traverse a map.

        \ No newline at end of file diff --git a/docs/codox/walkmap.stl.html b/docs/codox/walkmap.stl.html index dfe7091..2186cfe 100644 --- a/docs/codox/walkmap.stl.html +++ b/docs/codox/walkmap.stl.html @@ -1,6 +1,6 @@ -walkmap.stl documentation

        walkmap.stl

        Utility functions dealing with stereolithography (STL) files. Not a stable API yet!

        binary-stl

        A codec for binary STL files

        binary-stl-to-ascii

        (binary-stl-to-ascii in-filename)(binary-stl-to-ascii in-filename out-filename)

        Convert the binary STL file indicated by in-filename, and write it to out-filename, if specified; otherwise, to a file with the same basename as in-filename but the extension .ascii.stl.

        canonicalise

        (canonicalise o)(canonicalise o map-kind)(canonicalise o map-kind scale-vertex)

        Objects read in from STL won’t have all the keys/values we need them to have. o may be a map (representing a facet or a vertex), or a sequence of such maps; if it isn’t recognised it is at present just returned unchanged. map-kind, if passed, must be a keyword indicating the value represented by the z axis (defaults to :height). It is an error, and an exception will be thrown, if map-kind is not a keyword.

        decode-binary-stl

        (decode-binary-stl filename)(decode-binary-stl filename map-kind)(decode-binary-stl filename mapkind superstucture)(decode-binary-stl filename map-kind superstructure scale-vertex)

        Parse a binary STL file from this filename and return an STL structure representing its contents. map-kind, if passed, must be a keyword or sequence of keywords indicating the semantic value represented by the z axis (defaults to :height).

        +walkmap.stl documentation

        walkmap.stl

        Utility functions dealing with stereolithography (STL) files. Not a stable API yet!

        binary-stl

        A codec for binary STL files

        binary-stl-to-ascii

        (binary-stl-to-ascii in-filename)(binary-stl-to-ascii in-filename out-filename)

        Convert the binary STL file indicated by in-filename, and write it to out-filename, if specified; otherwise, to a file with the same basename as in-filename but the extension .ascii.stl.

        canonicalise

        (canonicalise o)(canonicalise o map-kind)(canonicalise o map-kind scale-vertex)

        Objects read in from STL won’t have all the keys/values we need them to have. o may be a map (representing a facet or a vertex), or a sequence of such maps; if it isn’t recognised it is at present just returned unchanged. map-kind, if passed, must be a keyword indicating the value represented by the z axis (defaults to :height). It is an error, and an exception will be thrown, if map-kind is not a keyword.

        decode-binary-stl

        (decode-binary-stl filename)(decode-binary-stl filename map-kind)(decode-binary-stl filename mapkind superstucture)(decode-binary-stl filename map-kind superstructure scale-vertex)

        Parse a binary STL file from this filename and return an STL structure representing its contents. map-kind, if passed, must be a keyword or sequence of keywords indicating the semantic value represented by the z axis (defaults to :height).

        If superstructure is supplied and is a map, the generated STL structure will be stored in that superstructure, which will be returned.

        If scale-vertex is supplied, it must be a three dimensional vertex (i.e. the :z key must have a numeric value) representing the amount by which each of the vertices read from the STL will be scaled.

        It is an error, and an exception will be thrown, if map-kind is not a keyword or sequence of keywords.

        diff --git a/docs/codox/walkmap.superstructure.html b/docs/codox/walkmap.superstructure.html index 56b4fec..0e62012 100644 --- a/docs/codox/walkmap.superstructure.html +++ b/docs/codox/walkmap.superstructure.html @@ -1,19 +1,20 @@ -walkmap.superstructure documentation

        walkmap.superstructure

        single indexing structure for walkmap objects

        in-retrieve

        (in-retrieve x s)

        Internal guts of retrieve, q.v. x can be anything; s must be a walkmap superstructure. TODO: recursive, quite likely to blow the fragile Clojure stack. Probably better to do this with walk, but I don’t yet understand that.

        in-store-find-objects

        (in-store-find-objects o)(in-store-find-objects o s)

        Return an id -> object map of every object within o. Internal to in-store, q.v. Use at your own peril.

        in-store-replace-with-keys

        (in-store-replace-with-keys o)

        Return a copy of o in which each reified walkmap object within o has been replaced with the :walkmap.id/id of that object. Internal to in-store, q.v. Use at your own peril.

        index-vertex

        (index-vertex s o v)

        Return a superstructure like s in which object o is indexed by vertex v. It is an error (and an exception may be thrown) if

        +walkmap.superstructure documentation

        walkmap.superstructure

        single indexing structure for walkmap objects

        find-nearest

        (find-nearest s target filter-fn radius)

        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).

        in-retrieve

        (in-retrieve x s)

        Internal guts of retrieve, q.v. x can be anything; s must be a walkmap superstructure. TODO: recursive, quite likely to blow the fragile Clojure stack. Probably better to do this with walk, but I don’t yet understand that.

        in-store-find-objects

        (in-store-find-objects o)(in-store-find-objects o s)

        Return an id -> object map of every object within o. Internal to in-store, q.v. Use at your own peril.

        in-store-replace-with-keys

        (in-store-replace-with-keys o)

        Return a copy of o in which each reified walkmap object within o has been replaced with the :walkmap.id/id of that object. Internal to in-store, q.v. Use at your own peril.

        index-vertex

        (index-vertex s o v)

        Return a superstructure like s in which object o is indexed by vertex v. It is an error (and an exception may be thrown) if

        1. s is not a map;
        2. o is not a map;
        3. o does not have a value for the key :walkmap.id/id;
        4. v is not a vertex.
        5. -

        index-vertices

        (index-vertices s o)

        Return a superstructure like s in which object o is indexed by its vertices. It is an error (and an exception may be thrown) if

        +

        index-vertices

        (index-vertices s o)

        Return a superstructure like s in which object o is indexed by its vertices. It is an error (and an exception may be thrown) if

        1. s is not a map;
        2. o is not a map;
        3. o does not have a value for the key :walkmap.id/id.
        4. -

        retrieve

        (retrieve id s)

        Retrieve the canonical representation of the object with this id from the superstructure s.

        search-vertices

        (search-vertices s minv maxv)(search-vertices s minv maxv d2?)

        Search superstructure s for vertices within the box defined by vertices minv and maxv. Every coordinate in minv must have a lower value than the equivalent coordinate in maxv. If d2? is supplied and not false, search only in the x,y projection.

        store

        (store o)(store o s)

        Return a superstructure like s with object o added. If only one argument is supplied it will be assumed to represent o and a new superstructure will be returned.

        +

        retrieve

        (retrieve id s)

        Retrieve the canonical representation of the object with this id from the superstructure s.

        search-vertices

        (search-vertices s minv maxv)(search-vertices s minv maxv d2?)

        Search superstructure s for vertices within the box defined by vertices minv and maxv. Every coordinate in minv must have a lower value than the equivalent coordinate in maxv. If d2? is supplied and not false, search only in the x,y projection.

        store

        (store o)(store o s)

        Return a superstructure like s with object o added. If only one argument is supplied it will be assumed to represent o and a new superstructure will be returned.

        It is an error (and an exception may be thrown) if

        1. s is not a map;
        2. o is not a recognisable walkmap object
        3. -

        vertex-index

        TODO: write docs

        vertices

        (vertices o)

        If o is an object with vertices, return those vertices, else nil.

        \ No newline at end of file +

        vertex-index

        TODO: write docs

        vertices

        (vertices o)

        If o is an object with vertices, return those vertices, else nil.

        \ No newline at end of file diff --git a/docs/codox/walkmap.svg.html b/docs/codox/walkmap.svg.html index 7b41486..f35158a 100644 --- a/docs/codox/walkmap.svg.html +++ b/docs/codox/walkmap.svg.html @@ -1,3 +1,3 @@ -walkmap.svg documentation

        walkmap.svg

        Utility functions for writing stereolithography (STL) files (and possibly, later, other geometry files of interest to us) as scalable vector graphics (SVG).

        *preferred-svg-render*

        dynamic

        Mainly for debugging dali; switch SVG renderer to use. Expected values: :dali, :hiccup.

        binary-stl-file->svg

        (binary-stl-file->svg in-filename)(binary-stl-file->svg in-filename out-filename)

        Given only an in-filename, parse the indicated file, expected to be binary STL, and return an equivalent SVG structure. Given both in-filename and out-filename, as side-effect write the SVG to the indicated output file.

        dali-stl->svg

        (dali-stl->svg stl minx maxx miny maxy)

        Format this stl as SVG for the dali renderer on a page with these bounds.

        hiccup-stl->svg

        (hiccup-stl->svg stl minx maxx miny maxy)

        Format this stl as SVG for the hiccup renderer on a page with these bounds.

        stl->svg

        (stl->svg stl)

        Convert this in-memory stl structure, as read by decode-binary-stl, into an in-memory hiccup representation of SVG structure, and return it.

        \ No newline at end of file +walkmap.svg documentation

        walkmap.svg

        Utility functions for writing stereolithography (STL) files (and possibly, later, other geometry files of interest to us) as scalable vector graphics (SVG).

        *preferred-svg-render*

        dynamic

        Mainly for debugging dali; switch SVG renderer to use. Expected values: :dali, :hiccup.

        binary-stl-file->svg

        (binary-stl-file->svg in-filename)(binary-stl-file->svg in-filename out-filename)

        Given only an in-filename, parse the indicated file, expected to be binary STL, and return an equivalent SVG structure. Given both in-filename and out-filename, as side-effect write the SVG to the indicated output file.

        dali-stl->svg

        (dali-stl->svg stl minx maxx miny maxy)

        Format this stl as SVG for the dali renderer on a page with these bounds.

        hiccup-stl->svg

        (hiccup-stl->svg stl minx maxx miny maxy)

        Format this stl as SVG for the hiccup renderer on a page with these bounds.

        stl->svg

        (stl->svg stl)

        Convert this in-memory stl structure, as read by decode-binary-stl, into an in-memory hiccup representation of SVG structure, and return it.

        \ No newline at end of file diff --git a/docs/codox/walkmap.tag.html b/docs/codox/walkmap.tag.html index 26ad5df..bbf3b21 100644 --- a/docs/codox/walkmap.tag.html +++ b/docs/codox/walkmap.tag.html @@ -1,6 +1,6 @@ -walkmap.tag documentation

        walkmap.tag

        Code for tagging, untagging, and finding tags on objects. Note the use of the namespaced keyword, :walkmap.tag/tags, denoted in this file ::tags. This is in an attempt to avoid name clashes with other uses of this key.

        tag

        (tag object & tags)

        Return an object like this object but with these tags added to its tags, if they are not already present. It is an error (and an exception will be thrown) if

        +walkmap.tag documentation

        walkmap.tag

        Code for tagging, untagging, and finding tags on objects. Note the use of the namespaced keyword, :walkmap.tag/tags, denoted in this file ::tags. This is in an attempt to avoid name clashes with other uses of this key.

        tag

        (tag object & tags)

        Return an object like this object but with these tags added to its tags, if they are not already present. It is an error (and an exception will be thrown) if

        1. object is not a map;
        2. any of tags is not a keyword or sequence of keywords.
        3. diff --git a/docs/codox/walkmap.utils.html b/docs/codox/walkmap.utils.html index 51a9a3a..80f6037 100644 --- a/docs/codox/walkmap.utils.html +++ b/docs/codox/walkmap.utils.html @@ -1,5 +1,5 @@ -walkmap.utils documentation

          walkmap.utils

          Miscellaneous utility functions.

          =ish

          (=ish n1 n2)(=ish n1 n2 tolerance)

          True if numbers n1, n2 are roughly equal; that is to say, equal to within tolerance (defaults to one part in a million).

          check-kind-type

          macro

          (check-kind-type object expected)(check-kind-type object checkfn expected)

          If object is not of kind-type expected, throws an IllegalArgumentException with an appropriate message; otherwise, returns object. If checkfn is supplied, it should be a function which tests whether the object is of the expected kind-type.

          -

          Macro, so that the exception is thrown from the calling function.

          check-kind-type-seq

          macro

          (check-kind-type-seq s expected)(check-kind-type-seq s checkfn expected)

          If some item on sequence s is not of the expected kind-type, throws an IllegalArgumentException with an appropriate message; otherwise, returns object. If checkfn is supplied, it should be a function which tests whether the object is of the expected kind-type.

          -

          Macro, so that the exception is thrown from the calling function.

          deep-merge

          (deep-merge & vals)

          Recursively merges maps. If vals are not maps, the last value wins.

          kind-type

          (kind-type object)

          Identify the type of an object, e.g. for logging. If it has a :kind key, it’s one of ours, and that’s what we want. Otherwise, we want its type; but the type of nil is nil, which doesn’t get printed when assembling error ,essages, so return “nil”.

          truncate

          (truncate s n)

          If string s is more than n characters long, return the first n characters; otherwise, return s.

          \ No newline at end of file +walkmap.utils documentation

          walkmap.utils

          Miscellaneous utility functions.

          =ish

          (=ish n1 n2)(=ish n1 n2 tolerance)

          True if numbers n1, n2 are roughly equal; that is to say, equal to within tolerance (defaults to one part in one hundred thousand).

          check-kind-type

          macro

          (check-kind-type object expected)(check-kind-type object checkfn expected)

          If object is not of kind-type expected, throws an IllegalArgumentException with an appropriate message; otherwise, returns object. If checkfn is supplied, it should be a function which tests whether the object is of the expected kind-type.

          +

          Macro, so that the exception is thrown from the calling function.

          check-kind-type-seq

          macro

          (check-kind-type-seq s expected)(check-kind-type-seq s checkfn expected)

          If some item on sequence s is not of the expected kind-type, throws an IllegalArgumentException with an appropriate message; otherwise, returns object. If checkfn is supplied, it should be a function which tests whether the object is of the expected kind-type.

          +

          Macro, so that the exception is thrown from the calling function.

          deep-merge

          (deep-merge & vals)

          Recursively merges maps. If vals are not maps, the last value wins.

          kind-type

          (kind-type object)

          Identify the type of an object, e.g. for logging. If it has a :kind key, it’s one of ours, and that’s what we want. Otherwise, we want its type; but the type of nil is nil, which doesn’t get printed when assembling error ,essages, so return “nil”.

          load-edn

          (load-edn source)

          Load edn from an io/reader source (filename or io/resource).

          truncate

          (truncate s n)

          If string s is more than n characters long, return the first n characters; otherwise, return s.

          \ No newline at end of file diff --git a/docs/codox/walkmap.vertex.html b/docs/codox/walkmap.vertex.html index 95d3948..d65d5f6 100644 --- a/docs/codox/walkmap.vertex.html +++ b/docs/codox/walkmap.vertex.html @@ -1,7 +1,7 @@ -walkmap.vertex documentation

          walkmap.vertex

          Essentially the specification for things we shall consider to be vertices.

          -

          Note that there’s no distance function here; to find the distance between two vertices, create an edge from them and use walkmap.edge/length.

          canonicalise

          (canonicalise o)

          If o is a map with numeric values for :x, :y and optionally :z, upgrade it to something we will recognise as a vertex.

          check-vertex

          macro

          (check-vertex o)

          If o is not a vertex, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

          check-vertices

          macro

          (check-vertices o)

          If o is not a sequence of vertices, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

          ensure2d

          If o is a vertex, set its :z value to zero; else throw an exception.

          ensure3d

          Given a vertex o, if o has a :z value, just return o; otherwise return a vertex like o but having this dflt value as the value of its :z key, or zero as the value of its :z key if dflt is not specified.

          -

          If o is not a vertex, throws an exception.

          vertex

          (vertex x y)(vertex x y z)

          Make a vertex with this x, y and (if provided) z values. Returns a map with those values, plus a unique :walkmap.id/id value, and :kind set to :vertex. It’s not necessary to use this function to create a vertex, but the :walkmap.id/id must be present and must be unique.

          vertex*

          (vertex* v1 v2)

          Return a vertex like v1, but with each of its coordinates multiplied by the equivalent vertex in v2. It is an error, and an exception will be thrown, if either v1 or v2 is not a vertex.

          vertex-key

          (vertex-key o)

          Making sure we get the same key everytime we key a vertex with the same coordinates. o must have numeric values for :x, :y, and optionally :z; it is an error and an exception will be thrown if o does not conform to this specification.

          +walkmap.vertex documentation

          walkmap.vertex

          Essentially the specification for things we shall consider to be vertices.

          +

          Note that there’s no distance function here; to find the distance between two vertices, create an edge from them and use walkmap.edge/length.

          canonicalise

          (canonicalise o)

          If o is a map with numeric values for :x, :y and optionally :z, upgrade it to something we will recognise as a vertex.

          check-vertex

          macro

          (check-vertex o)

          If o is not a vertex, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

          check-vertices

          macro

          (check-vertices o)

          If o is not a sequence of vertices, throw an IllegalArgumentException with an appropriate message; otherwise, returns o. Macro, so exception is thrown from the calling function.

          ensure2d

          If o is a vertex, set its :z value to zero; else throw an exception.

          ensure3d

          Given a vertex o, if o has a :z value, just return o; otherwise return a vertex like o but having this dflt value as the value of its :z key, or zero as the value of its :z key if dflt is not specified.

          +

          If o is not a vertex, throws an exception.

          vertex

          (vertex x y)(vertex x y z)

          Make a vertex with this x, y and (if provided) z values. Returns a map with those values, plus a unique :walkmap.id/id value, and :kind set to :vertex. It’s not necessary to use this function to create a vertex, but the :walkmap.id/id must be present and must be unique.

          vertex*

          (vertex* v1 v2)

          Return a vertex like v1, but with each of its coordinates multiplied by the equivalent vertex in v2. It is an error, and an exception will be thrown, if either v1 or v2 is not a vertex.

          vertex-key

          (vertex-key o)

          Making sure we get the same key everytime we key a vertex with the same coordinates. o must have numeric values for :x, :y, and optionally :z; it is an error and an exception will be thrown if o does not conform to this specification.

          Note: these keys can be quite long. No apology is made: it is required that the same key can never refer to two different locations in space.

          vertex=

          (vertex= v1 v2)

          True if vertices v1, v2 represent the same vertex.

          vertex?

          (vertex? o)

          True if o satisfies the conditions for a vertex. That is, essentially, that it must rerpresent a two- or three- dimensional vector. A vertex is shall be a map having at least the keys :x and :y, where the value of those keys is a number. If the key :z is also present, its value must also be a number.

          -

          The name vector? was not used as that would clash with a function of that name in clojure.core whose semantics are entirely different.

          within-box?

          (within-box? target minv maxv)

          True if target is within the box defined by minv and maxv. All arguments must be vertices; additionally, both minv and maxv must have :z coordinates.

          \ No newline at end of file +

          The name vector? was not used as that would clash with a function of that name in clojure.core whose semantics are entirely different.

          within-box?

          (within-box? target minv maxv)

          True if target is within the box defined by minv and maxv. All arguments must be vertices; additionally, both minv and maxv must have :z coordinates.

          \ No newline at end of file diff --git a/project.clj b/project.clj index 577dc87..0a448bb 100644 --- a/project.clj +++ b/project.clj @@ -14,9 +14,6 @@ [dali "0.7.4"] ;; not currently used because performance issues. [hiccup "1.0.5"] [me.raynes/fs "1.4.6"] - [mw-cli "0.1.6-SNAPSHOT"] - [mw-engine "0.1.6-SNAPSHOT"] - [mw-parser "0.1.6-SNAPSHOT"] [smee/binary "0.5.5"]] :deploy-repositories [["releases" :clojars] ["snapshots" :clojars]] diff --git a/src/walkmap/microworld.clj b/src/walkmap/microworld.clj index 5b88a99..f23380c 100644 --- a/src/walkmap/microworld.clj +++ b/src/walkmap/microworld.clj @@ -5,40 +5,17 @@ (:require [clojure.edn :as edn :only [read]] [clojure.java.io :as io] [clojure.string :as s] - [mw-cli.core :refer [process]] - [mw-engine.core :refer [run-world]] - [mw-engine.heightmap :as h] - [mw-engine.drainage :as d] - [mw-parser.bulk :as parser] [taoensso.timbre :as l] [walkmap.edge :as e] - [walkmap.polygon :as p :only [check-polygon polygon? rectangle]] + [walkmap.polygon :as p :only [rectangle]] [walkmap.superstructure :refer [store]] - [walkmap.tag :as t :only [tag tags]] - [walkmap.utils :as u :only [check-kind-type check-kind-type-seq kind-type truncate]] - [walkmap.vertex :as v :only [vertex vertex?]])) - -;; (def settlement-rules (parser/compile-file "resources/rules/settlement_rules.txt")) - -;; (def w0 (h/apply-heightmap "../the-great-game/resources/maps/heightmap.png")) -;; (def w1 (d/rain-world (d/flood-hollows w0))) -;; (def w2 (drainage/flow-world-nr w1)) - -;; (def w3 (run-world w2 nil settlement-rules 100)) - -;; (with-open [w (clojure.java.io/writer "settlement_1.edn")] -;; (binding [*out* w] -;; (pr -;; (run-world w0 nil settlement-rules 100)))) - -;; (process -;; (h/apply-heightmap "resources/small_hill.png") -;; (parser/compile-file "resources/rules/settlement_rules.txt") -;; 100 -;; "small_hill.edn" -;; "small_hill.html") + [walkmap.tag :as t :only [tag]] + [walkmap.vertex :as v :only [check-vertex vertex vertex?]])) (defn cell->polygon + "From this MicroWorld `cell`, construct a walkmap polygon (specifically, + a rectangle. If `scale-vector` passed and is a vertex, scale all the vertices + in the cell by that vector." ([cell] (cell->polygon cell (v/vertex 1 1 1))) ([cell scale-vector] @@ -46,7 +23,7 @@ (assoc (merge cell - (let [w (* (:x cell) (:x scale-vector)) + (let [w (* (:x cell) (:x (check-vertex scale-vector))) s (* (:y cell) (:y scale-vector)) e (+ w (:x scale-vector)) n (+ s (:y scale-vector)) diff --git a/src/walkmap/routing.clj b/src/walkmap/routing.clj index fc35d54..c223844 100644 --- a/src/walkmap/routing.clj +++ b/src/walkmap/routing.clj @@ -1,8 +1,10 @@ (ns walkmap.routing "Finding optimal routes to traverse a map." - (:require [walkmap.path :as p] + (:require [walkman.edge :as e] + [walkmap.path :as p] [walkmap.polygon :as q] - [walkmap.stl :as s] + [walkmap.superstructure :as s] + [walkmap.tag :as t] [walkmap.utils :as u] [walkmap.vertex :as v])) @@ -16,3 +18,64 @@ ;; https://faculty.nps.edu/ncrowe/opmpaper2.htm ;; ;; See https://simon-brooke.github.io/the-great-game/codox/Pathmaking.html + +(defn traversable? + "True if this object can be considered as part of the walkmap." + [object] + (and + (or + (and + (q/polygon? object) + (:centre object)) + (p/path? object)) + (not (t/tagged? object :no-traversal)))) + +(defn extend-frontier + "Return a sequence like `frontier` with all of these `candidates` which are + not already members either of `frontier` or of `rejects` appended." + ([frontier candidates] + (extend-frontier frontier candidates nil)) + ([frontier candidates rejects] + (if + (empty? frontier) + candidates + (let [fs (set (concat frontier rejects))] + (concat frontier (remove fs candidates)))))) + +;; (extend-frontier '(1 2 3 4 5) '(7 3 6 2 9 8) '(6 8)) +;; (extend-frontier '(1 2 3 4 5) '(7 3 6 2 9 8)) +;; (extend-frontier '(1 2 3 4 5) '()) +;; (extend-frontier '(1 2 3 4 5) nil) +;; (extend-frontier nil '(1 2 3 4 5)) + +(defn route + ;; NOT YET GOOD ENOUGH! Simple breadth first, and although it will + ;; reach the goal + ([from to s search-radius] + (loop [f from + t to + frontier (extend-frontier + nil + (s/neighbour-ids + (s/nearest s from :centre search-radius) + traversable? + s)) + visited nil] + (let [here (s/retrieve (first frontier) s)] + (cond + (< (e/length (e/edge (:centre here)) to) search-radius) + ;; close enough + (apply p/path (cons (:centre here) track)) + (empty? (rest frontier)) + ;; failed + nil + :else + (recur + f + t + (extend-frontier + (rest frontier) + (neighbour-ids here traversable? s) + visited) + (cons here visited))))))) + diff --git a/src/walkmap/superstructure.clj b/src/walkmap/superstructure.clj index dab1075..6d41aa7 100644 --- a/src/walkmap/superstructure.clj +++ b/src/walkmap/superstructure.clj @@ -181,7 +181,7 @@ #(v/within-box? % minv maxv) (filter #(= (:kind %) :vertex) (vals s)))))) -(defn find-nearest +(defn 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 @@ -219,3 +219,21 @@ :walkmap.id/id (search-vertices s minv maxv)))))))))))) +(defn neighbours + "Return a sequence of all those objects in superstructure `s` which share + at least one vertex with `target`, and which are matched by `filter-fn` + if supplied." + ([target s] + (neighbours identity s)) + ([target filter-fn s] + ;; TODO: write it. + nil)) + +(defn neighbour-ids + "Return a sequence of the ids all those objects in superstructure `s` which + share at least one vertex with `target`, and which are matched by + `filter-fn` if supplied." + ([target s] + (neighbour-ids target identity s)) + ([target filter-fn s] + (map :walkmap.id/id (neighbours target filter-fn s)))) diff --git a/src/walkmap/utils.clj b/src/walkmap/utils.clj index 427194e..5163d24 100644 --- a/src/walkmap/utils.clj +++ b/src/walkmap/utils.clj @@ -1,6 +1,8 @@ (ns walkmap.utils "Miscellaneous utility functions." - (:require [clojure.math.numeric-tower :as m] + (:require [clojure.edn :as edn :only [read]] + [clojure.java.io :as io] + [clojure.math.numeric-tower :as m] [clojure.string :as s])) (defn deep-merge