Merge branch 'feature/3' into develop

This commit is contained in:
Simon Brooke 2020-05-27 18:59:17 +01:00
commit 4df5c4dff4
No known key found for this signature in database
GPG key ID: A7A4F18D1D4DF987
43 changed files with 3469 additions and 976 deletions

View file

@ -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>

View file

@ -8,10 +8,10 @@
001&nbsp;&nbsp;(ns&nbsp;walkmap.core
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;At&nbsp;this&nbsp;stage,&nbsp;primarily&nbsp;utility&nbsp;functions&nbsp;dealing&nbsp;with&nbsp;stereolithography
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;This&nbsp;namespace&nbsp;mostly&nbsp;gets&nbsp;used&nbsp;as&nbsp;a&nbsp;scratchpad&nbsp;for&nbsp;ideas&nbsp;which&nbsp;haven&#x27;t&nbsp;yet
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;(STL)&nbsp;files.&nbsp;Not&nbsp;a&nbsp;stable&nbsp;API&nbsp;yet!&quot;
003&nbsp;&nbsp;&nbsp;&nbsp;solidified.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[clojure.java.io&nbsp;:as&nbsp;io&nbsp;:refer&nbsp;[file&nbsp;output-stream&nbsp;input-stream]]
@ -26,115 +26,10 @@
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[me.raynes.fs&nbsp;:as&nbsp;fs]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[taoensso.timbre&nbsp;:as&nbsp;l&nbsp;:refer&nbsp;[info&nbsp;error&nbsp;spy]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.stl&nbsp;:refer&nbsp;[decode-binary-stl]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.svg&nbsp;:refer&nbsp;[stl-&gt;svg]]))
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[taoensso.timbre&nbsp;:as&nbsp;l&nbsp;:refer&nbsp;[info&nbsp;error&nbsp;spy]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
011&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
012&nbsp;&nbsp;(def&nbsp;^:dynamic&nbsp;*sea-level*
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&quot;The&nbsp;sea&nbsp;level&nbsp;on&nbsp;heightmaps&nbsp;we&#x27;re&nbsp;currently&nbsp;handling.&nbsp;If&nbsp;characters&nbsp;are&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;able&nbsp;to&nbsp;swin&nbsp;in&nbsp;the&nbsp;sea,&nbsp;we&nbsp;must&nbsp;model&nbsp;the&nbsp;sea&nbsp;bottom,&nbsp;so&nbsp;we&nbsp;need
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;heightmaps&nbsp;which&nbsp;cover&nbsp;at&nbsp;least&nbsp;the&nbsp;continental&nbsp;shelf.&nbsp;However,&nbsp;the&nbsp;sea
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;bottom&nbsp;is&nbsp;not&nbsp;walkable&nbsp;territory&nbsp;and&nbsp;can&nbsp;be&nbsp;culled&nbsp;from&nbsp;walkmaps.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
017&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;**Note**&nbsp;must&nbsp;be&nbsp;a&nbsp;floating&nbsp;point&nbsp;number.&nbsp;`(=&nbsp;0&nbsp;0.0)`&nbsp;returns&nbsp;`false`!&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;0.0)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
020&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
021&nbsp;&nbsp;(defn&nbsp;ocean?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&quot;Of&nbsp;a&nbsp;`facet`,&nbsp;is&nbsp;the&nbsp;altitude&nbsp;of&nbsp;every&nbsp;vertice&nbsp;equal&nbsp;to&nbsp;`*sea-level*`?&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;[facet]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;(every?
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(=&nbsp;%&nbsp;*sea-level*)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;:z&nbsp;(:vertices&nbsp;facet))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
027&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
028&nbsp;&nbsp;(defn&nbsp;cull-ocean-facets
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&quot;Ye&nbsp;cannae&nbsp;walk&nbsp;on&nbsp;water.&nbsp;Remove&nbsp;all&nbsp;facets&nbsp;from&nbsp;this&nbsp;`stl`&nbsp;structure&nbsp;which
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;are&nbsp;at&nbsp;sea&nbsp;level.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;[stl]
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;stl&nbsp;:facets&nbsp;(remove&nbsp;ocean?&nbsp;(:facets&nbsp;stl))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
033&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
034&nbsp;&nbsp;(defn&nbsp;binary-stl-file-&gt;svg
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&quot;Given&nbsp;only&nbsp;an&nbsp;`in-filename`,&nbsp;parse&nbsp;the&nbsp;indicated&nbsp;file,&nbsp;expected&nbsp;to&nbsp;be
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;binary&nbsp;STL,&nbsp;and&nbsp;return&nbsp;an&nbsp;equivalent&nbsp;SVG&nbsp;structure.&nbsp;Given&nbsp;both&nbsp;`in-filename`
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;`out-filename`,&nbsp;as&nbsp;side-effect&nbsp;write&nbsp;the&nbsp;SVG&nbsp;to&nbsp;the&nbsp;indicated&nbsp;output&nbsp;file.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;([in-filename]
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(stl-&gt;svg&nbsp;(cull-ocean-facets&nbsp;(decode-binary-stl&nbsp;in-filename))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;([in-filename&nbsp;out-filename]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[s&nbsp;(binary-stl-file-&gt;svg&nbsp;in-filename)]
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(spit&nbsp;out-filename&nbsp;(html&nbsp;s))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
044&nbsp;&nbsp;
009&nbsp;&nbsp;
</span><br/>
</body>
</html>

View file

@ -20,235 +20,556 @@
005&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[clojure.math.numeric-tower&nbsp;:as&nbsp;m]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.path&nbsp;:refer&nbsp;[path?&nbsp;polygon-&gt;path]]
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.polygon&nbsp;:refer&nbsp;[polygon?]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.polygon&nbsp;:refer&nbsp;[polygon?]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.vertex&nbsp;:refer&nbsp;[ensure3d&nbsp;vertex?]]))
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.vertex&nbsp;:refer&nbsp;[ensure2d&nbsp;ensure3d&nbsp;vertex&nbsp;vertex=&nbsp;vertex?]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
009&nbsp;&nbsp;
008&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
010&nbsp;&nbsp;(defn&nbsp;edge?
009&nbsp;&nbsp;(defn&nbsp;edge
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;`o`&nbsp;satisfies&nbsp;the&nbsp;conditions&nbsp;for&nbsp;a&nbsp;path.&nbsp;A&nbsp;path&nbsp;shall&nbsp;be&nbsp;a&nbsp;map
010&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;an&nbsp;edge&nbsp;between&nbsp;vertices&nbsp;`v1`&nbsp;and&nbsp;`v2`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;having&nbsp;the&nbsp;keys&nbsp;`:start`&nbsp;and&nbsp;`:end`,&nbsp;such&nbsp;that&nbsp;the&nbsp;values&nbsp;of&nbsp;each&nbsp;of&nbsp;those
011&nbsp;&nbsp;&nbsp;&nbsp;[v1&nbsp;v2]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;keys&nbsp;shall&nbsp;be&nbsp;a&nbsp;vertex.&quot;
<span class="covered" title="1 out of 1 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;[o]
<span class="covered" title="10 out of 10 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(vertex?&nbsp;v1)&nbsp;(vertex?&nbsp;v2))
</span><br/>
<span class="partial" title="8 out of 9 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;(and
<span class="covered" title="13 out of 13 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:kind&nbsp;:edge&nbsp;:id&nbsp;(keyword&nbsp;(gensym&nbsp;&quot;edge&quot;))&nbsp;:start&nbsp;v1&nbsp;:end&nbsp;v2}
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;o)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vertex?&nbsp;(:start&nbsp;o))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vertex?&nbsp;(:end&nbsp;o))))
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;&quot;Must&nbsp;be&nbsp;vertices.&quot;))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
019&nbsp;&nbsp;
016&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
020&nbsp;&nbsp;(defn&nbsp;path-&gt;edges
017&nbsp;&nbsp;(defn&nbsp;edge?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&quot;if&nbsp;`o`&nbsp;is&nbsp;a&nbsp;path,&nbsp;a&nbsp;polygon,&nbsp;or&nbsp;a&nbsp;sequence&nbsp;of&nbsp;vertices,&nbsp;return&nbsp;a&nbsp;sequence&nbsp;of
018&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;`o`&nbsp;satisfies&nbsp;the&nbsp;conditions&nbsp;for&nbsp;a&nbsp;edge.&nbsp;An&nbsp;edge&nbsp;shall&nbsp;be&nbsp;a&nbsp;map
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;edges&nbsp;representing&nbsp;that&nbsp;path,&nbsp;polygon&nbsp;or&nbsp;sequence.&quot;
019&nbsp;&nbsp;&nbsp;&nbsp;having&nbsp;the&nbsp;keys&nbsp;`:start`&nbsp;and&nbsp;`:end`,&nbsp;such&nbsp;that&nbsp;the&nbsp;values&nbsp;of&nbsp;each&nbsp;of&nbsp;those
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;[o]
020&nbsp;&nbsp;&nbsp;&nbsp;keys&nbsp;shall&nbsp;be&nbsp;a&nbsp;vertex.&quot;
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;(cond
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;o)
<span class="covered" title="9 out of 9 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when
<span class="covered" title="3 out of 3 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;o)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
<span class="covered" title="5 out of 5 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vertex?&nbsp;(:start&nbsp;o))
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vertex?&nbsp;(first&nbsp;o))
<span class="covered" title="4 out of 4 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vertex?&nbsp;(:end&nbsp;o))))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vertex?&nbsp;(first&nbsp;(rest&nbsp;o))))
<span class="blank" title="0 out of 0 forms covered">
026&nbsp;&nbsp;
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons
<span class="covered" title="1 out of 1 forms covered">
027&nbsp;&nbsp;(defn&nbsp;length
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:start&nbsp;(first&nbsp;o)
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;the&nbsp;length&nbsp;of&nbsp;the&nbsp;edge&nbsp;`e`.&quot;
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:end&nbsp;(first&nbsp;(rest&nbsp;o))}
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;[e]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path-&gt;edges&nbsp;(rest&nbsp;o))))
<span class="covered" title="6 out of 6 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[start&nbsp;(ensure3d&nbsp;(:start&nbsp;e))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path?&nbsp;o)
<span class="covered" title="5 out of 5 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;(ensure3d&nbsp;(:end&nbsp;e))]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path-&gt;edges&nbsp;(:nodes&nbsp;o))
<span class="covered" title="2 out of 2 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(m&#x2F;sqrt
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(polygon?&nbsp;o)
<span class="covered" title="2 out of 2 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(reduce
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path-&gt;edges&nbsp;(polygon-&gt;path&nbsp;o))))
<span class="covered" title="1 out of 1 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(m&#x2F;expt&nbsp;(-&nbsp;(%&nbsp;end)&nbsp;(%&nbsp;start))&nbsp;2)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:x&nbsp;:y&nbsp;:z])))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
038&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
039&nbsp;&nbsp;(defn&nbsp;length
039&nbsp;&nbsp;(defn&nbsp;centre
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;the&nbsp;length&nbsp;of&nbsp;the&nbsp;edge&nbsp;`e`.&quot;
040&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;the&nbsp;vertex&nbsp;that&nbsp;represents&nbsp;the&nbsp;centre&nbsp;of&nbsp;this&nbsp;`edge`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;[e]
041&nbsp;&nbsp;&nbsp;&nbsp;[edge]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[start&nbsp;(ensure3d&nbsp;(:start&nbsp;e))
042&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[s&nbsp;(ensure3d&nbsp;(:start&nbsp;edge))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;(ensure3d&nbsp;(:end&nbsp;e))]
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e&nbsp;(ensure3d&nbsp;(:end&nbsp;edge))]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(m&#x2F;sqrt
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vertex
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(reduce
<span class="covered" title="16 out of 16 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(+&nbsp;(:x&nbsp;s)&nbsp;(&#x2F;&nbsp;(-&nbsp;(:x&nbsp;e)&nbsp;(:x&nbsp;s))&nbsp;2))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+
<span class="covered" title="16 out of 16 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(+&nbsp;(:y&nbsp;s)&nbsp;(&#x2F;&nbsp;(-&nbsp;(:y&nbsp;e)&nbsp;(:y&nbsp;s))&nbsp;2))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(m&#x2F;expt&nbsp;(-&nbsp;(%&nbsp;end)&nbsp;(%&nbsp;start))&nbsp;2)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:x&nbsp;:y&nbsp;:z])))))
<span class="covered" title="16 out of 16 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(+&nbsp;(:z&nbsp;s)&nbsp;(&#x2F;&nbsp;(-&nbsp;(:z&nbsp;e)&nbsp;(:z&nbsp;s))&nbsp;2)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
050&nbsp;&nbsp;
048&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
051&nbsp;&nbsp;(defn&nbsp;unit-vector
049&nbsp;&nbsp;(defn&nbsp;unit-vector
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;an&nbsp;vertex&nbsp;parallel&nbsp;to&nbsp;`e`&nbsp;starting&nbsp;from&nbsp;the&nbsp;coordinate&nbsp;origin.&nbsp;Two
050&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;an&nbsp;vertex&nbsp;parallel&nbsp;to&nbsp;`e`&nbsp;starting&nbsp;from&nbsp;the&nbsp;coordinate&nbsp;origin.&nbsp;Two
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;edges&nbsp;which&nbsp;are&nbsp;parallel&nbsp;will&nbsp;have&nbsp;the&nbsp;same&nbsp;unit&nbsp;vector.&quot;
051&nbsp;&nbsp;&nbsp;&nbsp;edges&nbsp;which&nbsp;are&nbsp;parallel&nbsp;will&nbsp;have&nbsp;the&nbsp;same&nbsp;unit&nbsp;vector.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;[e]
052&nbsp;&nbsp;&nbsp;&nbsp;[e]
</span><br/>
<span class="covered" title="14 out of 14 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[e&#x27;&nbsp;{:start&nbsp;(ensure3d&nbsp;(:start&nbsp;e))&nbsp;:end&nbsp;(ensure3d&nbsp;(:end&nbsp;e))}
053&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[e&#x27;&nbsp;{:start&nbsp;(ensure3d&nbsp;(:start&nbsp;e))&nbsp;:end&nbsp;(ensure3d&nbsp;(:end&nbsp;e))}
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l&nbsp;(length&nbsp;e&#x27;)]
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l&nbsp;(length&nbsp;e&#x27;)]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(reduce
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(reduce
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;merge
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;merge
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{}
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{}
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[k]
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[k]
</span><br/>
<span class="covered" title="17 out of 17 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{k&nbsp;(&#x2F;&nbsp;(-&nbsp;(k&nbsp;(:end&nbsp;e&#x27;))&nbsp;(k&nbsp;(:start&nbsp;e&#x27;)))&nbsp;l)})
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{k&nbsp;(&#x2F;&nbsp;(-&nbsp;(k&nbsp;(:end&nbsp;e&#x27;))&nbsp;(k&nbsp;(:start&nbsp;e&#x27;)))&nbsp;l)})
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:x&nbsp;:y&nbsp;:z]))))
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:x&nbsp;:y&nbsp;:z]))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
064&nbsp;&nbsp;
062&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
065&nbsp;&nbsp;(defn&nbsp;parallel?
063&nbsp;&nbsp;(defn&nbsp;parallel?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;all&nbsp;`edges`&nbsp;passed&nbsp;are&nbsp;parallel&nbsp;with&nbsp;one&nbsp;another.&quot;
064&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;all&nbsp;`edges`&nbsp;passed&nbsp;are&nbsp;parallel&nbsp;with&nbsp;one&nbsp;another.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;TODO:&nbsp;this&nbsp;bears&nbsp;being&nbsp;wary&nbsp;about,&nbsp;dealing&nbsp;with&nbsp;floating&nbsp;point&nbsp;arithmetic.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;Keep&nbsp;an&nbsp;eye&nbsp;out&nbsp;for&nbsp;spurious&nbsp;errors.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;[&amp;&nbsp;edges]
065&nbsp;&nbsp;&nbsp;&nbsp;[&amp;&nbsp;edges]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[uvs&nbsp;(map&nbsp;unit-vector&nbsp;edges)]
066&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[uvs&nbsp;(map&nbsp;unit-vector&nbsp;edges)]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(=&nbsp;%&nbsp;(first&nbsp;uvs))
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(vertex=&nbsp;%&nbsp;(first&nbsp;uvs))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rest&nbsp;uvs))))
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rest&nbsp;uvs))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
074&nbsp;&nbsp;
070&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
075&nbsp;&nbsp;(defn&nbsp;collinear?
071&nbsp;&nbsp;(defn&nbsp;collinear?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;edges&nbsp;`e1`&nbsp;and&nbsp;`e2`&nbsp;are&nbsp;collinear&nbsp;with&nbsp;one&nbsp;another.&quot;
072&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;edges&nbsp;`e1`&nbsp;and&nbsp;`e2`&nbsp;are&nbsp;collinear&nbsp;with&nbsp;one&nbsp;another.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;[e1&nbsp;e2]
073&nbsp;&nbsp;&nbsp;&nbsp;[e1&nbsp;e2]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;(parallel?
074&nbsp;&nbsp;&nbsp;&nbsp;(parallel?
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e1
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e1
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e2
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e2
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:start&nbsp;(:start&nbsp;e1)&nbsp;:end&nbsp;(:start&nbsp;e2)}))
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(vertex=&nbsp;(:start&nbsp;e1)&nbsp;(:start&nbsp;e2))
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:start&nbsp;(:start&nbsp;e1)&nbsp;:end&nbsp;(:end&nbsp;e2)}
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:start&nbsp;(:start&nbsp;e1)&nbsp;:end&nbsp;(:start&nbsp;e2)})))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
082&nbsp;&nbsp;
080&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
081&nbsp;&nbsp;(defn&nbsp;collinear2d?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;the&nbsp;projections&nbsp;of&nbsp;edges&nbsp;`e1`,&nbsp;`e2`&nbsp;onto&nbsp;the&nbsp;x,&nbsp;y&nbsp;plane&nbsp;are
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;collinear.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;[e1&nbsp;e2]
</span><br/>
<span class="covered" title="15 out of 15 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;(collinear?&nbsp;{:start&nbsp;(ensure2d&nbsp;(:start&nbsp;e1))&nbsp;:end&nbsp;(ensure2d&nbsp;(:end&nbsp;e1))}
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:start&nbsp;(ensure2d&nbsp;(:start&nbsp;e2))&nbsp;:end&nbsp;(ensure2d&nbsp;(:end&nbsp;e2))}))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
087&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
088&nbsp;&nbsp;(defn&nbsp;minimaxd
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&quot;Apply&nbsp;function&nbsp;`f`&nbsp;to&nbsp;`coord`&nbsp;of&nbsp;the&nbsp;vertices&nbsp;at&nbsp;start&nbsp;and&nbsp;end&nbsp;of&nbsp;`edge`
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;return&nbsp;the&nbsp;result.&nbsp;Intended&nbsp;use&nbsp;case&nbsp;is&nbsp;`f`&nbsp;=&nbsp;`min`&nbsp;or&nbsp;`max`,&nbsp;`coord`
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;is&nbsp;`:x`,&nbsp;`:y`&nbsp;or&nbsp;`:z`.&nbsp;No&nbsp;checks&nbsp;are&nbsp;made&nbsp;for&nbsp;sane&nbsp;arguments.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;[edge&nbsp;coord&nbsp;f]
</span><br/>
<span class="covered" title="15 out of 15 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;f&nbsp;(list&nbsp;(coord&nbsp;(:start&nbsp;edge))&nbsp;(coord&nbsp;(:end&nbsp;edge)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
094&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
095&nbsp;&nbsp;(defn&nbsp;on?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;the&nbsp;vertex&nbsp;`v`&nbsp;is&nbsp;on&nbsp;the&nbsp;edge&nbsp;`e`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;[e&nbsp;v]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[p&nbsp;(ensure3d&nbsp;(:start&nbsp;e))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q&nbsp;(ensure3d&nbsp;v)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r&nbsp;(ensure3d&nbsp;(:end&nbsp;e))]
</span><br/>
<span class="partial" title="20 out of 25 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(collinear?&nbsp;(edge&nbsp;p&nbsp;q)&nbsp;(edge&nbsp;q&nbsp;r))
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;=&nbsp;(:x&nbsp;q)&nbsp;(max&nbsp;(:x&nbsp;p)&nbsp;(:x&nbsp;r)))
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;=&nbsp;(:x&nbsp;q)&nbsp;(min&nbsp;(:x&nbsp;p)&nbsp;(:x&nbsp;r)))
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;=&nbsp;(:y&nbsp;q)&nbsp;(max&nbsp;(:y&nbsp;p)&nbsp;(:y&nbsp;r)))
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;=&nbsp;(:y&nbsp;q)&nbsp;(min&nbsp;(:y&nbsp;p)&nbsp;(:y&nbsp;r)))
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;=&nbsp;(:z&nbsp;q)&nbsp;(max&nbsp;(:z&nbsp;p)&nbsp;(:z&nbsp;r)))
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;=&nbsp;(:z&nbsp;q)&nbsp;(min&nbsp;(:z&nbsp;p)&nbsp;(:z&nbsp;r))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
109&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
110&nbsp;&nbsp;(defn&nbsp;on2d?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;vertex&nbsp;`v`&nbsp;is&nbsp;on&nbsp;edge&nbsp;`e`&nbsp;when&nbsp;projected&nbsp;onto&nbsp;the&nbsp;x,&nbsp;y&nbsp;plane.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;[e&nbsp;v]
</span><br/>
<span class="covered" title="15 out of 15 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;(on?&nbsp;(edge&nbsp;(ensure2d&nbsp;(:start&nbsp;e))&nbsp;(ensure2d&nbsp;(:end&nbsp;e)))&nbsp;v))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
114&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
115&nbsp;&nbsp;(defn&nbsp;overlaps2d?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;the&nbsp;recangle&nbsp;in&nbsp;the&nbsp;x,y&nbsp;plane&nbsp;bisected&nbsp;by&nbsp;edge&nbsp;`e1`&nbsp;overlaps&nbsp;that
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;bisected&nbsp;by&nbsp;edge&nbsp;`e2`.&nbsp;It&nbsp;is&nbsp;an&nbsp;error&nbsp;if&nbsp;either&nbsp;`e1`&nbsp;or&nbsp;`e2`&nbsp;is&nbsp;not&nbsp;an&nbsp;edge.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;[e1&nbsp;e2]
</span><br/>
<span class="partial" title="11 out of 12 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;(when&nbsp;(and&nbsp;(edge?&nbsp;e1)&nbsp;(edge?&nbsp;e2))
</span><br/>
<span class="partial" title="11 out of 13 forms covered">
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;(minimaxd&nbsp;e1&nbsp;:x&nbsp;max)&nbsp;(minimaxd&nbsp;e2&nbsp;:x&nbsp;min))
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;&nbsp;(minimaxd&nbsp;e1&nbsp;:x&nbsp;min)&nbsp;(minimaxd&nbsp;e2&nbsp;:x&nbsp;max))
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;(minimaxd&nbsp;e1&nbsp;:y&nbsp;max)&nbsp;(minimaxd&nbsp;e2&nbsp;:y&nbsp;min))
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;&nbsp;(minimaxd&nbsp;e1&nbsp;:y&nbsp;min)&nbsp;(minimaxd&nbsp;e2&nbsp;:y&nbsp;max)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
125&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
126&nbsp;&nbsp;;;&nbsp;Don&#x27;t&nbsp;think&nbsp;I&nbsp;need&nbsp;this.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
127&nbsp;&nbsp;;;&nbsp;(defn&nbsp;orientation
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
128&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&quot;Determine&nbsp;whether&nbsp;the&nbsp;ordered&nbsp;sequence&nbsp;of&nbsp;vertices&nbsp;`p`,&nbsp;`q`&nbsp;and&nbsp;`r`&nbsp;run
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
129&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;clockwise,&nbsp;collinear&nbsp;or&nbsp;anticlockwise&nbsp;in&nbsp;the&nbsp;x,y&nbsp;plane.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
130&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;[p&nbsp;q&nbsp;r]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
131&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;(let&nbsp;[v&nbsp;(-&nbsp;(*&nbsp;(-&nbsp;(:y&nbsp;q)&nbsp;(:y&nbsp;p))&nbsp;(-&nbsp;(:x&nbsp;r)&nbsp;(:x&nbsp;q)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
132&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*&nbsp;(-&nbsp;(:x&nbsp;q)&nbsp;(:x&nbsp;p))&nbsp;(-&nbsp;(:y&nbsp;r)&nbsp;(:y&nbsp;q))))]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
133&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
134&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(zero?&nbsp;v)&nbsp;:collinear
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
135&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pos?&nbsp;v)&nbsp;:clockwise
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
136&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
137&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:anticlockwise)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
138&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
139&nbsp;&nbsp;(defn&nbsp;intersection2d
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
140&nbsp;&nbsp;&nbsp;&nbsp;&quot;The&nbsp;probability&nbsp;of&nbsp;two&nbsp;lines&nbsp;intersecting&nbsp;in&nbsp;3d&nbsp;space&nbsp;is&nbsp;low,&nbsp;and&nbsp;actually
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
141&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;is&nbsp;mostly&nbsp;not&nbsp;something&nbsp;we&#x27;re&nbsp;interested&nbsp;in.&nbsp;We&#x27;re&nbsp;interested&nbsp;in
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
142&nbsp;&nbsp;&nbsp;&nbsp;intersection&nbsp;in&nbsp;the&nbsp;`x,y`&nbsp;plane.&nbsp;This&nbsp;function&nbsp;returns&nbsp;a&nbsp;vertex&nbsp;representing
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
143&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;point&nbsp;vertically&nbsp;over&nbsp;the&nbsp;intersection&nbsp;of&nbsp;edges&nbsp;`e1`,&nbsp;`e2`&nbsp;in&nbsp;the&nbsp;`x,y`
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
144&nbsp;&nbsp;&nbsp;&nbsp;plane,&nbsp;whose&nbsp;`z`&nbsp;coordinate&nbsp;is
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
145&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
146&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;0&nbsp;if&nbsp;both&nbsp;edges&nbsp;are&nbsp;2d&nbsp;(i.e.&nbsp;have&nbsp;missing&nbsp;or&nbsp;zero&nbsp;`z`&nbsp;coordinates);
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
147&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;if&nbsp;one&nbsp;edge&nbsp;is&nbsp;2d,&nbsp;then&nbsp;the&nbsp;point&nbsp;on&nbsp;the&nbsp;other&nbsp;edge&nbsp;over&nbsp;the&nbsp;intersection;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
148&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;otherwise,&nbsp;the&nbsp;average&nbsp;of&nbsp;the&nbsp;z&nbsp;coordinates&nbsp;of&nbsp;the&nbsp;points&nbsp;on&nbsp;the&nbsp;two
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
149&nbsp;&nbsp;&nbsp;&nbsp;edges&nbsp;over&nbsp;the&nbsp;intersection.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
150&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
151&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;no&nbsp;such&nbsp;intersection&nbsp;exists,&nbsp;`nil`&nbsp;is&nbsp;returned.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
152&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
153&nbsp;&nbsp;&nbsp;&nbsp;It&nbsp;is&nbsp;an&nbsp;error,&nbsp;and&nbsp;an&nbsp;exception&nbsp;will&nbsp;be&nbsp;thrown,&nbsp;if&nbsp;either&nbsp;`e1`&nbsp;or&nbsp;`e2`&nbsp;is
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
154&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;an&nbsp;edge.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
155&nbsp;&nbsp;&nbsp;&nbsp;[e1&nbsp;e2]
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
156&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(and&nbsp;(edge?&nbsp;e1)&nbsp;(edge?&nbsp;e2))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
157&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
158&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(overlaps2d?&nbsp;e1&nbsp;e2)&nbsp;;;&nbsp;relatively&nbsp;cheap&nbsp;check
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
159&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
160&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(collinear2d?&nbsp;e1&nbsp;e2)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
161&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;any&nbsp;point&nbsp;within&nbsp;the&nbsp;overlap&nbsp;will&nbsp;do,&nbsp;but&nbsp;we&#x27;ll&nbsp;pick&nbsp;the&nbsp;end&nbsp;of&nbsp;e1
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
162&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;which&nbsp;is&nbsp;on&nbsp;e2
</span><br/>
<span class="partial" title="10 out of 13 forms covered">
163&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(on2d?&nbsp;e2&nbsp;(:start&nbsp;e1))&nbsp;(:start&nbsp;e1)&nbsp;(:end&nbsp;e1))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
164&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;blatantly&nbsp;stolen&nbsp;from
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
165&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;https:&#x2F;&#x2F;gist.github.com&#x2F;cassiel&#x2F;3e725b49670356a9b936
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
166&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[x1&nbsp;(:x&nbsp;(:start&nbsp;e1))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
167&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x2&nbsp;(:x&nbsp;(:end&nbsp;e1))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
168&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x3&nbsp;(:x&nbsp;(:start&nbsp;e2))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
169&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x4&nbsp;(:x&nbsp;(:end&nbsp;e2))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
170&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y1&nbsp;(:y&nbsp;(:start&nbsp;e1))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
171&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y2&nbsp;(:y&nbsp;(:end&nbsp;e1))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
172&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y3&nbsp;(:y&nbsp;(:start&nbsp;e2))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
173&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y4&nbsp;(:y&nbsp;(:end&nbsp;e2))
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
174&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;denom&nbsp;(-&nbsp;(*&nbsp;(-&nbsp;x1&nbsp;x2)&nbsp;(-&nbsp;y3&nbsp;y4))
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
175&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*&nbsp;(-&nbsp;y1&nbsp;y2)&nbsp;(-&nbsp;x3&nbsp;x4)))
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
176&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x1y2-y1x2&nbsp;(-&nbsp;(*&nbsp;x1&nbsp;y2)&nbsp;(*&nbsp;y1&nbsp;x2))
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
177&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x3y4-y3x4&nbsp;(-&nbsp;(*&nbsp;x3&nbsp;y4)&nbsp;(*&nbsp;y3&nbsp;x4))
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
178&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;px-num&nbsp;(-&nbsp;(*&nbsp;x1y2-y1x2&nbsp;(-&nbsp;x3&nbsp;x4))
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
179&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*&nbsp;(-&nbsp;x1&nbsp;x2)&nbsp;x3y4-y3x4))
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
180&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;py-num&nbsp;(-&nbsp;(*&nbsp;x1y2-y1x2&nbsp;(-&nbsp;y3&nbsp;y4))
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
181&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*&nbsp;(-&nbsp;y1&nbsp;y2)&nbsp;x3y4-y3x4))
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
182&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;(when-not&nbsp;(zero?&nbsp;denom)
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
183&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vertex&nbsp;(&#x2F;&nbsp;px-num&nbsp;denom)&nbsp;(&#x2F;&nbsp;py-num&nbsp;denom)))]
</span><br/>
<span class="partial" title="19 out of 20 forms covered">
184&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when&nbsp;(and&nbsp;result&nbsp;(on2d?&nbsp;e1&nbsp;result)&nbsp;(on2d?&nbsp;e2&nbsp;result))&nbsp;result))))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
185&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
186&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
187&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Both&nbsp;`e1`&nbsp;and&nbsp;`e2`&nbsp;must&nbsp;be&nbsp;edges.&quot;
</span><br/>
<span class="covered" title="16 out of 16 forms covered">
188&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;#(or&nbsp;(:kind&nbsp;%)&nbsp;(type&nbsp;%))&nbsp;[e1&nbsp;e2]))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
189&nbsp;&nbsp;
</span><br/>
</body>
</html>

