Line intersection looking good.

This commit is contained in:
Simon Brooke 2020-05-27 18:54:36 +01:00
parent 79174af2c1
commit 1ab35dbe7d
No known key found for this signature in database
GPG key ID: A7A4F18D1D4DF987
29 changed files with 1725 additions and 853 deletions

View file

@ -27,29 +27,29 @@
</tr>
<tr>
<td><a href="walkmap/edge.clj.html">walkmap.edge</a></td><td class="with-bar"><div class="covered"
style="width:100.0%;
float:left;"> 164 </div></td>
<td class="with-number">100.00 %</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:100.0%;
float:left;"> 40 </div></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">70</td><td class="with-number">7</td><td class="with-number">40</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"
@ -79,39 +79,39 @@
style="width:84.21052631578948%;
float:left;"> 32 </div></td>
<td class="with-number">15.79 %</td>
<td class="with-number">76</td><td class="with-number">7</td><td class="with-number">38</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:91.30434782608695%;
float:left;"> 42 </div><div class="not-covered"
style="width:8.695652173913043%;
float:left;"> 4 </div></td>
<td class="with-number">91.30 %</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:88.88888888888889%;
float:left;"> 8 </div><div class="partial"
style="width:11.11111111111111%;
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">18</td><td class="with-number">3</td><td class="with-number">9</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:52.02156334231806%;
float:left;"> 193 </div><div class="not-covered"
style="width:47.97843665768194%;
float:left;"> 178 </div></td>
<td class="with-number">52.02 %</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:36.8421052631579%;
float:left;"> 28 </div><div class="partial"
style="width:11.842105263157896%;
float:left;"> 9 </div><div class="not-covered"
style="width:51.31578947368421%;
float:left;"> 39 </div></td>
<td class="with-number">48.68 %</td>
<td class="with-number">148</td><td class="with-number">13</td><td class="with-number">76</td>
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">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"
@ -126,7 +126,7 @@
style="width:85.18518518518519%;
float:left;"> 23 </div></td>
<td class="with-number">14.81 %</td>
<td class="with-number">74</td><td class="with-number">8</td><td class="with-number">27</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"
@ -167,30 +167,30 @@
style="width:70.0%;
float:left;"> 7 </div></td>
<td class="with-number">30.00 %</td>
<td class="with-number">26</td><td class="with-number">2</td><td class="with-number">10</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:84.92063492063492%;
float:left;"> 214 </div><div class="not-covered"
style="width:15.079365079365079%;
float:left;"> 38 </div></td>
<td class="with-number">84.92 %</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:66.66666666666667%;
float:left;"> 28 </div><div class="partial"
style="width:16.666666666666668%;
float:left;"> 7 </div><div class="not-covered"
style="width:16.666666666666668%;
float:left;"> 7 </div></td>
<td class="with-number">83.33 %</td>
<td class="with-number">82</td><td class="with-number">9</td><td class="with-number">42</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">44.01 %</td>
<td class="with-number">61.24 %</td>
<td class="with-bar"></td>
<td class="with-number">50.55 %</td>
<td class="with-number">61.28 %</td>
</tr>
</table>
</body>

View file

