Merge branch 'feature/3' into develop
This commit is contained in:
commit
4df5c4dff4
|
@ -16,133 +16,181 @@
|
|||
</tr></thead>
|
||||
<tr>
|
||||
<td><a href="walkmap/core.clj.html">walkmap.core</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:12.244897959183673%;
|
||||
float:left;"> 6 </div><div class="not-covered"
|
||||
style="width:87.75510204081633%;
|
||||
float:left;"> 43 </div></td>
|
||||
<td class="with-number">12.24 %</td>
|
||||
style="width:100.0%;
|
||||
float:left;"> 1 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:38.46153846153846%;
|
||||
float:left;"> 5 </div><div class="not-covered"
|
||||
style="width:61.53846153846154%;
|
||||
float:left;"> 8 </div></td>
|
||||
<td class="with-number">38.46 %</td>
|
||||
<td class="with-number">44</td><td class="with-number">6</td><td class="with-number">13</td>
|
||||
style="width:100.0%;
|
||||
float:left;"> 1 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">9</td><td class="with-number">1</td><td class="with-number">1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/edge.clj.html">walkmap.edge</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:69.38775510204081%;
|
||||
float:left;"> 136 </div><div class="not-covered"
|
||||
style="width:30.612244897959183%;
|
||||
float:left;"> 60 </div></td>
|
||||
<td class="with-number">69.39 %</td>
|
||||
style="width:98.31697054698458%;
|
||||
float:left;"> 701 </div><div class="not-covered"
|
||||
style="width:1.6830294530154277%;
|
||||
float:left;"> 12 </div></td>
|
||||
<td class="with-number">98.32 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:70.0%;
|
||||
float:left;"> 35 </div><div class="partial"
|
||||
style="width:2.0%;
|
||||
float:left;"> 1 </div><div class="not-covered"
|
||||
style="width:28.0%;
|
||||
float:left;"> 14 </div></td>
|
||||
<td class="with-number">72.00 %</td>
|
||||
<td class="with-number">82</td><td class="with-number">7</td><td class="with-number">50</td>
|
||||
style="width:95.1923076923077%;
|
||||
float:left;"> 99 </div><div class="partial"
|
||||
style="width:4.8076923076923075%;
|
||||
float:left;"> 5 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">189</td><td class="with-number">18</td><td class="with-number">104</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/geometry.clj.html">walkmap.geometry</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:1.6260162601626016%;
|
||||
float:left;"> 2 </div><div class="not-covered"
|
||||
style="width:98.3739837398374%;
|
||||
float:left;"> 121 </div></td>
|
||||
<td class="with-number">1.63 %</td>
|
||||
style="width:100.0%;
|
||||
float:left;"> 62 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:15.384615384615385%;
|
||||
float:left;"> 2 </div><div class="not-covered"
|
||||
style="width:84.61538461538461%;
|
||||
float:left;"> 11 </div></td>
|
||||
<td class="with-number">15.38 %</td>
|
||||
<td class="with-number">24</td><td class="with-number">3</td><td class="with-number">13</td>
|
||||
style="width:100.0%;
|
||||
float:left;"> 10 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">17</td><td class="with-number">1</td><td class="with-number">10</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/ocean.clj.html">walkmap.ocean</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:17.857142857142858%;
|
||||
float:left;"> 5 </div><div class="not-covered"
|
||||
style="width:82.14285714285714%;
|
||||
float:left;"> 23 </div></td>
|
||||
<td class="with-number">17.86 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:50.0%;
|
||||
float:left;"> 4 </div><div class="not-covered"
|
||||
style="width:50.0%;
|
||||
float:left;"> 4 </div></td>
|
||||
<td class="with-number">50.00 %</td>
|
||||
<td class="with-number">24</td><td class="with-number">4</td><td class="with-number">8</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/path.clj.html">walkmap.path</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:5.555555555555555%;
|
||||
float:left;"> 3 </div><div class="not-covered"
|
||||
style="width:94.44444444444444%;
|
||||
float:left;"> 51 </div></td>
|
||||
<td class="with-number">5.56 %</td>
|
||||
style="width:3.5294117647058822%;
|
||||
float:left;"> 6 </div><div class="not-covered"
|
||||
style="width:96.47058823529412%;
|
||||
float:left;"> 164 </div></td>
|
||||
<td class="with-number">3.53 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:23.076923076923077%;
|
||||
float:left;"> 3 </div><div class="not-covered"
|
||||
style="width:76.92307692307692%;
|
||||
float:left;"> 10 </div></td>
|
||||
<td class="with-number">23.08 %</td>
|
||||
<td class="with-number">30</td><td class="with-number">4</td><td class="with-number">13</td>
|
||||
style="width:15.789473684210526%;
|
||||
float:left;"> 6 </div><div class="not-covered"
|
||||
style="width:84.21052631578948%;
|
||||
float:left;"> 32 </div></td>
|
||||
<td class="with-number">15.79 %</td>
|
||||
<td class="with-number">78</td><td class="with-number">7</td><td class="with-number">38</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/polygon.clj.html">walkmap.polygon</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:7.407407407407407%;
|
||||
float:left;"> 2 </div><div class="not-covered"
|
||||
style="width:92.5925925925926%;
|
||||
float:left;"> 25 </div></td>
|
||||
<td class="with-number">7.41 %</td>
|
||||
style="width:90.56603773584905%;
|
||||
float:left;"> 48 </div><div class="not-covered"
|
||||
style="width:9.433962264150944%;
|
||||
float:left;"> 5 </div></td>
|
||||
<td class="with-number">90.57 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:25.0%;
|
||||
float:left;"> 2 </div><div class="not-covered"
|
||||
style="width:75.0%;
|
||||
float:left;"> 6 </div></td>
|
||||
<td class="with-number">25.00 %</td>
|
||||
<td class="with-number">17</td><td class="with-number">3</td><td class="with-number">8</td>
|
||||
style="width:90.0%;
|
||||
float:left;"> 9 </div><div class="partial"
|
||||
style="width:10.0%;
|
||||
float:left;"> 1 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">19</td><td class="with-number">3</td><td class="with-number">10</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/stl.clj.html">walkmap.stl</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:17.228464419475657%;
|
||||
float:left;"> 46 </div><div class="not-covered"
|
||||
style="width:82.77153558052434%;
|
||||
float:left;"> 221 </div></td>
|
||||
<td class="with-number">17.23 %</td>
|
||||
style="width:56.777996070726914%;
|
||||
float:left;"> 289 </div><div class="not-covered"
|
||||
style="width:43.222003929273086%;
|
||||
float:left;"> 220 </div></td>
|
||||
<td class="with-number">56.78 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:28.125%;
|
||||
float:left;"> 18 </div><div class="not-covered"
|
||||
style="width:71.875%;
|
||||
style="width:44.0%;
|
||||
float:left;"> 44 </div><div class="partial"
|
||||
style="width:10.0%;
|
||||
float:left;"> 10 </div><div class="not-covered"
|
||||
style="width:46.0%;
|
||||
float:left;"> 46 </div></td>
|
||||
<td class="with-number">28.13 %</td>
|
||||
<td class="with-number">126</td><td class="with-number">12</td><td class="with-number">64</td>
|
||||
<td class="with-number">54.00 %</td>
|
||||
<td class="with-number">191</td><td class="with-number">14</td><td class="with-number">100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/superstructure.clj.html">walkmap.superstructure</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:2.5974025974025974%;
|
||||
float:left;"> 4 </div><div class="not-covered"
|
||||
style="width:97.40259740259741%;
|
||||
float:left;"> 150 </div></td>
|
||||
<td class="with-number">2.60 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:14.814814814814815%;
|
||||
float:left;"> 4 </div><div class="not-covered"
|
||||
style="width:85.18518518518519%;
|
||||
float:left;"> 23 </div></td>
|
||||
<td class="with-number">14.81 %</td>
|
||||
<td class="with-number">85</td><td class="with-number">9</td><td class="with-number">27</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/svg.clj.html">walkmap.svg</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:2.8776978417266186%;
|
||||
float:left;"> 4 </div><div class="not-covered"
|
||||
style="width:97.12230215827338%;
|
||||
float:left;"> 135 </div></td>
|
||||
<td class="with-number">2.88 %</td>
|
||||
style="width:3.7542662116040955%;
|
||||
float:left;"> 11 </div><div class="not-covered"
|
||||
style="width:96.24573378839591%;
|
||||
float:left;"> 282 </div></td>
|
||||
<td class="with-number">3.75 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:8.571428571428571%;
|
||||
style="width:12.121212121212121%;
|
||||
float:left;"> 8 </div><div class="not-covered"
|
||||
style="width:87.87878787878788%;
|
||||
float:left;"> 58 </div></td>
|
||||
<td class="with-number">12.12 %</td>
|
||||
<td class="with-number">108</td><td class="with-number">7</td><td class="with-number">66</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/tag.clj.html">walkmap.tag</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 137 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 36 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">65</td><td class="with-number">7</td><td class="with-number">36</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/utils.clj.html">walkmap.utils</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:7.894736842105263%;
|
||||
float:left;"> 3 </div><div class="not-covered"
|
||||
style="width:91.42857142857143%;
|
||||
float:left;"> 32 </div></td>
|
||||
<td class="with-number">8.57 %</td>
|
||||
<td class="with-number">50</td><td class="with-number">2</td><td class="with-number">35</td>
|
||||
style="width:92.10526315789474%;
|
||||
float:left;"> 35 </div></td>
|
||||
<td class="with-number">7.89 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:30.0%;
|
||||
float:left;"> 3 </div><div class="not-covered"
|
||||
style="width:70.0%;
|
||||
float:left;"> 7 </div></td>
|
||||
<td class="with-number">30.00 %</td>
|
||||
<td class="with-number">23</td><td class="with-number">3</td><td class="with-number">10</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/vertex.clj.html">walkmap.vertex</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:72.94117647058823%;
|
||||
float:left;"> 62 </div><div class="not-covered"
|
||||
style="width:27.058823529411764%;
|
||||
float:left;"> 23 </div></td>
|
||||
<td class="with-number">72.94 %</td>
|
||||
style="width:78.08641975308642%;
|
||||
float:left;"> 253 </div><div class="not-covered"
|
||||
style="width:21.91358024691358%;
|
||||
float:left;"> 71 </div></td>
|
||||
<td class="with-number">78.09 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:63.63636363636363%;
|
||||
float:left;"> 14 </div><div class="partial"
|
||||
style="width:13.636363636363637%;
|
||||
float:left;"> 3 </div><div class="not-covered"
|
||||
style="width:22.727272727272727%;
|
||||
float:left;"> 5 </div></td>
|
||||
<td class="with-number">77.27 %</td>
|
||||
<td class="with-number">43</td><td class="with-number">5</td><td class="with-number">22</td>
|
||||
style="width:70.0%;
|
||||
float:left;"> 42 </div><div class="partial"
|
||||
style="width:10.0%;
|
||||
float:left;"> 6 </div><div class="not-covered"
|
||||
style="width:20.0%;
|
||||
float:left;"> 12 </div></td>
|
||||
<td class="with-number">80.00 %</td>
|
||||
<td class="with-number">114</td><td class="with-number">11</td><td class="with-number">60</td>
|
||||
</tr>
|
||||
<tr><td>Totals:</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">27.77 %</td>
|
||||
<td class="with-number">61.24 %</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">39.45 %</td>
|
||||
<td class="with-number">61.28 %</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
001 (ns walkmap.core
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "At this stage, primarily utility functions dealing with stereolithography
|
||||
002 "This namespace mostly gets used as a scratchpad for ideas which haven't yet
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 (STL) files. Not a stable API yet!"
|
||||
003 solidified."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 (:require [clojure.java.io :as io :refer [file output-stream input-stream]]
|
||||
|
@ -26,115 +26,10 @@
|
|||
007 [me.raynes.fs :as fs]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 [taoensso.timbre :as l :refer [info error spy]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 [walkmap.stl :refer [decode-binary-stl]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 [walkmap.svg :refer [stl->svg]]))
|
||||
008 [taoensso.timbre :as l :refer [info error spy]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
011
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
012 (def ^:dynamic *sea-level*
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 "The sea level on heightmaps we're currently handling. If characters are to
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 be able to swin in the sea, we must model the sea bottom, so we need
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 heightmaps which cover at least the continental shelf. However, the sea
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 bottom is not walkable territory and can be culled from walkmaps.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
017
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 **Note** must be a floating point number. `(= 0 0.0)` returns `false`!"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 0.0)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
020
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
021 (defn ocean?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 "Of a `facet`, is the altitude of every vertice equal to `*sea-level*`?"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 [facet]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
024 (every?
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
025 #(= % *sea-level*)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
026 (map :z (:vertices facet))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
027
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
028 (defn cull-ocean-facets
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 "Ye cannae walk on water. Remove all facets from this `stl` structure which
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 are at sea level."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 [stl]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
032 (assoc stl :facets (remove ocean? (:facets stl))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
033
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
034 (defn binary-stl-file->svg
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 "Given only an `in-filename`, parse the indicated file, expected to be
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 binary STL, and return an equivalent SVG structure. Given both `in-filename`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 and `out-filename`, as side-effect write the SVG to the indicated output file."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 ([in-filename]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
039 (stl->svg (cull-ocean-facets (decode-binary-stl in-filename))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 ([in-filename out-filename]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
041 (let [s (binary-stl-file->svg in-filename)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
042 (spit out-filename (html s))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
043 s)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
044
|
||||
009
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -20,235 +20,556 @@
|
|||
005 (:require [clojure.math.numeric-tower :as m]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 [walkmap.path :refer [path? polygon->path]]
|
||||
006 [walkmap.polygon :refer [polygon?]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 [walkmap.polygon :refer [polygon?]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 [walkmap.vertex :refer [ensure3d vertex?]]))
|
||||
007 [walkmap.vertex :refer [ensure2d ensure3d vertex vertex= vertex?]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
009
|
||||
008
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
010 (defn edge?
|
||||
009 (defn edge
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 "True if `o` satisfies the conditions for a path. A path shall be a map
|
||||
010 "Return an edge between vertices `v1` and `v2`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 having the keys `:start` and `:end`, such that the values of each of those
|
||||
011 [v1 v2]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 keys shall be a vertex."
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
012 (if
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 [o]
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
013 (and (vertex? v1) (vertex? v2))
|
||||
</span><br/>
|
||||
<span class="partial" title="8 out of 9 forms covered">
|
||||
015 (and
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
014 {:kind :edge :id (keyword (gensym "edge")) :start v1 :end v2}
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
016 (map? o)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
017 (vertex? (:start o))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
018 (vertex? (:end o))))
|
||||
015 (throw (IllegalArgumentException. "Must be vertices."))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
019
|
||||
016
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
020 (defn path->edges
|
||||
017 (defn edge?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 "if `o` is a path, a polygon, or a sequence of vertices, return a sequence of
|
||||
018 "True if `o` satisfies the conditions for a edge. An edge shall be a map
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 edges representing that path, polygon or sequence."
|
||||
019 having the keys `:start` and `:end`, such that the values of each of those
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 [o]
|
||||
020 keys shall be a vertex."
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
024 (cond
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 [o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
025 (seq? o)
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
022 (and
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
026 (when
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
023 (map? o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
027 (and
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
024 (vertex? (:start o))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
028 (vertex? (first o))
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
025 (vertex? (:end o))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
029 (vertex? (first (rest o))))
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
026
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
030 (cons
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
027 (defn length
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
031 {:start (first o)
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 "Return the length of the edge `e`."
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
032 :end (first (rest o))}
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 [e]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
033 (path->edges (rest o))))
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
030 (let [start (ensure3d (:start e))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
034 (path? o)
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
031 end (ensure3d (:end e))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
035 (path->edges (:nodes o))
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
032 (m/sqrt
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
036 (polygon? o)
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
033 (reduce
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
037 (path->edges (polygon->path o))))
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
034 +
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
035 (map
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
036 #(m/expt (- (% end) (% start)) 2)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
037 [:x :y :z])))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
038
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
039 (defn length
|
||||
039 (defn centre
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 "Return the length of the edge `e`."
|
||||
040 "Return the vertex that represents the centre of this `edge`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
041 [e]
|
||||
041 [edge]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
042 (let [start (ensure3d (:start e))
|
||||
042 (let [s (ensure3d (:start edge))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
043 end (ensure3d (:end e))]
|
||||
043 e (ensure3d (:end edge))]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
044 (m/sqrt
|
||||
044 (vertex
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
045 (reduce
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
045 (+ (:x s) (/ (- (:x e) (:x s)) 2))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
046 +
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
046 (+ (:y s) (/ (- (:y e) (:y s)) 2))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
047 (map
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
048 #(m/expt (- (% end) (% start)) 2)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
049 [:x :y :z])))))
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
047 (+ (:z s) (/ (- (:z e) (:z s)) 2)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
050
|
||||
048
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
051 (defn unit-vector
|
||||
049 (defn unit-vector
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 "Return an vertex parallel to `e` starting from the coordinate origin. Two
|
||||
050 "Return an vertex parallel to `e` starting from the coordinate origin. Two
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 edges which are parallel will have the same unit vector."
|
||||
051 edges which are parallel will have the same unit vector."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 [e]
|
||||
052 [e]
|
||||
</span><br/>
|
||||
<span class="covered" title="14 out of 14 forms covered">
|
||||
055 (let [e' {:start (ensure3d (:start e)) :end (ensure3d (:end e))}
|
||||
053 (let [e' {:start (ensure3d (:start e)) :end (ensure3d (:end e))}
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
056 l (length e')]
|
||||
054 l (length e')]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
057 (reduce
|
||||
055 (reduce
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
058 merge
|
||||
056 merge
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
059 {}
|
||||
057 {}
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
060 (map
|
||||
058 (map
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
061 (fn [k]
|
||||
059 (fn [k]
|
||||
</span><br/>
|
||||
<span class="covered" title="17 out of 17 forms covered">
|
||||
062 {k (/ (- (k (:end e')) (k (:start e'))) l)})
|
||||
060 {k (/ (- (k (:end e')) (k (:start e'))) l)})
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
063 [:x :y :z]))))
|
||||
061 [:x :y :z]))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
064
|
||||
062
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
065 (defn parallel?
|
||||
063 (defn parallel?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 "True if all `edges` passed are parallel with one another."
|
||||
064 "True if all `edges` passed are parallel with one another."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
067 ;; TODO: this bears being wary about, dealing with floating point arithmetic.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
068 ;; Keep an eye out for spurious errors.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
069 [& edges]
|
||||
065 [& edges]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
070 (let [uvs (map unit-vector edges)]
|
||||
066 (let [uvs (map unit-vector edges)]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
071 (every?
|
||||
067 (every?
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
072 #(= % (first uvs))
|
||||
068 #(vertex= % (first uvs))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
073 (rest uvs))))
|
||||
069 (rest uvs))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
074
|
||||
070
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
075 (defn collinear?
|
||||
071 (defn collinear?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076 "True if edges `e1` and `e2` are collinear with one another."
|
||||
072 "True if edges `e1` and `e2` are collinear with one another."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
077 [e1 e2]
|
||||
073 [e1 e2]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
078 (parallel?
|
||||
074 (parallel?
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
079 e1
|
||||
075 e1
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
080 e2
|
||||
076 e2
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
081 {:start (:start e1) :end (:start e2)}))
|
||||
077 (if (vertex= (:start e1) (:start e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
078 {:start (:start e1) :end (:end e2)}
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
079 {:start (:start e1) :end (:start e2)})))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
082
|
||||
080
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
081 (defn collinear2d?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
082 "True if the projections of edges `e1`, `e2` onto the x, y plane are
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
083 collinear."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
084 [e1 e2]
|
||||
</span><br/>
|
||||
<span class="covered" title="15 out of 15 forms covered">
|
||||
085 (collinear? {:start (ensure2d (:start e1)) :end (ensure2d (:end e1))}
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
086 {:start (ensure2d (:start e2)) :end (ensure2d (:end e2))}))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
087
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
088 (defn minimaxd
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
089 "Apply function `f` to `coord` of the vertices at start and end of `edge`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 and return the result. Intended use case is `f` = `min` or `max`, `coord`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
091 is `:x`, `:y` or `:z`. No checks are made for sane arguments."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
092 [edge coord f]
|
||||
</span><br/>
|
||||
<span class="covered" title="15 out of 15 forms covered">
|
||||
093 (apply f (list (coord (:start edge)) (coord (:end edge)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
094
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
095 (defn on?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
096 "True if the vertex `v` is on the edge `e`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
097 [e v]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
098 (let [p (ensure3d (:start e))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
099 q (ensure3d v)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
100 r (ensure3d (:end e))]
|
||||
</span><br/>
|
||||
<span class="partial" title="20 out of 25 forms covered">
|
||||
101 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
102 (collinear? (edge p q) (edge q r))
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
103 (<= (:x q) (max (:x p) (:x r)))
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
104 (>= (:x q) (min (:x p) (:x r)))
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
105 (<= (:y q) (max (:y p) (:y r)))
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
106 (>= (:y q) (min (:y p) (:y r)))
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
107 (<= (:z q) (max (:z p) (:z r)))
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
108 (>= (:z q) (min (:z p) (:z r))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
109
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
110 (defn on2d?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
111 "True if vertex `v` is on edge `e` when projected onto the x, y plane."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
112 [e v]
|
||||
</span><br/>
|
||||
<span class="covered" title="15 out of 15 forms covered">
|
||||
113 (on? (edge (ensure2d (:start e)) (ensure2d (:end e))) v))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
114
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
115 (defn overlaps2d?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
116 "True if the recangle in the x,y plane bisected by edge `e1` overlaps that
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
117 bisected by edge `e2`. It is an error if either `e1` or `e2` is not an edge."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
118 [e1 e2]
|
||||
</span><br/>
|
||||
<span class="partial" title="11 out of 12 forms covered">
|
||||
119 (when (and (edge? e1) (edge? e2))
|
||||
</span><br/>
|
||||
<span class="partial" title="11 out of 13 forms covered">
|
||||
120 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
121 (> (minimaxd e1 :x max) (minimaxd e2 :x min))
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
122 (< (minimaxd e1 :x min) (minimaxd e2 :x max))
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
123 (> (minimaxd e1 :y max) (minimaxd e2 :y min))
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
124 (< (minimaxd e1 :y min) (minimaxd e2 :y max)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
125
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
126 ;; Don't think I need this.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
127 ;; (defn orientation
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
128 ;; "Determine whether the ordered sequence of vertices `p`, `q` and `r` run
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
129 ;; clockwise, collinear or anticlockwise in the x,y plane."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
130 ;; [p q r]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
131 ;; (let [v (- (* (- (:y q) (:y p)) (- (:x r) (:x q)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
132 ;; (* (- (:x q) (:x p)) (- (:y r) (:y q))))]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
133 ;; (cond
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
134 ;; (zero? v) :collinear
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
135 ;; (pos? v) :clockwise
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
136 ;; :else
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
137 ;; :anticlockwise)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
138
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
139 (defn intersection2d
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
140 "The probability of two lines intersecting in 3d space is low, and actually
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
141 that is mostly not something we're interested in. We're interested in
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
142 intersection in the `x,y` plane. This function returns a vertex representing
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
143 a point vertically over the intersection of edges `e1`, `e2` in the `x,y`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
144 plane, whose `z` coordinate is
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
145
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
146 * 0 if both edges are 2d (i.e. have missing or zero `z` coordinates);
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
147 * if one edge is 2d, then the point on the other edge over the intersection;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
148 * otherwise, the average of the z coordinates of the points on the two
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
149 edges over the intersection.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
150
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
151 If no such intersection exists, `nil` is returned.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
152
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
153 It is an error, and an exception will be thrown, if either `e1` or `e2` is
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
154 not an edge."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
155 [e1 e2]
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
156 (if (and (edge? e1) (edge? e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
157 (when
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
158 (overlaps2d? e1 e2) ;; relatively cheap check
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
159 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
160 (collinear2d? e1 e2)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
161 ;; any point within the overlap will do, but we'll pick the end of e1
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
162 ;; which is on e2
|
||||
</span><br/>
|
||||
<span class="partial" title="10 out of 13 forms covered">
|
||||
163 (if (on2d? e2 (:start e1)) (:start e1) (:end e1))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
164 ;; blatantly stolen from
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
165 ;; https://gist.github.com/cassiel/3e725b49670356a9b936
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
166 (let [x1 (:x (:start e1))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
167 x2 (:x (:end e1))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
168 x3 (:x (:start e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
169 x4 (:x (:end e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
170 y1 (:y (:start e1))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
171 y2 (:y (:end e1))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
172 y3 (:y (:start e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
173 y4 (:y (:end e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
174 denom (- (* (- x1 x2) (- y3 y4))
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
175 (* (- y1 y2) (- x3 x4)))
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
176 x1y2-y1x2 (- (* x1 y2) (* y1 x2))
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
177 x3y4-y3x4 (- (* x3 y4) (* y3 x4))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
178 px-num (- (* x1y2-y1x2 (- x3 x4))
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
179 (* (- x1 x2) x3y4-y3x4))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
180 py-num (- (* x1y2-y1x2 (- y3 y4))
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
181 (* (- y1 y2) x3y4-y3x4))
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
182 result (when-not (zero? denom)
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
183 (vertex (/ px-num denom) (/ py-num denom)))]
|
||||
</span><br/>
|
||||
<span class="partial" title="19 out of 20 forms covered">
|
||||
184 (when (and result (on2d? e1 result) (on2d? e2 result)) result))))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
185 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
186 (str
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
187 "Both `e1` and `e2` must be edges."
|
||||
</span><br/>
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
188 (map #(or (:kind %) (type %)) [e1 e2]))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
189
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -11,70 +11,49 @@
|
|||
002 (:require [clojure.math.combinatorics :as combo]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 [clojure.math.numeric-tower :as m]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 [walkmap.edge :as e]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 [walkmap.path :refer [path? polygon->path]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 [walkmap.polygon :refer [polygon?]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 [walkmap.vertex :as v]))
|
||||
003 [clojure.math.numeric-tower :as m]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
008
|
||||
004
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
009 (defn on?
|
||||
005 (defn =ish
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 "True if the vertex `v` is on the edge `e`."
|
||||
006 "True if numbers `n1`, `n2` are roughly equal; that is to say, equal to
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 [e v]
|
||||
007 within `tolerance` (defaults to one part in a million)."
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
012 (let [p (v/ensure3d (:start e))
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 ([n1 n2]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
013 q (v/ensure3d v)
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
009 (if (and (number? n1) (number? n2))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
014 r (v/ensure3d (:end e))]
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
010 (let [m (m/abs (min n1 n2))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 25 forms covered">
|
||||
015 (and
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
011 t (if (zero? m) 0.000001 (* 0.000001 m))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
016 (e/collinear? p q r)
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
012 (=ish n1 n2 t))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
017 (<= (:x q) (max (:x p) (:x r)))
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
013 (= n1 n2)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
018 (>= (:x q) (min (:x p) (:x r)))
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 ([n1 n2 tolerance]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
019 (<= (:y q) (max (:y p) (:y r)))
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
015 (if (and (number? n1) (number? n2))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
020 (>= (:y q) (min (:y p) (:y r)))
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
016 (< (m/abs (- n1 n2)) tolerance)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
021 (<= (:z q) (max (:z p) (:z r)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 12 forms covered">
|
||||
022 (>= (:z q) (min (:z p) (:z r))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
023
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
024
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
017 (= n1 n2))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
80
docs/cloverage/walkmap/ocean.clj.html
Normal file
80
docs/cloverage/walkmap/ocean.clj.html
Normal file
|
@ -0,0 +1,80 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../coverage.css"/> <title> walkmap/ocean.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns walkmap.ocean
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Deal with (specifically, at this stage, cull) ocean areas")
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
003
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
004 (def ^:dynamic *sea-level*
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 "The sea level on heightmaps we're currently handling. If characters are to
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 be able to swin in the sea, we must model the sea bottom, so we need
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 heightmaps which cover at least the continental shelf. However, the sea
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 bottom is not walkable territory and can be culled from walkmaps.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
009
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 **Note** must be a floating point number. `(= 0 0.0)` returns `false`!"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 0.0)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
012
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
013 (defn ocean?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 "Of a `facet`, is the altitude of every vertice equal to `*sea-level*`?"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 [facet]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
016 (every?
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
017 #(= % *sea-level*)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
018 (map :z (:vertices facet))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
019
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
020 (defn cull-ocean-facets
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 "Ye cannae walk on water. Remove all facets from this `stl` structure which
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 are at sea level."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 [stl]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
024 (assoc stl :facets (remove ocean? (:facets stl))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
|
@ -8,91 +8,235 @@
|
|||
001 (ns walkmap.path
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Essentially the specification for things we shall consider to be path."
|
||||
002 "Essentially the specification for things we shall consider to be path.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 (:require [walkmap.polygon :refer [polygon?]]
|
||||
003 **Note that** for these purposes `path` means any continuous linear
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 [walkmap.vertex :refer [vertex?]]))
|
||||
004 feature, where such features specifically include watercourses."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 (:require [walkmap.edge :as e]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 [walkmap.polygon :refer [polygon?]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 [walkmap.vertex :refer [vertex?]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
005
|
||||
008
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
006 (defn path?
|
||||
009 (defn path?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 "True if `o` satisfies the conditions for a path. A path shall be a map
|
||||
010 "True if `o` satisfies the conditions for a path. A path shall be a map
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 having the key `:nodes`, whose value shall be a sequence of vertices as
|
||||
011 having the key `:vertices`, whose value shall be a sequence of vertices as
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 defined in `walkmap.vertex`."
|
||||
012 defined in `walkmap.vertex`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 [o]
|
||||
013 [o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
011 (let
|
||||
014 (let
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
012 [v (:nodes o)]
|
||||
015 [v (:vertices o)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
013 (and
|
||||
<span class="not-covered" title="0 out of 22 forms covered">
|
||||
016 (and
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
014 (seq? v)
|
||||
017 (seq? v)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
015 (> (count v) 2)
|
||||
018 (> (count v) 2)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
019 (every? vertex? v)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
016 (every? vertex? v))))
|
||||
020 (:id o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
021 (or (nil? (:kind o)) (= (:kind o) :path)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
017
|
||||
022
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
018 (defn polygon->path
|
||||
023 (defn path
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 "If `o` is a polygon, return an equivalent path. What's different about
|
||||
024 "Return a path constructed from these `vertices`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 a path is that in polygons there is an implicit edge between the first
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 vertex and the last. In paths, there isn't, so we need to add that
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 edge explicitly.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
023
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 If `o` is not a polygon, will throw an exception."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 [o]
|
||||
025 [& vertices]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
026 (if
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
027 (polygon? o)
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
027 (every? vertex? vertices)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 19 forms covered">
|
||||
028 (assoc (dissoc o :vertices) :nodes (concat (:vertices o) (list (first (:vertices o)))))
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
028 {:vertices vertices :id (keyword (gensym "path")) :kind :path}
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
029 (throw (Exception. "Not a polygon!"))))
|
||||
029 (throw (IllegalArgumentException. "Each item on path must be a vertex."))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
030
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
031 (defn polygon->path
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 "If `o` is a polygon, return an equivalent path. What's different about
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 a path is that in polygons there is an implicit edge between the first
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 vertex and the last. In paths, there isn't, so we need to add that
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 edge explicitly.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
036
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 If `o` is not a polygon, will throw an exception."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 [o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
039 (if
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
040 (polygon? o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 21 forms covered">
|
||||
041 (assoc (dissoc o :vertices) :kind :path :vertices (concat (:vertices o) (list (first (:vertices o)))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
042 (throw (IllegalArgumentException. "Not a polygon!"))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
043
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
044 (defn path->edges
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 "if `o` is a path, a polygon, or a sequence of vertices, return a sequence of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 edges representing that path, polygon or sequence.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
047
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
048 Throws `IllegalArgumentException` if `o` is not a path, a polygon, or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 sequence of vertices."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050 [o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
051 (cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
052 (seq? o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
053 (when
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
054 (and
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
055 (vertex? (first o))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
056 (vertex? (first (rest o))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
057 (cons
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 ;; TODO: think about: when constructing an edge from a path, should the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059 ;; constructed edge be tagged with the tags of the path?
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
060 (e/edge (first o) (rest o))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
061 (path->edges (rest o))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
062 (path? o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
063 (path->edges (:vertices o))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
064 :else
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
065 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 "Not a path or sequence of vertices!"))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
067
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
068 (defn length
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
069 "Return the length of this path, in metres. **Note that**
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
070 1. This is not the same as the distance from the start to the end of the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 path, which, except for absolutely straight paths, will be shorter;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
072 2. It is not even quite the same as the length of the path *as rendered*,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
073 since paths will generally be rendered as spline curves."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
074 [path]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
075 (if
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
076 (path? path)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
077 (reduce + (map e/length (path->edges path)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
078 (throw (IllegalArgumentException. "Not a path!"))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -31,29 +31,35 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 [o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
010 (let
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
011 [v (:vertices o)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
<span class="partial" title="17 out of 22 forms covered">
|
||||
012 (and
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
013 (seq? v)
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
013 (coll? v)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
014 (> (count v) 2)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
015 (every? vertex? v))))
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
015 (every? vertex? v)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
016 (:id o)
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
017 (or (nil? (:kind o)) (= (:kind o) :polygon)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
016
|
||||
018
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
017
|
||||
019
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -26,361 +26,556 @@
|
|||
007 [taoensso.timbre :as l :refer [info error spy]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 [walkmap.polygon :refer [polygon?]])
|
||||
008 [walkmap.edge :as e]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 (:import org.clojars.smee.binary.core.BinaryIO
|
||||
009 [walkmap.polygon :refer [polygon?]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 java.io.DataInput))
|
||||
010 [walkmap.tag :refer [tag]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 [walkmap.vertex :as v])
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 (:import org.clojars.smee.binary.core.BinaryIO
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 java.io.DataInput))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
011
|
||||
014
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
012 (defn stl?
|
||||
015 (defn stl?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 "True if `o` is recogniseable as an STL structure. An STL structure must
|
||||
016 "True if `o` is recogniseable as an STL structure. An STL structure must
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 have a key `:facets`, whose value must be a sequence of polygons; and
|
||||
017 have a key `:facets`, whose value must be a sequence of polygons; and
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 may have a key `:header` whose value should be a string, and/or a key
|
||||
018 may have a key `:header` whose value should be a string, and/or a key
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 `:count`, whose value should be a positive integer.
|
||||
019 `:count`, whose value should be a positive integer.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
017
|
||||
020
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 If `verify-count?` is passed and is not `false`, verify that the value of
|
||||
021 If `verify-count?` is passed and is not `false`, verify that the value of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 the `:count` header is equal to the number of facets."
|
||||
022 the `:count` header is equal to the number of facets."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 ([o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
021 (stl? o false))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 ([o verify-count?]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 22 forms covered">
|
||||
023 (and
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
024 (map? o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
025 (:facets o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
026 (every? polygon? (:facets o))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
027 (if (:header o) (string? (:header o)) true)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
028 (if (:count o) (integer? (:count o)) true)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
029 (if verify-count? (= (:count o) (count (:facets o))) true))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
030
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
031 (def vect
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 "A codec for vectors within a binary STL file."
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
033 (b/ordered-map
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 :x :float-le
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 :y :float-le
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 :z :float-le))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
037
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
038 (def facet
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 "A codec for a facet (triangle) within a binary STL file."
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
040 (b/ordered-map
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
041 :normal vect
|
||||
023 ([o]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
042 :vertices [vect vect vect]
|
||||
024 (stl? o false))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043 :abc :ushort-le))
|
||||
025 ([o verify-count?]
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
044
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
045 (def binary-stl
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 "A codec for binary STL files"
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
047 (b/ordered-map
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
048 :header (b/string "ISO-8859-1" :length 80) ;; for the time being we neither know nor care what's in this.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 :count :uint-le
|
||||
<span class="partial" title="20 out of 26 forms covered">
|
||||
026 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
050 :facets (b/repeated facet)))
|
||||
027 (map? o)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
028 (:facets o)
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
029 (every? polygon? (:facets o))
|
||||
</span><br/>
|
||||
<span class="partial" title="9 out of 10 forms covered">
|
||||
030 (if (:header o) (string? (:header o)) true)
|
||||
</span><br/>
|
||||
<span class="partial" title="9 out of 10 forms covered">
|
||||
031 (if (:count o) (integer? (:count o)) true)
|
||||
</span><br/>
|
||||
<span class="partial" title="14 out of 15 forms covered">
|
||||
032 (or (nil? (:kind o)) (= (:kind o) :stl))
|
||||
</span><br/>
|
||||
<span class="partial" title="1 out of 11 forms covered">
|
||||
033 (if verify-count? (= (:count o) (count (:facets o))) true))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
051
|
||||
034
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
052 (defn decode-binary-stl
|
||||
035 (def vect
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 "Parse a binary STL file from this `filename` and return an STL structure
|
||||
036 "A codec for vectors within a binary STL file."
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
037 (b/ordered-map
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 representing its contents.
|
||||
038 :x :float-le
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 :y :float-le
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 :z :float-le))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
041
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
042 (def facet
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043 "A codec for a facet (triangle) within a binary STL file."
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
044 (b/ordered-map
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
045 :normal vect
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
046 :vertices [vect vect vect]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 :abc :ushort-le))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
048
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
049 (def binary-stl
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050 "A codec for binary STL files"
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
051 (b/ordered-map
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
052 :header (b/string "ISO-8859-1" :length 80) ;; for the time being we neither know nor care what's in this.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 :count :uint-le
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
054 :facets (b/repeated facet)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
055
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
056 **NOTE** that we've no way of verifying that the input file is binary STL
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
056 (defn centre
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
057 data, if it is not this will run but will return garbage."
|
||||
057 "Return a canonicalised `facet` (i.e. a triangular polygon) with an added
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 [filename]
|
||||
058 key `:centre` whose value represents the centre of this facet in 3
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
059 (let [in (io/input-stream filename)]
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059 dimensions. This only works for triangles, so is here not in
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
060 (b/decode binary-stl in)))
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
060 `walkmap.polygon`. It is an error (although no exception is currently
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
061
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
061 thrown) if the object past is not a triangular polygon."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
062 [facet]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
063 (let [vs (:vertices facet)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
064 v1 (first vs)
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
065 opposite (e/edge (nth vs 1) (nth vs 2))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
066 oc (e/centre opposite)]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
067 (assoc
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
068 facet
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
069 :centre
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
062 (defn- vect->str [prefix v]
|
||||
070 (v/vertex
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 16 forms covered">
|
||||
063 (str prefix " " (:x v) " " (:y v) " " (:z v) "\n"))
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
071 (+ (:x v1) (* (- (:x oc) (:x v1)) 2/3))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
064
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
072 (+ (:y v1) (* (- (:y oc) (:y v1)) 2/3))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
065 (defn- facet2str [tri]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
066 (str
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
067 (vect->str "facet normal" (:normal tri))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
068 "outer loop\n"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
069 (apply str
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
070 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
071 #(vect->str "vertex" %)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
072 (:vertices tri)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
073 "endloop\nendfacet\n"))
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
073 (+ (:z v1) (* (- (:z oc) (:z v1)) 2/3))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
074
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
075 (defn stl->ascii
|
||||
075 (defn canonicalise
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076 "Return as a string an ASCII rendering of the `stl` structure."
|
||||
076 "Objects read in from STL won't have all the keys/values we need them to have.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
077 ([stl]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
078 (stl->ascii stl "unknown"))
|
||||
077 `o` may be a map (representing a facet or a vertex), or a sequence of such maps;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
079 ([stl solidname]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
080 (str
|
||||
078 if it isn't recognised it is at present just returned unchanged. `map-kind`, if
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
081 "solid "
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
082 solidname
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
083 (s/trim (:header stl))
|
||||
079 passed, must be a keyword indicating the value represented by the `z` axis
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
084 "\n"
|
||||
080 (defaults to `:height`). It is an error, and an exception will be thrown, if
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
081 `map-kind` is not a keyword."
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
082 ([o] (canonicalise o :height))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
083 ([o map-kind]
|
||||
</span><br/>
|
||||
<span class="partial" title="2 out of 3 forms covered">
|
||||
084 (when-not
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
085 (keyword? map-kind)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
085 (apply
|
||||
086 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
086 str
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
087 (subs (str "Must be a keyword: " (or map-kind "nil")) 0 80))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
087 (map
|
||||
<span class="partial" title="4 out of 5 forms covered">
|
||||
088 (cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
088 facet2str
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
089 (:facets stl)))
|
||||
<span class="partial" title="19 out of 20 forms covered">
|
||||
089 (and (coll? o) (not (map? o))) (map #(canonicalise % map-kind) o)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 "endsolid "
|
||||
090 ;; if it has :facets it's an STL structure, but it doesn't yet conform to `stl?`
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
091 solidname
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
091 (:facets o) (assoc o
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
092 "\n")))
|
||||
092 :kind :stl
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
093
|
||||
<span class="partial" title="11 out of 12 forms covered">
|
||||
093 :id (or (:id o) (keyword (gensym "stl")))
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
094 :facets (canonicalise (:facets o) map-kind))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
095 ;; if it has :vertices it's a polygon, but it doesn't yet conform to `polygon?`
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
096 (:vertices o) (centre
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
097 (tag
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
098 (assoc o
|
||||
</span><br/>
|
||||
<span class="partial" title="11 out of 12 forms covered">
|
||||
099 :id (or (:id o) (keyword (gensym "poly")))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
100 :kind :polygon
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
101 :vertices (canonicalise (:vertices o) map-kind))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
094 (defn write-ascii-stl
|
||||
102 :facet map-kind))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
095 "Write an `stl` structure as read by `decode-binary-stl` to this
|
||||
103 ;; if it has a value for :x it's a vertex, but it doesn't yet conform to `vertex?`
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
104 (:x o) (v/canonicalise o)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
096 `filename` as ASCII encoded STL."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
097 ([filename stl]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
098 (let [b (fs/base-name filename true)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
099 (write-ascii-stl
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
100 filename stl
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 15 forms covered">
|
||||
101 (subs b 0 (or (s/index-of b ".") (count b))))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
102 ([filename stl solidname]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 16 forms covered">
|
||||
103 (l/debug "Solid name is " solidname)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
104 (spit
|
||||
105 ;; shouldn't happen
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
105 filename
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
106 (stl->ascii stl solidname))))
|
||||
106 :else o)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
107
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
108 (defn binary-stl-to-ascii
|
||||
108 (defn decode-binary-stl
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
109 "Convert the binary STL file indicated by `in-filename`, and write it to
|
||||
109 "Parse a binary STL file from this `filename` and return an STL structure
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
110 `out-filename`, if specified; otherwise, to a file with the same basename
|
||||
110 representing its contents. `map-kind`, if passed, must be a keyword
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
111 as `in-filename` but the extension `.ascii.stl`."
|
||||
111 indicating the value represented by the `z` axis (defaults to `:height`).
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
112 ([in-filename]
|
||||
112 It is an error, and an exception will be thrown, if `map-kind` is not a
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
113 keyword.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
114
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
115 **NOTE** that we've no way of verifying that the input file is binary STL
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
116 data, if it is not this will run but will return garbage."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
117 ([filename]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
113 (let [[_ ext] (fs/split-ext in-filename)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
114 (binary-stl-to-ascii
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
115 in-filename
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
116 (str
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
117 (subs
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
118 in-filename
|
||||
118 (decode-binary-stl filename :height))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
119 0
|
||||
119 ([filename map-kind]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
120 (or
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
120 (when-not
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
121 (keyword? map-kind)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
122 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
123 (subs (str "Must be a keyword: " (or map-kind "nil")) 0 80))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
121 (s/last-index-of in-filename ".")
|
||||
124 (let [in (io/input-stream filename)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
122 (count in-filename)))
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
125 (canonicalise (b/decode binary-stl in) map-kind))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
123 ".ascii"
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
126
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
124 ext))))
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
127 (defn- vect->str [prefix v]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
125 ([in-filename out-filename]
|
||||
<span class="not-covered" title="0 out of 16 forms covered">
|
||||
128 (str prefix " " (:x v) " " (:y v) " " (:z v) "\n"))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
129
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
130 (defn- facet2str [tri]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
131 (str
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
126 (write-ascii-stl out-filename (decode-binary-stl in-filename))))
|
||||
132 (vect->str "facet normal" (:normal tri))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
133 "outer loop\n"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
134 (apply str
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
135 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
136 #(vect->str "vertex" %)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
137 (:vertices tri)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
138 "endloop\nendfacet\n"))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
139
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
140 (defn stl->ascii
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
141 "Return as a string an ASCII rendering of the `stl` structure."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
142 ([stl]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
143 (stl->ascii stl "unknown"))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
144 ([stl solidname]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
145 (str
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
146 "solid "
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
147 solidname
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
148 (s/trim (:header stl))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
149 "\n"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
150 (apply
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
151 str
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
152 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
153 facet2str
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
154 (:facets stl)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
155 "endsolid "
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
156 solidname
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
157 "\n")))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
158
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
159 (defn write-ascii-stl
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
160 "Write an `stl` structure as read by `decode-binary-stl` to this
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
161 `filename` as ASCII encoded STL."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
162 ([filename stl]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
163 (let [b (fs/base-name filename true)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
164 (write-ascii-stl
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
165 filename stl
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 15 forms covered">
|
||||
166 (subs b 0 (or (s/index-of b ".") (count b))))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
167 ([filename stl solidname]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 16 forms covered">
|
||||
168 (l/debug "Solid name is " solidname)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
169 (spit
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
170 filename
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
171 (stl->ascii stl solidname))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
172
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
173 (defn binary-stl-to-ascii
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
174 "Convert the binary STL file indicated by `in-filename`, and write it to
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
175 `out-filename`, if specified; otherwise, to a file with the same basename
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
176 as `in-filename` but the extension `.ascii.stl`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
177 ([in-filename]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
178 (let [[_ ext] (fs/split-ext in-filename)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
179 (binary-stl-to-ascii
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
180 in-filename
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
181 (str
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
182 (subs
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
183 in-filename
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
184 0
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
185 (or
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
186 (s/last-index-of in-filename ".")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
187 (count in-filename)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
188 ".ascii"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
189 ext))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
190 ([in-filename out-filename]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
191 (write-ascii-stl out-filename (decode-binary-stl in-filename))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
263
docs/cloverage/walkmap/superstructure.clj.html
Normal file
263
docs/cloverage/walkmap/superstructure.clj.html
Normal file
|
@ -0,0 +1,263 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../coverage.css"/> <title> walkmap/superstructure.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns walkmap.superstructure
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "single indexing structure for walkmap objects"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 (:require [walkmap.path :as p]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 [walkmap.polygon :as q]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 [walkmap.stl :as s]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 [walkmap.utils :as u]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 [walkmap.vertex :as v]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
008
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 ;; TODO: Think about reification/dereification. How can we cull a polygon, if
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 ;; some vertices still index it? I *think* that what's needed is that when
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 ;; we store something in the superstructure, we replace all its vertices (and
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 ;; other dependent structures, if any with their ids - as well as, obviously,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 ;; adding/merging those vertices/dependent structures into the superstructure
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 ;; as first class objects in themselves. That means, for each identified thing,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 ;; the superstructure only contains one copy of it.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 ;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 ;; The question then is, when we want to do things with those objects, do we
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 ;; exteract a copy with its dependent structures fixed back up (reification),
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 ;; or do we indirect through the superstructure every time we want to access
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 ;; them? In a sense, the copy in the superstructure is the 'one true copy',
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 ;; but it may become very difficult then to have one true copy of the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 ;; superstructure - unless we replace the superstructure altogether with a
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 ;; database, which may be the Right Thing To Do.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
024
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
025 (defn index-vertex
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 "Return a superstructure like `s` in which object `o` is indexed by vertex
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 `v`. It is an error (and an exception may be thrown) if
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
028
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 1. `s` is not a map;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 2. `o` is not a map;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 3. `o` does not have a value for the key `:id`;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 4. `v` is not a vertex."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 [s o v]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
034 (if-not (v/vertex? o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
035 (if (:id o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
036 (if (v/vertex? v)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
037 (let [vi (or (:vertex-index s) {})
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
038 current (or (vi (:id v)) {})]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 ;; deep-merge doesn't merge sets, only maps; so at this
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 ;; stage we need to build a map.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 15 forms covered">
|
||||
041 (assoc vi (:id v) (assoc current (:id o) (:id v))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
042 (throw (IllegalArgumentException. "Not a vertex: " v)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
043 (throw (IllegalArgumentException. (subs (str "No `:id` value: " o) 0 80))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044 ;; it shouldn't actually be an error to try to index a vertex, but it
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 ;; also isn't useful to do so, so I'd be inclined to ignore it.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
046 (:vertex-index s)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
047
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
048 (defn index-vertices
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 "Return a superstructure like `s` in which object `o` is indexed by its
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050 vertices. It is an error (and an exception may be thrown) if
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
051
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 1. `s` is not a map;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 2. `o` is not a map;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 3. `o` does not have a value for the key `:id`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
055 [s o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
056 (assoc
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
057 s
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 :vertex-index
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
059 (reduce
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
060 u/deep-merge
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
061 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
062 #(index-vertex s o %)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
063 (u/vertices o)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
064
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
065 (defn add-to-superstructure
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 "Return a superstructure like `s` with object `o` added. If `o` is a collection,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
067 return a superstructure like `s` with each element of `o` added. If only one
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
068 argument is supplied it will be assumed to represent `o` and a new
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
069 superstructure will be returned.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
070
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 It is an error (and an exception may be thrown) if
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
072
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
073 1. `s` is not a map;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
074 2. `o` is not a map, or a sequence of maps."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
075 ([o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
076 (add-to-superstructure {} o))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
077 ([s o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
078 (cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 18 forms covered">
|
||||
079 (map? o) (let [o' (if (:id o) o (assoc o :id (keyword (gensym "obj"))))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
080 (index-vertices (assoc s (:id o') o') o'))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 14 forms covered">
|
||||
081 (coll? o) (reduce u/deep-merge (map #(add-to-superstructure s %) o))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
082 (nil? o) o
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
083 :else
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
084 (throw (IllegalArgumentException. (str "Don't know how to index " (or (type o) "nil")))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
085
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
|
@ -20,139 +20,313 @@
|
|||
005 (:require [clojure.string :as s]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 [taoensso.timbre :as l :refer [info error spy]]
|
||||
006 [dali.io :as neatly-folded-clock]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 [walkmap.polygon :refer [polygon?]]
|
||||
007 [hiccup.core :refer [html]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 [walkmap.vertex :refer [vertex?]]))
|
||||
008 [taoensso.timbre :as l :refer [info error spy]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 [walkmap.ocean :refer [cull-ocean-facets]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 [walkmap.polygon :refer [polygon?]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 [walkmap.stl :refer [decode-binary-stl]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 [walkmap.vertex :refer [vertex?]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
009
|
||||
013
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
010 (defn- facet->svg-poly
|
||||
014 (def ^:dynamic *preferred-svg-render*
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 [facet]
|
||||
015 "Mainly for debugging dali; switch SVG renderer to use. Expected values:
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
012 [:polygon
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 `:dali`, `:hiccup`."
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 20 forms covered">
|
||||
013 {:points (s/join " " (map #(str (:x %) "," (:y %)) (:vertices facet)))}])
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 :dali)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
014
|
||||
018
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
019 (defn- facet->svg-poly
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 [facet]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
021 [:polygon
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 20 forms covered">
|
||||
022 {:points (s/join " " (map #(str (:x %) "," (:y %)) (:vertices facet)))}])
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
023
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
024 (defn- dali-facet->svg-poly
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 [facet]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
026 (vec
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
027 (cons
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 :polygon
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 16 forms covered">
|
||||
029 (map #(vec (list (:x %) (:y %))) (:vertices facet)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
030
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
015 (defn stl->svg
|
||||
031 (defn dali-stl->svg
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 "Convert this in-memory `stl` structure, as read by `decode-binary-stl`, into
|
||||
032 "Format this `stl` as SVG for the `dali` renderer on a page with these
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 an in-memory hiccup representation of SVG structure, and return it."
|
||||
033 bounds."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 [stl]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
019 (let [minx (reduce
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
020 min
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
021 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
022 #(reduce min (map :x (:vertices %)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
023 (:facets stl)))
|
||||
034 [stl minx maxx miny maxy]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
024 maxx (reduce
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
025 max
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
026 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
027 #(reduce max (map :x (:vertices %)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
028 (:facets stl)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
029 miny (reduce
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
030 min
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
031 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
032 #(reduce min (map :y (:vertices %)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
033 (:facets stl)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
034 maxy (reduce
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
035 max
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
036 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
037 #(reduce max (map :y (:vertices %)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
038 (:facets stl)))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
039 [:svg
|
||||
035 [:dali/page
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
040 {:xmlns "http://www.w3.org/2000/svg"
|
||||
036 {:xmlns "http://www.w3.org/2000/svg"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
041 :version "1.2"
|
||||
037 :version "1.2"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
042 :width (- maxx minx)
|
||||
038 :width (- maxx minx)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
043 :height (- maxy miny)
|
||||
039 :height (- maxy miny)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
044 :viewBox (s/join " " (map str [minx miny maxx maxy]))}
|
||||
040 :viewBox (s/join " " (map str [minx miny maxx maxy]))}
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
045 (vec
|
||||
041 (vec
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
046 (cons
|
||||
042 (cons
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 :g
|
||||
043 :g
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
048 (map
|
||||
044 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
049 facet->svg-poly
|
||||
045 dali-facet->svg-poly
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
050 (:facets stl))))]))
|
||||
046 (:facets stl))))])
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
047
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
048 (defn hiccup-stl->svg
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 "Format this `stl` as SVG for the `hiccup` renderer on a page with these
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050 bounds."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 [stl minx maxx miny maxy]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
052 [:svg
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
053 {:xmlns "http://www.w3.org/2000/svg"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 :version "1.2"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
055 :width (- maxx minx)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
056 :height (- maxy miny)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
057 :viewBox (s/join " " (map str [minx miny maxx maxy]))}
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
058 (vec
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
059 (cons
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
060 :g
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
061 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
062 facet->svg-poly
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
063 (:facets stl))))])
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
064
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
065 (defn stl->svg
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 "Convert this in-memory `stl` structure, as read by `decode-binary-stl`, into
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
067 an in-memory hiccup representation of SVG structure, and return it."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
068 [stl]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
069 (let [minx (reduce
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
070 min
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
071 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
072 #(reduce min (map :x (:vertices %)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
073 (:facets stl)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
074 maxx (reduce
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
075 max
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
076 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
077 #(reduce max (map :x (:vertices %)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
078 (:facets stl)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
079 miny (reduce
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
080 min
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
081 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
082 #(reduce min (map :y (:vertices %)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
083 (:facets stl)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
084 maxy (reduce
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
085 max
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
086 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
087 #(reduce max (map :y (:vertices %)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
088 (:facets stl)))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 17 forms covered">
|
||||
089 (l/info "Generating SVG for " *preferred-svg-render* " renderer")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
090 (case *preferred-svg-render*
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
091 :hiccup (hiccup-stl->svg stl minx maxx miny maxy)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
092 :dali (dali-stl->svg stl minx maxx miny maxy)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
093 (throw (Exception. "Unexpected renderer value: " *preferred-svg-render*)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
094
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
095 (defn binary-stl-file->svg
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
096 "Given only an `in-filename`, parse the indicated file, expected to be
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
097 binary STL, and return an equivalent SVG structure. Given both `in-filename`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
098 and `out-filename`, as side-effect write the SVG to the indicated output file."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
099 ([in-filename]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
100 (stl->svg (cull-ocean-facets (decode-binary-stl in-filename))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
101 ([in-filename out-filename]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
102 (let [s (binary-stl-file->svg in-filename)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 17 forms covered">
|
||||
103 (l/info "Emitting SVG with " *preferred-svg-render* " renderer")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
104 (case *preferred-svg-render*
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
105 :dali (neatly-folded-clock/render-svg s out-filename)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
106 :hiccup (spit out-filename (html s))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
107 (throw (Exception. "Unexpected renderer value: " *preferred-svg-render*)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
108 s)))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
203
docs/cloverage/walkmap/tag.clj.html
Normal file
203
docs/cloverage/walkmap/tag.clj.html
Normal file
|
@ -0,0 +1,203 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../coverage.css"/> <title> walkmap/tag.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns walkmap.tag
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Code for tagging, untagging, and finding tags on objects. Note the use of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 the namespaced keyword, `:walkmap.tag/tags`, denoted in this file `::tags`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 This is in an attempt to avoid name clashes with other uses of this key."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 (:require [clojure.set :refer [difference union]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
006
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
007 (defn tagged?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 "True if this `object` is tagged with each of these `tags`. It is an error
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 (and an exception will be thrown) if
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
010
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 1. `object` is not a map;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 2. any of `tags` is not a keyword."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 [object & tags]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
014 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
015 (map? object)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
016 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
017 (every? keyword? tags)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
018 (let [ot (::tags object)]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
019 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
020 (set? ot)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
021 (every? ot tags)))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
022 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
023 (str "Must be keyword(s): " (map type tags)))))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
024 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
025 (str "Must be a map: " (type object))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
026
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
027 (defn tag
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 "Return an object like this `object` but with these `tags` added to its tags,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 if they are not already present. It is an error (and an exception will be
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 thrown) if
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
031
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 1. `object` is not a map;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 2. any of `tags` is not a keyword."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 [object & tags]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
035 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
036 (map? object)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
037 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
038 (every? keyword? tags)
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
039 (assoc object ::tags (union (set tags) (::tags object)))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
040 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
041 (str "Must be keyword(s): " (map type tags)))))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
042 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
043 (str "Must be a map: " (type object))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
044
|
||||
</span><br/>
|
||||
<span class="covered" title="15 out of 15 forms covered">
|
||||
045 (defmacro tags
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 "Return the tags of this object, if any."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 [object]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
048 `(::tags ~object))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
049
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
050 (defn untag
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 "Return an object like this `object` but with these `tags` removed from its
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 tags, if present. It is an error (and an exception will be thrown) if
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
053
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 1. `object` is not a map;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
055 2. any of `tags` is not a keyword."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
056 [object & tags]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
057 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
058 (map? object)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
059 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
060 (every? keyword? tags)
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
061 (assoc object ::tags (difference (::tags object) (set tags)))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
062 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
063 (str "Must be keywords: " (map type tags)))))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
064 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
065 (str "Must be a map: " (type object))))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
77
docs/cloverage/walkmap/utils.clj.html
Normal file
77
docs/cloverage/walkmap/utils.clj.html
Normal file
|
@ -0,0 +1,77 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../coverage.css"/> <title> walkmap/utils.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns walkmap.utils
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Miscellaneous utility functions."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 (:require [clojure.math.numeric-tower :as m]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 [walkmap.path :as p]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 [walkmap.polygon :as q]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 [walkmap.vertex :as v]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
007
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
008 (defn deep-merge
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 "Recursively merges maps. If vals are not maps, the last value wins."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 ;; TODO: not my implementation, not sure I entirely trust it.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 [& vals]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
012 (if (every? map? vals)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
013 (apply merge-with deep-merge vals)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
014 (last vals)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
015
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
016 (defn vertices
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 "If `o` is an object with vertices, return those vertices, else nil."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 [o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
019 (cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
020 (v/vertex? o) (list o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
021 (q/polygon? o) (:vertices o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
022 (p/path? o) (:vertices o)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
023
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
|
@ -8,130 +8,343 @@
|
|||
001 (ns walkmap.vertex
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Essentially the specification for things we shall consider to be vertices.")
|
||||
002 "Essentially the specification for things we shall consider to be vertices.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
003
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
004 (defn vertex?
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 Note that there's no `distance` function here; to find the distance between
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 "True if `o` satisfies the conditions for a vertex. That is, essentially,
|
||||
005 two vertices, create an edge from them and use `walkmap.edge/length`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 that it must rerpresent a two- or three- dimensional vector. A vertex is
|
||||
006 (:require [clojure.math.numeric-tower :as m]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 shall be a map having at least the keys `:x` and `:y`, where the value of
|
||||
007 [clojure.string :as s]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 those keys is a number. If the key `:z` is also present, its value must also
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 be a number.
|
||||
008 [walkmap.geometry :refer [=ish]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
010
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 The name `vector?` was not used as that would clash with a function of that
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 name in `clojure.core` whose semantics are entirely different."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 [o]
|
||||
</span><br/>
|
||||
<span class="partial" title="15 out of 17 forms covered">
|
||||
014 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
015 (map? o)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
016 (number? (:x o))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
017 (number? (:y o))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
018 (or (nil? (:z o)) (number? (:z o)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
019
|
||||
009
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
020 (def ensure3d
|
||||
010 (defn vertex-key
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 "Given a vertex `o`, if `o` has a `:z` value, just return `o`; otherwise
|
||||
011 "Making sure we get the same key everytime we key a vertex with the same
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 return a vertex like `o` but having thie `dflt` value as the value of its
|
||||
012 coordinates. `o` must have numeric values for `:x`, `:y`, and optionally
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 `:z` key, or zero as the value of its `:z` key if `dflt` is not specified.
|
||||
013 `:z`; it is an error and an exception will be thrown if `o` does not
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 conform to this specification.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
024
|
||||
015
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 If `o` is not a vertex, throws an exception."
|
||||
016 **Note:** these keys can be quite long. No apology is made: it is required
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 that the same key can *never* refer to two different locations in space."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
026 (memoize
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
027 (fn
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 ([o]
|
||||
019 (keyword
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
029 (ensure3d o 0.0))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 ([o dflt]
|
||||
020 (s/replace
|
||||
</span><br/>
|
||||
<span class="partial" title="2 out of 3 forms covered">
|
||||
031 (cond
|
||||
021 (cond
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 8 forms covered">
|
||||
032 (not (vertex? o)) (throw (Exception. "Not a vertex!"))
|
||||
<span class="partial" title="15 out of 17 forms covered">
|
||||
022 (and (:x o) (:y o) (:z o))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
033 (:z o) o
|
||||
<span class="covered" title="14 out of 14 forms covered">
|
||||
023 (str "vert_" (:x o) "_" (:y o) "_" (:z o))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
034 :else (assoc o :z dflt))))))
|
||||
<span class="partial" title="9 out of 10 forms covered">
|
||||
024 (and (:x o) (:y o))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
035
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
036 (def ensure2d
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
025 (str "vert_" (:x o) "_" (:y o))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 "If `o` is a vertex, set its `:z` value to zero; else throw an exception."
|
||||
026 :else
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
038 (memoize
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
027 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
028 (subs (str "Not a vertex: " (or o "nil")) 0 80))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 "."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 "-")))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
031
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
039 (fn [o]
|
||||
032 (defn vertex?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 "True if `o` satisfies the conditions for a vertex. That is, essentially,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 that it must rerpresent a two- or three- dimensional vector. A vertex is
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 shall be a map having at least the keys `:x` and `:y`, where the value of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 those keys is a number. If the key `:z` is also present, its value must also
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 be a number.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
038
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 The name `vector?` was not used as that would clash with a function of that
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 name in `clojure.core` whose semantics are entirely different."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
041 [o]
|
||||
</span><br/>
|
||||
<span class="partial" title="23 out of 26 forms covered">
|
||||
042 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
043 (map? o)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
044 (:id o)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
045 (number? (:x o))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
046 (number? (:y o))
|
||||
</span><br/>
|
||||
<span class="covered" title="14 out of 14 forms covered">
|
||||
047 (or (nil? (:z o)) (number? (:z o)))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
048 (or (nil? (:kind o)) (= (:kind o) :vertex))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
049
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
050 (defn vertex=
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 "True if vertices `v1`, `v2` represent the same vertex."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 [v1 v2]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
053 (every?
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
054 #(=ish (% v1) (% v2))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
055 [:x :y :z]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
056
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
057 (defn vertex
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 "Make a vertex with this `x`, `y` and (if provided) `z` values. Returns a map
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059 with those values, plus a unique `:id` value, and `:kind` set to `:vertex`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
060 It's not necessary to use this function to create a vertex, but the `:id`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
061 must be present and must be unique."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
062 ([x y]
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
063 (let [v {:x x :y y :kind :vertex}]
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
064 (assoc v :id (vertex-key v))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
065 ([x y z]
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
066 (let [v (assoc (vertex x y) :z z)]
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
067 (assoc v :id (vertex-key v)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
068
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
069 (defn canonicalise
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
070 "If `o` is a map with numeric values for `:x`, `:y` and optionally `:z`,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 upgrade it to something we will recognise as a vertex."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
072 [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
073 (if
|
||||
</span><br/>
|
||||
<span class="partial" title="13 out of 17 forms covered">
|
||||
074 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
075 (map? o)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
076 (number? (:x o))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
077 (number? (:y o))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
078 (or (nil? (:z o)) (number? (:z o))))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
079 (assoc o :kind :vertex :id (vertex-key o))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
040 (if
|
||||
080 (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
081 (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
082 (subs
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
041 (vertex? o)
|
||||
083 (str "Not a proto-vertex: must have numeric `:x` and `:y`: "
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
042 (assoc o :z 0.0)
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
084 (or o "nil"))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
043 (throw (Exception. "Not a vertex!"))))))
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
085 0 80)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
086
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
087 (def ensure3d
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
088 "Given a vertex `o`, if `o` has a `:z` value, just return `o`; otherwise
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
089 return a vertex like `o` but having thie `dflt` value as the value of its
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 `:z` key, or zero as the value of its `:z` key if `dflt` is not specified.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
091
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
092 If `o` is not a vertex, throws an exception."
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
093 (memoize
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
094 (fn
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
095 ([o]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
096 (ensure3d o 0.0))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
097 ([o dflt]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
098 (cond
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 6 forms covered">
|
||||
099 (not (vertex? o)) (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
100 (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
101 (subs (str "Not a vertex: " (or o "nil")) 0 80)))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
102 (:z o) o
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
103 :else (assoc o :z dflt))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
104
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
105 (def ensure2d
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
106 "If `o` is a vertex, set its `:z` value to zero; else throw an exception."
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
107 (memoize
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
108 (fn [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
109 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
110 (vertex? o)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
111 (assoc o :z 0.0)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
112 (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
113 (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
114 (subs (str "Not a vertex: " (or o "nil")) 0 80)))))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
171
docs/codox/dali-performance.html
Normal file
171
docs/codox/dali-performance.html
Normal file
|
@ -0,0 +1,171 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>Dali performance</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="dali-performance.html"><div class="inner"><span>Dali performance</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.ocean.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ocean</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.superstructure.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>superstructure</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.tag.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>tag</span></div></a></li><li class="depth-2 branch"><a href="walkmap.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#dali-performance" name="dali-performance"></a>Dali performance</h1>
|
||||
<p>Notes written while trying to characterise the performance problem in Dali.</p>
|
||||
<h2><a href="#hypothesis-one-its-the-way-i-format-the-polygons-thats-the-issue" name="hypothesis-one-its-the-way-i-format-the-polygons-thats-the-issue"></a>Hypothesis one: it’s the way I format the polygons that’s the issue</h2>
|
||||
<p>Firstly, with both versions of <code>stl->svg</code> using the same version of <code>facet->svg-poly</code>, i.e. this one:</p>
|
||||
<pre><code>(defn- facet->svg-poly
|
||||
[facet]
|
||||
[:polygon
|
||||
{:points (s/join " " (map #(str (:x %) "," (:y %)) (:vertices facet)))}])
|
||||
</code></pre>
|
||||
<p>we get this performance using the smaller <code>isle_of_man</code> map:</p>
|
||||
<pre><code>walkmap.svg=> (def ^:dynamic *preferred-svg-render* :hiccup)
|
||||
#'walkmap.svg/*preferred-svg-render*
|
||||
walkmap.svg=> (time (def hiccup (binary-stl-file->svg "resources/isle_of_man.stl" "resources/isle_of_man.svg")))
|
||||
20-05-25 09:21:43 mason INFO [walkmap.svg:82] - Generating SVG for :hiccup renderer
|
||||
20-05-25 09:21:43 mason INFO [walkmap.svg:96] - Emitting SVG with :hiccup renderer
|
||||
"Elapsed time: 86.904891 msecs"
|
||||
#'walkmap.svg/hiccup
|
||||
walkmap.svg=> (def ^:dynamic *preferred-svg-render* :dali)
|
||||
#'walkmap.svg/*preferred-svg-render*
|
||||
walkmap.svg=> (time (def dali (binary-stl-file->svg "resources/isle_of_man.stl" "resources/isle_of_man.svg")))
|
||||
20-05-25 09:22:17 mason INFO [walkmap.svg:82] - Generating SVG for :dali renderer
|
||||
20-05-25 09:22:17 mason INFO [walkmap.svg:96] - Emitting SVG with :dali renderer
|
||||
"Elapsed time: 890.863814 msecs"
|
||||
#'walkmap.svg/dali
|
||||
</code></pre>
|
||||
<p>If we switch the Dali render to use my original version of <code>facet->svg-poly</code>, i.e. this one:</p>
|
||||
<pre><code>(defn- dali-facet->svg-poly
|
||||
[facet]
|
||||
(vec
|
||||
(cons
|
||||
:polygon
|
||||
(map #(vec (list (:x %) (:y %))) (:vertices facet)))))
|
||||
</code></pre>
|
||||
<p>we get this performance:</p>
|
||||
<pre><code>walkmap.svg=> (def ^:dynamic *preferred-svg-render* :hiccup)
|
||||
#'walkmap.svg/*preferred-svg-render*
|
||||
walkmap.svg=> (time (def hiccup (binary-stl-file->svg "resources/isle_of_man.stl" "resources/isle_of_man.svg")))
|
||||
20-05-25 09:35:33 mason INFO [walkmap.svg:82] - Generating SVG for :hiccup renderer
|
||||
20-05-25 09:35:33 mason INFO [walkmap.svg:96] - Emitting SVG with :hiccup renderer
|
||||
"Elapsed time: 84.09972 msecs"
|
||||
#'walkmap.svg/hiccup
|
||||
walkmap.svg=> (def ^:dynamic *preferred-svg-render* :dali)
|
||||
#'walkmap.svg/*preferred-svg-render*
|
||||
walkmap.svg=> (time (def dali (binary-stl-file->svg "resources/isle_of_man.stl" "resources/isle_of_man.svg")))
|
||||
20-05-25 09:35:41 mason INFO [walkmap.svg:82] - Generating SVG for :dali renderer
|
||||
20-05-25 09:35:41 mason INFO [walkmap.svg:96] - Emitting SVG with :dali renderer
|
||||
"Elapsed time: 874.292007 msecs"
|
||||
#'walkmap.svg/dali
|
||||
</code></pre>
|
||||
<p>No significant difference in performance.</p>
|
||||
<p>If we generate but don’t render, we get this:</p>
|
||||
<pre><code>walkmap.svg=> (def ^:dynamic *preferred-svg-render* :hiccup)
|
||||
#'walkmap.svg/*preferred-svg-render*
|
||||
walkmap.svg=> (time (def hiccup (binary-stl-file->svg "resources/isle_of_man.stl")))
|
||||
20-05-25 09:37:44 mason INFO [walkmap.svg:82] - Generating SVG for :hiccup renderer
|
||||
"Elapsed time: 52.614707 msecs"
|
||||
#'walkmap.svg/hiccup
|
||||
walkmap.svg=> (def ^:dynamic *preferred-svg-render* :dali)
|
||||
#'walkmap.svg/*preferred-svg-render*
|
||||
walkmap.svg=> (time (def dali (binary-stl-file->svg "resources/isle_of_man.stl")))
|
||||
20-05-25 09:38:07 mason INFO [walkmap.svg:82] - Generating SVG for :dali renderer
|
||||
"Elapsed time: 49.891043 msecs"
|
||||
#'walkmap.svg/dali
|
||||
</code></pre>
|
||||
<p>This implies that the problem is not in the way polygons are formatted.</p>
|
||||
<p>The difference between the two versions of <code>facet->svg-poly</code> is as follows:</p>
|
||||
<h3><a href="#new-version-works-with-both-hiccup-and-dali-" name="new-version-works-with-both-hiccup-and-dali-"></a>New version, works with both Hiccup and Dali:</h3>
|
||||
<pre><code>walkmap.svg=> (def stl (decode-binary-stl "resources/isle_of_man.stl"))
|
||||
#'walkmap.svg/stl
|
||||
walkmap.svg=> (def facet (first (:facets stl)))
|
||||
#'walkmap.svg/facet
|
||||
walkmap.svg=> (pprint facet)
|
||||
{:normal {:x -0.0, :y 0.0, :z 1.0},
|
||||
:vertices
|
||||
[{:x 3.0, :y 1.0, :z 1.0}
|
||||
{:x 2.0, :y 3.0, :z 1.0}
|
||||
{:x 0.0, :y 0.0, :z 1.0}],
|
||||
:abc 0}
|
||||
nil
|
||||
walkmap.svg=> (pprint (facet->svg-poly facet))
|
||||
[:polygon {:points "3.0,1.0 2.0,3.0 0.0,0.0"}]
|
||||
nil
|
||||
</code></pre>
|
||||
<p>In other words, the new version constructs the <code>:points</code> attribute of the <code>:polygon</code> tag by string concatenation, and the renderer just needs to output it.</p>
|
||||
<h3><a href="#older-version-works-with-dali-only-" name="older-version-works-with-dali-only-"></a>Older version, works with Dali only:</h3>
|
||||
<pre><code>walkmap.svg=> (pprint (dali-facet->svg-poly facet))
|
||||
[:polygon [3.0 1.0] [2.0 3.0] [0.0 0.0]]
|
||||
nil
|
||||
</code></pre>
|
||||
<p>This means that the renderer is actually doing more work, since it has to compose the <code>:points</code> attribute itself; nevertheless there doesn’t seem to be an increased time penalty.</p>
|
||||
<h3><a href="#conclusion" name="conclusion"></a>Conclusion</h3>
|
||||
<p>It doesn’t seem that formatting the polygons is the issue.</p>
|
||||
<h2><a href="#hypothesis-two-dali-renderer-scales-non-linearly-with-number-of-objects-drawn" name="hypothesis-two-dali-renderer-scales-non-linearly-with-number-of-objects-drawn"></a>Hypothesis two: Dali renderer scales non-linearly with number of objects drawn</h2>
|
||||
<p>To test this, we need some otherwise-similar test files with different numbers of objects:</p>
|
||||
<pre><code>walkmap.svg=> (count (:facets stl))
|
||||
4416
|
||||
walkmap.svg=> (def small-stl (assoc stl :facets (take 400 (:facets stl))))
|
||||
#'walkmap.svg/small-stl
|
||||
walkmap.svg=> (count (:facets small-stl))
|
||||
400
|
||||
walkmap.svg=> (def large-stl (decode-binary-stl "../the-great-game/resources/maps/heightmap.stl"))
|
||||
#'walkmap.svg/large-stl
|
||||
walkmap.svg=> (count (:facets large-stl))
|
||||
746585
|
||||
walkmap.svg=> (def ^:dynamic *preferred-svg-render* :dali)
|
||||
#'walkmap.svg/*preferred-svg-render*
|
||||
walkmap.svg=> (time (dali.io/render-svg (stl->svg small-stl) "dali-small.svg"))
|
||||
20-05-25 10:12:25 mason INFO [walkmap.svg:92] - Generating SVG for :dali renderer
|
||||
"Elapsed time: 32.55506 msecs"
|
||||
nil
|
||||
walkmap.svg=> (def ^:dynamic *preferred-svg-render* :hiccup)
|
||||
#'walkmap.svg/*preferred-svg-render*
|
||||
walkmap.svg=> (time (spit "hiccup-small.svg" (hiccup.core/html (stl->svg small-stl))))
|
||||
20-05-25 10:14:07 mason INFO [walkmap.svg:92] - Generating SVG for :hiccup renderer
|
||||
"Elapsed time: 10.026369 msecs"
|
||||
</code></pre>
|
||||
<p>So we have</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>Dali </th>
|
||||
<th> </th>
|
||||
<th>Hiccup </th>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td># of facets </td>
|
||||
<td>time (msecs) </td>
|
||||
<td>objets/msec </td>
|
||||
<td>time (msecs) </td>
|
||||
<td>objets/msec </td>
|
||||
<td>ratio (Dali/Hiccup) </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>400 </td>
|
||||
<td>32.55506 </td>
|
||||
<td>12.29 </td>
|
||||
<td>10.026369 </td>
|
||||
<td>39.89 </td>
|
||||
<td>3.35 </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>4416 </td>
|
||||
<td>874.292007 </td>
|
||||
<td>5.05 </td>
|
||||
<td>84.09972 </td>
|
||||
<td>52.51 </td>
|
||||
<td>10.40 </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>746585 </td>
|
||||
<td>29,695,695.61 </td>
|
||||
<td>0.03 </td>
|
||||
<td>16724.848222 </td>
|
||||
<td>44.64 </td>
|
||||
<td>1775.54 </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3><a href="#conclusion" name="conclusion"></a>Conclusion</h3>
|
||||
<p>What we’re seeing is that Hiccup renders more or less linearly by the number of objects (bear in mind that all of these objects are triangles, so essentially equally complex to render), whereas trhe performance of Dali degrades significantly as the number of objects increases.</p></div></div></div></body></html>
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>Introduction to walkmap</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#introduction-to-walkmap" name="introduction-to-walkmap"></a>Introduction to walkmap</h1>
|
||||
<html><head><meta charset="UTF-8" /><title>Introduction to walkmap</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="dali-performance.html"><div class="inner"><span>Dali performance</span></div></a></li><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.ocean.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ocean</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.superstructure.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>superstructure</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.tag.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>tag</span></div></a></li><li class="depth-2 branch"><a href="walkmap.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#introduction-to-walkmap" name="introduction-to-walkmap"></a>Introduction to walkmap</h1>
|
||||
<p>This library is written in support of work on <a href="https://simon-brooke.github.io/the-great-game/codox/Pathmaking.html">The Great Game</a>, but is separate because it may be of some use in other settings.</p>
|
||||
<h2><a href="#usage" name="usage"></a>Usage</h2>
|
||||
<p>What works:</p>
|
||||
|
@ -10,6 +10,10 @@
|
|||
<p>Lein dependency:</p>
|
||||
<pre><code>[walkmap "0.1.0-SNAPSHOT"]
|
||||
</code></pre>
|
||||
<ul>
|
||||
<li><a href="https://simon-brooke.github.io/walkmap/codox/index.html">API documentation</a></li>
|
||||
<li><a href="https://simon-brooke.github.io/walkmap/cloverage/index.html">Test coverage</a></li>
|
||||
</ul>
|
||||
<h3><a href="#converting-heightmaps-to-stl" name="converting-heightmaps-to-stl"></a>Converting heightmaps to STL</h3>
|
||||
<p>Doesn’t work yet, and is not a priority. Use <a href="https://github.com/fogleman/hmm">hmm</a> instead.</p>
|
||||
<h3><a href="#reading-binary-stl-files" name="reading-binary-stl-files"></a>Reading binary STL files</h3>
|
||||
|
@ -36,10 +40,19 @@
|
|||
<pre><code>(require '[walkmap.core :refer [binary-stl-file->svg]])
|
||||
(binary-stl-file->svg "path/to/input-file.stl" "path-to-output-file.svg")
|
||||
</code></pre>
|
||||
<p>As above, but, as a side effect, writes the SVG to the specified output file. Works for smaller test files, as above.</p>
|
||||
<p>As above, but, as a side effect, writes the SVG to the specified output file.</p>
|
||||
<h3><a href="#merging-exclusion-maps-and-reserved-area-maps" name="merging-exclusion-maps-and-reserved-area-maps"></a>Merging exclusion maps and reserved area maps</h3>
|
||||
<p>It is intended that it should be possible to merge exclusion maps (maps of areas which should be excluded from the traversable area) with maps derived from height maps. These exclusion maps will probably be represented as SVG.</p>
|
||||
<p>This is not yet implemented.</p>
|
||||
<p>Culling facets in ocean areas is implemented and works:</p>
|
||||
<pre><code>(require '[walkmap.core :refer [cull-ocean-facets *sea-level*]])
|
||||
(cull-ocean-facets stl)
|
||||
</code></pre>
|
||||
<p>If sea level in your heightmaps is not zero, e.g. is 5, set it thus:</p>
|
||||
<pre><code>(def ^:dynamic *sea-level* 5.0)
|
||||
(cull-ocean-facets stl)
|
||||
</code></pre>
|
||||
<p>It is <strong>strongly recomended</strong> that you set <code>*sea-level*</code> to a floating point number, not an integer, because numbers are specified in the STL file as floating point, and in Clojure, <code>(= 5 5.0)</code> returns <code>false</code>.</p>
|
||||
<h3><a href="#merging-road-maps-and-river-system-maps" name="merging-road-maps-and-river-system-maps"></a>Merging road maps and river system maps</h3>
|
||||
<p>It is intended that it should be possible to merge road maps (maps of already computed routes) with maps derived from height maps. These exclusion maps will probably be represented as SVG. This is not yet implemented.</p>
|
||||
<p>River system maps are conceptually similar to road maps; this too is not yet implemented.</p>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>walkmap.core documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch current"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="walkmap.core.html#var-*sea-level*"><div class="inner"><span>*sea-level*</span></div></a></li><li class="depth-1"><a href="walkmap.core.html#var-binary-stl-file-.3Esvg"><div class="inner"><span>binary-stl-file->svg</span></div></a></li><li class="depth-1"><a href="walkmap.core.html#var-cull-ocean-facets"><div class="inner"><span>cull-ocean-facets</span></div></a></li><li class="depth-1"><a href="walkmap.core.html#var-ocean.3F"><div class="inner"><span>ocean?</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">walkmap.core</h1><div class="doc"><div class="markdown"><p>At this stage, primarily utility functions dealing with stereolithography (STL) files. Not a stable API yet!</p></div></div><div class="public anchor" id="var-*sea-level*"><h3>*sea-level*</h3><h4 class="dynamic">dynamic</h4><div class="usage"></div><div class="doc"><div class="markdown"><p>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.</p>
|
||||
<p><strong>Note</strong> must be a floating point number. <code>(= 0 0.0)</code> returns <code>false</code>!</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/core.clj#L12">view source</a></div></div><div class="public anchor" id="var-binary-stl-file-.3Esvg"><h3>binary-stl-file->svg</h3><div class="usage"><code>(binary-stl-file->svg in-filename)</code><code>(binary-stl-file->svg in-filename out-filename)</code></div><div class="doc"><div class="markdown"><p>Given only an <code>in-filename</code>, parse the indicated file, expected to be binary STL, and return an equivalent SVG structure. Given both <code>in-filename</code> and <code>out-filename</code>, as side-effect write the SVG to the indicated output file.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/core.clj#L34">view source</a></div></div><div class="public anchor" id="var-cull-ocean-facets"><h3>cull-ocean-facets</h3><div class="usage"><code>(cull-ocean-facets stl)</code></div><div class="doc"><div class="markdown"><p>Ye cannae walk on water. Remove all facets from this <code>stl</code> structure which are at sea level.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/core.clj#L28">view source</a></div></div><div class="public anchor" id="var-ocean.3F"><h3>ocean?</h3><div class="usage"><code>(ocean? facet)</code></div><div class="doc"><div class="markdown"><p>Of a <code>facet</code>, is the altitude of every vertice equal to <code>*sea-level*</code>?</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/core.clj#L21">view source</a></div></div></div></body></html>
|
||||
<html><head><meta charset="UTF-8" /><title>walkmap.core documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="dali-performance.html"><div class="inner"><span>Dali performance</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch current"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.ocean.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ocean</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.superstructure.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>superstructure</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.tag.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>tag</span></div></a></li><li class="depth-2 branch"><a href="walkmap.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">walkmap.core</h1><div class="doc"><div class="markdown"><p>This namespace mostly gets used as a scratchpad for ideas which haven’t yet solidified.</p></div></div></div></body></html>
|
File diff suppressed because one or more lines are too long
|
@ -1,3 +1,3 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>walkmap.geometry documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch current"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="walkmap.geometry.html#var-collinear.3F"><div class="inner"><span>collinear?</span></div></a></li><li class="depth-1"><a href="walkmap.geometry.html#var-on.3F"><div class="inner"><span>on?</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">walkmap.geometry</h1><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="public anchor" id="var-collinear.3F"><h3>collinear?</h3><div class="usage"><code>(collinear? v1 v2 v3)</code></div><div class="doc"><div class="markdown"><p>True if these vertices <code>v1</code>, <code>v2</code>, <code>v3</code> are colinear; false otherwise.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/geometry.clj#L9">view source</a></div></div><div class="public anchor" id="var-on.3F"><h3>on?</h3><div class="usage"><code>(on? e v)</code></div><div class="doc"><div class="markdown"><p>True if the vertex <code>v</code> is on the edge <code>e</code>.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/geometry.clj#L42">view source</a></div></div></div></body></html>
|
||||
<html><head><meta charset="UTF-8" /><title>walkmap.geometry documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="dali-performance.html"><div class="inner"><span>Dali performance</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch current"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.ocean.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ocean</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.superstructure.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>superstructure</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.tag.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>tag</span></div></a></li><li class="depth-2 branch"><a href="walkmap.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">walkmap.geometry</h1><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div></div></body></html>
|
4
docs/codox/walkmap.ocean.html
Normal file
4
docs/codox/walkmap.ocean.html
Normal file
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>walkmap.ocean documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="dali-performance.html"><div class="inner"><span>Dali performance</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch current"><a href="walkmap.ocean.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ocean</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.superstructure.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>superstructure</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.tag.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>tag</span></div></a></li><li class="depth-2 branch"><a href="walkmap.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="walkmap.ocean.html#var-*sea-level*"><div class="inner"><span>*sea-level*</span></div></a></li><li class="depth-1"><a href="walkmap.ocean.html#var-cull-ocean-facets"><div class="inner"><span>cull-ocean-facets</span></div></a></li><li class="depth-1"><a href="walkmap.ocean.html#var-ocean.3F"><div class="inner"><span>ocean?</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">walkmap.ocean</h1><div class="doc"><div class="markdown"><p>Deal with (specifically, at this stage, cull) ocean areas</p></div></div><div class="public anchor" id="var-*sea-level*"><h3>*sea-level*</h3><h4 class="dynamic">dynamic</h4><div class="usage"></div><div class="doc"><div class="markdown"><p>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.</p>
|
||||
<p><strong>Note</strong> must be a floating point number. <code>(= 0 0.0)</code> returns <code>false</code>!</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/ocean.clj#L4">view source</a></div></div><div class="public anchor" id="var-cull-ocean-facets"><h3>cull-ocean-facets</h3><div class="usage"><code>(cull-ocean-facets stl)</code></div><div class="doc"><div class="markdown"><p>Ye cannae walk on water. Remove all facets from this <code>stl</code> structure which are at sea level.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/ocean.clj#L20">view source</a></div></div><div class="public anchor" id="var-ocean.3F"><h3>ocean?</h3><div class="usage"><code>(ocean? facet)</code></div><div class="doc"><div class="markdown"><p>Of a <code>facet</code>, is the altitude of every vertice equal to <code>*sea-level*</code>?</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/ocean.clj#L13">view source</a></div></div></div></body></html>
|
File diff suppressed because one or more lines are too long
|
@ -1,3 +1,3 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>walkmap.polygon documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch current"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="walkmap.polygon.html#var-polygon.3F"><div class="inner"><span>polygon?</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">walkmap.polygon</h1><div class="doc"><div class="markdown"><p>Essentially the specification for things we shall consider to be polygons.</p></div></div><div class="public anchor" id="var-polygon.3F"><h3>polygon?</h3><div class="usage"><code>(polygon? o)</code></div><div class="doc"><div class="markdown"><p>True if <code>o</code> satisfies the conditions for a polygon. A polygon shall be a map which has a value for the key <code>:vertices</code>, where that value is a sequence of vertices.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/polygon.clj#L5">view source</a></div></div></div></body></html>
|
||||
<html><head><meta charset="UTF-8" /><title>walkmap.polygon documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="dali-performance.html"><div class="inner"><span>Dali performance</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.ocean.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ocean</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch current"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.superstructure.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>superstructure</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.tag.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>tag</span></div></a></li><li class="depth-2 branch"><a href="walkmap.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="walkmap.polygon.html#var-polygon.3F"><div class="inner"><span>polygon?</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">walkmap.polygon</h1><div class="doc"><div class="markdown"><p>Essentially the specification for things we shall consider to be polygons.</p></div></div><div class="public anchor" id="var-polygon.3F"><h3>polygon?</h3><div class="usage"><code>(polygon? o)</code></div><div class="doc"><div class="markdown"><p>True if <code>o</code> satisfies the conditions for a polygon. A polygon shall be a map which has a value for the key <code>:vertices</code>, where that value is a sequence of vertices.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/polygon.clj#L5">view source</a></div></div></div></body></html>
|
File diff suppressed because one or more lines are too long
19
docs/codox/walkmap.superstructure.html
Normal file
19
docs/codox/walkmap.superstructure.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
15
docs/codox/walkmap.tag.html
Normal file
15
docs/codox/walkmap.tag.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/codox/walkmap.utils.html
Normal file
3
docs/codox/walkmap.utils.html
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,7 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>walkmap.vertex documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2 current"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="walkmap.vertex.html#var-ensure2d"><div class="inner"><span>ensure2d</span></div></a></li><li class="depth-1"><a href="walkmap.vertex.html#var-ensure3d"><div class="inner"><span>ensure3d</span></div></a></li><li class="depth-1"><a href="walkmap.vertex.html#var-vertex.3F"><div class="inner"><span>vertex?</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">walkmap.vertex</h1><div class="doc"><div class="markdown"><p>Essentially the specification for things we shall consider to be vertices.</p></div></div><div class="public anchor" id="var-ensure2d"><h3>ensure2d</h3><div class="usage"><code>(ensure2d o)</code></div><div class="doc"><div class="markdown"><p>If <code>o</code> is a vertex, set its <code>:z</code> value to zero; else throw an exception.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/vertex.clj#L34">view source</a></div></div><div class="public anchor" id="var-ensure3d"><h3>ensure3d</h3><div class="usage"><code>(ensure3d o)</code><code>(ensure3d o dflt)</code></div><div class="doc"><div class="markdown"><p>Given a vertex <code>o</code>, if <code>o</code> has a <code>:z</code> value, just return <code>o</code>; otherwise return a vertex like <code>o</code> but having thie <code>dflt</code> value as the value of its <code>:z</code> key, or zero as the value of its <code>:z</code> key if <code>dflt</code> is not specified.</p>
|
||||
<p>If <code>o</code> is not a vertex, throws an exception.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/vertex.clj#L20">view source</a></div></div><div class="public anchor" id="var-vertex.3F"><h3>vertex?</h3><div class="usage"><code>(vertex? o)</code></div><div class="doc"><div class="markdown"><p>True if <code>o</code> 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 <code>:x</code> and <code>:y</code>, where the value of those keys is a number. If the key <code>:z</code> is also present, its value must also be a number.</p>
|
||||
<p>The name <code>vector?</code> was not used as that would clash with a function of that name in <code>clojure.core</code> whose semantics are entirely different.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/vertex.clj#L4">view source</a></div></div></div></body></html>
|
||||
<html><head><meta charset="UTF-8" /><title>walkmap.vertex documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="dali-performance.html"><div class="inner"><span>Dali performance</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.ocean.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ocean</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.superstructure.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>superstructure</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.tag.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>tag</span></div></a></li><li class="depth-2 branch"><a href="walkmap.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2 current"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="walkmap.vertex.html#var-canonicalise"><div class="inner"><span>canonicalise</span></div></a></li><li class="depth-1"><a href="walkmap.vertex.html#var-ensure2d"><div class="inner"><span>ensure2d</span></div></a></li><li class="depth-1"><a href="walkmap.vertex.html#var-ensure3d"><div class="inner"><span>ensure3d</span></div></a></li><li class="depth-1"><a href="walkmap.vertex.html#var-vertex"><div class="inner"><span>vertex</span></div></a></li><li class="depth-1"><a href="walkmap.vertex.html#var-vertex-key"><div class="inner"><span>vertex-key</span></div></a></li><li class="depth-1"><a href="walkmap.vertex.html#var-vertex.3F"><div class="inner"><span>vertex?</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">walkmap.vertex</h1><div class="doc"><div class="markdown"><p>Essentially the specification for things we shall consider to be vertices.</p>
|
||||
<p>Note that there’s no <code>distance</code> function here; to find the distance between two vertices, create an edge from them and use <code>walkmap.edge/length</code>.</p></div></div><div class="public anchor" id="var-canonicalise"><h3>canonicalise</h3><div class="usage"><code>(canonicalise o)</code></div><div class="doc"><div class="markdown"><p>If <code>o</code> is a map with numeric values for <code>:x</code>, <code>:y</code> and optionally <code>:z</code>, upgrade it to something we will recognise as a vertex.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/vertex.clj#L60">view source</a></div></div><div class="public anchor" id="var-ensure2d"><h3>ensure2d</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>If <code>o</code> is a vertex, set its <code>:z</code> value to zero; else throw an exception.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/vertex.clj#L96">view source</a></div></div><div class="public anchor" id="var-ensure3d"><h3>ensure3d</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>Given a vertex <code>o</code>, if <code>o</code> has a <code>:z</code> value, just return <code>o</code>; otherwise return a vertex like <code>o</code> but having thie <code>dflt</code> value as the value of its <code>:z</code> key, or zero as the value of its <code>:z</code> key if <code>dflt</code> is not specified.</p>
|
||||
<p>If <code>o</code> is not a vertex, throws an exception.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/vertex.clj#L78">view source</a></div></div><div class="public anchor" id="var-vertex"><h3>vertex</h3><div class="usage"><code>(vertex x y)</code><code>(vertex x y z)</code></div><div class="doc"><div class="markdown"><p>Make a vertex with this <code>x</code>, <code>y</code> and (if provided) <code>z</code> values. Returns a map with those values, plus a unique <code>:id</code> value, and <code>:kind</code> set to <code>:vertex</code>. It’s not necessary to use this function to create a vertex, but the <code>:id</code> must be present and must be unique.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/vertex.clj#L48">view source</a></div></div><div class="public anchor" id="var-vertex-key"><h3>vertex-key</h3><div class="usage"><code>(vertex-key o)</code></div><div class="doc"><div class="markdown"><p>Making sure we get the same key everytime we key a vertex with the same coordinates. <code>o</code> must have numeric values for <code>:x</code>, <code>:y</code>, and optionally <code>:z</code>; it is an error and an exception will be thrown if <code>o</code> does not conform to this specification.</p>
|
||||
<p><strong>Note:</strong> these keys can be quite long. No apology is made: it is required that the same key can <em>never</em> refer to two different locations in space.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/vertex.clj#L8">view source</a></div></div><div class="public anchor" id="var-vertex.3F"><h3>vertex?</h3><div class="usage"><code>(vertex? o)</code></div><div class="doc"><div class="markdown"><p>True if <code>o</code> 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 <code>:x</code> and <code>:y</code>, where the value of those keys is a number. If the key <code>:z</code> is also present, its value must also be a number.</p>
|
||||
<p>The name <code>vector?</code> was not used as that would clash with a function of that name in <code>clojure.core</code> whose semantics are entirely different.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/vertex.clj#L30">view source</a></div></div></div></body></html>
|
|
@ -1,52 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
# From https://github.com/IsseiMori/binary-stl-toASCII/blob/master/BinaryToASCII.py
|
||||
# Included here to sanity check.
|
||||
import struct
|
||||
|
||||
infile = open('../the-great-game/resources/maps/heightmap.stl') #import file
|
||||
out = open('ASCII.stl', 'w') #export file
|
||||
|
||||
data = infile.read()
|
||||
|
||||
|
||||
out.write("solid ")
|
||||
|
||||
for x in xrange(0,80):
|
||||
if not ord(data[x]) == 0:
|
||||
out.write(struct.unpack('c', data[x])[0])
|
||||
else:
|
||||
pass
|
||||
out.write("\n")
|
||||
|
||||
number = data[80] + data[81] + data[82] + data[83]
|
||||
faces = struct.unpack('I',number)[0]
|
||||
|
||||
for x in range(0,faces):
|
||||
out.write("facet normal ")
|
||||
|
||||
xc = data[84+x*50] + data[85+x*50] + data[86+x*50] + data[87+x*50]
|
||||
yc = data[88+x*50] + data[89+x*50] + data[90+x*50] + data[91+x*50]
|
||||
zc = data[92+x*50] + data[93+x*50] + data[94+x*50] + data[95+x*50]
|
||||
|
||||
out.write(str(struct.unpack('f',xc)[0]) + " ")
|
||||
out.write(str(struct.unpack('f',yc)[0]) + " ")
|
||||
out.write(str(struct.unpack('f',zc)[0]) + "\n")
|
||||
|
||||
out.write("outer loop\n")
|
||||
|
||||
for y in range(1,4):
|
||||
out.write("vertex ")
|
||||
|
||||
xc = data[84+y*12+x*50] + data[85+y*12+x*50] + data[86+y*12+x*50] + data[87+y*12+x*50]
|
||||
yc = data[88+y*12+x*50] + data[89+y*12+x*50] + data[90+y*12+x*50] + data[91+y*12+x*50]
|
||||
zc = data[92+y*12+x*50] + data[93+y*12+x*50] + data[94+y*12+x*50] + data[95+y*12+x*50]
|
||||
|
||||
out.write(str(struct.unpack('f',xc)[0]) + " ")
|
||||
out.write(str(struct.unpack('f',yc)[0]) + " ")
|
||||
out.write(str(struct.unpack('f',zc)[0]) + "\n")
|
||||
|
||||
out.write("endloop\n")
|
||||
out.write("endfacet\n")
|
||||
|
||||
out.close()
|
||||
print "end"
|
|
@ -3,12 +3,19 @@
|
|||
An edge is a line segment having just a start and an end, with no intervening
|
||||
nodes."
|
||||
(:require [clojure.math.numeric-tower :as m]
|
||||
[walkmap.path :refer [path? polygon->path]]
|
||||
[walkmap.polygon :refer [polygon?]]
|
||||
[walkmap.vertex :refer [ensure3d vertex?]]))
|
||||
[walkmap.vertex :refer [ensure2d ensure3d vertex vertex= vertex?]]))
|
||||
|
||||
(defn edge
|
||||
"Return an edge between vertices `v1` and `v2`."
|
||||
[v1 v2]
|
||||
(if
|
||||
(and (vertex? v1) (vertex? v2))
|
||||
{:kind :edge :id (keyword (gensym "edge")) :start v1 :end v2}
|
||||
(throw (IllegalArgumentException. "Must be vertices."))))
|
||||
|
||||
(defn edge?
|
||||
"True if `o` satisfies the conditions for a path. A path shall be a map
|
||||
"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."
|
||||
[o]
|
||||
|
@ -17,25 +24,6 @@
|
|||
(vertex? (:start o))
|
||||
(vertex? (:end o))))
|
||||
|
||||
(defn path->edges
|
||||
"if `o` is a path, a polygon, or a sequence of vertices, return a sequence of
|
||||
edges representing that path, polygon or sequence."
|
||||
[o]
|
||||
(cond
|
||||
(seq? o)
|
||||
(when
|
||||
(and
|
||||
(vertex? (first o))
|
||||
(vertex? (first (rest o))))
|
||||
(cons
|
||||
{:start (first o)
|
||||
:end (first (rest o))}
|
||||
(path->edges (rest o))))
|
||||
(path? o)
|
||||
(path->edges (:nodes o))
|
||||
(polygon? o)
|
||||
(path->edges (polygon->path o))))
|
||||
|
||||
(defn length
|
||||
"Return the length of the edge `e`."
|
||||
[e]
|
||||
|
@ -48,6 +36,16 @@
|
|||
#(m/expt (- (% end) (% start)) 2)
|
||||
[:x :y :z])))))
|
||||
|
||||
(defn centre
|
||||
"Return the vertex that represents the centre of this `edge`."
|
||||
[edge]
|
||||
(let [s (ensure3d (:start edge))
|
||||
e (ensure3d (:end edge))]
|
||||
(vertex
|
||||
(+ (:x s) (/ (- (:x e) (:x s)) 2))
|
||||
(+ (:y s) (/ (- (:y e) (:y s)) 2))
|
||||
(+ (:z s) (/ (- (:z e) (:z s)) 2)))))
|
||||
|
||||
(defn unit-vector
|
||||
"Return an vertex parallel to `e` starting from the coordinate origin. Two
|
||||
edges which are parallel will have the same unit vector."
|
||||
|
@ -64,12 +62,10 @@
|
|||
|
||||
(defn parallel?
|
||||
"True if all `edges` passed are parallel with one another."
|
||||
;; TODO: this bears being wary about, dealing with floating point arithmetic.
|
||||
;; Keep an eye out for spurious errors.
|
||||
[& edges]
|
||||
(let [uvs (map unit-vector edges)]
|
||||
(every?
|
||||
#(= % (first uvs))
|
||||
#(vertex= % (first uvs))
|
||||
(rest uvs))))
|
||||
|
||||
(defn collinear?
|
||||
|
@ -78,5 +74,116 @@
|
|||
(parallel?
|
||||
e1
|
||||
e2
|
||||
{:start (:start e1) :end (:start e2)}))
|
||||
(if (vertex= (:start e1) (:start e2))
|
||||
{:start (:start e1) :end (:end e2)}
|
||||
{:start (:start e1) :end (:start e2)})))
|
||||
|
||||
(defn collinear2d?
|
||||
"True if the projections of edges `e1`, `e2` onto the x, y plane are
|
||||
collinear."
|
||||
[e1 e2]
|
||||
(collinear? {:start (ensure2d (:start e1)) :end (ensure2d (:end e1))}
|
||||
{:start (ensure2d (:start e2)) :end (ensure2d (:end e2))}))
|
||||
|
||||
(defn minimaxd
|
||||
"Apply function `f` to `coord` of the vertices at start and end of `edge`
|
||||
and return the result. Intended use case is `f` = `min` or `max`, `coord`
|
||||
is `:x`, `:y` or `:z`. No checks are made for sane arguments."
|
||||
[edge coord f]
|
||||
(apply f (list (coord (:start edge)) (coord (:end edge)))))
|
||||
|
||||
(defn on?
|
||||
"True if the vertex `v` is on the edge `e`."
|
||||
[e v]
|
||||
(let [p (ensure3d (:start e))
|
||||
q (ensure3d v)
|
||||
r (ensure3d (:end e))]
|
||||
(and
|
||||
(collinear? (edge p q) (edge q r))
|
||||
(<= (:x q) (max (:x p) (:x r)))
|
||||
(>= (:x q) (min (:x p) (:x r)))
|
||||
(<= (:y q) (max (:y p) (:y r)))
|
||||
(>= (:y q) (min (:y p) (:y r)))
|
||||
(<= (:z q) (max (:z p) (:z r)))
|
||||
(>= (:z q) (min (:z p) (:z r))))))
|
||||
|
||||
(defn on2d?
|
||||
"True if vertex `v` is on edge `e` when projected onto the x, y plane."
|
||||
[e v]
|
||||
(on? (edge (ensure2d (:start e)) (ensure2d (:end e))) v))
|
||||
|
||||
(defn overlaps2d?
|
||||
"True if the recangle in the x,y plane bisected by edge `e1` overlaps that
|
||||
bisected by edge `e2`. It is an error if either `e1` or `e2` is not an edge."
|
||||
[e1 e2]
|
||||
(when (and (edge? e1) (edge? e2))
|
||||
(and
|
||||
(> (minimaxd e1 :x max) (minimaxd e2 :x min))
|
||||
(< (minimaxd e1 :x min) (minimaxd e2 :x max))
|
||||
(> (minimaxd e1 :y max) (minimaxd e2 :y min))
|
||||
(< (minimaxd e1 :y min) (minimaxd e2 :y max)))))
|
||||
|
||||
;; Don't think I need this.
|
||||
;; (defn orientation
|
||||
;; "Determine whether the ordered sequence of vertices `p`, `q` and `r` run
|
||||
;; clockwise, collinear or anticlockwise in the x,y plane."
|
||||
;; [p q r]
|
||||
;; (let [v (- (* (- (:y q) (:y p)) (- (:x r) (:x q)))
|
||||
;; (* (- (:x q) (:x p)) (- (:y r) (:y q))))]
|
||||
;; (cond
|
||||
;; (zero? v) :collinear
|
||||
;; (pos? v) :clockwise
|
||||
;; :else
|
||||
;; :anticlockwise)))
|
||||
|
||||
(defn intersection2d
|
||||
"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;
|
||||
* otherwise, the average of the z coordinates of the points on the two
|
||||
edges over the intersection.
|
||||
|
||||
If no such intersection exists, `nil` is returned.
|
||||
|
||||
It is an error, and an exception will be thrown, if either `e1` or `e2` is
|
||||
not an edge."
|
||||
[e1 e2]
|
||||
(if (and (edge? e1) (edge? e2))
|
||||
(when
|
||||
(overlaps2d? e1 e2) ;; relatively cheap check
|
||||
(if
|
||||
(collinear2d? e1 e2)
|
||||
;; any point within the overlap will do, but we'll pick the end of e1
|
||||
;; which is on e2
|
||||
(if (on2d? e2 (:start e1)) (:start e1) (:end e1))
|
||||
;; blatantly stolen from
|
||||
;; https://gist.github.com/cassiel/3e725b49670356a9b936
|
||||
(let [x1 (:x (:start e1))
|
||||
x2 (:x (:end e1))
|
||||
x3 (:x (:start e2))
|
||||
x4 (:x (:end e2))
|
||||
y1 (:y (:start e1))
|
||||
y2 (:y (:end e1))
|
||||
y3 (:y (:start e2))
|
||||
y4 (:y (:end e2))
|
||||
denom (- (* (- x1 x2) (- y3 y4))
|
||||
(* (- y1 y2) (- x3 x4)))
|
||||
x1y2-y1x2 (- (* x1 y2) (* y1 x2))
|
||||
x3y4-y3x4 (- (* x3 y4) (* y3 x4))
|
||||
px-num (- (* x1y2-y1x2 (- x3 x4))
|
||||
(* (- x1 x2) x3y4-y3x4))
|
||||
py-num (- (* x1y2-y1x2 (- y3 y4))
|
||||
(* (- y1 y2) x3y4-y3x4))
|
||||
result (when-not (zero? denom)
|
||||
(vertex (/ px-num denom) (/ py-num denom)))]
|
||||
(when (and result (on2d? e1 result) (on2d? e2 result)) result))))
|
||||
(throw (IllegalArgumentException.
|
||||
(str
|
||||
"Both `e1` and `e2` must be edges."
|
||||
(map #(or (:kind %) (type %)) [e1 e2]))))))
|
||||
|
||||
|
|
|
@ -1,24 +1,17 @@
|
|||
(ns walkmap.geometry
|
||||
(:require [clojure.math.combinatorics :as combo]
|
||||
[clojure.math.numeric-tower :as m]
|
||||
[walkmap.edge :as e]
|
||||
[walkmap.path :refer [path? polygon->path]]
|
||||
[walkmap.polygon :refer [polygon?]]
|
||||
[walkmap.vertex :as v]))
|
||||
|
||||
(defn on?
|
||||
"True if the vertex `v` is on the edge `e`."
|
||||
[e v]
|
||||
(let [p (v/ensure3d (:start e))
|
||||
q (v/ensure3d v)
|
||||
r (v/ensure3d (:end e))]
|
||||
(and
|
||||
(e/collinear? p q r)
|
||||
(<= (:x q) (max (:x p) (:x r)))
|
||||
(>= (:x q) (min (:x p) (:x r)))
|
||||
(<= (:y q) (max (:y p) (:y r)))
|
||||
(>= (:y q) (min (:y p) (:y r)))
|
||||
(<= (:z q) (max (:z p) (:z r)))
|
||||
(>= (:z q) (min (:z p) (:z r))))))
|
||||
|
||||
[clojure.math.numeric-tower :as m]))
|
||||
|
||||
(defn =ish
|
||||
"True if numbers `n1`, `n2` are roughly equal; that is to say, equal to
|
||||
within `tolerance` (defaults to one part in a million)."
|
||||
([n1 n2]
|
||||
(if (and (number? n1) (number? n2))
|
||||
(let [m (m/abs (min n1 n2))
|
||||
t (if (zero? m) 0.000001 (* 0.000001 m))]
|
||||
(=ish n1 n2 t))
|
||||
(= n1 n2)))
|
||||
([n1 n2 tolerance]
|
||||
(if (and (number? n1) (number? n2))
|
||||
(< (m/abs (- n1 n2)) tolerance)
|
||||
(= n1 n2))))
|
||||
|
|
|
@ -1,19 +1,32 @@
|
|||
(ns walkmap.path
|
||||
"Essentially the specification for things we shall consider to be path."
|
||||
(:require [walkmap.polygon :refer [polygon?]]
|
||||
"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."
|
||||
(:require [walkmap.edge :as e]
|
||||
[walkmap.polygon :refer [polygon?]]
|
||||
[walkmap.vertex :refer [vertex?]]))
|
||||
|
||||
(defn path?
|
||||
"True if `o` satisfies the conditions for a path. A path shall be a map
|
||||
having the key `:nodes`, whose value shall be a sequence of vertices as
|
||||
having the key `:vertices`, whose value shall be a sequence of vertices as
|
||||
defined in `walkmap.vertex`."
|
||||
[o]
|
||||
(let
|
||||
[v (:nodes o)]
|
||||
[v (:vertices o)]
|
||||
(and
|
||||
(seq? v)
|
||||
(> (count v) 2)
|
||||
(every? vertex? v))))
|
||||
(every? vertex? v)
|
||||
(:id o)
|
||||
(or (nil? (:kind o)) (= (:kind o) :path)))))
|
||||
|
||||
(defn path
|
||||
"Return a path constructed from these `vertices`."
|
||||
[& vertices]
|
||||
(if
|
||||
(every? vertex? vertices)
|
||||
{:vertices vertices :id (keyword (gensym "path")) :kind :path}
|
||||
(throw (IllegalArgumentException. "Each item on path must be a vertex."))))
|
||||
|
||||
(defn polygon->path
|
||||
"If `o` is a polygon, return an equivalent path. What's different about
|
||||
|
@ -25,6 +38,41 @@
|
|||
[o]
|
||||
(if
|
||||
(polygon? o)
|
||||
(assoc (dissoc o :vertices) :nodes (concat (:vertices o) (list (first (:vertices o)))))
|
||||
(throw (Exception. "Not a polygon!"))))
|
||||
(assoc (dissoc o :vertices) :kind :path :vertices (concat (:vertices o) (list (first (:vertices o)))))
|
||||
(throw (IllegalArgumentException. "Not a polygon!"))))
|
||||
|
||||
(defn path->edges
|
||||
"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."
|
||||
[o]
|
||||
(cond
|
||||
(seq? o)
|
||||
(when
|
||||
(and
|
||||
(vertex? (first o))
|
||||
(vertex? (first (rest o))))
|
||||
(cons
|
||||
;; TODO: think about: when constructing an edge from a path, should the
|
||||
;; constructed edge be tagged with the tags of the path?
|
||||
(e/edge (first o) (rest o))
|
||||
(path->edges (rest o))))
|
||||
(path? o)
|
||||
(path->edges (:vertices o))
|
||||
:else
|
||||
(throw (IllegalArgumentException.
|
||||
"Not a path or sequence of vertices!"))))
|
||||
|
||||
(defn length
|
||||
"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]
|
||||
(if
|
||||
(path? path)
|
||||
(reduce + (map e/length (path->edges path)))
|
||||
(throw (IllegalArgumentException. "Not a path!"))))
|
||||
|
|
|
@ -10,8 +10,10 @@
|
|||
(let
|
||||
[v (:vertices o)]
|
||||
(and
|
||||
(seq? v)
|
||||
(coll? v)
|
||||
(> (count v) 2)
|
||||
(every? vertex? v))))
|
||||
(every? vertex? v)
|
||||
(:id o)
|
||||
(or (nil? (:kind o)) (= (:kind o) :polygon)))))
|
||||
|
||||
|
||||
|
|
18
src/walkmap/routing.clj
Normal file
18
src/walkmap/routing.clj
Normal file
|
@ -0,0 +1,18 @@
|
|||
(ns walkmap.core
|
||||
"Finding optimal routes to traverse a map."
|
||||
(:require [walkmap.path :as p]
|
||||
[walkmap.polygon :as q]
|
||||
[walkmap.stl :as s]
|
||||
[walkmap.utils :as u]
|
||||
[walkmap.vertex :as v]))
|
||||
|
||||
;; Breadth first search is a good algorithm for terrain in which all steps have
|
||||
;; equal, but in our world (like the real world), they don't.
|
||||
|
||||
;; Reading list:
|
||||
;;
|
||||
;; https://en.wikipedia.org/wiki/A*_search_algorithm
|
||||
;; https://www.redblobgames.com/pathfinding/a-star/introduction.html
|
||||
;; https://faculty.nps.edu/ncrowe/opmpaper2.htm
|
||||
;;
|
||||
;; See https://simon-brooke.github.io/the-great-game/codox/Pathmaking.html
|
|
@ -5,7 +5,10 @@
|
|||
[me.raynes.fs :as fs]
|
||||
[org.clojars.smee.binary.core :as b]
|
||||
[taoensso.timbre :as l :refer [info error spy]]
|
||||
[walkmap.polygon :refer [polygon?]])
|
||||
[walkmap.edge :as e]
|
||||
[walkmap.polygon :refer [polygon?]]
|
||||
[walkmap.tag :refer [tag]]
|
||||
[walkmap.vertex :as v])
|
||||
(:import org.clojars.smee.binary.core.BinaryIO
|
||||
java.io.DataInput))
|
||||
|
||||
|
@ -26,6 +29,7 @@
|
|||
(every? polygon? (:facets o))
|
||||
(if (:header o) (string? (:header o)) true)
|
||||
(if (:count o) (integer? (:count o)) true)
|
||||
(or (nil? (:kind o)) (= (:kind o) :stl))
|
||||
(if verify-count? (= (:count o) (count (:facets o))) true))))
|
||||
|
||||
(def vect
|
||||
|
@ -49,15 +53,76 @@
|
|||
:count :uint-le
|
||||
:facets (b/repeated facet)))
|
||||
|
||||
(defn centre
|
||||
"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."
|
||||
[facet]
|
||||
(let [vs (:vertices facet)
|
||||
v1 (first vs)
|
||||
opposite (e/edge (nth vs 1) (nth vs 2))
|
||||
oc (e/centre opposite)]
|
||||
(assoc
|
||||
facet
|
||||
:centre
|
||||
(v/vertex
|
||||
(+ (:x v1) (* (- (:x oc) (:x v1)) 2/3))
|
||||
(+ (:y v1) (* (- (:y oc) (:y v1)) 2/3))
|
||||
(+ (:z v1) (* (- (:z oc) (:z v1)) 2/3))))))
|
||||
|
||||
(defn canonicalise
|
||||
"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."
|
||||
([o] (canonicalise o :height))
|
||||
([o map-kind]
|
||||
(when-not
|
||||
(keyword? map-kind)
|
||||
(throw (IllegalArgumentException.
|
||||
(subs (str "Must be a keyword: " (or map-kind "nil")) 0 80))))
|
||||
(cond
|
||||
(and (coll? o) (not (map? o))) (map #(canonicalise % map-kind) o)
|
||||
;; if it has :facets it's an STL structure, but it doesn't yet conform to `stl?`
|
||||
(:facets o) (assoc o
|
||||
:kind :stl
|
||||
:id (or (:id o) (keyword (gensym "stl")))
|
||||
:facets (canonicalise (:facets o) map-kind))
|
||||
;; if it has :vertices it's a polygon, but it doesn't yet conform to `polygon?`
|
||||
(:vertices o) (centre
|
||||
(tag
|
||||
(assoc o
|
||||
:id (or (:id o) (keyword (gensym "poly")))
|
||||
:kind :polygon
|
||||
:vertices (canonicalise (:vertices o) map-kind))
|
||||
:facet map-kind))
|
||||
;; if it has a value for :x it's a vertex, but it doesn't yet conform to `vertex?`
|
||||
(:x o) (v/canonicalise o)
|
||||
;; shouldn't happen
|
||||
:else o)))
|
||||
|
||||
(defn decode-binary-stl
|
||||
"Parse a binary STL file from this `filename` and return an STL structure
|
||||
representing its contents.
|
||||
representing its contents. `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.
|
||||
|
||||
**NOTE** that we've no way of verifying that the input file is binary STL
|
||||
data, if it is not this will run but will return garbage."
|
||||
[filename]
|
||||
([filename]
|
||||
(decode-binary-stl filename :height))
|
||||
([filename map-kind]
|
||||
(when-not
|
||||
(keyword? map-kind)
|
||||
(throw (IllegalArgumentException.
|
||||
(subs (str "Must be a keyword: " (or map-kind "nil")) 0 80))))
|
||||
(let [in (io/input-stream filename)]
|
||||
(b/decode binary-stl in)))
|
||||
(canonicalise (b/decode binary-stl in) map-kind))))
|
||||
|
||||
(defn- vect->str [prefix v]
|
||||
(str prefix " " (:x v) " " (:y v) " " (:z v) "\n"))
|
||||
|
|
85
src/walkmap/superstructure.clj
Normal file
85
src/walkmap/superstructure.clj
Normal file
|
@ -0,0 +1,85 @@
|
|||
(ns walkmap.superstructure
|
||||
"single indexing structure for walkmap objects"
|
||||
(:require [walkmap.path :as p]
|
||||
[walkmap.polygon :as q]
|
||||
[walkmap.stl :as s]
|
||||
[walkmap.utils :as u]
|
||||
[walkmap.vertex :as v]))
|
||||
|
||||
;; TODO: Think about reification/dereification. How can we cull a polygon, if
|
||||
;; some vertices still index it? I *think* that what's needed is that when
|
||||
;; we store something in the superstructure, we replace all its vertices (and
|
||||
;; other dependent structures, if any with their ids - as well as, obviously,
|
||||
;; adding/merging those vertices/dependent structures into the superstructure
|
||||
;; as first class objects in themselves. That means, for each identified thing,
|
||||
;; the superstructure only contains one copy of it.
|
||||
;;
|
||||
;; The question then is, when we want to do things with those objects, do we
|
||||
;; exteract a copy with its dependent structures fixed back up (reification),
|
||||
;; or do we indirect through the superstructure every time we want to access
|
||||
;; them? In a sense, the copy in the superstructure is the 'one true copy',
|
||||
;; but it may become very difficult then to have one true copy of the
|
||||
;; superstructure - unless we replace the superstructure altogether with a
|
||||
;; database, which may be the Right Thing To Do.
|
||||
|
||||
(defn index-vertex
|
||||
"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 `:id`;
|
||||
4. `v` is not a vertex."
|
||||
[s o v]
|
||||
(if-not (v/vertex? o)
|
||||
(if (:id o)
|
||||
(if (v/vertex? v)
|
||||
(let [vi (or (:vertex-index s) {})
|
||||
current (or (vi (:id v)) {})]
|
||||
;; deep-merge doesn't merge sets, only maps; so at this
|
||||
;; stage we need to build a map.
|
||||
(assoc vi (:id v) (assoc current (:id o) (:id v))))
|
||||
(throw (IllegalArgumentException. "Not a vertex: " v)))
|
||||
(throw (IllegalArgumentException. (subs (str "No `:id` value: " o) 0 80))))
|
||||
;; it shouldn't actually be an error to try to index a vertex, but it
|
||||
;; also isn't useful to do so, so I'd be inclined to ignore it.
|
||||
(:vertex-index s)))
|
||||
|
||||
(defn index-vertices
|
||||
"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 `:id`."
|
||||
[s o]
|
||||
(assoc
|
||||
s
|
||||
:vertex-index
|
||||
(reduce
|
||||
u/deep-merge
|
||||
(map
|
||||
#(index-vertex s o %)
|
||||
(u/vertices o)))))
|
||||
|
||||
(defn add-to-superstructure
|
||||
"Return a superstructure like `s` with object `o` added. If `o` is a collection,
|
||||
return a superstructure like `s` with each element of `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 map, or a sequence of maps."
|
||||
([o]
|
||||
(add-to-superstructure {} o))
|
||||
([s o]
|
||||
(cond
|
||||
(map? o) (let [o' (if (:id o) o (assoc o :id (keyword (gensym "obj"))))]
|
||||
(index-vertices (assoc s (:id o') o') o'))
|
||||
(coll? o) (reduce u/deep-merge (map #(add-to-superstructure s %) o))
|
||||
(nil? o) o
|
||||
:else
|
||||
(throw (IllegalArgumentException. (str "Don't know how to index " (or (type o) "nil")))))))
|
||||
|
65
src/walkmap/tag.clj
Normal file
65
src/walkmap/tag.clj
Normal file
|
@ -0,0 +1,65 @@
|
|||
(ns 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."
|
||||
(:require [clojure.set :refer [difference union]]))
|
||||
|
||||
(defn tagged?
|
||||
"True if this `object` is tagged with each of these `tags`. 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."
|
||||
[object & tags]
|
||||
(if
|
||||
(map? object)
|
||||
(if
|
||||
(every? keyword? tags)
|
||||
(let [ot (::tags object)]
|
||||
(and
|
||||
(set? ot)
|
||||
(every? ot tags)))
|
||||
(throw (IllegalArgumentException.
|
||||
(str "Must be keyword(s): " (map type tags)))))
|
||||
(throw (IllegalArgumentException.
|
||||
(str "Must be a map: " (type object))))))
|
||||
|
||||
(defn tag
|
||||
"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."
|
||||
[object & tags]
|
||||
(if
|
||||
(map? object)
|
||||
(if
|
||||
(every? keyword? tags)
|
||||
(assoc object ::tags (union (set tags) (::tags object)))
|
||||
(throw (IllegalArgumentException.
|
||||
(str "Must be keyword(s): " (map type tags)))))
|
||||
(throw (IllegalArgumentException.
|
||||
(str "Must be a map: " (type object))))))
|
||||
|
||||
(defmacro tags
|
||||
"Return the tags of this object, if any."
|
||||
[object]
|
||||
`(::tags ~object))
|
||||
|
||||
(defn untag
|
||||
"Return an object like this `object` but with these `tags` removed from its
|
||||
tags, if 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."
|
||||
[object & tags]
|
||||
(if
|
||||
(map? object)
|
||||
(if
|
||||
(every? keyword? tags)
|
||||
(assoc object ::tags (difference (::tags object) (set tags)))
|
||||
(throw (IllegalArgumentException.
|
||||
(str "Must be keywords: " (map type tags)))))
|
||||
(throw (IllegalArgumentException.
|
||||
(str "Must be a map: " (type object))))))
|
23
src/walkmap/utils.clj
Normal file
23
src/walkmap/utils.clj
Normal file
|
@ -0,0 +1,23 @@
|
|||
(ns walkmap.utils
|
||||
"Miscellaneous utility functions."
|
||||
(:require [clojure.math.numeric-tower :as m]
|
||||
[walkmap.path :as p]
|
||||
[walkmap.polygon :as q]
|
||||
[walkmap.vertex :as v]))
|
||||
|
||||
(defn deep-merge
|
||||
"Recursively merges maps. If vals are not maps, the last value wins."
|
||||
;; TODO: not my implementation, not sure I entirely trust it.
|
||||
[& vals]
|
||||
(if (every? map? vals)
|
||||
(apply merge-with deep-merge vals)
|
||||
(last vals)))
|
||||
|
||||
(defn vertices
|
||||
"If `o` is an object with vertices, return those vertices, else nil."
|
||||
[o]
|
||||
(cond
|
||||
(v/vertex? o) (list o)
|
||||
(q/polygon? o) (:vertices o)
|
||||
(p/path? o) (:vertices o)))
|
||||
|
|
@ -1,5 +1,33 @@
|
|||
(ns walkmap.vertex
|
||||
"Essentially the specification for things we shall consider to be vertices.")
|
||||
"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`."
|
||||
(:require [clojure.math.numeric-tower :as m]
|
||||
[clojure.string :as s]
|
||||
[walkmap.geometry :refer [=ish]]))
|
||||
|
||||
(defn vertex-key
|
||||
"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."
|
||||
[o]
|
||||
(keyword
|
||||
(s/replace
|
||||
(cond
|
||||
(and (:x o) (:y o) (:z o))
|
||||
(str "vert_" (:x o) "_" (:y o) "_" (:z o))
|
||||
(and (:x o) (:y o))
|
||||
(str "vert_" (:x o) "_" (:y o))
|
||||
:else
|
||||
(throw (IllegalArgumentException.
|
||||
(subs (str "Not a vertex: " (or o "nil")) 0 80))))
|
||||
"."
|
||||
"-")))
|
||||
|
||||
(defn vertex?
|
||||
"True if `o` satisfies the conditions for a vertex. That is, essentially,
|
||||
|
@ -13,9 +41,48 @@
|
|||
[o]
|
||||
(and
|
||||
(map? o)
|
||||
(:id o)
|
||||
(number? (:x o))
|
||||
(number? (:y o))
|
||||
(or (nil? (:z o)) (number? (:z o)))))
|
||||
(or (nil? (:z o)) (number? (:z o)))
|
||||
(or (nil? (:kind o)) (= (:kind o) :vertex))))
|
||||
|
||||
(defn vertex=
|
||||
"True if vertices `v1`, `v2` represent the same vertex."
|
||||
[v1 v2]
|
||||
(every?
|
||||
#(=ish (% v1) (% v2))
|
||||
[:x :y :z]))
|
||||
|
||||
(defn vertex
|
||||
"Make a vertex with this `x`, `y` and (if provided) `z` values. Returns a map
|
||||
with those values, plus a unique `:id` value, and `:kind` set to `:vertex`.
|
||||
It's not necessary to use this function to create a vertex, but the `:id`
|
||||
must be present and must be unique."
|
||||
([x y]
|
||||
(let [v {:x x :y y :kind :vertex}]
|
||||
(assoc v :id (vertex-key v))))
|
||||
([x y z]
|
||||
(let [v (assoc (vertex x y) :z z)]
|
||||
(assoc v :id (vertex-key v)))))
|
||||
|
||||
(defn canonicalise
|
||||
"If `o` is a map with numeric values for `:x`, `:y` and optionally `:z`,
|
||||
upgrade it to something we will recognise as a vertex."
|
||||
[o]
|
||||
(if
|
||||
(and
|
||||
(map? o)
|
||||
(number? (:x o))
|
||||
(number? (:y o))
|
||||
(or (nil? (:z o)) (number? (:z o))))
|
||||
(assoc o :kind :vertex :id (vertex-key o))
|
||||
(throw
|
||||
(IllegalArgumentException.
|
||||
(subs
|
||||
(str "Not a proto-vertex: must have numeric `:x` and `:y`: "
|
||||
(or o "nil"))
|
||||
0 80)))))
|
||||
|
||||
(def ensure3d
|
||||
"Given a vertex `o`, if `o` has a `:z` value, just return `o`; otherwise
|
||||
|
@ -29,7 +96,9 @@
|
|||
(ensure3d o 0.0))
|
||||
([o dflt]
|
||||
(cond
|
||||
(not (vertex? o)) (throw (Exception. "Not a vertex!"))
|
||||
(not (vertex? o)) (throw
|
||||
(IllegalArgumentException.
|
||||
(subs (str "Not a vertex: " (or o "nil")) 0 80)))
|
||||
(:z o) o
|
||||
:else (assoc o :z dflt))))))
|
||||
|
||||
|
@ -40,4 +109,6 @@
|
|||
(if
|
||||
(vertex? o)
|
||||
(assoc o :z 0.0)
|
||||
(throw (Exception. "Not a vertex!"))))))
|
||||
(throw
|
||||
(IllegalArgumentException.
|
||||
(subs (str "Not a vertex: " (or o "nil")) 0 80)))))))
|
||||
|
|
|
@ -1,46 +1,121 @@
|
|||
(ns walkmap.edge-test
|
||||
(:require [clojure.test :refer :all]
|
||||
[walkmap.edge :refer :all]))
|
||||
(:require [clojure.math.numeric-tower :as m]
|
||||
[clojure.test :refer :all]
|
||||
[walkmap.edge :refer :all]
|
||||
[walkmap.vertex :refer [vertex]]))
|
||||
|
||||
(deftest edge-test
|
||||
(testing "identification of edges."
|
||||
(is (edge? {:start {:x 0.0 :y 0.0 :z 0.0} :end {:x 3 :y 4 :z 0.0}}) "It is.")
|
||||
(is (not (edge? {:start {:y 0.0 :z 0.0} :end {:x 3 :y 4 :z 0.0}})) "Start lacks :x key")
|
||||
(is (not (edge? {:start {:x nil :y 0.0 :z 0.0} :end {:x 3 :y 4 :z 0.0}})) "Start lacks :x value")
|
||||
(is (not (edge? {:begin {:x nil :y 0.0 :z 0.0} :end {:x 3 :y 4 :z 0.0}})) "Lacks start key")
|
||||
(is (not (edge? {:start {:x nil :y 0.0 :z 0.0} :finish {:x 3 :y 4 :z 0.0}})) "Lacks end key")
|
||||
(is (not (edge? {:start {:x "zero" :y 0.0 :z 0.0} :end {:x 3 :y 4 :z 0.0}})) "Value of x in start is not a number")
|
||||
(is (edge? {:start (vertex 0.0 0.0 0.0)
|
||||
:end (vertex 3 4 0.0)}) "It is.")
|
||||
(is (not (edge? {:start {:y 0.0 :z 0.0 :id 'foo}
|
||||
:end {:x 3 :y 4 :z 0.0 :id 'bar}})) "Start lacks :x key")
|
||||
(is (not (edge? {:start {:x nil :y 0.0 :z 0.0 :id 'foo}
|
||||
:end {:x 3 :y 4 :z 0.0 :id 'bar}})) "Start lacks :x value")
|
||||
(is (not (edge? {:begin {:x nil :y 0.0 :z 0.0 :id 'foo}
|
||||
:end {:x 3 :y 4 :z 0.0 :id 'bar}})) "Lacks start key")
|
||||
(is (not (edge? {:start {:x nil :y 0.0 :z 0.0 :id 'foo}
|
||||
:finish {:x 3 :y 4 :z 0.0 :id 'bar}})) "Lacks end key")
|
||||
(is (not (edge? {:start {:x "zero" :y 0.0 :z 0.0 :id 'foo}
|
||||
:end {:x 3 :y 4 :z 0.0 :id 'bar}})) "Value of x in start is not a number")
|
||||
(is (false? (edge? "I am not an edge")) "Edge mustbe a map.")))
|
||||
|
||||
(deftest collinear-test
|
||||
(testing "collinearity"
|
||||
(is (collinear? {:start {:x 0.0 :y 0.0 :z 0.0 :id 'foo} :end {:x 3.0 :y 4.0 :z 0.0 :id 'bar}}
|
||||
{:start {:x 3.0 :y 4.0 :z 0.0 :id 'foo} :end {:x 9.0 :y 12.0 :z 0.0 :id 'bar}})
|
||||
"Should be")
|
||||
(is (not
|
||||
(collinear? {:start {:x 0.0 :y 0.0 :z 0.0 :id 'foo} :end {:x 3 :y 4 :z 0.0 :id 'bar}}
|
||||
{:start {:x 1.0 :y 2.0 :z 3.5 :id 'foo} :end {:x 4.0 :y 6.0 :z 3.5 :id 'bar}}))
|
||||
"Should not be!")
|
||||
(is (collinear? {:start {:x 0.0 :y 0.0 :z 0.0 :id 'foo} :end {:x 3.0 :y 4.0 :z 0.0 :id 'bar}}
|
||||
{:start {:x 0.0 :y 0.0 :z 0.0 :id 'foo} :end {:x 9.0 :y 12.0 :z 0.0 :id 'bar}})
|
||||
"Edge case: same start location")
|
||||
(is (collinear? {:start {:x 0.0 :y 0.0 :z 0.0 :id 'foo} :end {:x 9.0 :y 12.0 :z 0.0 :id 'bar}}
|
||||
{:start {:x 3.0 :y 4.0 :z 0.0 :id 'foo} :end {:x 9.0 :y 12.0 :z 0.0 :id 'bar}})
|
||||
"Edge case: same end location")
|
||||
))
|
||||
|
||||
(deftest collinear2d-test
|
||||
(testing "Collinearity when projected onto the x,y plane."
|
||||
(is (collinear2d? (edge (vertex 1.0 1.0) (vertex 5.0 5.0))
|
||||
(edge (vertex 4.0 4.0) (vertex 6.0 6.0)))
|
||||
"Collinear, overlapping.")
|
||||
(is (collinear2d? (edge (vertex 1.0 1.0 0.0) (vertex 5.0 5.0 5.0))
|
||||
(edge (vertex 4.0 4.0 79.3) (vertex 6.0 6.0 0.2)))
|
||||
"Separated in the z axis, but collinear in x, y.")))
|
||||
|
||||
(deftest construction-test
|
||||
(testing "Construction of edges."
|
||||
(is (edge? (edge (vertex 1.0 2.0 3.0) (vertex 4.0 8.0 12.0)))
|
||||
"If both arguments are vertices, we should get an edge")
|
||||
(is (thrown? IllegalArgumentException (edge "Not a vertex" (vertex 1 2)))
|
||||
"If first argument is not a vertex, we should get an exception.")
|
||||
(is (thrown? IllegalArgumentException (edge (vertex 1 2) "Not a vertex"))
|
||||
"If second argument is not a vertex, we should get an exception.")))
|
||||
|
||||
(deftest intersection2d-test
|
||||
(testing "intersection of two edges projected onto the x,y plane."
|
||||
(is (thrown? IllegalArgumentException
|
||||
(intersection2d
|
||||
(edge (vertex 1.0 1.0) (vertex 5.0 5.0))
|
||||
"This is not an edge"))
|
||||
"Not an edge (second arg) -> exception.")
|
||||
(is (thrown? IllegalArgumentException
|
||||
(intersection2d
|
||||
"This is not an edge"
|
||||
(edge (vertex 1.0 1.0) (vertex 5.0 5.0))))
|
||||
"Not an edge (first arg) -> exception.")
|
||||
(is (nil? (intersection2d (edge (vertex 1.0 1.0) (vertex 5.0 5.0))
|
||||
(edge (vertex 1.0 2.0) (vertex 5.0 6.0))))
|
||||
"Parallel but not intersecting.")
|
||||
(is (:x (intersection2d (edge (vertex 1.0 1.0) (vertex 5.0 5.0))
|
||||
(edge (vertex 4.0 4.0) (vertex 6.0 6.0)))
|
||||
5.0)
|
||||
"Collinear, overlapping, should choose the overlapping end of the first edge.")
|
||||
(is (= (:x (intersection2d (edge (vertex 1.0 1.0) (vertex 5.0 5.0))
|
||||
(edge (vertex 1.0 5.0) (vertex 5.0 1.0))))
|
||||
3.0)
|
||||
"Crossing, should intersect at 3.0, 3.0: x coord.")
|
||||
(is (= (:y (intersection2d (edge (vertex 1.0 1.0) (vertex 5.0 5.0))
|
||||
(edge (vertex 1.0 5.0) (vertex 5.0 1.0))))
|
||||
3.0)
|
||||
"Crossing, should intersect at 3.0, 3.0: y coord.")
|
||||
(is (= (:y (intersection2d (edge (vertex 1.0 1.0 0.0) (vertex 5.0 5.0 0.0))
|
||||
(edge (vertex 1.0 5.0 999) (vertex 5.0 1.0 379))))
|
||||
3.0)
|
||||
"Crossing, presence of z coordinate should make no difference")))
|
||||
|
||||
(deftest length-test
|
||||
(testing "length of an edge"
|
||||
(is (= (length {:start {:x 0.0 :y 0.0 :z 0.0} :end {:x 3.0 :y 4.0 :z 0.0}}) 5.0))))
|
||||
(is (= (length {:start {:x 0.0 :y 0.0 :z 0.0 :id 'foo} :end {:x 3.0 :y 4.0 :z 0.0 :id 'bar}}) 5.0))))
|
||||
|
||||
(deftest minimad-test
|
||||
(testing "finding minimum and maximum coordinates of edges."
|
||||
(is (= (minimaxd (edge (vertex 1.0 2.0 3.0) (vertex 4.0 8.0 12.0)) :x min) 1.0))
|
||||
(is (= (minimaxd (edge (vertex 1.0 2.0 3.0) (vertex 4.0 8.0 12.0)) :y max) 8.0))))
|
||||
|
||||
(deftest parallel-test
|
||||
(testing "parallelism"
|
||||
(is (parallel? {:start {:x 0.0 :y 0.0 :z 0.0 :id 'foo} :end {:x 3 :y 4 :z 0.0 :id 'bar}}
|
||||
{:start {:x 1.0 :y 2.0 :z 3.5 :id 'foo} :end {:x 4.0 :y 6.0 :z 3.5 :id 'bar}})
|
||||
"Should be")
|
||||
(is (not
|
||||
(parallel? {:start {:x 0.0 :y 0.0 :z 0.0 :id 'foo} :end {:x 3 :y 4 :z 0.0 :id 'bar}}
|
||||
{:start {:x 1.0 :y 2.0 :z 3.5 :id 'foo} :end {:x 4.0 :y 6.0 :z 3.49 :id 'bar}}))
|
||||
"Should not be!")))
|
||||
|
||||
(deftest overlaps2d-test
|
||||
(testing "whether two edges are in the same area of the x,y plane."
|
||||
(is (false? (overlaps2d? (edge (vertex 1 1) (vertex 4 4)) (edge (vertex 5 5) (vertex 8 8)))))
|
||||
(is (overlaps2d? (edge (vertex 1 1) (vertex 4 4)) (edge (vertex 4 4) (vertex 1 1))))))
|
||||
|
||||
(deftest unit-vector-test
|
||||
(testing "deriving the unit vector"
|
||||
(is (=
|
||||
(unit-vector {:start {:x 0.0 :y 0.0 :z 0.0} :end {:x 3 :y 4 :z 0.0}})
|
||||
(unit-vector {:start {:x 0.0 :y 0.0 :z 0.0 :id 'foo} :end {:x 3 :y 4 :z 0.0 :id 'bar}})
|
||||
{:x 0.6, :y 0.8, :z 0.0}))
|
||||
(is (=
|
||||
(unit-vector {:start {:x 1.0 :y 2.0 :z 3.5} :end {:x 4.0 :y 6.0 :z 3.5}})
|
||||
(unit-vector {:start {:x 1.0 :y 2.0 :z 3.5 :id 'foo} :end {:x 4.0 :y 6.0 :z 3.5 :id 'bar}})
|
||||
{:x 0.6, :y 0.8, :z 0.0}))))
|
||||
|
||||
(deftest parallel-test
|
||||
(testing "parallelism"
|
||||
(is (parallel? {:start {:x 0.0 :y 0.0 :z 0.0} :end {:x 3 :y 4 :z 0.0}}
|
||||
{:start {:x 1.0 :y 2.0 :z 3.5} :end {:x 4.0 :y 6.0 :z 3.5}})
|
||||
"Should be")
|
||||
(is (not
|
||||
(parallel? {:start {:x 0.0 :y 0.0 :z 0.0} :end {:x 3 :y 4 :z 0.0}}
|
||||
{:start {:x 1.0 :y 2.0 :z 3.5} :end {:x 4.0 :y 6.0 :z 3.49}}))
|
||||
"Should not be!")))
|
||||
|
||||
(deftest collinear-test
|
||||
(testing "collinearity"
|
||||
(is (collinear? {:start {:x 0.0 :y 0.0 :z 0.0} :end {:x 3.0 :y 4.0 :z 0.0}}
|
||||
{:start {:x 3.0 :y 4.0 :z 0.0} :end {:x 9.0 :y 12.0 :z 0.0}})
|
||||
"Should be")
|
||||
(is (not
|
||||
(collinear? {:start {:x 0.0 :y 0.0 :z 0.0} :end {:x 3 :y 4 :z 0.0}}
|
||||
{:start {:x 1.0 :y 2.0 :z 3.5} :end {:x 4.0 :y 6.0 :z 3.5}}))
|
||||
"Should not be!")))
|
||||
|
|
14
test/walkmap/geometry_test.clj
Normal file
14
test/walkmap/geometry_test.clj
Normal file
|
@ -0,0 +1,14 @@
|
|||
(ns walkmap.geometry-test
|
||||
(:require [clojure.test :refer :all]
|
||||
[walkmap.geometry :refer :all]))
|
||||
|
||||
(deftest =ish-tests
|
||||
(testing "Rough equality"
|
||||
(is (=ish 5.00000001 5.00000002) "Close enough.")
|
||||
(is (=ish 5 5) "Perfect.")
|
||||
(is (not (=ish 5.01 5.02)) "Not close enough.")
|
||||
(is (=ish 22/7 3.142857) "We hope so!")
|
||||
(is (=ish 0 0.0) "Tricky conrer case!")
|
||||
(is (=ish :foo :foo) "Fails over to plain old equals for non-numbers.")
|
||||
(is (=ish 6 5 10000) "If tolerance is wide enough, anything can be equal.")
|
||||
(is (=ish "hello" "goodbye" 10000) "Well, except non-numbers, of course.")))
|
96
test/walkmap/stl_test.clj
Normal file
96
test/walkmap/stl_test.clj
Normal file
|
@ -0,0 +1,96 @@
|
|||
(ns walkmap.stl-test
|
||||
(:require [clojure.test :refer :all]
|
||||
[walkmap.stl :refer :all]
|
||||
[walkmap.polygon :refer [polygon?]]
|
||||
[walkmap.vertex :refer [vertex?]]))
|
||||
|
||||
(deftest canonicalise-test
|
||||
(testing "Canonicalisation of objects read from STL: vertices."
|
||||
(is (vertex? (canonicalise {:x 3.0, :y 1.0, :z 1.0}))
|
||||
"Vertex: should have an `:id` and `:kind` = `:vertex`.")
|
||||
(is (= (:x (canonicalise {:x 3.0, :y 1.0, :z 1.0})) 3.0)
|
||||
"`:x` value should be unchanged.")
|
||||
(is (= (:y (canonicalise {:x 3.0, :y 1.0, :z 1.0})) 1.0)
|
||||
"`:y` value should be unchanged.")
|
||||
(is (= (:z (canonicalise {:x 3.0, :y 1.0, :z 1.0})) 1.0)
|
||||
"`:z` value should be unchanged.")
|
||||
(is (every?
|
||||
vertex?
|
||||
(canonicalise [{:x 3.0, :y 1.0, :z 1.0}
|
||||
{:x 2.0, :y 3.0, :z 1.0}
|
||||
{:x 0.0, :y 0.0, :z 1.0}]))
|
||||
"Vertices: should recurse."))
|
||||
(testing "Canonicalisation of objects read from STL: facets/polygons."
|
||||
(let [p {:normal {:x -0.0, :y 0.0, :z 1.0},
|
||||
:vertices [{:x 3.0, :y 1.0, :z 1.0}
|
||||
{:x 2.0, :y 3.0, :z 1.0}
|
||||
{:x 0.0, :y 0.0, :z 1.0}],
|
||||
:abc 0}
|
||||
p' (canonicalise p)]
|
||||
(is (polygon? p')
|
||||
"Polygon: should have an `:id` and `:kind` = `:polygon`.")
|
||||
(is (= (count (:vertices p)) (count (:vertices p')))
|
||||
"Number of vertices should not change")
|
||||
(map
|
||||
#(is (= (map % (:vertices p))(map % (:vertices p')))
|
||||
(str "Order of vertices should not change: " %))
|
||||
[:x :y :z]))
|
||||
(is (every?
|
||||
polygon?
|
||||
(canonicalise
|
||||
[{:normal {:x -0.0, :y 0.0, :z 1.0},
|
||||
:vertices [{:x 3.0, :y 1.0, :z 1.0}
|
||||
{:x 2.0, :y 3.0, :z 1.0}
|
||||
{:x 0.0, :y 0.0, :z 1.0}],
|
||||
:abc 0}
|
||||
{:normal {:x 0.0, :y 0.0, :z 1.0},
|
||||
:vertices [{:x 10.0, :y 4.0, :z 1.0}
|
||||
{:x 22.0, :y 3.0, :z 1.0}
|
||||
{:x 13.0, :y 5.0, :z 1.0}],
|
||||
:abc 0}
|
||||
{:normal {:x 0.0, :y 0.0, :z 1.0},
|
||||
:vertices [{:x 26.0, :y 46.0, :z 1.0}
|
||||
{:x 29.0, :y 49.0, :z 1.0}
|
||||
{:x 31.0, :y 61.0, :z 1.0}],
|
||||
:abc 0}
|
||||
{:normal {:x -0.0, :y 0.0, :z 1.0},
|
||||
:vertices [{:x 16.0, :y 33.0, :z 1.0}
|
||||
{:x 15.0, :y 35.0, :z 1.0}
|
||||
{:x 13.0, :y 32.0, :z 1.0}],
|
||||
:abc 0}
|
||||
{:normal {:x 0.0, :y 0.0, :z 1.0},
|
||||
:vertices [{:x 81.0, :y 0.0, :z 1.0}
|
||||
{:x 54.0, :y 27.0, :z 1.0}
|
||||
{:x 51.0, :y 20.0, :z 1.0}],
|
||||
:abc 0}]))
|
||||
"Facets/polygons: should recurse."))
|
||||
(testing "Canonicalisation of entire STL structure."
|
||||
(let [stl {:header "Dummy test STL",
|
||||
:count 5,
|
||||
:facets [{:normal {:x -0.0, :y 0.0, :z 1.0},
|
||||
:vertices [{:x 3.0, :y 1.0, :z 1.0}
|
||||
{:x 2.0, :y 3.0, :z 1.0}
|
||||
{:x 0.0, :y 0.0, :z 1.0}],
|
||||
:abc 0}
|
||||
{:normal {:x 0.0, :y 0.0, :z 1.0},
|
||||
:vertices [{:x 10.0, :y 4.0, :z 1.0}
|
||||
{:x 22.0, :y 3.0, :z 1.0}
|
||||
{:x 13.0, :y 5.0, :z 1.0}],
|
||||
:abc 0}
|
||||
{:normal {:x 0.0, :y 0.0, :z 1.0},
|
||||
:vertices [{:x 26.0, :y 46.0, :z 1.0}
|
||||
{:x 29.0, :y 49.0, :z 1.0}
|
||||
{:x 31.0, :y 61.0, :z 1.0}],
|
||||
:abc 0}
|
||||
{:normal {:x -0.0, :y 0.0, :z 1.0},
|
||||
:vertices [{:x 16.0, :y 33.0, :z 1.0}
|
||||
{:x 15.0, :y 35.0, :z 1.0}
|
||||
{:x 13.0, :y 32.0, :z 1.0}],
|
||||
:abc 0}
|
||||
{:normal {:x 0.0, :y 0.0, :z 1.0},
|
||||
:vertices [{:x 81.0, :y 0.0, :z 1.0}
|
||||
{:x 54.0, :y 27.0, :z 1.0}
|
||||
{:x 51.0, :y 20.0, :z 1.0}],
|
||||
:abc 0}]}
|
||||
stl' (canonicalise stl)]
|
||||
(is (stl? stl') "Stl: should have an `:id` and `:kind` = `:stl`."))))
|
51
test/walkmap/tag_test.clj
Normal file
51
test/walkmap/tag_test.clj
Normal file
|
@ -0,0 +1,51 @@
|
|||
(ns walkmap.tag-test
|
||||
(:require [clojure.test :refer :all]
|
||||
[walkmap.tag :refer :all]))
|
||||
|
||||
(deftest tag-tests
|
||||
(testing "Tagging"
|
||||
(is (set? (:walkmap.tag/tags (tag {} :foo :bar :ban :froboz)))
|
||||
"The value of `:walkmap.tag/tags` should be a set.")
|
||||
(is (= (count (:walkmap.tag/tags (tag {} :foo :bar :ban :froboz))) 4)
|
||||
"All the tags passed should be added.")
|
||||
(is (:walkmap.tag/tags (tag {} :foo :bar :ban :froboz) :ban)
|
||||
"`:ban` should be present in the set, and, as it is a set, it
|
||||
should be valid to apply it to a keyword.")
|
||||
(is (not ((:walkmap.tag/tags (tag {} :foo :bar :ban :froboz)) :cornflakes))
|
||||
"`:cornflakes should not be present.")
|
||||
(is (true? (tagged? (tag {} :foo :bar :ban :froboz) :bar))
|
||||
"`tagged?` should return an explicit `true`, not any other value.")
|
||||
(is (tagged? (tag {} :foo :bar :ban :froboz) :bar :froboz)
|
||||
"We should be able to test for the presence of more than one tag")
|
||||
(is (false? (tagged? {} :foo))
|
||||
"A missing `:walkmap.tag/tags` should not cause an error.")
|
||||
(is (= (tagged? (tag {} :foo :bar :ban :froboz) :bar :cornflakes) false)
|
||||
"If any of the queried tags is missing, false should be returned")
|
||||
(is (tagged? (tag (tag {} :foo) :bar) :foo :bar)
|
||||
"We should be able to add tags to an already tagged object")
|
||||
(is (false? (tagged? (tag {} :foo :bar) :cornflakes))
|
||||
"`tagged?` should return an explicit `false` if a queried tag is missing.")
|
||||
(is (= (tags (tag {} :foo)) #{:foo})
|
||||
"`tags` should return the tags on the object, if any.")
|
||||
(is (every? nil? (map #(tags %) [1 :one "one" [:one] {:one 1}]))
|
||||
"Things which don't have tags don't have tags, and that's not a problem.")
|
||||
(let [object (tag {} :foo :bar :ban :froboz)]
|
||||
(is (= (untag object :cornflakes) object)
|
||||
"Removing a missing tag should have no effect.")
|
||||
(is (tagged? (untag object :foo) :bar :ban :froboz)
|
||||
"All tags not explicitly removed should still be present.")
|
||||
(is (false? (tagged? (untag object :bar) :bar))
|
||||
"But the tag which has been removed should be removed."))
|
||||
(is (thrown? IllegalArgumentException (tag [] :foo))
|
||||
"An exception should be thrown if `object` is not a map: `tag`.")
|
||||
(is (thrown? IllegalArgumentException (tagged? [] :foo))
|
||||
"An exception should be thrown if `object` is not a map: `tagged?`.")
|
||||
(is (thrown? IllegalArgumentException (untag [] :foo))
|
||||
"An exception should be thrown if `object` is not a map: `untag`.")
|
||||
(is (thrown? IllegalArgumentException (tag {} :foo "bar" :ban))
|
||||
"An exception should be thrown if any of `tags` is not a keyword: `tag`.")
|
||||
(is (thrown? IllegalArgumentException (tagged? {} :foo "bar" :ban))
|
||||
"An exception should be thrown if any of `tags` is not a keyword: `tagged?`.")
|
||||
(is (thrown? IllegalArgumentException (untag {} :foo "bar" :ban))
|
||||
"An exception should be thrown if any of `tags` is not a keywordp: `untag`.")))
|
||||
|
Loading…
Reference in a new issue