View file

@ -11,70 +11,49 @@
002&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[clojure.math.combinatorics&nbsp;:as&nbsp;combo]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.math.numeric-tower&nbsp;:as&nbsp;m]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.edge&nbsp;:as&nbsp;e]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.path&nbsp;:refer&nbsp;[path?&nbsp;polygon-&gt;path]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.polygon&nbsp;:refer&nbsp;[polygon?]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.vertex&nbsp;:as&nbsp;v]))
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.math.numeric-tower&nbsp;:as&nbsp;m]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
008&nbsp;&nbsp;
004&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
009&nbsp;&nbsp;(defn&nbsp;on?
005&nbsp;&nbsp;(defn&nbsp;=ish
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;the&nbsp;vertex&nbsp;`v`&nbsp;is&nbsp;on&nbsp;the&nbsp;edge&nbsp;`e`.&quot;
006&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;numbers&nbsp;`n1`,&nbsp;`n2`&nbsp;are&nbsp;roughly&nbsp;equal;&nbsp;that&nbsp;is&nbsp;to&nbsp;say,&nbsp;equal&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;[e&nbsp;v]
007&nbsp;&nbsp;&nbsp;&nbsp;within&nbsp;`tolerance`&nbsp;(defaults&nbsp;to&nbsp;one&nbsp;part&nbsp;in&nbsp;a&nbsp;million).&quot;
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[p&nbsp;(v&#x2F;ensure3d&nbsp;(:start&nbsp;e))
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;([n1&nbsp;n2]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q&nbsp;(v&#x2F;ensure3d&nbsp;v)
<span class="covered" title="11 out of 11 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(and&nbsp;(number?&nbsp;n1)&nbsp;(number?&nbsp;n2))
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r&nbsp;(v&#x2F;ensure3d&nbsp;(:end&nbsp;e))]
<span class="covered" title="7 out of 7 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[m&nbsp;(m&#x2F;abs&nbsp;(min&nbsp;n1&nbsp;n2))
</span><br/>
<span class="not-covered" title="0 out of 25 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
<span class="covered" title="9 out of 9 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t&nbsp;(if&nbsp;(zero?&nbsp;m)&nbsp;0.000001&nbsp;(*&nbsp;0.000001&nbsp;m))]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(e&#x2F;collinear?&nbsp;p&nbsp;q&nbsp;r)
<span class="covered" title="5 out of 5 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=ish&nbsp;n1&nbsp;n2&nbsp;t))
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;=&nbsp;(:x&nbsp;q)&nbsp;(max&nbsp;(:x&nbsp;p)&nbsp;(:x&nbsp;r)))
<span class="covered" title="4 out of 4 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;n1&nbsp;n2)))
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;=&nbsp;(:x&nbsp;q)&nbsp;(min&nbsp;(:x&nbsp;p)&nbsp;(:x&nbsp;r)))
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;([n1&nbsp;n2&nbsp;tolerance]
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;=&nbsp;(:y&nbsp;q)&nbsp;(max&nbsp;(:y&nbsp;p)&nbsp;(:y&nbsp;r)))
<span class="covered" title="11 out of 11 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(and&nbsp;(number?&nbsp;n1)&nbsp;(number?&nbsp;n2))
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;=&nbsp;(:y&nbsp;q)&nbsp;(min&nbsp;(:y&nbsp;p)&nbsp;(:y&nbsp;r)))
<span class="covered" title="9 out of 9 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;&nbsp;(m&#x2F;abs&nbsp;(-&nbsp;n1&nbsp;n2))&nbsp;tolerance)
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;=&nbsp;(:z&nbsp;q)&nbsp;(max&nbsp;(:z&nbsp;p)&nbsp;(:z&nbsp;r)))
</span><br/>
<span class="not-covered" title="0 out of 12 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;=&nbsp;(:z&nbsp;q)&nbsp;(min&nbsp;(:z&nbsp;p)&nbsp;(:z&nbsp;r))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
023&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
024&nbsp;&nbsp;
<span class="covered" title="4 out of 4 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;n1&nbsp;n2))))
</span><br/>
</body>
</html>

View 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&nbsp;&nbsp;(ns&nbsp;walkmap.ocean
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Deal&nbsp;with&nbsp;(specifically,&nbsp;at&nbsp;this&nbsp;stage,&nbsp;cull)&nbsp;ocean&nbsp;areas&quot;)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
003&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
004&nbsp;&nbsp;(def&nbsp;^:dynamic&nbsp;*sea-level*
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&quot;The&nbsp;sea&nbsp;level&nbsp;on&nbsp;heightmaps&nbsp;we&#x27;re&nbsp;currently&nbsp;handling.&nbsp;If&nbsp;characters&nbsp;are&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;able&nbsp;to&nbsp;swin&nbsp;in&nbsp;the&nbsp;sea,&nbsp;we&nbsp;must&nbsp;model&nbsp;the&nbsp;sea&nbsp;bottom,&nbsp;so&nbsp;we&nbsp;need
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;heightmaps&nbsp;which&nbsp;cover&nbsp;at&nbsp;least&nbsp;the&nbsp;continental&nbsp;shelf.&nbsp;However,&nbsp;the&nbsp;sea
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;bottom&nbsp;is&nbsp;not&nbsp;walkable&nbsp;territory&nbsp;and&nbsp;can&nbsp;be&nbsp;culled&nbsp;from&nbsp;walkmaps.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
009&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;**Note**&nbsp;must&nbsp;be&nbsp;a&nbsp;floating&nbsp;point&nbsp;number.&nbsp;`(=&nbsp;0&nbsp;0.0)`&nbsp;returns&nbsp;`false`!&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;0.0)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
012&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
013&nbsp;&nbsp;(defn&nbsp;ocean?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&quot;Of&nbsp;a&nbsp;`facet`,&nbsp;is&nbsp;the&nbsp;altitude&nbsp;of&nbsp;every&nbsp;vertice&nbsp;equal&nbsp;to&nbsp;`*sea-level*`?&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;[facet]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;(every?
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(=&nbsp;%&nbsp;*sea-level*)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;:z&nbsp;(:vertices&nbsp;facet))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
019&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
020&nbsp;&nbsp;(defn&nbsp;cull-ocean-facets
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&quot;Ye&nbsp;cannae&nbsp;walk&nbsp;on&nbsp;water.&nbsp;Remove&nbsp;all&nbsp;facets&nbsp;from&nbsp;this&nbsp;`stl`&nbsp;structure&nbsp;which
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;are&nbsp;at&nbsp;sea&nbsp;level.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;[stl]
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;stl&nbsp;:facets&nbsp;(remove&nbsp;ocean?&nbsp;(:facets&nbsp;stl))))
</span><br/>
</body>
</html>

View file

@ -8,91 +8,235 @@
001&nbsp;&nbsp;(ns&nbsp;walkmap.path
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Essentially&nbsp;the&nbsp;specification&nbsp;for&nbsp;things&nbsp;we&nbsp;shall&nbsp;consider&nbsp;to&nbsp;be&nbsp;path.&quot;
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Essentially&nbsp;the&nbsp;specification&nbsp;for&nbsp;things&nbsp;we&nbsp;shall&nbsp;consider&nbsp;to&nbsp;be&nbsp;path.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[walkmap.polygon&nbsp;:refer&nbsp;[polygon?]]
003&nbsp;&nbsp;&nbsp;&nbsp;**Note&nbsp;that**&nbsp;for&nbsp;these&nbsp;purposes&nbsp;`path`&nbsp;means&nbsp;any&nbsp;continuous&nbsp;linear
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.vertex&nbsp;:refer&nbsp;[vertex?]]))
004&nbsp;&nbsp;&nbsp;&nbsp;feature,&nbsp;where&nbsp;such&nbsp;features&nbsp;specifically&nbsp;include&nbsp;watercourses.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[walkmap.edge&nbsp;:as&nbsp;e]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.polygon&nbsp;:refer&nbsp;[polygon?]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.vertex&nbsp;:refer&nbsp;[vertex?]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
005&nbsp;&nbsp;
008&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
006&nbsp;&nbsp;(defn&nbsp;path?
009&nbsp;&nbsp;(defn&nbsp;path?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;`o`&nbsp;satisfies&nbsp;the&nbsp;conditions&nbsp;for&nbsp;a&nbsp;path.&nbsp;A&nbsp;path&nbsp;shall&nbsp;be&nbsp;a&nbsp;map
010&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;`o`&nbsp;satisfies&nbsp;the&nbsp;conditions&nbsp;for&nbsp;a&nbsp;path.&nbsp;A&nbsp;path&nbsp;shall&nbsp;be&nbsp;a&nbsp;map
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;having&nbsp;the&nbsp;key&nbsp;`:nodes`,&nbsp;whose&nbsp;value&nbsp;shall&nbsp;be&nbsp;a&nbsp;sequence&nbsp;of&nbsp;vertices&nbsp;as
011&nbsp;&nbsp;&nbsp;&nbsp;having&nbsp;the&nbsp;key&nbsp;`:vertices`,&nbsp;whose&nbsp;value&nbsp;shall&nbsp;be&nbsp;a&nbsp;sequence&nbsp;of&nbsp;vertices&nbsp;as
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;defined&nbsp;in&nbsp;`walkmap.vertex`.&quot;
012&nbsp;&nbsp;&nbsp;&nbsp;defined&nbsp;in&nbsp;`walkmap.vertex`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;[o]
013&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;(let
014&nbsp;&nbsp;&nbsp;&nbsp;(let
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[v&nbsp;(:nodes&nbsp;o)]
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[v&nbsp;(:vertices&nbsp;o)]
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
<span class="not-covered" title="0 out of 22 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;v)
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;v)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;(count&nbsp;v)&nbsp;2)
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;(count&nbsp;v)&nbsp;2)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;vertex?&nbsp;v)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;vertex?&nbsp;v))))
020&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:id&nbsp;o)
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;(:kind&nbsp;o))&nbsp;(=&nbsp;(:kind&nbsp;o)&nbsp;:path)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
017&nbsp;&nbsp;
022&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
018&nbsp;&nbsp;(defn&nbsp;polygon-&gt;path
023&nbsp;&nbsp;(defn&nbsp;path
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;&quot;If&nbsp;`o`&nbsp;is&nbsp;a&nbsp;polygon,&nbsp;return&nbsp;an&nbsp;equivalent&nbsp;path.&nbsp;What&#x27;s&nbsp;different&nbsp;about
024&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;path&nbsp;constructed&nbsp;from&nbsp;these&nbsp;`vertices`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;path&nbsp;is&nbsp;that&nbsp;in&nbsp;polygons&nbsp;there&nbsp;is&nbsp;an&nbsp;implicit&nbsp;edge&nbsp;between&nbsp;the&nbsp;first
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;vertex&nbsp;and&nbsp;the&nbsp;last.&nbsp;In&nbsp;paths,&nbsp;there&nbsp;isn&#x27;t,&nbsp;so&nbsp;we&nbsp;need&nbsp;to&nbsp;add&nbsp;that
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;edge&nbsp;explicitly.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
023&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;`o`&nbsp;is&nbsp;not&nbsp;a&nbsp;polygon,&nbsp;will&nbsp;throw&nbsp;an&nbsp;exception.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;[o]
025&nbsp;&nbsp;&nbsp;&nbsp;[&amp;&nbsp;vertices]
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(polygon?&nbsp;o)
<span class="not-covered" title="0 out of 4 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;vertex?&nbsp;vertices)
</span><br/>
<span class="not-covered" title="0 out of 19 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;(dissoc&nbsp;o&nbsp;:vertices)&nbsp;:nodes&nbsp;(concat&nbsp;(:vertices&nbsp;o)&nbsp;(list&nbsp;(first&nbsp;(:vertices&nbsp;o)))))
<span class="not-covered" title="0 out of 11 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:vertices&nbsp;vertices&nbsp;:id&nbsp;(keyword&nbsp;(gensym&nbsp;&quot;path&quot;))&nbsp;:kind&nbsp;:path}
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(Exception.&nbsp;&quot;Not&nbsp;a&nbsp;polygon!&quot;))))
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;&quot;Each&nbsp;item&nbsp;on&nbsp;path&nbsp;must&nbsp;be&nbsp;a&nbsp;vertex.&quot;))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
030&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
031&nbsp;&nbsp;(defn&nbsp;polygon-&gt;path
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&quot;If&nbsp;`o`&nbsp;is&nbsp;a&nbsp;polygon,&nbsp;return&nbsp;an&nbsp;equivalent&nbsp;path.&nbsp;What&#x27;s&nbsp;different&nbsp;about
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;path&nbsp;is&nbsp;that&nbsp;in&nbsp;polygons&nbsp;there&nbsp;is&nbsp;an&nbsp;implicit&nbsp;edge&nbsp;between&nbsp;the&nbsp;first
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;vertex&nbsp;and&nbsp;the&nbsp;last.&nbsp;In&nbsp;paths,&nbsp;there&nbsp;isn&#x27;t,&nbsp;so&nbsp;we&nbsp;need&nbsp;to&nbsp;add&nbsp;that
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;edge&nbsp;explicitly.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
036&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;`o`&nbsp;is&nbsp;not&nbsp;a&nbsp;polygon,&nbsp;will&nbsp;throw&nbsp;an&nbsp;exception.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(polygon?&nbsp;o)
</span><br/>
<span class="not-covered" title="0 out of 21 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;(dissoc&nbsp;o&nbsp;:vertices)&nbsp;:kind&nbsp;:path&nbsp;:vertices&nbsp;(concat&nbsp;(:vertices&nbsp;o)&nbsp;(list&nbsp;(first&nbsp;(:vertices&nbsp;o)))))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;&quot;Not&nbsp;a&nbsp;polygon!&quot;))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
043&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
044&nbsp;&nbsp;(defn&nbsp;path-&gt;edges
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&quot;if&nbsp;`o`&nbsp;is&nbsp;a&nbsp;path,&nbsp;a&nbsp;polygon,&nbsp;or&nbsp;a&nbsp;sequence&nbsp;of&nbsp;vertices,&nbsp;return&nbsp;a&nbsp;sequence&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;edges&nbsp;representing&nbsp;that&nbsp;path,&nbsp;polygon&nbsp;or&nbsp;sequence.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
047&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;Throws&nbsp;`IllegalArgumentException`&nbsp;if&nbsp;`o`&nbsp;is&nbsp;not&nbsp;a&nbsp;path,&nbsp;a&nbsp;polygon,&nbsp;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;sequence&nbsp;of&nbsp;vertices.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;o)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vertex?&nbsp;(first&nbsp;o))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vertex?&nbsp;(first&nbsp;(rest&nbsp;o))))
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;TODO:&nbsp;think&nbsp;about:&nbsp;when&nbsp;constructing&nbsp;an&nbsp;edge&nbsp;from&nbsp;a&nbsp;path,&nbsp;should&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;constructed&nbsp;edge&nbsp;be&nbsp;tagged&nbsp;with&nbsp;the&nbsp;tags&nbsp;of&nbsp;the&nbsp;path?
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(e&#x2F;edge&nbsp;(first&nbsp;o)&nbsp;(rest&nbsp;o))
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path-&gt;edges&nbsp;(rest&nbsp;o))))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path?&nbsp;o)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path-&gt;edges&nbsp;(:vertices&nbsp;o))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Not&nbsp;a&nbsp;path&nbsp;or&nbsp;sequence&nbsp;of&nbsp;vertices!&quot;))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
067&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
068&nbsp;&nbsp;(defn&nbsp;length
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;the&nbsp;length&nbsp;of&nbsp;this&nbsp;path,&nbsp;in&nbsp;metres.&nbsp;**Note&nbsp;that**
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;This&nbsp;is&nbsp;not&nbsp;the&nbsp;same&nbsp;as&nbsp;the&nbsp;distance&nbsp;from&nbsp;the&nbsp;start&nbsp;to&nbsp;the&nbsp;end&nbsp;of&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;path,&nbsp;which,&nbsp;except&nbsp;for&nbsp;absolutely&nbsp;straight&nbsp;paths,&nbsp;will&nbsp;be&nbsp;shorter;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;It&nbsp;is&nbsp;not&nbsp;even&nbsp;quite&nbsp;the&nbsp;same&nbsp;as&nbsp;the&nbsp;length&nbsp;of&nbsp;the&nbsp;path&nbsp;*as&nbsp;rendered*,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;since&nbsp;paths&nbsp;will&nbsp;generally&nbsp;be&nbsp;rendered&nbsp;as&nbsp;spline&nbsp;curves.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;[path]
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path?&nbsp;path)
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(reduce&nbsp;+&nbsp;(map&nbsp;e&#x2F;length&nbsp;(path-&gt;edges&nbsp;path)))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;&quot;Not&nbsp;a&nbsp;path!&quot;))))
</span><br/>
</body>
</html>

View file

@ -31,29 +31,35 @@
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;[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&nbsp;&nbsp;&nbsp;&nbsp;(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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[v&nbsp;(:vertices&nbsp;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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;v)
<span class="covered" title="3 out of 3 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;(count&nbsp;v)&nbsp;2)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;vertex?&nbsp;v))))
<span class="covered" title="4 out of 4 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;vertex?&nbsp;v)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:id&nbsp;o)
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;(:kind&nbsp;o))&nbsp;(=&nbsp;(:kind&nbsp;o)&nbsp;:polygon)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
016&nbsp;&nbsp;
018&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
017&nbsp;&nbsp;
019&nbsp;&nbsp;
</span><br/>
</body>
</html>

View file

@ -26,361 +26,556 @@
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[taoensso.timbre&nbsp;:as&nbsp;l&nbsp;:refer&nbsp;[info&nbsp;error&nbsp;spy]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.polygon&nbsp;:refer&nbsp;[polygon?]])
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.edge&nbsp;:as&nbsp;e]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;(:import&nbsp;org.clojars.smee.binary.core.BinaryIO
009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.polygon&nbsp;:refer&nbsp;[polygon?]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;java.io.DataInput))
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.tag&nbsp;:refer&nbsp;[tag]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.vertex&nbsp;:as&nbsp;v])
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;(:import&nbsp;org.clojars.smee.binary.core.BinaryIO
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;java.io.DataInput))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
011&nbsp;&nbsp;
014&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
012&nbsp;&nbsp;(defn&nbsp;stl?
015&nbsp;&nbsp;(defn&nbsp;stl?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;`o`&nbsp;is&nbsp;recogniseable&nbsp;as&nbsp;an&nbsp;STL&nbsp;structure.&nbsp;An&nbsp;STL&nbsp;structure&nbsp;must
016&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;`o`&nbsp;is&nbsp;recogniseable&nbsp;as&nbsp;an&nbsp;STL&nbsp;structure.&nbsp;An&nbsp;STL&nbsp;structure&nbsp;must
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;have&nbsp;a&nbsp;key&nbsp;`:facets`,&nbsp;whose&nbsp;value&nbsp;must&nbsp;be&nbsp;a&nbsp;sequence&nbsp;of&nbsp;polygons;&nbsp;and
017&nbsp;&nbsp;&nbsp;&nbsp;have&nbsp;a&nbsp;key&nbsp;`:facets`,&nbsp;whose&nbsp;value&nbsp;must&nbsp;be&nbsp;a&nbsp;sequence&nbsp;of&nbsp;polygons;&nbsp;and
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;may&nbsp;have&nbsp;a&nbsp;key&nbsp;`:header`&nbsp;whose&nbsp;value&nbsp;should&nbsp;be&nbsp;a&nbsp;string,&nbsp;and&#x2F;or&nbsp;a&nbsp;key
018&nbsp;&nbsp;&nbsp;&nbsp;may&nbsp;have&nbsp;a&nbsp;key&nbsp;`:header`&nbsp;whose&nbsp;value&nbsp;should&nbsp;be&nbsp;a&nbsp;string,&nbsp;and&#x2F;or&nbsp;a&nbsp;key
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;`:count`,&nbsp;whose&nbsp;value&nbsp;should&nbsp;be&nbsp;a&nbsp;positive&nbsp;integer.
019&nbsp;&nbsp;&nbsp;&nbsp;`:count`,&nbsp;whose&nbsp;value&nbsp;should&nbsp;be&nbsp;a&nbsp;positive&nbsp;integer.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
017&nbsp;&nbsp;
020&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;`verify-count?`&nbsp;is&nbsp;passed&nbsp;and&nbsp;is&nbsp;not&nbsp;`false`,&nbsp;verify&nbsp;that&nbsp;the&nbsp;value&nbsp;of
021&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;`verify-count?`&nbsp;is&nbsp;passed&nbsp;and&nbsp;is&nbsp;not&nbsp;`false`,&nbsp;verify&nbsp;that&nbsp;the&nbsp;value&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;`:count`&nbsp;header&nbsp;is&nbsp;equal&nbsp;to&nbsp;the&nbsp;number&nbsp;of&nbsp;facets.&quot;
022&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;`:count`&nbsp;header&nbsp;is&nbsp;equal&nbsp;to&nbsp;the&nbsp;number&nbsp;of&nbsp;facets.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;([o]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(stl?&nbsp;o&nbsp;false))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;([o&nbsp;verify-count?]
</span><br/>
<span class="not-covered" title="0 out of 22 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;o)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;o)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;polygon?&nbsp;(:facets&nbsp;o))
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(:header&nbsp;o)&nbsp;(string?&nbsp;(:header&nbsp;o))&nbsp;true)
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(:count&nbsp;o)&nbsp;(integer?&nbsp;(:count&nbsp;o))&nbsp;true)
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;verify-count?&nbsp;(=&nbsp;(:count&nbsp;o)&nbsp;(count&nbsp;(:facets&nbsp;o)))&nbsp;true))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
030&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
031&nbsp;&nbsp;(def&nbsp;vect
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&quot;A&nbsp;codec&nbsp;for&nbsp;vectors&nbsp;within&nbsp;a&nbsp;binary&nbsp;STL&nbsp;file.&quot;
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;(b&#x2F;ordered-map
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:x&nbsp;:float-le
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:y&nbsp;:float-le
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:z&nbsp;:float-le))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
037&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
038&nbsp;&nbsp;(def&nbsp;facet
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&quot;A&nbsp;codec&nbsp;for&nbsp;a&nbsp;facet&nbsp;(triangle)&nbsp;within&nbsp;a&nbsp;binary&nbsp;STL&nbsp;file.&quot;
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;(b&#x2F;ordered-map
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:normal&nbsp;vect
023&nbsp;&nbsp;&nbsp;&nbsp;([o]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:vertices&nbsp;[vect&nbsp;vect&nbsp;vect]
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(stl?&nbsp;o&nbsp;false))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:abc&nbsp;:ushort-le))
025&nbsp;&nbsp;&nbsp;&nbsp;([o&nbsp;verify-count?]
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
044&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
045&nbsp;&nbsp;(def&nbsp;binary-stl
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&quot;A&nbsp;codec&nbsp;for&nbsp;binary&nbsp;STL&nbsp;files&quot;
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;(b&#x2F;ordered-map
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:header&nbsp;(b&#x2F;string&nbsp;&quot;ISO-8859-1&quot;&nbsp;:length&nbsp;80)&nbsp;;;&nbsp;for&nbsp;the&nbsp;time&nbsp;being&nbsp;we&nbsp;neither&nbsp;know&nbsp;nor&nbsp;care&nbsp;what&#x27;s&nbsp;in&nbsp;this.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:count&nbsp;:uint-le
<span class="partial" title="20 out of 26 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:facets&nbsp;(b&#x2F;repeated&nbsp;facet)))
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;o)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;o)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;polygon?&nbsp;(:facets&nbsp;o))
</span><br/>
<span class="partial" title="9 out of 10 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(:header&nbsp;o)&nbsp;(string?&nbsp;(:header&nbsp;o))&nbsp;true)
</span><br/>
<span class="partial" title="9 out of 10 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(:count&nbsp;o)&nbsp;(integer?&nbsp;(:count&nbsp;o))&nbsp;true)
</span><br/>
<span class="partial" title="14 out of 15 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;(:kind&nbsp;o))&nbsp;(=&nbsp;(:kind&nbsp;o)&nbsp;:stl))
</span><br/>
<span class="partial" title="1 out of 11 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;verify-count?&nbsp;(=&nbsp;(:count&nbsp;o)&nbsp;(count&nbsp;(:facets&nbsp;o)))&nbsp;true))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
051&nbsp;&nbsp;
034&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
052&nbsp;&nbsp;(defn&nbsp;decode-binary-stl
035&nbsp;&nbsp;(def&nbsp;vect
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&quot;Parse&nbsp;a&nbsp;binary&nbsp;STL&nbsp;file&nbsp;from&nbsp;this&nbsp;`filename`&nbsp;and&nbsp;return&nbsp;an&nbsp;STL&nbsp;structure
036&nbsp;&nbsp;&nbsp;&nbsp;&quot;A&nbsp;codec&nbsp;for&nbsp;vectors&nbsp;within&nbsp;a&nbsp;binary&nbsp;STL&nbsp;file.&quot;
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;(b&#x2F;ordered-map
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;representing&nbsp;its&nbsp;contents.
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:x&nbsp;:float-le
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:y&nbsp;:float-le
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:z&nbsp;:float-le))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
041&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
042&nbsp;&nbsp;(def&nbsp;facet
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&quot;A&nbsp;codec&nbsp;for&nbsp;a&nbsp;facet&nbsp;(triangle)&nbsp;within&nbsp;a&nbsp;binary&nbsp;STL&nbsp;file.&quot;
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;(b&#x2F;ordered-map
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:normal&nbsp;vect
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:vertices&nbsp;[vect&nbsp;vect&nbsp;vect]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:abc&nbsp;:ushort-le))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
048&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
049&nbsp;&nbsp;(def&nbsp;binary-stl
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&quot;A&nbsp;codec&nbsp;for&nbsp;binary&nbsp;STL&nbsp;files&quot;
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;(b&#x2F;ordered-map
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:header&nbsp;(b&#x2F;string&nbsp;&quot;ISO-8859-1&quot;&nbsp;:length&nbsp;80)&nbsp;;;&nbsp;for&nbsp;the&nbsp;time&nbsp;being&nbsp;we&nbsp;neither&nbsp;know&nbsp;nor&nbsp;care&nbsp;what&#x27;s&nbsp;in&nbsp;this.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:count&nbsp;:uint-le
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:facets&nbsp;(b&#x2F;repeated&nbsp;facet)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
055&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;**NOTE**&nbsp;that&nbsp;we&#x27;ve&nbsp;no&nbsp;way&nbsp;of&nbsp;verifying&nbsp;that&nbsp;the&nbsp;input&nbsp;file&nbsp;is&nbsp;binary&nbsp;STL
<span class="covered" title="1 out of 1 forms covered">
056&nbsp;&nbsp;(defn&nbsp;centre
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;data,&nbsp;if&nbsp;it&nbsp;is&nbsp;not&nbsp;this&nbsp;will&nbsp;run&nbsp;but&nbsp;will&nbsp;return&nbsp;garbage.&quot;
057&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;canonicalised&nbsp;`facet`&nbsp;(i.e.&nbsp;a&nbsp;triangular&nbsp;polygon)&nbsp;with&nbsp;an&nbsp;added
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;[filename]
058&nbsp;&nbsp;&nbsp;&nbsp;key&nbsp;`:centre`&nbsp;whose&nbsp;value&nbsp;represents&nbsp;the&nbsp;centre&nbsp;of&nbsp;this&nbsp;facet&nbsp;in&nbsp;3
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[in&nbsp;(io&#x2F;input-stream&nbsp;filename)]
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;dimensions.&nbsp;This&nbsp;only&nbsp;works&nbsp;for&nbsp;triangles,&nbsp;so&nbsp;is&nbsp;here&nbsp;not&nbsp;in
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(b&#x2F;decode&nbsp;binary-stl&nbsp;in)))
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;`walkmap.polygon`.&nbsp;It&nbsp;is&nbsp;an&nbsp;error&nbsp;(although&nbsp;no&nbsp;exception&nbsp;is&nbsp;currently
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
061&nbsp;&nbsp;
<span class="not-tracked" title="0 out of 0 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;thrown)&nbsp;if&nbsp;the&nbsp;object&nbsp;past&nbsp;is&nbsp;not&nbsp;a&nbsp;triangular&nbsp;polygon.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;[facet]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[vs&nbsp;(:vertices&nbsp;facet)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;v1&nbsp;(first&nbsp;vs)
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;opposite&nbsp;(e&#x2F;edge&nbsp;(nth&nbsp;vs&nbsp;1)&nbsp;(nth&nbsp;vs&nbsp;2))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oc&nbsp;(e&#x2F;centre&nbsp;opposite)]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;facet
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:centre
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
062&nbsp;&nbsp;(defn-&nbsp;vect-&gt;str&nbsp;[prefix&nbsp;v]
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(v&#x2F;vertex
</span><br/>
<span class="not-covered" title="0 out of 16 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;prefix&nbsp;&quot;&nbsp;&quot;&nbsp;(:x&nbsp;v)&nbsp;&quot;&nbsp;&quot;&nbsp;(:y&nbsp;v)&nbsp;&quot;&nbsp;&quot;&nbsp;(:z&nbsp;v)&nbsp;&quot;\n&quot;))
<span class="covered" title="16 out of 16 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(+&nbsp;(:x&nbsp;v1)&nbsp;(*&nbsp;(-&nbsp;(:x&nbsp;oc)&nbsp;(:x&nbsp;v1))&nbsp;2&#x2F;3))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
064&nbsp;&nbsp;
<span class="covered" title="16 out of 16 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(+&nbsp;(:y&nbsp;v1)&nbsp;(*&nbsp;(-&nbsp;(:y&nbsp;oc)&nbsp;(:y&nbsp;v1))&nbsp;2&#x2F;3))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
065&nbsp;&nbsp;(defn-&nbsp;facet2str&nbsp;[tri]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vect-&gt;str&nbsp;&quot;facet&nbsp;normal&quot;&nbsp;(:normal&nbsp;tri))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;outer&nbsp;loop\n&quot;
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;str
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(vect-&gt;str&nbsp;&quot;vertex&quot;&nbsp;%)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:vertices&nbsp;tri)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;endloop\nendfacet\n&quot;))
<span class="covered" title="16 out of 16 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(+&nbsp;(:z&nbsp;v1)&nbsp;(*&nbsp;(-&nbsp;(:z&nbsp;oc)&nbsp;(:z&nbsp;v1))&nbsp;2&#x2F;3))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
074&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
075&nbsp;&nbsp;(defn&nbsp;stl-&gt;ascii
075&nbsp;&nbsp;(defn&nbsp;canonicalise
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;as&nbsp;a&nbsp;string&nbsp;an&nbsp;ASCII&nbsp;rendering&nbsp;of&nbsp;the&nbsp;`stl`&nbsp;structure.&quot;
076&nbsp;&nbsp;&nbsp;&nbsp;&quot;Objects&nbsp;read&nbsp;in&nbsp;from&nbsp;STL&nbsp;won&#x27;t&nbsp;have&nbsp;all&nbsp;the&nbsp;keys&#x2F;values&nbsp;we&nbsp;need&nbsp;them&nbsp;to&nbsp;have.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;([stl]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(stl-&gt;ascii&nbsp;stl&nbsp;&quot;unknown&quot;))
077&nbsp;&nbsp;&nbsp;&nbsp;`o`&nbsp;may&nbsp;be&nbsp;a&nbsp;map&nbsp;(representing&nbsp;a&nbsp;facet&nbsp;or&nbsp;a&nbsp;vertex),&nbsp;or&nbsp;a&nbsp;sequence&nbsp;of&nbsp;such&nbsp;maps;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;([stl&nbsp;solidname]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str
078&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;it&nbsp;isn&#x27;t&nbsp;recognised&nbsp;it&nbsp;is&nbsp;at&nbsp;present&nbsp;just&nbsp;returned&nbsp;unchanged.&nbsp;`map-kind`,&nbsp;if
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;solid&nbsp;&quot;
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;solidname
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(s&#x2F;trim&nbsp;(:header&nbsp;stl))
079&nbsp;&nbsp;&nbsp;&nbsp;passed,&nbsp;must&nbsp;be&nbsp;a&nbsp;keyword&nbsp;indicating&nbsp;the&nbsp;value&nbsp;represented&nbsp;by&nbsp;the&nbsp;`z`&nbsp;axis
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;\n&quot;
080&nbsp;&nbsp;&nbsp;&nbsp;(defaults&nbsp;to&nbsp;`:height`).&nbsp;It&nbsp;is&nbsp;an&nbsp;error,&nbsp;and&nbsp;an&nbsp;exception&nbsp;will&nbsp;be&nbsp;thrown,&nbsp;if
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;`map-kind`&nbsp;is&nbsp;not&nbsp;a&nbsp;keyword.&quot;
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;([o]&nbsp;(canonicalise&nbsp;o&nbsp;:height))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;([o&nbsp;map-kind]
</span><br/>
<span class="partial" title="2 out of 3 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when-not
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(keyword?&nbsp;map-kind)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str
<span class="not-covered" title="0 out of 13 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(subs&nbsp;(str&nbsp;&quot;Must&nbsp;be&nbsp;a&nbsp;keyword:&nbsp;&quot;&nbsp;(or&nbsp;map-kind&nbsp;&quot;nil&quot;))&nbsp;0&nbsp;80))))
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
<span class="partial" title="4 out of 5 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;facet2str
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;stl)))
<span class="partial" title="19 out of 20 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(coll?&nbsp;o)&nbsp;(not&nbsp;(map?&nbsp;o)))&nbsp;(map&nbsp;#(canonicalise&nbsp;%&nbsp;map-kind)&nbsp;o)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;endsolid&nbsp;&quot;
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;if&nbsp;it&nbsp;has&nbsp;:facets&nbsp;it&#x27;s&nbsp;an&nbsp;STL&nbsp;structure,&nbsp;but&nbsp;it&nbsp;doesn&#x27;t&nbsp;yet&nbsp;conform&nbsp;to&nbsp;`stl?`
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;solidname
<span class="covered" title="10 out of 10 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;o)&nbsp;(assoc&nbsp;o
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;\n&quot;)))
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:kind&nbsp;:stl
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
093&nbsp;&nbsp;
<span class="partial" title="11 out of 12 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:id&nbsp;(or&nbsp;(:id&nbsp;o)&nbsp;(keyword&nbsp;(gensym&nbsp;&quot;stl&quot;)))
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:facets&nbsp;(canonicalise&nbsp;(:facets&nbsp;o)&nbsp;map-kind))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;if&nbsp;it&nbsp;has&nbsp;:vertices&nbsp;it&#x27;s&nbsp;a&nbsp;polygon,&nbsp;but&nbsp;it&nbsp;doesn&#x27;t&nbsp;yet&nbsp;conform&nbsp;to&nbsp;`polygon?`
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:vertices&nbsp;o)&nbsp;(centre
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(tag
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;o
</span><br/>
<span class="partial" title="11 out of 12 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:id&nbsp;(or&nbsp;(:id&nbsp;o)&nbsp;(keyword&nbsp;(gensym&nbsp;&quot;poly&quot;)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:kind&nbsp;:polygon
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:vertices&nbsp;(canonicalise&nbsp;(:vertices&nbsp;o)&nbsp;map-kind))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
094&nbsp;&nbsp;(defn&nbsp;write-ascii-stl
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:facet&nbsp;map-kind))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&quot;Write&nbsp;an&nbsp;`stl`&nbsp;structure&nbsp;as&nbsp;read&nbsp;by&nbsp;`decode-binary-stl`&nbsp;to&nbsp;this
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;if&nbsp;it&nbsp;has&nbsp;a&nbsp;value&nbsp;for&nbsp;:x&nbsp;it&#x27;s&nbsp;a&nbsp;vertex,&nbsp;but&nbsp;it&nbsp;doesn&#x27;t&nbsp;yet&nbsp;conform&nbsp;to&nbsp;`vertex?`
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:x&nbsp;o)&nbsp;(v&#x2F;canonicalise&nbsp;o)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;`filename`&nbsp;as&nbsp;ASCII&nbsp;encoded&nbsp;STL.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;([filename&nbsp;stl]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[b&nbsp;(fs&#x2F;base-name&nbsp;filename&nbsp;true)]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(write-ascii-stl
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filename&nbsp;stl
</span><br/>
<span class="not-covered" title="0 out of 15 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(subs&nbsp;b&nbsp;0&nbsp;(or&nbsp;(s&#x2F;index-of&nbsp;b&nbsp;&quot;.&quot;)&nbsp;(count&nbsp;b))))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;([filename&nbsp;stl&nbsp;solidname]
</span><br/>
<span class="not-covered" title="0 out of 16 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(l&#x2F;debug&nbsp;&quot;Solid&nbsp;name&nbsp;is&nbsp;&quot;&nbsp;solidname)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(spit
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;shouldn&#x27;t&nbsp;happen
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filename
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(stl-&gt;ascii&nbsp;stl&nbsp;solidname))))
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;o)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
107&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
108&nbsp;&nbsp;(defn&nbsp;binary-stl-to-ascii
108&nbsp;&nbsp;(defn&nbsp;decode-binary-stl
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&quot;Convert&nbsp;the&nbsp;binary&nbsp;STL&nbsp;file&nbsp;indicated&nbsp;by&nbsp;`in-filename`,&nbsp;and&nbsp;write&nbsp;it&nbsp;to
109&nbsp;&nbsp;&nbsp;&nbsp;&quot;Parse&nbsp;a&nbsp;binary&nbsp;STL&nbsp;file&nbsp;from&nbsp;this&nbsp;`filename`&nbsp;and&nbsp;return&nbsp;an&nbsp;STL&nbsp;structure
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;`out-filename`,&nbsp;if&nbsp;specified;&nbsp;otherwise,&nbsp;to&nbsp;a&nbsp;file&nbsp;with&nbsp;the&nbsp;same&nbsp;basename
110&nbsp;&nbsp;&nbsp;&nbsp;representing&nbsp;its&nbsp;contents.&nbsp;`map-kind`,&nbsp;if&nbsp;passed,&nbsp;must&nbsp;be&nbsp;a&nbsp;keyword
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;as&nbsp;`in-filename`&nbsp;but&nbsp;the&nbsp;extension&nbsp;`.ascii.stl`.&quot;
111&nbsp;&nbsp;&nbsp;&nbsp;indicating&nbsp;the&nbsp;value&nbsp;represented&nbsp;by&nbsp;the&nbsp;`z`&nbsp;axis&nbsp;(defaults&nbsp;to&nbsp;`:height`).
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;([in-filename]
112&nbsp;&nbsp;&nbsp;&nbsp;It&nbsp;is&nbsp;an&nbsp;error,&nbsp;and&nbsp;an&nbsp;exception&nbsp;will&nbsp;be&nbsp;thrown,&nbsp;if&nbsp;`map-kind`&nbsp;is&nbsp;not&nbsp;a
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;keyword.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
114&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;**NOTE**&nbsp;that&nbsp;we&#x27;ve&nbsp;no&nbsp;way&nbsp;of&nbsp;verifying&nbsp;that&nbsp;the&nbsp;input&nbsp;file&nbsp;is&nbsp;binary&nbsp;STL
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;data,&nbsp;if&nbsp;it&nbsp;is&nbsp;not&nbsp;this&nbsp;will&nbsp;run&nbsp;but&nbsp;will&nbsp;return&nbsp;garbage.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;([filename]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[[_&nbsp;ext]&nbsp;(fs&#x2F;split-ext&nbsp;in-filename)]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(binary-stl-to-ascii
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in-filename
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(subs
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in-filename
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(decode-binary-stl&nbsp;filename&nbsp;:height))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0
119&nbsp;&nbsp;&nbsp;&nbsp;([filename&nbsp;map-kind]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or
<span class="not-covered" title="0 out of 3 forms covered">
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when-not
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(keyword?&nbsp;map-kind)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(subs&nbsp;(str&nbsp;&quot;Must&nbsp;be&nbsp;a&nbsp;keyword:&nbsp;&quot;&nbsp;(or&nbsp;map-kind&nbsp;&quot;nil&quot;))&nbsp;0&nbsp;80))))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(s&#x2F;last-index-of&nbsp;in-filename&nbsp;&quot;.&quot;)
124&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[in&nbsp;(io&#x2F;input-stream&nbsp;filename)]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(count&nbsp;in-filename)))
<span class="not-covered" title="0 out of 7 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(canonicalise&nbsp;(b&#x2F;decode&nbsp;binary-stl&nbsp;in)&nbsp;map-kind))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;.ascii&quot;
<span class="blank" title="0 out of 0 forms covered">
126&nbsp;&nbsp;
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ext))))
<span class="covered" title="2 out of 2 forms covered">
127&nbsp;&nbsp;(defn-&nbsp;vect-&gt;str&nbsp;[prefix&nbsp;v]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;([in-filename&nbsp;out-filename]
<span class="not-covered" title="0 out of 16 forms covered">
128&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;prefix&nbsp;&quot;&nbsp;&quot;&nbsp;(:x&nbsp;v)&nbsp;&quot;&nbsp;&quot;&nbsp;(:y&nbsp;v)&nbsp;&quot;&nbsp;&quot;&nbsp;(:z&nbsp;v)&nbsp;&quot;\n&quot;))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
129&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
130&nbsp;&nbsp;(defn-&nbsp;facet2str&nbsp;[tri]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
131&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
126&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(write-ascii-stl&nbsp;out-filename&nbsp;(decode-binary-stl&nbsp;in-filename))))
132&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vect-&gt;str&nbsp;&quot;facet&nbsp;normal&quot;&nbsp;(:normal&nbsp;tri))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
133&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;outer&nbsp;loop\n&quot;
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
134&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;str
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
135&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
136&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(vect-&gt;str&nbsp;&quot;vertex&quot;&nbsp;%)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
137&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:vertices&nbsp;tri)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
138&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;endloop\nendfacet\n&quot;))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
139&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
140&nbsp;&nbsp;(defn&nbsp;stl-&gt;ascii
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
141&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;as&nbsp;a&nbsp;string&nbsp;an&nbsp;ASCII&nbsp;rendering&nbsp;of&nbsp;the&nbsp;`stl`&nbsp;structure.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
142&nbsp;&nbsp;&nbsp;&nbsp;([stl]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
143&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(stl-&gt;ascii&nbsp;stl&nbsp;&quot;unknown&quot;))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
144&nbsp;&nbsp;&nbsp;&nbsp;([stl&nbsp;solidname]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
145&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
146&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;solid&nbsp;&quot;
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
147&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;solidname
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(s&#x2F;trim&nbsp;(:header&nbsp;stl))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
149&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;\n&quot;
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
150&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
151&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
152&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
153&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;facet2str
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
154&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;stl)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;endsolid&nbsp;&quot;
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
156&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;solidname
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
157&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;\n&quot;)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
158&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
159&nbsp;&nbsp;(defn&nbsp;write-ascii-stl
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
160&nbsp;&nbsp;&nbsp;&nbsp;&quot;Write&nbsp;an&nbsp;`stl`&nbsp;structure&nbsp;as&nbsp;read&nbsp;by&nbsp;`decode-binary-stl`&nbsp;to&nbsp;this
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
161&nbsp;&nbsp;&nbsp;&nbsp;`filename`&nbsp;as&nbsp;ASCII&nbsp;encoded&nbsp;STL.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
162&nbsp;&nbsp;&nbsp;&nbsp;([filename&nbsp;stl]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
163&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[b&nbsp;(fs&#x2F;base-name&nbsp;filename&nbsp;true)]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
164&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(write-ascii-stl
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
165&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filename&nbsp;stl
</span><br/>
<span class="not-covered" title="0 out of 15 forms covered">
166&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(subs&nbsp;b&nbsp;0&nbsp;(or&nbsp;(s&#x2F;index-of&nbsp;b&nbsp;&quot;.&quot;)&nbsp;(count&nbsp;b))))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
167&nbsp;&nbsp;&nbsp;&nbsp;([filename&nbsp;stl&nbsp;solidname]
</span><br/>
<span class="not-covered" title="0 out of 16 forms covered">
168&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(l&#x2F;debug&nbsp;&quot;Solid&nbsp;name&nbsp;is&nbsp;&quot;&nbsp;solidname)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
169&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(spit
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
170&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filename
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
171&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(stl-&gt;ascii&nbsp;stl&nbsp;solidname))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
172&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
173&nbsp;&nbsp;(defn&nbsp;binary-stl-to-ascii
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
174&nbsp;&nbsp;&nbsp;&nbsp;&quot;Convert&nbsp;the&nbsp;binary&nbsp;STL&nbsp;file&nbsp;indicated&nbsp;by&nbsp;`in-filename`,&nbsp;and&nbsp;write&nbsp;it&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
175&nbsp;&nbsp;&nbsp;&nbsp;`out-filename`,&nbsp;if&nbsp;specified;&nbsp;otherwise,&nbsp;to&nbsp;a&nbsp;file&nbsp;with&nbsp;the&nbsp;same&nbsp;basename
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
176&nbsp;&nbsp;&nbsp;&nbsp;as&nbsp;`in-filename`&nbsp;but&nbsp;the&nbsp;extension&nbsp;`.ascii.stl`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
177&nbsp;&nbsp;&nbsp;&nbsp;([in-filename]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
178&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[[_&nbsp;ext]&nbsp;(fs&#x2F;split-ext&nbsp;in-filename)]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
179&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(binary-stl-to-ascii
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
180&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in-filename
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
181&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
182&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(subs
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
183&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in-filename
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
184&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
185&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
186&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(s&#x2F;last-index-of&nbsp;in-filename&nbsp;&quot;.&quot;)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
187&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(count&nbsp;in-filename)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
188&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;.ascii&quot;
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
189&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ext))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
190&nbsp;&nbsp;&nbsp;&nbsp;([in-filename&nbsp;out-filename]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
191&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(write-ascii-stl&nbsp;out-filename&nbsp;(decode-binary-stl&nbsp;in-filename))))
</span><br/>
</body>
</html>

View 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&nbsp;&nbsp;(ns&nbsp;walkmap.superstructure
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;single&nbsp;indexing&nbsp;structure&nbsp;for&nbsp;walkmap&nbsp;objects&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[walkmap.path&nbsp;:as&nbsp;p]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.polygon&nbsp;:as&nbsp;q]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.stl&nbsp;:as&nbsp;s]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.utils&nbsp;:as&nbsp;u]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.vertex&nbsp;:as&nbsp;v]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
008&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;;;&nbsp;TODO:&nbsp;Think&nbsp;about&nbsp;reification&#x2F;dereification.&nbsp;How&nbsp;can&nbsp;we&nbsp;cull&nbsp;a&nbsp;polygon,&nbsp;if
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;;;&nbsp;some&nbsp;vertices&nbsp;still&nbsp;index&nbsp;it?&nbsp;I&nbsp;*think*&nbsp;that&nbsp;what&#x27;s&nbsp;needed&nbsp;is&nbsp;that&nbsp;when
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;;;&nbsp;we&nbsp;store&nbsp;something&nbsp;in&nbsp;the&nbsp;superstructure,&nbsp;we&nbsp;replace&nbsp;all&nbsp;its&nbsp;vertices&nbsp;(and
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;;;&nbsp;other&nbsp;dependent&nbsp;structures,&nbsp;if&nbsp;any&nbsp;with&nbsp;their&nbsp;ids&nbsp;-&nbsp;as&nbsp;well&nbsp;as,&nbsp;obviously,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;;;&nbsp;adding&#x2F;merging&nbsp;those&nbsp;vertices&#x2F;dependent&nbsp;structures&nbsp;into&nbsp;the&nbsp;superstructure
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;;;&nbsp;as&nbsp;first&nbsp;class&nbsp;objects&nbsp;in&nbsp;themselves.&nbsp;That&nbsp;means,&nbsp;for&nbsp;each&nbsp;identified&nbsp;thing,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;;;&nbsp;the&nbsp;superstructure&nbsp;only&nbsp;contains&nbsp;one&nbsp;copy&nbsp;of&nbsp;it.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;;;&nbsp;The&nbsp;question&nbsp;then&nbsp;is,&nbsp;when&nbsp;we&nbsp;want&nbsp;to&nbsp;do&nbsp;things&nbsp;with&nbsp;those&nbsp;objects,&nbsp;do&nbsp;we
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;;;&nbsp;exteract&nbsp;a&nbsp;copy&nbsp;with&nbsp;its&nbsp;dependent&nbsp;structures&nbsp;fixed&nbsp;back&nbsp;up&nbsp;(reification),
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;;;&nbsp;or&nbsp;do&nbsp;we&nbsp;indirect&nbsp;through&nbsp;the&nbsp;superstructure&nbsp;every&nbsp;time&nbsp;we&nbsp;want&nbsp;to&nbsp;access
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;;;&nbsp;them?&nbsp;In&nbsp;a&nbsp;sense,&nbsp;the&nbsp;copy&nbsp;in&nbsp;the&nbsp;superstructure&nbsp;is&nbsp;the&nbsp;&#x27;one&nbsp;true&nbsp;copy&#x27;,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;;;&nbsp;but&nbsp;it&nbsp;may&nbsp;become&nbsp;very&nbsp;difficult&nbsp;then&nbsp;to&nbsp;have&nbsp;one&nbsp;true&nbsp;copy&nbsp;of&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;;;&nbsp;superstructure&nbsp;-&nbsp;unless&nbsp;we&nbsp;replace&nbsp;the&nbsp;superstructure&nbsp;altogether&nbsp;with&nbsp;a
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;;;&nbsp;database,&nbsp;which&nbsp;may&nbsp;be&nbsp;the&nbsp;Right&nbsp;Thing&nbsp;To&nbsp;Do.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
024&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
025&nbsp;&nbsp;(defn&nbsp;index-vertex
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;superstructure&nbsp;like&nbsp;`s`&nbsp;in&nbsp;which&nbsp;object&nbsp;`o`&nbsp;is&nbsp;indexed&nbsp;by&nbsp;vertex
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;`v`.&nbsp;It&nbsp;is&nbsp;an&nbsp;error&nbsp;(and&nbsp;an&nbsp;exception&nbsp;may&nbsp;be&nbsp;thrown)&nbsp;if
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
028&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;`s`&nbsp;is&nbsp;not&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;`o`&nbsp;is&nbsp;not&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;3.&nbsp;`o`&nbsp;does&nbsp;not&nbsp;have&nbsp;a&nbsp;value&nbsp;for&nbsp;the&nbsp;key&nbsp;`:id`;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;4.&nbsp;`v`&nbsp;is&nbsp;not&nbsp;a&nbsp;vertex.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;[s&nbsp;o&nbsp;v]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;(if-not&nbsp;(v&#x2F;vertex?&nbsp;o)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(:id&nbsp;o)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(v&#x2F;vertex?&nbsp;v)
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[vi&nbsp;(or&nbsp;(:vertex-index&nbsp;s)&nbsp;{})
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current&nbsp;(or&nbsp;(vi&nbsp;(:id&nbsp;v))&nbsp;{})]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;deep-merge&nbsp;doesn&#x27;t&nbsp;merge&nbsp;sets,&nbsp;only&nbsp;maps;&nbsp;so&nbsp;at&nbsp;this
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;stage&nbsp;we&nbsp;need&nbsp;to&nbsp;build&nbsp;a&nbsp;map.
</span><br/>
<span class="not-covered" title="0 out of 15 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;vi&nbsp;(:id&nbsp;v)&nbsp;(assoc&nbsp;current&nbsp;(:id&nbsp;o)&nbsp;(:id&nbsp;v))))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;&quot;Not&nbsp;a&nbsp;vertex:&nbsp;&quot;&nbsp;v)))
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;(subs&nbsp;(str&nbsp;&quot;No&nbsp;`:id`&nbsp;value:&nbsp;&quot;&nbsp;o)&nbsp;0&nbsp;80))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;it&nbsp;shouldn&#x27;t&nbsp;actually&nbsp;be&nbsp;an&nbsp;error&nbsp;to&nbsp;try&nbsp;to&nbsp;index&nbsp;a&nbsp;vertex,&nbsp;but&nbsp;it
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;also&nbsp;isn&#x27;t&nbsp;useful&nbsp;to&nbsp;do&nbsp;so,&nbsp;so&nbsp;I&#x27;d&nbsp;be&nbsp;inclined&nbsp;to&nbsp;ignore&nbsp;it.
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:vertex-index&nbsp;s)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
047&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
048&nbsp;&nbsp;(defn&nbsp;index-vertices
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;superstructure&nbsp;like&nbsp;`s`&nbsp;in&nbsp;which&nbsp;object&nbsp;`o`&nbsp;is&nbsp;indexed&nbsp;by&nbsp;its
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;vertices.&nbsp;It&nbsp;is&nbsp;an&nbsp;error&nbsp;(and&nbsp;an&nbsp;exception&nbsp;may&nbsp;be&nbsp;thrown)&nbsp;if
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
051&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;`s`&nbsp;is&nbsp;not&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;`o`&nbsp;is&nbsp;not&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;3.&nbsp;`o`&nbsp;does&nbsp;not&nbsp;have&nbsp;a&nbsp;value&nbsp;for&nbsp;the&nbsp;key&nbsp;`:id`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;[s&nbsp;o]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;(assoc
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:vertex-index
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(reduce
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u&#x2F;deep-merge
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(index-vertex&nbsp;s&nbsp;o&nbsp;%)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(u&#x2F;vertices&nbsp;o)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
064&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
065&nbsp;&nbsp;(defn&nbsp;add-to-superstructure
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;superstructure&nbsp;like&nbsp;`s`&nbsp;with&nbsp;object&nbsp;`o`&nbsp;added.&nbsp;If&nbsp;`o`&nbsp;is&nbsp;a&nbsp;collection,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;a&nbsp;superstructure&nbsp;like&nbsp;`s`&nbsp;with&nbsp;each&nbsp;element&nbsp;of&nbsp;`o`&nbsp;added.&nbsp;If&nbsp;only&nbsp;one
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;argument&nbsp;is&nbsp;supplied&nbsp;it&nbsp;will&nbsp;be&nbsp;assumed&nbsp;to&nbsp;represent&nbsp;`o`&nbsp;and&nbsp;a&nbsp;new
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;superstructure&nbsp;will&nbsp;be&nbsp;returned.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
070&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;It&nbsp;is&nbsp;an&nbsp;error&nbsp;(and&nbsp;an&nbsp;exception&nbsp;may&nbsp;be&nbsp;thrown)&nbsp;if
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
072&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;`s`&nbsp;is&nbsp;not&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;`o`&nbsp;is&nbsp;not&nbsp;a&nbsp;map,&nbsp;or&nbsp;a&nbsp;sequence&nbsp;of&nbsp;maps.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;([o]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(add-to-superstructure&nbsp;{}&nbsp;o))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;([s&nbsp;o]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 18 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;o)&nbsp;(let&nbsp;[o&#x27;&nbsp;(if&nbsp;(:id&nbsp;o)&nbsp;o&nbsp;(assoc&nbsp;o&nbsp;:id&nbsp;(keyword&nbsp;(gensym&nbsp;&quot;obj&quot;))))]
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(index-vertices&nbsp;(assoc&nbsp;s&nbsp;(:id&nbsp;o&#x27;)&nbsp;o&#x27;)&nbsp;o&#x27;))
</span><br/>
<span class="not-covered" title="0 out of 14 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;o)&nbsp;(reduce&nbsp;u&#x2F;deep-merge&nbsp;(map&nbsp;#(add-to-superstructure&nbsp;s&nbsp;%)&nbsp;o))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(nil?&nbsp;o)&nbsp;o
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;(str&nbsp;&quot;Don&#x27;t&nbsp;know&nbsp;how&nbsp;to&nbsp;index&nbsp;&quot;&nbsp;(or&nbsp;(type&nbsp;o)&nbsp;&quot;nil&quot;)))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
085&nbsp;&nbsp;
</span><br/>
</body>
</html>

View file

@ -20,139 +20,313 @@
005&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[clojure.string&nbsp;:as&nbsp;s]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[taoensso.timbre&nbsp;:as&nbsp;l&nbsp;:refer&nbsp;[info&nbsp;error&nbsp;spy]]
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[dali.io&nbsp;:as&nbsp;neatly-folded-clock]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.polygon&nbsp;:refer&nbsp;[polygon?]]
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[hiccup.core&nbsp;:refer&nbsp;[html]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.vertex&nbsp;:refer&nbsp;[vertex?]]))
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[taoensso.timbre&nbsp;:as&nbsp;l&nbsp;:refer&nbsp;[info&nbsp;error&nbsp;spy]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.ocean&nbsp;:refer&nbsp;[cull-ocean-facets]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.polygon&nbsp;:refer&nbsp;[polygon?]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.stl&nbsp;:refer&nbsp;[decode-binary-stl]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.vertex&nbsp;:refer&nbsp;[vertex?]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
009&nbsp;&nbsp;
013&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
010&nbsp;&nbsp;(defn-&nbsp;facet-&gt;svg-poly
014&nbsp;&nbsp;(def&nbsp;^:dynamic&nbsp;*preferred-svg-render*
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;[facet]
015&nbsp;&nbsp;&nbsp;&nbsp;&quot;Mainly&nbsp;for&nbsp;debugging&nbsp;dali;&nbsp;switch&nbsp;SVG&nbsp;renderer&nbsp;to&nbsp;use.&nbsp;Expected&nbsp;values:
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;[:polygon
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;`:dali`,&nbsp;`:hiccup`.&quot;
</span><br/>
<span class="not-covered" title="0 out of 20 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:points&nbsp;(s&#x2F;join&nbsp;&quot;&nbsp;&quot;&nbsp;(map&nbsp;#(str&nbsp;(:x&nbsp;%)&nbsp;&quot;,&quot;&nbsp;(:y&nbsp;%))&nbsp;(:vertices&nbsp;facet)))}])
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;:dali)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
014&nbsp;&nbsp;
018&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
019&nbsp;&nbsp;(defn-&nbsp;facet-&gt;svg-poly
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;[facet]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;[:polygon
</span><br/>
<span class="not-covered" title="0 out of 20 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:points&nbsp;(s&#x2F;join&nbsp;&quot;&nbsp;&quot;&nbsp;(map&nbsp;#(str&nbsp;(:x&nbsp;%)&nbsp;&quot;,&quot;&nbsp;(:y&nbsp;%))&nbsp;(:vertices&nbsp;facet)))}])
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
023&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
024&nbsp;&nbsp;(defn-&nbsp;dali-facet-&gt;svg-poly
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;[facet]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;(vec
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:polygon
</span><br/>
<span class="not-covered" title="0 out of 16 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;#(vec&nbsp;(list&nbsp;(:x&nbsp;%)&nbsp;(:y&nbsp;%)))&nbsp;(:vertices&nbsp;facet)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
030&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
015&nbsp;&nbsp;(defn&nbsp;stl-&gt;svg
031&nbsp;&nbsp;(defn&nbsp;dali-stl-&gt;svg
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&quot;Convert&nbsp;this&nbsp;in-memory&nbsp;`stl`&nbsp;structure,&nbsp;as&nbsp;read&nbsp;by&nbsp;`decode-binary-stl`,&nbsp;into
032&nbsp;&nbsp;&nbsp;&nbsp;&quot;Format&nbsp;this&nbsp;`stl`&nbsp;as&nbsp;SVG&nbsp;for&nbsp;the&nbsp;`dali`&nbsp;renderer&nbsp;on&nbsp;a&nbsp;page&nbsp;with&nbsp;these
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;an&nbsp;in-memory&nbsp;hiccup&nbsp;representation&nbsp;of&nbsp;SVG&nbsp;structure,&nbsp;and&nbsp;return&nbsp;it.&quot;
033&nbsp;&nbsp;&nbsp;&nbsp;bounds.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;[stl]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[minx&nbsp;(reduce
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(reduce&nbsp;min&nbsp;(map&nbsp;:x&nbsp;(:vertices&nbsp;%)))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;stl)))
034&nbsp;&nbsp;&nbsp;&nbsp;[stl&nbsp;minx&nbsp;maxx&nbsp;miny&nbsp;maxy]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxx&nbsp;(reduce
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(reduce&nbsp;max&nbsp;(map&nbsp;:x&nbsp;(:vertices&nbsp;%)))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;stl)))
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;miny&nbsp;(reduce
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(reduce&nbsp;min&nbsp;(map&nbsp;:y&nbsp;(:vertices&nbsp;%)))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;stl)))
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxy&nbsp;(reduce
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(reduce&nbsp;max&nbsp;(map&nbsp;:y&nbsp;(:vertices&nbsp;%)))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;stl)))]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:svg
035&nbsp;&nbsp;&nbsp;&nbsp;[:dali&#x2F;page
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:xmlns&nbsp;&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot;
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:xmlns&nbsp;&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:version&nbsp;&quot;1.2&quot;
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:version&nbsp;&quot;1.2&quot;
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:width&nbsp;(-&nbsp;maxx&nbsp;minx)
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:width&nbsp;(-&nbsp;maxx&nbsp;minx)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:height&nbsp;(-&nbsp;maxy&nbsp;miny)
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:height&nbsp;(-&nbsp;maxy&nbsp;miny)
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:viewBox&nbsp;(s&#x2F;join&nbsp;&quot;&nbsp;&quot;&nbsp;(map&nbsp;str&nbsp;[minx&nbsp;miny&nbsp;maxx&nbsp;maxy]))}
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:viewBox&nbsp;(s&#x2F;join&nbsp;&quot;&nbsp;&quot;&nbsp;(map&nbsp;str&nbsp;[minx&nbsp;miny&nbsp;maxx&nbsp;maxy]))}
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vec
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vec
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:g
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:g
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;facet-&gt;svg-poly
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dali-facet-&gt;svg-poly
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;stl))))]))
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;stl))))])
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
047&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
048&nbsp;&nbsp;(defn&nbsp;hiccup-stl-&gt;svg
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&quot;Format&nbsp;this&nbsp;`stl`&nbsp;as&nbsp;SVG&nbsp;for&nbsp;the&nbsp;`hiccup`&nbsp;renderer&nbsp;on&nbsp;a&nbsp;page&nbsp;with&nbsp;these
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;bounds.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;[stl&nbsp;minx&nbsp;maxx&nbsp;miny&nbsp;maxy]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;[:svg
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:xmlns&nbsp;&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:version&nbsp;&quot;1.2&quot;
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:width&nbsp;(-&nbsp;maxx&nbsp;minx)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:height&nbsp;(-&nbsp;maxy&nbsp;miny)
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:viewBox&nbsp;(s&#x2F;join&nbsp;&quot;&nbsp;&quot;&nbsp;(map&nbsp;str&nbsp;[minx&nbsp;miny&nbsp;maxx&nbsp;maxy]))}
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vec
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:g
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;facet-&gt;svg-poly
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;stl))))])
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
064&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
065&nbsp;&nbsp;(defn&nbsp;stl-&gt;svg
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&quot;Convert&nbsp;this&nbsp;in-memory&nbsp;`stl`&nbsp;structure,&nbsp;as&nbsp;read&nbsp;by&nbsp;`decode-binary-stl`,&nbsp;into
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;an&nbsp;in-memory&nbsp;hiccup&nbsp;representation&nbsp;of&nbsp;SVG&nbsp;structure,&nbsp;and&nbsp;return&nbsp;it.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;[stl]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[minx&nbsp;(reduce
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(reduce&nbsp;min&nbsp;(map&nbsp;:x&nbsp;(:vertices&nbsp;%)))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;stl)))
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxx&nbsp;(reduce
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(reduce&nbsp;max&nbsp;(map&nbsp;:x&nbsp;(:vertices&nbsp;%)))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;stl)))
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;miny&nbsp;(reduce
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(reduce&nbsp;min&nbsp;(map&nbsp;:y&nbsp;(:vertices&nbsp;%)))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;stl)))
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxy&nbsp;(reduce
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(reduce&nbsp;max&nbsp;(map&nbsp;:y&nbsp;(:vertices&nbsp;%)))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;stl)))]
</span><br/>
<span class="not-covered" title="0 out of 17 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(l&#x2F;info&nbsp;&quot;Generating&nbsp;SVG&nbsp;for&nbsp;&quot;&nbsp;*preferred-svg-render*&nbsp;&quot;&nbsp;renderer&quot;)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;*preferred-svg-render*
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:hiccup&nbsp;(hiccup-stl-&gt;svg&nbsp;stl&nbsp;minx&nbsp;maxx&nbsp;miny&nbsp;maxy)
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:dali&nbsp;(dali-stl-&gt;svg&nbsp;stl&nbsp;minx&nbsp;maxx&nbsp;miny&nbsp;maxy)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(Exception.&nbsp;&quot;Unexpected&nbsp;renderer&nbsp;value:&nbsp;&quot;&nbsp;*preferred-svg-render*)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
094&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
095&nbsp;&nbsp;(defn&nbsp;binary-stl-file-&gt;svg
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&quot;Given&nbsp;only&nbsp;an&nbsp;`in-filename`,&nbsp;parse&nbsp;the&nbsp;indicated&nbsp;file,&nbsp;expected&nbsp;to&nbsp;be
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;binary&nbsp;STL,&nbsp;and&nbsp;return&nbsp;an&nbsp;equivalent&nbsp;SVG&nbsp;structure.&nbsp;Given&nbsp;both&nbsp;`in-filename`
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;`out-filename`,&nbsp;as&nbsp;side-effect&nbsp;write&nbsp;the&nbsp;SVG&nbsp;to&nbsp;the&nbsp;indicated&nbsp;output&nbsp;file.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;([in-filename]
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(stl-&gt;svg&nbsp;(cull-ocean-facets&nbsp;(decode-binary-stl&nbsp;in-filename))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;([in-filename&nbsp;out-filename]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[s&nbsp;(binary-stl-file-&gt;svg&nbsp;in-filename)]
</span><br/>
<span class="not-covered" title="0 out of 17 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(l&#x2F;info&nbsp;&quot;Emitting&nbsp;SVG&nbsp;with&nbsp;&quot;&nbsp;*preferred-svg-render*&nbsp;&quot;&nbsp;renderer&quot;)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;*preferred-svg-render*
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:dali&nbsp;(neatly-folded-clock&#x2F;render-svg&nbsp;s&nbsp;out-filename)
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:hiccup&nbsp;(spit&nbsp;out-filename&nbsp;(html&nbsp;s))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(Exception.&nbsp;&quot;Unexpected&nbsp;renderer&nbsp;value:&nbsp;&quot;&nbsp;*preferred-svg-render*)))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s)))
</span><br/>
</body>
</html>

View 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&nbsp;&nbsp;(ns&nbsp;walkmap.tag
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Code&nbsp;for&nbsp;tagging,&nbsp;untagging,&nbsp;and&nbsp;finding&nbsp;tags&nbsp;on&nbsp;objects.&nbsp;Note&nbsp;the&nbsp;use&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;namespaced&nbsp;keyword,&nbsp;`:walkmap.tag&#x2F;tags`,&nbsp;denoted&nbsp;in&nbsp;this&nbsp;file&nbsp;`::tags`.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;This&nbsp;is&nbsp;in&nbsp;an&nbsp;attempt&nbsp;to&nbsp;avoid&nbsp;name&nbsp;clashes&nbsp;with&nbsp;other&nbsp;uses&nbsp;of&nbsp;this&nbsp;key.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[clojure.set&nbsp;:refer&nbsp;[difference&nbsp;union]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
006&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
007&nbsp;&nbsp;(defn&nbsp;tagged?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;this&nbsp;`object`&nbsp;is&nbsp;tagged&nbsp;with&nbsp;each&nbsp;of&nbsp;these&nbsp;`tags`.&nbsp;It&nbsp;is&nbsp;an&nbsp;error
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;an&nbsp;exception&nbsp;will&nbsp;be&nbsp;thrown)&nbsp;if
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
010&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;`object`&nbsp;is&nbsp;not&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;any&nbsp;of&nbsp;`tags`&nbsp;is&nbsp;not&nbsp;a&nbsp;keyword.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;[object&nbsp;&amp;&nbsp;tags]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;object)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;keyword?&nbsp;tags)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[ot&nbsp;(::tags&nbsp;object)]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(set?&nbsp;ot)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;ot&nbsp;tags)))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;Must&nbsp;be&nbsp;keyword(s):&nbsp;&quot;&nbsp;(map&nbsp;type&nbsp;tags)))))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;Must&nbsp;be&nbsp;a&nbsp;map:&nbsp;&quot;&nbsp;(type&nbsp;object))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
026&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
027&nbsp;&nbsp;(defn&nbsp;tag
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;an&nbsp;object&nbsp;like&nbsp;this&nbsp;`object`&nbsp;but&nbsp;with&nbsp;these&nbsp;`tags`&nbsp;added&nbsp;to&nbsp;its&nbsp;tags,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;they&nbsp;are&nbsp;not&nbsp;already&nbsp;present.&nbsp;It&nbsp;is&nbsp;an&nbsp;error&nbsp;(and&nbsp;an&nbsp;exception&nbsp;will&nbsp;be
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;thrown)&nbsp;if
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
031&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;`object`&nbsp;is&nbsp;not&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;any&nbsp;of&nbsp;`tags`&nbsp;is&nbsp;not&nbsp;a&nbsp;keyword.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;[object&nbsp;&amp;&nbsp;tags]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;object)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;keyword?&nbsp;tags)
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;object&nbsp;::tags&nbsp;(union&nbsp;(set&nbsp;tags)&nbsp;(::tags&nbsp;object)))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;Must&nbsp;be&nbsp;keyword(s):&nbsp;&quot;&nbsp;(map&nbsp;type&nbsp;tags)))))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;Must&nbsp;be&nbsp;a&nbsp;map:&nbsp;&quot;&nbsp;(type&nbsp;object))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
044&nbsp;&nbsp;
</span><br/>
<span class="covered" title="15 out of 15 forms covered">
045&nbsp;&nbsp;(defmacro&nbsp;tags
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;the&nbsp;tags&nbsp;of&nbsp;this&nbsp;object,&nbsp;if&nbsp;any.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;[object]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;`(::tags&nbsp;~object))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
049&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
050&nbsp;&nbsp;(defn&nbsp;untag
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;an&nbsp;object&nbsp;like&nbsp;this&nbsp;`object`&nbsp;but&nbsp;with&nbsp;these&nbsp;`tags`&nbsp;removed&nbsp;from&nbsp;its
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;tags,&nbsp;if&nbsp;present.&nbsp;It&nbsp;is&nbsp;an&nbsp;error&nbsp;(and&nbsp;an&nbsp;exception&nbsp;will&nbsp;be&nbsp;thrown)&nbsp;if
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
053&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;`object`&nbsp;is&nbsp;not&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;any&nbsp;of&nbsp;`tags`&nbsp;is&nbsp;not&nbsp;a&nbsp;keyword.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;[object&nbsp;&amp;&nbsp;tags]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;object)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;keyword?&nbsp;tags)
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;object&nbsp;::tags&nbsp;(difference&nbsp;(::tags&nbsp;object)&nbsp;(set&nbsp;tags)))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;Must&nbsp;be&nbsp;keywords:&nbsp;&quot;&nbsp;(map&nbsp;type&nbsp;tags)))))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;Must&nbsp;be&nbsp;a&nbsp;map:&nbsp;&quot;&nbsp;(type&nbsp;object))))))
</span><br/>
</body>
</html>

View 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&nbsp;&nbsp;(ns&nbsp;walkmap.utils
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Miscellaneous&nbsp;utility&nbsp;functions.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[clojure.math.numeric-tower&nbsp;:as&nbsp;m]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.path&nbsp;:as&nbsp;p]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.polygon&nbsp;:as&nbsp;q]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.vertex&nbsp;:as&nbsp;v]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
007&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
008&nbsp;&nbsp;(defn&nbsp;deep-merge
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;&quot;Recursively&nbsp;merges&nbsp;maps.&nbsp;If&nbsp;vals&nbsp;are&nbsp;not&nbsp;maps,&nbsp;the&nbsp;last&nbsp;value&nbsp;wins.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;TODO:&nbsp;not&nbsp;my&nbsp;implementation,&nbsp;not&nbsp;sure&nbsp;I&nbsp;entirely&nbsp;trust&nbsp;it.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;[&amp;&nbsp;vals]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(every?&nbsp;map?&nbsp;vals)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;merge-with&nbsp;deep-merge&nbsp;vals)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(last&nbsp;vals)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
015&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
016&nbsp;&nbsp;(defn&nbsp;vertices
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&quot;If&nbsp;`o`&nbsp;is&nbsp;an&nbsp;object&nbsp;with&nbsp;vertices,&nbsp;return&nbsp;those&nbsp;vertices,&nbsp;else&nbsp;nil.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(v&#x2F;vertex?&nbsp;o)&nbsp;(list&nbsp;o)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(q&#x2F;polygon?&nbsp;o)&nbsp;(:vertices&nbsp;o)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(p&#x2F;path?&nbsp;o)&nbsp;(:vertices&nbsp;o)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
023&nbsp;&nbsp;
</span><br/>
</body>
</html>

View file

@ -8,130 +8,343 @@
001&nbsp;&nbsp;(ns&nbsp;walkmap.vertex
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Essentially&nbsp;the&nbsp;specification&nbsp;for&nbsp;things&nbsp;we&nbsp;shall&nbsp;consider&nbsp;to&nbsp;be&nbsp;vertices.&quot;)
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Essentially&nbsp;the&nbsp;specification&nbsp;for&nbsp;things&nbsp;we&nbsp;shall&nbsp;consider&nbsp;to&nbsp;be&nbsp;vertices.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
003&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
004&nbsp;&nbsp;(defn&nbsp;vertex?
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;Note&nbsp;that&nbsp;there&#x27;s&nbsp;no&nbsp;`distance`&nbsp;function&nbsp;here;&nbsp;to&nbsp;find&nbsp;the&nbsp;distance&nbsp;between
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;`o`&nbsp;satisfies&nbsp;the&nbsp;conditions&nbsp;for&nbsp;a&nbsp;vertex.&nbsp;That&nbsp;is,&nbsp;essentially,
005&nbsp;&nbsp;&nbsp;&nbsp;two&nbsp;vertices,&nbsp;create&nbsp;an&nbsp;edge&nbsp;from&nbsp;them&nbsp;and&nbsp;use&nbsp;`walkmap.edge&#x2F;length`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;it&nbsp;must&nbsp;rerpresent&nbsp;a&nbsp;two-&nbsp;or&nbsp;three-&nbsp;dimensional&nbsp;vector.&nbsp;A&nbsp;vertex&nbsp;is
006&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[clojure.math.numeric-tower&nbsp;:as&nbsp;m]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;shall&nbsp;be&nbsp;a&nbsp;map&nbsp;having&nbsp;at&nbsp;least&nbsp;the&nbsp;keys&nbsp;`:x`&nbsp;and&nbsp;`:y`,&nbsp;where&nbsp;the&nbsp;value&nbsp;of
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.string&nbsp;:as&nbsp;s]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;those&nbsp;keys&nbsp;is&nbsp;a&nbsp;number.&nbsp;If&nbsp;the&nbsp;key&nbsp;`:z`&nbsp;is&nbsp;also&nbsp;present,&nbsp;its&nbsp;value&nbsp;must&nbsp;also
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;a&nbsp;number.
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.geometry&nbsp;:refer&nbsp;[=ish]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
010&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;name&nbsp;&nbsp;`vector?`&nbsp;was&nbsp;not&nbsp;used&nbsp;as&nbsp;that&nbsp;would&nbsp;clash&nbsp;with&nbsp;a&nbsp;function&nbsp;of&nbsp;that
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;in&nbsp;`clojure.core`&nbsp;whose&nbsp;semantics&nbsp;are&nbsp;entirely&nbsp;different.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="partial" title="15 out of 17 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;o)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:x&nbsp;o))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:y&nbsp;o))
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;(:z&nbsp;o))&nbsp;(number?&nbsp;(:z&nbsp;o)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
019&nbsp;&nbsp;
009&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
020&nbsp;&nbsp;(def&nbsp;ensure3d
010&nbsp;&nbsp;(defn&nbsp;vertex-key
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&quot;Given&nbsp;a&nbsp;vertex&nbsp;`o`,&nbsp;if&nbsp;`o`&nbsp;has&nbsp;a&nbsp;`:z`&nbsp;value,&nbsp;just&nbsp;return&nbsp;`o`;&nbsp;otherwise
011&nbsp;&nbsp;&nbsp;&nbsp;&quot;Making&nbsp;sure&nbsp;we&nbsp;get&nbsp;the&nbsp;same&nbsp;key&nbsp;everytime&nbsp;we&nbsp;key&nbsp;a&nbsp;vertex&nbsp;with&nbsp;the&nbsp;same
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;a&nbsp;vertex&nbsp;like&nbsp;`o`&nbsp;but&nbsp;having&nbsp;thie&nbsp;`dflt`&nbsp;value&nbsp;as&nbsp;the&nbsp;value&nbsp;of&nbsp;its
012&nbsp;&nbsp;&nbsp;&nbsp;coordinates.&nbsp;`o`&nbsp;must&nbsp;have&nbsp;numeric&nbsp;values&nbsp;for&nbsp;`:x`,&nbsp;`:y`,&nbsp;and&nbsp;optionally
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;`:z`&nbsp;key,&nbsp;or&nbsp;zero&nbsp;as&nbsp;the&nbsp;value&nbsp;of&nbsp;its&nbsp;`:z`&nbsp;key&nbsp;if&nbsp;`dflt`&nbsp;is&nbsp;not&nbsp;specified.
013&nbsp;&nbsp;&nbsp;&nbsp;`:z`;&nbsp;it&nbsp;is&nbsp;an&nbsp;error&nbsp;and&nbsp;an&nbsp;exception&nbsp;will&nbsp;be&nbsp;thrown&nbsp;if&nbsp;`o`&nbsp;does&nbsp;not
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;conform&nbsp;to&nbsp;this&nbsp;specification.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
024&nbsp;&nbsp;
015&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;`o`&nbsp;is&nbsp;not&nbsp;a&nbsp;vertex,&nbsp;throws&nbsp;an&nbsp;exception.&quot;
016&nbsp;&nbsp;&nbsp;&nbsp;**Note:**&nbsp;these&nbsp;keys&nbsp;can&nbsp;be&nbsp;quite&nbsp;long.&nbsp;No&nbsp;apology&nbsp;is&nbsp;made:&nbsp;it&nbsp;is&nbsp;required
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;the&nbsp;same&nbsp;key&nbsp;can&nbsp;*never*&nbsp;refer&nbsp;to&nbsp;two&nbsp;different&nbsp;locations&nbsp;in&nbsp;space.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;(memoize
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;([o]
019&nbsp;&nbsp;&nbsp;&nbsp;(keyword
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ensure3d&nbsp;o&nbsp;0.0))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;([o&nbsp;dflt]
020&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(s&#x2F;replace
</span><br/>
<span class="partial" title="2 out of 3 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="partial" title="5 out of 8 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(not&nbsp;(vertex?&nbsp;o))&nbsp;(throw&nbsp;(Exception.&nbsp;&quot;Not&nbsp;a&nbsp;vertex!&quot;))
<span class="partial" title="15 out of 17 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(:x&nbsp;o)&nbsp;(:y&nbsp;o)&nbsp;(:z&nbsp;o))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:z&nbsp;o)&nbsp;o
<span class="covered" title="14 out of 14 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;vert_&quot;&nbsp;(:x&nbsp;o)&nbsp;&quot;_&quot;&nbsp;(:y&nbsp;o)&nbsp;&quot;_&quot;&nbsp;(:z&nbsp;o))
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(assoc&nbsp;o&nbsp;:z&nbsp;dflt))))))
<span class="partial" title="9 out of 10 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(:x&nbsp;o)&nbsp;(:y&nbsp;o))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
035&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
036&nbsp;&nbsp;(def&nbsp;ensure2d
<span class="covered" title="10 out of 10 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;vert_&quot;&nbsp;(:x&nbsp;o)&nbsp;&quot;_&quot;&nbsp;(:y&nbsp;o))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&quot;If&nbsp;`o`&nbsp;is&nbsp;a&nbsp;vertex,&nbsp;set&nbsp;its&nbsp;`:z`&nbsp;value&nbsp;to&nbsp;zero;&nbsp;else&nbsp;throw&nbsp;an&nbsp;exception.&quot;
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;(memoize
<span class="not-covered" title="0 out of 2 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(subs&nbsp;(str&nbsp;&quot;Not&nbsp;a&nbsp;vertex:&nbsp;&quot;&nbsp;(or&nbsp;o&nbsp;&quot;nil&quot;))&nbsp;0&nbsp;80))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;-&quot;)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
031&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[o]
032&nbsp;&nbsp;(defn&nbsp;vertex?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;`o`&nbsp;satisfies&nbsp;the&nbsp;conditions&nbsp;for&nbsp;a&nbsp;vertex.&nbsp;That&nbsp;is,&nbsp;essentially,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;it&nbsp;must&nbsp;rerpresent&nbsp;a&nbsp;two-&nbsp;or&nbsp;three-&nbsp;dimensional&nbsp;vector.&nbsp;A&nbsp;vertex&nbsp;is
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;shall&nbsp;be&nbsp;a&nbsp;map&nbsp;having&nbsp;at&nbsp;least&nbsp;the&nbsp;keys&nbsp;`:x`&nbsp;and&nbsp;`:y`,&nbsp;where&nbsp;the&nbsp;value&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;those&nbsp;keys&nbsp;is&nbsp;a&nbsp;number.&nbsp;If&nbsp;the&nbsp;key&nbsp;`:z`&nbsp;is&nbsp;also&nbsp;present,&nbsp;its&nbsp;value&nbsp;must&nbsp;also
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;a&nbsp;number.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
038&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;name&nbsp;&nbsp;`vector?`&nbsp;was&nbsp;not&nbsp;used&nbsp;as&nbsp;that&nbsp;would&nbsp;clash&nbsp;with&nbsp;a&nbsp;function&nbsp;of&nbsp;that
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;in&nbsp;`clojure.core`&nbsp;whose&nbsp;semantics&nbsp;are&nbsp;entirely&nbsp;different.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="partial" title="23 out of 26 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;o)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:id&nbsp;o)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:x&nbsp;o))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:y&nbsp;o))
</span><br/>
<span class="covered" title="14 out of 14 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;(:z&nbsp;o))&nbsp;(number?&nbsp;(:z&nbsp;o)))
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;(:kind&nbsp;o))&nbsp;(=&nbsp;(:kind&nbsp;o)&nbsp;:vertex))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
049&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
050&nbsp;&nbsp;(defn&nbsp;vertex=
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;vertices&nbsp;`v1`,&nbsp;`v2`&nbsp;represent&nbsp;the&nbsp;same&nbsp;vertex.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;[v1&nbsp;v2]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;(every?
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(=ish&nbsp;(%&nbsp;v1)&nbsp;(%&nbsp;v2))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:x&nbsp;:y&nbsp;:z]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
056&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
057&nbsp;&nbsp;(defn&nbsp;vertex
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&quot;Make&nbsp;a&nbsp;vertex&nbsp;with&nbsp;this&nbsp;`x`,&nbsp;`y`&nbsp;and&nbsp;(if&nbsp;provided)&nbsp;`z`&nbsp;values.&nbsp;Returns&nbsp;a&nbsp;map
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;those&nbsp;values,&nbsp;plus&nbsp;a&nbsp;unique&nbsp;`:id`&nbsp;value,&nbsp;and&nbsp;`:kind`&nbsp;set&nbsp;to&nbsp;`:vertex`.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;It&#x27;s&nbsp;not&nbsp;necessary&nbsp;to&nbsp;use&nbsp;this&nbsp;function&nbsp;to&nbsp;create&nbsp;a&nbsp;vertex,&nbsp;but&nbsp;the&nbsp;`:id`
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;must&nbsp;be&nbsp;present&nbsp;and&nbsp;must&nbsp;be&nbsp;unique.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;([x&nbsp;y]
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[v&nbsp;{:x&nbsp;x&nbsp;:y&nbsp;y&nbsp;:kind&nbsp;:vertex}]
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;v&nbsp;:id&nbsp;(vertex-key&nbsp;v))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;([x&nbsp;y&nbsp;z]
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[v&nbsp;(assoc&nbsp;(vertex&nbsp;x&nbsp;y)&nbsp;:z&nbsp;z)]
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;v&nbsp;:id&nbsp;(vertex-key&nbsp;v)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
068&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
069&nbsp;&nbsp;(defn&nbsp;canonicalise
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&quot;If&nbsp;`o`&nbsp;is&nbsp;a&nbsp;map&nbsp;with&nbsp;numeric&nbsp;values&nbsp;for&nbsp;`:x`,&nbsp;`:y`&nbsp;and&nbsp;optionally&nbsp;`:z`,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;upgrade&nbsp;it&nbsp;to&nbsp;something&nbsp;we&nbsp;will&nbsp;recognise&nbsp;as&nbsp;a&nbsp;vertex.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="partial" title="13 out of 17 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;o)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:x&nbsp;o))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:y&nbsp;o))
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;(:z&nbsp;o))&nbsp;(number?&nbsp;(:z&nbsp;o))))
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;o&nbsp;:kind&nbsp;:vertex&nbsp;:id&nbsp;(vertex-key&nbsp;o))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(IllegalArgumentException.
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(subs
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vertex?&nbsp;o)
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;Not&nbsp;a&nbsp;proto-vertex:&nbsp;must&nbsp;have&nbsp;numeric&nbsp;`:x`&nbsp;and&nbsp;`:y`:&nbsp;&quot;
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;o&nbsp;:z&nbsp;0.0)
<span class="not-covered" title="0 out of 6 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;o&nbsp;&quot;nil&quot;))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(Exception.&nbsp;&quot;Not&nbsp;a&nbsp;vertex!&quot;))))))
<span class="not-tracked" title="0 out of 0 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;80)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
086&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
087&nbsp;&nbsp;(def&nbsp;ensure3d
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&quot;Given&nbsp;a&nbsp;vertex&nbsp;`o`,&nbsp;if&nbsp;`o`&nbsp;has&nbsp;a&nbsp;`:z`&nbsp;value,&nbsp;just&nbsp;return&nbsp;`o`;&nbsp;otherwise
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;a&nbsp;vertex&nbsp;like&nbsp;`o`&nbsp;but&nbsp;having&nbsp;thie&nbsp;`dflt`&nbsp;value&nbsp;as&nbsp;the&nbsp;value&nbsp;of&nbsp;its
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;`:z`&nbsp;key,&nbsp;or&nbsp;zero&nbsp;as&nbsp;the&nbsp;value&nbsp;of&nbsp;its&nbsp;`:z`&nbsp;key&nbsp;if&nbsp;`dflt`&nbsp;is&nbsp;not&nbsp;specified.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
091&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;`o`&nbsp;is&nbsp;not&nbsp;a&nbsp;vertex,&nbsp;throws&nbsp;an&nbsp;exception.&quot;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;(memoize
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;([o]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ensure3d&nbsp;o&nbsp;0.0))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;([o&nbsp;dflt]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="partial" title="5 out of 6 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(not&nbsp;(vertex?&nbsp;o))&nbsp;(throw
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(IllegalArgumentException.
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(subs&nbsp;(str&nbsp;&quot;Not&nbsp;a&nbsp;vertex:&nbsp;&quot;&nbsp;(or&nbsp;o&nbsp;&quot;nil&quot;))&nbsp;0&nbsp;80)))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:z&nbsp;o)&nbsp;o
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(assoc&nbsp;o&nbsp;:z&nbsp;dflt))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
104&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
105&nbsp;&nbsp;(def&nbsp;ensure2d
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&quot;If&nbsp;`o`&nbsp;is&nbsp;a&nbsp;vertex,&nbsp;set&nbsp;its&nbsp;`:z`&nbsp;value&nbsp;to&nbsp;zero;&nbsp;else&nbsp;throw&nbsp;an&nbsp;exception.&quot;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;(memoize
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[o]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vertex?&nbsp;o)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;o&nbsp;:z&nbsp;0.0)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(IllegalArgumentException.
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(subs&nbsp;(str&nbsp;&quot;Not&nbsp;a&nbsp;vertex:&nbsp;&quot;&nbsp;(or&nbsp;o&nbsp;&quot;nil&quot;))&nbsp;0&nbsp;80)))))))
</span><br/>
</body>
</html>