@ -23,7 +23,7 @@
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;[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">
008&nbsp;&nbsp;
@ -119,100 +119,457 @@
038&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
039&nbsp;&nbsp;(defn&nbsp;unit-vector
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;an&nbsp;vertex&nbsp;parallel&nbsp;to&nbsp;`e`&nbsp;starting&nbsp;from&nbsp;the&nbsp;coordinate&nbsp;origin.&nbsp;Two
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;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">
042&nbsp;&nbsp;&nbsp;&nbsp;[e]
</span><br/>
<span class="covered" title="14 out of 14 forms covered">
043&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">
044&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">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(reduce
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;merge
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{}
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
049&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">
050&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">
051&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">
052&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
053&nbsp;&nbsp;(defn&nbsp;parallel?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&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">
055&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">
056&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">
057&nbsp;&nbsp;&nbsp;&nbsp;[&amp;&nbsp;edges]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
058&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">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?
041&nbsp;&nbsp;&nbsp;&nbsp;[edge]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(=&nbsp;%&nbsp;(first&nbsp;uvs))
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;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;(vertex
</span><br/>
<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="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="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">
048&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
049&nbsp;&nbsp;(defn&nbsp;unit-vector
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
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">
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">
052&nbsp;&nbsp;&nbsp;&nbsp;[e]
</span><br/>
<span class="covered" title="14 out of 14 forms covered">
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">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rest&nbsp;uvs))))
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">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(reduce
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;merge
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{}
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
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">
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">
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">
062&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
063&nbsp;&nbsp;(defn&nbsp;collinear?
063&nbsp;&nbsp;(defn&nbsp;parallel?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&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;
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">
065&nbsp;&nbsp;&nbsp;&nbsp;[e1&nbsp;e2]
065&nbsp;&nbsp;&nbsp;&nbsp;[&amp;&nbsp;edges]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;(parallel?
<span class="covered" title="5 out of 5 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[uvs&nbsp;(map&nbsp;unit-vector&nbsp;edges)]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e1
<span class="covered" title="3 out of 3 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e2
<span class="covered" title="6 out of 6 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(vertex=&nbsp;%&nbsp;(first&nbsp;uvs))
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:start&nbsp;(:start&nbsp;e1)&nbsp;:end&nbsp;(:start&nbsp;e2)}))
<span class="covered" title="3 out of 3 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rest&nbsp;uvs))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
070&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
071&nbsp;&nbsp;(defn&nbsp;collinear?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
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">
073&nbsp;&nbsp;&nbsp;&nbsp;[e1&nbsp;e2]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;(parallel?
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e1
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e2
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
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">
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

@ -35,7 +35,7 @@
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">
011&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">
012&nbsp;&nbsp;&nbsp;&nbsp;defined&nbsp;in&nbsp;`walkmap.vertex`.&quot;
@ -47,7 +47,7 @@
014&nbsp;&nbsp;&nbsp;&nbsp;(let
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
015&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 22 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
@ -86,7 +86,7 @@
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;vertex?&nbsp;vertices)
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:nodes&nbsp;vertices&nbsp;:id&nbsp;(keyword&nbsp;(gensym&nbsp;&quot;path&quot;))&nbsp;:kind&nbsp;:path}
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;(IllegalArgumentException.&nbsp;&quot;Each&nbsp;item&nbsp;on&nbsp;path&nbsp;must&nbsp;be&nbsp;a&nbsp;vertex.&quot;))))
@ -125,7 +125,7 @@
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;:nodes&nbsp;(concat&nbsp;(:vertices&nbsp;o)&nbsp;(list&nbsp;(first&nbsp;(:vertices&nbsp;o)))))
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;))))
@ -175,62 +175,68 @@
<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">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(e&#x2F;edge&nbsp;(first&nbsp;o)&nbsp;(rest&nbsp;o))
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">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path-&gt;edges&nbsp;(rest&nbsp;o))))
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">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path?&nbsp;o)
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path?&nbsp;o)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path-&gt;edges&nbsp;(:nodes&nbsp;o))
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">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&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;))))
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">
065&nbsp;&nbsp;
067&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
066&nbsp;&nbsp;(defn&nbsp;length
068&nbsp;&nbsp;(defn&nbsp;length
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;the&nbsp;length&nbsp;of&nbsp;this&nbsp;path,&nbsp;in&nbsp;metres.&nbsp;**Note&nbsp;that**
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">
068&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
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">
069&nbsp;&nbsp;&nbsp;&nbsp;path,&nbsp;which,&nbsp;except&nbsp;for&nbsp;absolutely&nbsp;straight&nbsp;paths,&nbsp;will&nbsp;be&nbsp;shorter;
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">
070&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*,
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">
071&nbsp;&nbsp;&nbsp;&nbsp;since&nbsp;paths&nbsp;will&nbsp;generally&nbsp;be&nbsp;rendered&nbsp;as&nbsp;spline&nbsp;curves.&quot;
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">
072&nbsp;&nbsp;&nbsp;&nbsp;[path]
074&nbsp;&nbsp;&nbsp;&nbsp;[path]
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;(if
075&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path?&nbsp;path)
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(path?&nbsp;path)
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(reduce&nbsp;+&nbsp;(map&nbsp;e&#x2F;length&nbsp;(path-&gt;edges&nbsp;path)))
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">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;&quot;Not&nbsp;a&nbsp;path!&quot;))))
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;&quot;Not&nbsp;a&nbsp;path!&quot;))))
</span><br/>
</body>
</html>

View file

@ -37,7 +37,7 @@
<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="partial" title="14 out of 18 forms covered">
<span class="partial" title="17 out of 22 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
@ -49,14 +49,17 @@
<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="9 out of 9 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;(:kind&nbsp;o))&nbsp;(=&nbsp;(:kind&nbsp;o)&nbsp;:polygon)))))
<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="blank" title="0 out of 0 forms covered">
017&nbsp;&nbsp;
<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">
018&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
019&nbsp;&nbsp;
</span><br/>
</body>
</html>

View file