View 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: its the way I format the polygons thats the issue</h2>
<p>Firstly, with both versions of <code>stl-&gt;svg</code> using the same version of <code>facet-&gt;svg-poly</code>, i.e. this one:</p>
<pre><code>(defn- facet-&gt;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=&gt; (def ^:dynamic *preferred-svg-render* :hiccup)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (def hiccup (binary-stl-file-&gt;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=&gt; (def ^:dynamic *preferred-svg-render* :dali)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (def dali (binary-stl-file-&gt;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-&gt;svg-poly</code>, i.e. this one:</p>
<pre><code>(defn- dali-facet-&gt;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=&gt; (def ^:dynamic *preferred-svg-render* :hiccup)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (def hiccup (binary-stl-file-&gt;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=&gt; (def ^:dynamic *preferred-svg-render* :dali)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (def dali (binary-stl-file-&gt;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 dont render, we get this:</p>
<pre><code>walkmap.svg=&gt; (def ^:dynamic *preferred-svg-render* :hiccup)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (def hiccup (binary-stl-file-&gt;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=&gt; (def ^:dynamic *preferred-svg-render* :dali)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (def dali (binary-stl-file-&gt;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-&gt;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=&gt; (def stl (decode-binary-stl "resources/isle_of_man.stl"))
#'walkmap.svg/stl
walkmap.svg=&gt; (def facet (first (:facets stl)))
#'walkmap.svg/facet
walkmap.svg=&gt; (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=&gt; (pprint (facet-&gt;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=&gt; (pprint (dali-facet-&gt;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 doesnt seem to be an increased time penalty.</p>
<h3><a href="#conclusion" name="conclusion"></a>Conclusion</h3>
<p>It doesnt 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=&gt; (count (:facets stl))
4416
walkmap.svg=&gt; (def small-stl (assoc stl :facets (take 400 (:facets stl))))
#'walkmap.svg/small-stl
walkmap.svg=&gt; (count (:facets small-stl))
400
walkmap.svg=&gt; (def large-stl (decode-binary-stl "../the-great-game/resources/maps/heightmap.stl"))
#'walkmap.svg/large-stl
walkmap.svg=&gt; (count (:facets large-stl))
746585
walkmap.svg=&gt; (def ^:dynamic *preferred-svg-render* :dali)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (dali.io/render-svg (stl-&gt;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=&gt; (def ^:dynamic *preferred-svg-render* :hiccup)
#'walkmap.svg/*preferred-svg-render*
walkmap.svg=&gt; (time (spit "hiccup-small.svg" (hiccup.core/html (stl-&gt;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 were 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

View file

@ -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>Doesnt 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-&gt;svg]])
(binary-stl-file-&gt;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>

View file

@ -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-&gt;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 were 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-&gt;svg</h3><div class="usage"><code>(binary-stl-file-&gt;svg in-filename)</code><code>(binary-stl-file-&gt;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 havent yet solidified.</p></div></div></div></body></html>

File diff suppressed because one or more lines are too long

View file

@ -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>

View 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 were 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

View file

@ -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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -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 theres 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>. Its 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>

View file

@ -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"

View file

@ -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]))))))

View file

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

View file

@ -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!"))))

View file

@ -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
View 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

View file

@ -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"))

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

View file

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

View file

@ -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!")))

View 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
View 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
View 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`.")))