@ -26,427 +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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.vertex&nbsp;:as&nbsp;v])
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;(:import&nbsp;org.clojars.smee.binary.core.BinaryIO
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;java.io.DataInput))
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">
012&nbsp;&nbsp;
014&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
013&nbsp;&nbsp;(defn&nbsp;stl?
015&nbsp;&nbsp;(defn&nbsp;stl?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&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">
015&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">
016&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">
017&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">
018&nbsp;&nbsp;
020&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&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">
020&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">
021&nbsp;&nbsp;&nbsp;&nbsp;([o]
023&nbsp;&nbsp;&nbsp;&nbsp;([o]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(stl?&nbsp;o&nbsp;false))
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(stl?&nbsp;o&nbsp;false))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;([o&nbsp;verify-count?]
025&nbsp;&nbsp;&nbsp;&nbsp;([o&nbsp;verify-count?]
</span><br/>
<span class="partial" title="20 out of 26 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;o)
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;o)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;o)
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;o)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;polygon?&nbsp;(:facets&nbsp;o))
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">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(:header&nbsp;o)&nbsp;(string?&nbsp;(:header&nbsp;o))&nbsp;true)
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">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(:count&nbsp;o)&nbsp;(integer?&nbsp;(:count&nbsp;o))&nbsp;true)
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">
030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;(:kind&nbsp;o))&nbsp;(=&nbsp;(:kind&nbsp;o)&nbsp;:stl))
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">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;verify-count?&nbsp;(=&nbsp;(:count&nbsp;o)&nbsp;(count&nbsp;(:facets&nbsp;o)))&nbsp;true))))
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">
032&nbsp;&nbsp;
034&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
033&nbsp;&nbsp;(def&nbsp;vect
035&nbsp;&nbsp;(def&nbsp;vect
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&quot;A&nbsp;codec&nbsp;for&nbsp;vectors&nbsp;within&nbsp;a&nbsp;binary&nbsp;STL&nbsp;file.&quot;
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">
035&nbsp;&nbsp;&nbsp;&nbsp;(b&#x2F;ordered-map
037&nbsp;&nbsp;&nbsp;&nbsp;(b&#x2F;ordered-map
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:x&nbsp;:float-le
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:x&nbsp;:float-le
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:y&nbsp;:float-le
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:y&nbsp;:float-le
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:z&nbsp;:float-le))
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:z&nbsp;:float-le))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
039&nbsp;&nbsp;
041&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
040&nbsp;&nbsp;(def&nbsp;facet
042&nbsp;&nbsp;(def&nbsp;facet
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&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;
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">
042&nbsp;&nbsp;&nbsp;&nbsp;(b&#x2F;ordered-map
044&nbsp;&nbsp;&nbsp;&nbsp;(b&#x2F;ordered-map
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:normal&nbsp;vect
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:normal&nbsp;vect
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:vertices&nbsp;[vect&nbsp;vect&nbsp;vect]
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">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:abc&nbsp;:ushort-le))
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:abc&nbsp;:ushort-le))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
046&nbsp;&nbsp;
048&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
047&nbsp;&nbsp;(def&nbsp;binary-stl
049&nbsp;&nbsp;(def&nbsp;binary-stl
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&quot;A&nbsp;codec&nbsp;for&nbsp;binary&nbsp;STL&nbsp;files&quot;
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">
049&nbsp;&nbsp;&nbsp;&nbsp;(b&#x2F;ordered-map
051&nbsp;&nbsp;&nbsp;&nbsp;(b&#x2F;ordered-map
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
050&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.
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">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:count&nbsp;:uint-le
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:count&nbsp;:uint-le
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:facets&nbsp;(b&#x2F;repeated&nbsp;facet)))
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">
053&nbsp;&nbsp;
055&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
054&nbsp;&nbsp;(defn&nbsp;canonicalise
056&nbsp;&nbsp;(defn&nbsp;centre
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&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.&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">
056&nbsp;&nbsp;&nbsp;&nbsp;[o]
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-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-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="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">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(v&#x2F;vertex
</span><br/>
<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="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="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;canonicalise
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
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;`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">
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">
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">
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">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.
</span><br/>
<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="partial" title="4 out of 5 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;(cond
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="partial" title="15 out of 16 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(coll?&nbsp;o)&nbsp;(not&nbsp;(map?&nbsp;o)))&nbsp;(map&nbsp;canonicalise&nbsp;o)
<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">
059&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?`
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="covered" title="10 out of 10 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:facets&nbsp;o)&nbsp;(assoc&nbsp;o
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">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:kind&nbsp;:stl
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="partial" title="11 out of 12 forms covered">
062&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="5 out of 5 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:facets&nbsp;(canonicalise&nbsp;(:facets&nbsp;o)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&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="10 out of 10 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:vertices&nbsp;o)&nbsp;(assoc&nbsp;o
</span><br/>
<span class="partial" title="11 out of 12 forms covered">
066&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">
067&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="5 out of 5 forms covered">
068&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)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&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?`
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">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:x&nbsp;o)&nbsp;(v&#x2F;canonicalise&nbsp;o)
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">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;shouldn&#x27;t&nbsp;happen
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="not-covered" title="0 out of 1 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;o))
<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="blank" title="0 out of 0 forms covered">
073&nbsp;&nbsp;
<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">
074&nbsp;&nbsp;(defn&nbsp;decode-binary-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">
075&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
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">
076&nbsp;&nbsp;&nbsp;&nbsp;representing&nbsp;its&nbsp;contents.
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">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;o)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
077&nbsp;&nbsp;
107&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
108&nbsp;&nbsp;(defn&nbsp;decode-binary-stl
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&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
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">
079&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;
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">
080&nbsp;&nbsp;&nbsp;&nbsp;[filename]
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;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">
081&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[in&nbsp;(io&#x2F;input-stream&nbsp;filename)]
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(decode-binary-stl&nbsp;filename&nbsp;:height))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(canonicalise&nbsp;(b&#x2F;decode&nbsp;binary-stl&nbsp;in))))
<span class="not-tracked" title="0 out of 0 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;([filename&nbsp;map-kind]
</span><br/>
<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">
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 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="blank" title="0 out of 0 forms covered">
083&nbsp;&nbsp;
126&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
084&nbsp;&nbsp;(defn-&nbsp;vect-&gt;str&nbsp;[prefix&nbsp;v]
127&nbsp;&nbsp;(defn-&nbsp;vect-&gt;str&nbsp;[prefix&nbsp;v]
</span><br/>
<span class="not-covered" title="0 out of 16 forms covered">
085&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">
086&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
087&nbsp;&nbsp;(defn-&nbsp;facet2str&nbsp;[tri]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
089&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">
090&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">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;str
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
092&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">
093&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">
094&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">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;endloop\nendfacet\n&quot;))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
096&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
097&nbsp;&nbsp;(defn&nbsp;stl-&gt;ascii
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
098&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">
099&nbsp;&nbsp;&nbsp;&nbsp;([stl]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
100&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">
101&nbsp;&nbsp;&nbsp;&nbsp;([stl&nbsp;solidname]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;solid&nbsp;&quot;
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;solidname
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
105&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">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;\n&quot;
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
110&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">
111&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">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;endsolid&nbsp;&quot;
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;solidname
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;\n&quot;)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
115&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
116&nbsp;&nbsp;(defn&nbsp;write-ascii-stl
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
117&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">
118&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">
119&nbsp;&nbsp;&nbsp;&nbsp;([filename&nbsp;stl]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
120&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">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(write-ascii-stl
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
122&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">
123&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">
124&nbsp;&nbsp;&nbsp;&nbsp;([filename&nbsp;stl&nbsp;solidname]
</span><br/>
<span class="not-covered" title="0 out of 16 forms covered">
125&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">
126&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(spit
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
127&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filename
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
128&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(stl-&gt;ascii&nbsp;stl&nbsp;solidname))))
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="1 out of 1 forms covered">
130&nbsp;&nbsp;(defn&nbsp;binary-stl-to-ascii
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
131&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">
132&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">
133&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">
134&nbsp;&nbsp;&nbsp;&nbsp;([in-filename]
<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">
135&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">
136&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(binary-stl-to-ascii
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
137&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in-filename
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
138&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
139&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">
140&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">
141&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">
142&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">
143&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">
144&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">
145&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">
146&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">
147&nbsp;&nbsp;&nbsp;&nbsp;([in-filename&nbsp;out-filename]
131&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
148&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

@ -28,203 +28,236 @@
<span class="blank" title="0 out of 0 forms covered">
008&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
009&nbsp;&nbsp;(defn&nbsp;index-vertex
<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;&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
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;&nbsp;`v`.&nbsp;It&nbsp;is&nbsp;an&nbsp;error&nbsp;(and&nbsp;an&nbsp;exception&nbsp;may&nbsp;be&nbsp;thrown)&nbsp;if
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">
012&nbsp;&nbsp;
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">
013&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;`s`&nbsp;is&nbsp;not&nbsp;a&nbsp;map;
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">
014&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;`o`&nbsp;is&nbsp;not&nbsp;a&nbsp;map;
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">
015&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`;
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">
016&nbsp;&nbsp;&nbsp;&nbsp;4.&nbsp;`v`&nbsp;is&nbsp;not&nbsp;a&nbsp;vertex.&quot;
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">
017&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;two&nbsp;copies&nbsp;of&nbsp;the&nbsp;same&nbsp;vertex&nbsp;are&nbsp;not&nbsp;identical&nbsp;enough&nbsp;to&nbsp;one&nbsp;another
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">
018&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;to&nbsp;be&nbsp;used&nbsp;as&nbsp;keys&nbsp;in&nbsp;a&nbsp;map.&nbsp;So&nbsp;our&nbsp;vertices&nbsp;need&nbsp;to&nbsp;have&nbsp;ids,&nbsp;and&nbsp;we&nbsp;need
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">
019&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;to&nbsp;key&nbsp;the&nbsp;vertex-index&nbsp;by&nbsp;vertex&nbsp;ids.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;TODO:&nbsp;BUT&nbsp;WE&nbsp;CANNOT&nbsp;USE&nbsp;GENSYMED&nbsp;ids,&nbsp;because&nbsp;two&nbsp;vertices&nbsp;with&nbsp;the&nbsp;same
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;vertices&nbsp;must&nbsp;have&nbsp;the&nbsp;same&nbsp;id!
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;[s&nbsp;o&nbsp;v]
033&nbsp;&nbsp;&nbsp;&nbsp;[s&nbsp;o&nbsp;v]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;(if-not&nbsp;(v&#x2F;vertex?&nbsp;o)
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">
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(:id&nbsp;o)
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">
025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(v&#x2F;vertex?&nbsp;v)
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">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[vi&nbsp;(or&nbsp;(:vertex-index&nbsp;s)&nbsp;{})
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">
027&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;{})]
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">
028&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
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">
029&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.
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">
030&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))))
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">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;&quot;Not&nbsp;a&nbsp;vertex:&nbsp;&quot;&nbsp;v)))
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">
032&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))))
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">
033&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
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">
034&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.
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">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:vertex-index&nbsp;s)))
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:vertex-index&nbsp;s)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
036&nbsp;&nbsp;
047&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
037&nbsp;&nbsp;(defn&nbsp;index-vertices
048&nbsp;&nbsp;(defn&nbsp;index-vertices
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&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
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">
039&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
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">
040&nbsp;&nbsp;
051&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;`s`&nbsp;is&nbsp;not&nbsp;a&nbsp;map;
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">
042&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;`o`&nbsp;is&nbsp;not&nbsp;a&nbsp;map;
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">
043&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;
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">
044&nbsp;&nbsp;&nbsp;&nbsp;[s&nbsp;o]
055&nbsp;&nbsp;&nbsp;&nbsp;[s&nbsp;o]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;(assoc
056&nbsp;&nbsp;&nbsp;&nbsp;(assoc
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:vertex-index
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:vertex-index
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(reduce
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(reduce
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u&#x2F;deep-merge
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">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(index-vertex&nbsp;s&nbsp;o&nbsp;%)
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">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(u&#x2F;vertices&nbsp;o)))))
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">
053&nbsp;&nbsp;
064&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
054&nbsp;&nbsp;(defn&nbsp;add-to-superstructure
065&nbsp;&nbsp;(defn&nbsp;add-to-superstructure
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&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,
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">
056&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
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">
057&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
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">
058&nbsp;&nbsp;&nbsp;&nbsp;superstructure&nbsp;will&nbsp;be&nbsp;returned.
069&nbsp;&nbsp;&nbsp;&nbsp;superstructure&nbsp;will&nbsp;be&nbsp;returned.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
059&nbsp;&nbsp;
070&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&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
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">
061&nbsp;&nbsp;
072&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;`s`&nbsp;is&nbsp;not&nbsp;a&nbsp;map;
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">
063&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;
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">
064&nbsp;&nbsp;&nbsp;&nbsp;([o]
075&nbsp;&nbsp;&nbsp;&nbsp;([o]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(add-to-superstructure&nbsp;{}&nbsp;o))
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">
066&nbsp;&nbsp;&nbsp;&nbsp;([s&nbsp;o]
077&nbsp;&nbsp;&nbsp;&nbsp;([s&nbsp;o]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;(cond
078&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 18 forms covered">
068&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;))))]
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">
069&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;))
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">
070&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))
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">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(nil?&nbsp;o)&nbsp;o
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">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
073&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;)))))))
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">
074&nbsp;&nbsp;
085&nbsp;&nbsp;
</span><br/>
</body>
</html>

View file

@ -89,7 +89,7 @@
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.It&nbsp;is&nbsp;an&nbsp;error&nbsp;(and&nbsp;an&nbsp;exception&nbsp;will&nbsp;be
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

View file

@ -11,76 +11,67 @@
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;[walkmap.path&nbsp;:as&nbsp;p]
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.polygon&nbsp;:as&nbsp;q]
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.vertex&nbsp;:as&nbsp;v]))
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">
006&nbsp;&nbsp;
007&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
007&nbsp;&nbsp;(defn&nbsp;deep-merge
008&nbsp;&nbsp;(defn&nbsp;deep-merge
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&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;
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">
009&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;TODO:&nbsp;not&nbsp;my&nbsp;implementation,&nbsp;not&nbsp;sure&nbsp;I&nbsp;entirely&nbsp;trust&nbsp;it.
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">
010&nbsp;&nbsp;&nbsp;&nbsp;[&amp;&nbsp;vals]
011&nbsp;&nbsp;&nbsp;&nbsp;[&amp;&nbsp;vals]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(every?&nbsp;map?&nbsp;vals)
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">
012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;merge-with&nbsp;deep-merge&nbsp;vals)
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">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(last&nbsp;vals)))
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(last&nbsp;vals)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
014&nbsp;&nbsp;
015&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
015&nbsp;&nbsp;(defn&nbsp;vertices
016&nbsp;&nbsp;(defn&nbsp;vertices
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&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;
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">
017&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;TODO:&nbsp;it&#x27;s&nbsp;possibly&nbsp;a&nbsp;design&nbsp;mistake&nbsp;that&nbsp;I&#x27;m&nbsp;currently&nbsp;distinguishing
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;between&nbsp;polygons&nbsp;and&nbsp;paths&nbsp;on&nbsp;the&nbsp;basis&nbsp;that&nbsp;one&nbsp;has&nbsp;`:vertices`&nbsp;and
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;the&nbsp;other&nbsp;has&nbsp;`:nodes`.&nbsp;Possibly&nbsp;it&nbsp;would&nbsp;be&nbsp;better&nbsp;to&nbsp;have&nbsp;a&nbsp;key
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;`:closed`&nbsp;which&nbsp;was&nbsp;`true`&nbsp;for&nbsp;polygons,&nbsp;`false`&nbsp;(or&nbsp;missing)&nbsp;for
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;paths.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;[o]
018&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;(cond
019&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(v&#x2F;vertex?&nbsp;o)&nbsp;(list&nbsp;o)
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">
025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(q&#x2F;polygon?&nbsp;o)&nbsp;(:vertices&nbsp;o)
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">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(p&#x2F;path?&nbsp;o)&nbsp;(:nodes&nbsp;o)))
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

@ -17,238 +17,334 @@
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;two&nbsp;vertices,&nbsp;create&nbsp;an&nbsp;edge&nbsp;from&nbsp;them&nbsp;and&nbsp;use&nbsp;`walkmap.edge&#x2F;length`.&quot;)
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;(: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;&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;&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">
006&nbsp;&nbsp;
009&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
007&nbsp;&nbsp;(defn&nbsp;vertex-key
010&nbsp;&nbsp;(defn&nbsp;vertex-key
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&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
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">
009&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
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">
010&nbsp;&nbsp;&nbsp;&nbsp;`:z`.&quot;
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">
011&nbsp;&nbsp;&nbsp;&nbsp;[o]
014&nbsp;&nbsp;&nbsp;&nbsp;conform&nbsp;to&nbsp;this&nbsp;specification.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
015&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
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">
019&nbsp;&nbsp;&nbsp;&nbsp;(keyword
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(s&#x2F;replace
</span><br/>
<span class="partial" title="2 out of 3 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;(cond
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="partial" title="32 out of 34 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(:x&nbsp;o)&nbsp;(:y&nbsp;o)&nbsp;(:z&nbsp;o))&nbsp;(keyword&nbsp;(str&nbsp;&quot;vert{&quot;&nbsp;(:x&nbsp;o)&nbsp;&quot;|&quot;&nbsp;(:y&nbsp;o)&nbsp;&quot;|&quot;&nbsp;(:z&nbsp;o)&nbsp;&quot;}&quot;))
</span><br/>
<span class="partial" title="22 out of 23 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(:x&nbsp;o)&nbsp;(:y&nbsp;o))&nbsp;(keyword&nbsp;(str&nbsp;&quot;vert{&quot;&nbsp;(:x&nbsp;o)&nbsp;&quot;|&quot;&nbsp;(:y&nbsp;o)&nbsp;&quot;}&quot;))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;&quot;Not&nbsp;a&nbsp;vertex.&quot;))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
016&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
017&nbsp;&nbsp;(defn&nbsp;vertex?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&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">
019&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">
020&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">
021&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">
022&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;a&nbsp;number.
</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;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">
025&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">
026&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="partial" title="23 out of 26 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;o)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:id&nbsp;o)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:x&nbsp;o))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:y&nbsp;o))
<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="14 out of 14 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;(:z&nbsp;o))&nbsp;(number?&nbsp;(:z&nbsp;o)))
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="covered" title="9 out of 9 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;(:kind&nbsp;o))&nbsp;(=&nbsp;(:kind&nbsp;o)&nbsp;:vertex))))
<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="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">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<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">
034&nbsp;&nbsp;
031&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
035&nbsp;&nbsp;(defn&nbsp;vertex
032&nbsp;&nbsp;(defn&nbsp;vertex?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&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
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">
037&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`.
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">
038&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`
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">
039&nbsp;&nbsp;&nbsp;&nbsp;must&nbsp;be&nbsp;present&nbsp;and&nbsp;must&nbsp;be&nbsp;unique.&quot;
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">
040&nbsp;&nbsp;&nbsp;&nbsp;([x&nbsp;y]
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
041&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">
042&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">
043&nbsp;&nbsp;&nbsp;&nbsp;([x&nbsp;y&nbsp;z]
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;(vertex&nbsp;x&nbsp;y)&nbsp;:z&nbsp;z)))
037&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;a&nbsp;number.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
045&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
046&nbsp;&nbsp;(defn&nbsp;canonicalise
038&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&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`,
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">
048&nbsp;&nbsp;&nbsp;&nbsp;upgrade&nbsp;it&nbsp;to&nbsp;something&nbsp;we&nbsp;will&nbsp;recognise&nbsp;as&nbsp;a&nbsp;vertex.&quot;
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">
049&nbsp;&nbsp;&nbsp;&nbsp;[o]
041&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="partial" title="13 out of 17 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
<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">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;o)
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">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:x&nbsp;o))
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:x&nbsp;o))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:y&nbsp;o))
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">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;(:z&nbsp;o))&nbsp;(number?&nbsp;(:z&nbsp;o))))
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">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;o&nbsp;:kind&nbsp;:vertex&nbsp;:id&nbsp;(vertex-key&nbsp;o))
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="not-covered" title="0 out of 3 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;&quot;Not&nbsp;a&nbsp;proto-vertex:&nbsp;must&nbsp;have&nbsp;numeric&nbsp;`:x`&nbsp;and&nbsp;`:y`.&quot;))))
<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">
058&nbsp;&nbsp;
068&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
059&nbsp;&nbsp;(def&nbsp;ensure3d
069&nbsp;&nbsp;(defn&nbsp;canonicalise
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&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
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">
061&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
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">
062&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">
063&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&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">
065&nbsp;&nbsp;&nbsp;&nbsp;(memoize
072&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn
073&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;([o]
<span class="partial" title="13 out of 17 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ensure3d&nbsp;o&nbsp;0.0))
<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="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;([o&nbsp;dflt]
<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="partial" title="2 out of 3 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
<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="partial" title="5 out of 8 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(not&nbsp;(vertex?&nbsp;o))&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;&quot;Not&nbsp;a&nbsp;vertex!&quot;))
<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="4 out of 4 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:z&nbsp;o)&nbsp;o
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
073&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">
074&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
075&nbsp;&nbsp;(def&nbsp;ensure2d
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
076&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">
077&nbsp;&nbsp;&nbsp;&nbsp;(memoize
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[o]
<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">
079&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">
080&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">
081&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">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.&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>

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,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="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><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-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#L9">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>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -5,15 +5,15 @@
<ol>
<li><code>s</code> is not a map;</li>
<li><code>o</code> is not a map, or a sequence of maps.</li>
</ol></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/superstructure.clj#L54">view source</a></div></div><div class="public anchor" id="var-index-vertex"><h3>index-vertex</h3><div class="usage"><code>(index-vertex s o v)</code></div><div class="doc"><div class="markdown"><p>Return a superstructure like <code>s</code> in which object <code>o</code> is indexed by vertex <code>v</code>. It is an error (and an exception may be thrown) if</p>
</ol></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/superstructure.clj#L65">view source</a></div></div><div class="public anchor" id="var-index-vertex"><h3>index-vertex</h3><div class="usage"><code>(index-vertex s o v)</code></div><div class="doc"><div class="markdown"><p>Return a superstructure like <code>s</code> in which object <code>o</code> is indexed by vertex <code>v</code>. It is an error (and an exception may be thrown) if</p>
<ol>
<li><code>s</code> is not a map;</li>
<li><code>o</code> is not a map;</li>
<li><code>o</code> does not have a value for the key <code>:id</code>;</li>
<li><code>v</code> is not a vertex.</li>
</ol></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/superstructure.clj#L9">view source</a></div></div><div class="public anchor" id="var-index-vertices"><h3>index-vertices</h3><div class="usage"><code>(index-vertices s o)</code></div><div class="doc"><div class="markdown"><p>Return a superstructure like <code>s</code> in which object <code>o</code> is indexed by its vertices. It is an error (and an exception may be thrown) if</p>
</ol></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/superstructure.clj#L25">view source</a></div></div><div class="public anchor" id="var-index-vertices"><h3>index-vertices</h3><div class="usage"><code>(index-vertices s o)</code></div><div class="doc"><div class="markdown"><p>Return a superstructure like <code>s</code> in which object <code>o</code> is indexed by its vertices. It is an error (and an exception may be thrown) if</p>
<ol>
<li><code>s</code> is not a map;</li>
<li><code>o</code> is not a map;</li>
<li><code>o</code> does not have a value for the key <code>:id</code>.</li>
</ol></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/superstructure.clj#L37">view source</a></div></div></div></body></html>
</ol></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/superstructure.clj#L48">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

View file

@ -4,7 +4,7 @@
nodes."
(:require [clojure.math.numeric-tower :as m]
[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`."
@ -36,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."
@ -52,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?
@ -66,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

@ -8,11 +8,11 @@
(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)
@ -25,7 +25,7 @@
[& vertices]
(if
(every? vertex? vertices)
{:nodes vertices :id (keyword (gensym "path")) :kind :path}
{:vertices vertices :id (keyword (gensym "path")) :kind :path}
(throw (IllegalArgumentException. "Each item on path must be a vertex."))))
(defn polygon->path
@ -38,7 +38,7 @@
[o]
(if
(polygon? o)
(assoc (dissoc o :vertices) :kind :path :nodes (concat (:vertices o) (list (first (:vertices o)))))
(assoc (dissoc o :vertices) :kind :path :vertices (concat (:vertices o) (list (first (:vertices o)))))
(throw (IllegalArgumentException. "Not a polygon!"))))
(defn path->edges
@ -60,7 +60,7 @@
(e/edge (first o) (rest o))
(path->edges (rest o))))
(path? o)
(path->edges (:nodes o))
(path->edges (:vertices o))
:else
(throw (IllegalArgumentException.
"Not a path or sequence of vertices!"))))

View file

@ -13,6 +13,7 @@
(coll? v)
(> (count v) 2)
(every? vertex? v)
(:id o)
(or (nil? (:kind o)) (= (:kind o) :polygon)))))

View file

@ -5,7 +5,9 @@
[me.raynes.fs :as fs]
[org.clojars.smee.binary.core :as b]
[taoensso.timbre :as l :refer [info error spy]]
[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))
@ -51,35 +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]
(cond
(and (coll? o) (not (map? o))) (map canonicalise 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)))
;; if it has :vertices it's a polygon, but it doesn't yet conform to `polygon?`
(:vertices o) (assoc o
:id (or (:id o) (keyword (gensym "poly")))
:kind :polygon
:vertices (canonicalise (:vertices o)))
;; 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))
"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]
(let [in (io/input-stream filename)]
(canonicalise (b/decode binary-stl in))))
([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)]
(canonicalise (b/decode binary-stl in) map-kind))))
(defn- vect->str [prefix v]
(str prefix " " (:x v) " " (:y v) " " (:z v) "\n"))

View file

@ -6,6 +6,22 @@
[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
@ -14,11 +30,6 @@
2. `o` is not a map;
3. `o` does not have a value for the key `:id`;
4. `v` is not a vertex."
;; two copies of the same vertex are not identical enough to one another
;; to be used as keys in a map. So our vertices need to have ids, and we need
;; to key the vertex-index by vertex ids.
;; TODO: BUT WE CANNOT USE GENSYMED ids, because two vertices with the same
;; vertices must have the same id!
[s o v]
(if-not (v/vertex? o)
(if (:id o)

View file

@ -26,7 +26,7 @@
(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
if they are not already present. It is an error (and an exception will be
thrown) if
1. `object` is not a map;

View file

@ -1,6 +1,7 @@
(ns walkmap.utils
"Miscellaneous utility functions."
(:require [walkmap.path :as p]
(:require [clojure.math.numeric-tower :as m]
[walkmap.path :as p]
[walkmap.polygon :as q]
[walkmap.vertex :as v]))
@ -14,13 +15,9 @@
(defn vertices
"If `o` is an object with vertices, return those vertices, else nil."
;; TODO: it's possibly a design mistake that I'm currently distinguishing
;; between polygons and paths on the basis that one has `:vertices` and
;; the other has `:nodes`. Possibly it would be better to have a key
;; `:closed` which was `true` for polygons, `false` (or missing) for
;; paths.
[o]
(cond
(v/vertex? o) (list o)
(q/polygon? o) (:vertices o)
(p/path? o) (:nodes o)))
(p/path? o) (:vertices o)))

View file

@ -2,17 +2,32 @@
"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`.")
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`."
`: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]
(cond
(and (:x o) (:y o) (:z o)) (keyword (str "vert{" (:x o) "|" (:y o) "|" (:z o) "}"))
(and (:x o) (:y o)) (keyword (str "vert{" (:x o) "|" (:y o) "}"))
:else (throw (IllegalArgumentException. "Not a vertex."))))
(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,
@ -32,6 +47,13 @@
(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`.
@ -41,7 +63,8 @@
(let [v {:x x :y y :kind :vertex}]
(assoc v :id (vertex-key v))))
([x y z]
(assoc (vertex x y) :z 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`,
@ -54,7 +77,12 @@
(number? (:y o))
(or (nil? (:z o)) (number? (:z o))))
(assoc o :kind :vertex :id (vertex-key o))
(throw (IllegalArgumentException. "Not a proto-vertex: must have numeric `:x` and `:y`."))))
(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
@ -68,7 +96,9 @@
(ensure3d o 0.0))
([o dflt]
(cond
(not (vertex? o)) (throw (IllegalArgumentException. "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))))))
@ -79,4 +109,6 @@
(if
(vertex? o)
(assoc o :z 0.0)
(throw (IllegalArgumentException. "Not a vertex!"))))))
(throw
(IllegalArgumentException.
(subs (str "Not a vertex: " (or o "nil")) 0 80)))))))

View file

@ -1,5 +1,6 @@
(ns walkmap.edge-test
(:require [clojure.test :refer :all]
(:require [clojure.math.numeric-tower :as m]
[clojure.test :refer :all]
[walkmap.edge :refer :all]
[walkmap.vertex :refer [vertex]]))
@ -19,6 +20,32 @@
: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)))
@ -28,18 +55,46 @@
(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 :id 'foo} :end {:x 3.0 :y 4.0 :z 0.0 :id 'bar}}) 5.0))))
(deftest unit-vector-test
(testing "deriving the unit vector"
(is (=
(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 :id 'foo} :end {:x 4.0 :y 6.0 :z 3.5 :id 'bar}})
{:x 0.6, :y 0.8, :z 0.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"
@ -51,12 +106,16 @@
{: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 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!")))
(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 :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 :id 'foo} :end {:x 4.0 :y 6.0 :z 3.5 :id 'bar}})
{:x 0.6, :y 0.8, :z 0.0}))))

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