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>
<tr> <tr>
<td><a href="walkmap/edge.clj.html">walkmap.edge</a></td><td class="with-bar"><div class="covered" <td><a href="walkmap/edge.clj.html">walkmap.edge</a></td><td class="with-bar"><div class="covered"
style="width:100.0%; style="width:98.31697054698458%;
float:left;"> 164 </div></td> float:left;"> 701 </div><div class="not-covered"
<td class="with-number">100.00 %</td> style="width:1.6830294530154277%;
float:left;"> 12 </div></td>
<td class="with-number">98.32 %</td>
<td class="with-bar"><div class="covered" <td class="with-bar"><div class="covered"
style="width:100.0%; style="width:95.1923076923077%;
float:left;"> 40 </div></td> 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">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>
<tr> <tr>
<td><a href="walkmap/geometry.clj.html">walkmap.geometry</a></td><td class="with-bar"><div class="covered" <td><a href="walkmap/geometry.clj.html">walkmap.geometry</a></td><td class="with-bar"><div class="covered"
style="width:1.6260162601626016%; style="width:100.0%;
float:left;"> 2 </div><div class="not-covered" float:left;"> 62 </div></td>
style="width:98.3739837398374%; <td class="with-number">100.00 %</td>
float:left;"> 121 </div></td>
<td class="with-number">1.63 %</td>
<td class="with-bar"><div class="covered" <td class="with-bar"><div class="covered"
style="width:15.384615384615385%; style="width:100.0%;
float:left;"> 2 </div><div class="not-covered" float:left;"> 10 </div></td>
style="width:84.61538461538461%; <td class="with-number">100.00 %</td>
float:left;"> 11 </div></td> <td class="with-number">17</td><td class="with-number">1</td><td class="with-number">10</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>
</tr> </tr>
<tr> <tr>
<td><a href="walkmap/ocean.clj.html">walkmap.ocean</a></td><td class="with-bar"><div class="covered" <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%; style="width:84.21052631578948%;
float:left;"> 32 </div></td> float:left;"> 32 </div></td>
<td class="with-number">15.79 %</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>
<tr> <tr>
<td><a href="walkmap/polygon.clj.html">walkmap.polygon</a></td><td class="with-bar"><div class="covered" <td><a href="walkmap/polygon.clj.html">walkmap.polygon</a></td><td class="with-bar"><div class="covered"
style="width:91.30434782608695%; style="width:90.56603773584905%;
float:left;"> 42 </div><div class="not-covered" float:left;"> 48 </div><div class="not-covered"
style="width:8.695652173913043%; style="width:9.433962264150944%;
float:left;"> 4 </div></td> float:left;"> 5 </div></td>
<td class="with-number">91.30 %</td> <td class="with-number">90.57 %</td>
<td class="with-bar"><div class="covered" <td class="with-bar"><div class="covered"
style="width:88.88888888888889%; style="width:90.0%;
float:left;"> 8 </div><div class="partial" float:left;"> 9 </div><div class="partial"
style="width:11.11111111111111%; style="width:10.0%;
float:left;"> 1 </div></td> float:left;"> 1 </div></td>
<td class="with-number">100.00 %</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>
<tr> <tr>
<td><a href="walkmap/stl.clj.html">walkmap.stl</a></td><td class="with-bar"><div class="covered" <td><a href="walkmap/stl.clj.html">walkmap.stl</a></td><td class="with-bar"><div class="covered"
style="width:52.02156334231806%; style="width:56.777996070726914%;
float:left;"> 193 </div><div class="not-covered" float:left;"> 289 </div><div class="not-covered"
style="width:47.97843665768194%; style="width:43.222003929273086%;
float:left;"> 178 </div></td> float:left;"> 220 </div></td>
<td class="with-number">52.02 %</td> <td class="with-number">56.78 %</td>
<td class="with-bar"><div class="covered" <td class="with-bar"><div class="covered"
style="width:36.8421052631579%; style="width:44.0%;
float:left;"> 28 </div><div class="partial" float:left;"> 44 </div><div class="partial"
style="width:11.842105263157896%; style="width:10.0%;
float:left;"> 9 </div><div class="not-covered" float:left;"> 10 </div><div class="not-covered"
style="width:51.31578947368421%; style="width:46.0%;
float:left;"> 39 </div></td> float:left;"> 46 </div></td>
<td class="with-number">48.68 %</td> <td class="with-number">54.00 %</td>
<td class="with-number">148</td><td class="with-number">13</td><td class="with-number">76</td> <td class="with-number">191</td><td class="with-number">14</td><td class="with-number">100</td>
</tr> </tr>
<tr> <tr>
<td><a href="walkmap/superstructure.clj.html">walkmap.superstructure</a></td><td class="with-bar"><div class="covered" <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%; style="width:85.18518518518519%;
float:left;"> 23 </div></td> float:left;"> 23 </div></td>
<td class="with-number">14.81 %</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>
<tr> <tr>
<td><a href="walkmap/svg.clj.html">walkmap.svg</a></td><td class="with-bar"><div class="covered" <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%; style="width:70.0%;
float:left;"> 7 </div></td> float:left;"> 7 </div></td>
<td class="with-number">30.00 %</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>
<tr> <tr>
<td><a href="walkmap/vertex.clj.html">walkmap.vertex</a></td><td class="with-bar"><div class="covered" <td><a href="walkmap/vertex.clj.html">walkmap.vertex</a></td><td class="with-bar"><div class="covered"
style="width:84.92063492063492%; style="width:78.08641975308642%;
float:left;"> 214 </div><div class="not-covered" float:left;"> 253 </div><div class="not-covered"
style="width:15.079365079365079%; style="width:21.91358024691358%;
float:left;"> 38 </div></td> float:left;"> 71 </div></td>
<td class="with-number">84.92 %</td> <td class="with-number">78.09 %</td>
<td class="with-bar"><div class="covered" <td class="with-bar"><div class="covered"
style="width:66.66666666666667%; style="width:70.0%;
float:left;"> 28 </div><div class="partial" float:left;"> 42 </div><div class="partial"
style="width:16.666666666666668%; style="width:10.0%;
float:left;"> 7 </div><div class="not-covered" float:left;"> 6 </div><div class="not-covered"
style="width:16.666666666666668%; style="width:20.0%;
float:left;"> 7 </div></td> float:left;"> 12 </div></td>
<td class="with-number">83.33 %</td> <td class="with-number">80.00 %</td>
<td class="with-number">82</td><td class="with-number">9</td><td class="with-number">42</td> <td class="with-number">114</td><td class="with-number">11</td><td class="with-number">60</td>
</tr> </tr>
<tr><td>Totals:</td> <tr><td>Totals:</td>
<td class="with-bar"></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-bar"></td>
<td class="with-number">50.55 %</td> <td class="with-number">61.28 %</td>
</tr> </tr>
</table> </table>
</body> </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?]] 006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[walkmap.polygon&nbsp;:refer&nbsp;[polygon?]]
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
008&nbsp;&nbsp; 008&nbsp;&nbsp;
@ -119,100 +119,457 @@
038&nbsp;&nbsp; 038&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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; 041&nbsp;&nbsp;&nbsp;&nbsp;[edge]
</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?
</span><br/> </span><br/>
<span class="covered" title="6 out of 6 forms covered"> <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><br/>
<span class="covered" title="3 out of 3 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
062&nbsp;&nbsp; 062&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="covered" title="2 out of 2 forms covered"> <span class="covered" title="5 out of 5 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;(parallel? 066&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[uvs&nbsp;(map&nbsp;unit-vector&nbsp;edges)]
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <span class="covered" title="3 out of 3 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e1 067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <span class="covered" title="6 out of 6 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e2 068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(vertex=&nbsp;%&nbsp;(first&nbsp;uvs))
</span><br/> </span><br/>
<span class="covered" title="9 out of 9 forms covered"> <span class="covered" title="3 out of 3 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:start&nbsp;(:start&nbsp;e1)&nbsp;:end&nbsp;(:start&nbsp;e2)})) 069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rest&nbsp;uvs))))
</span><br/> </span><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
070&nbsp;&nbsp; 070&nbsp;&nbsp;
</span><br/> </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> </body>
</html> </html>

View file

@ -11,70 +11,49 @@
002&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[clojure.math.combinatorics&nbsp;:as&nbsp;combo] 002&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[clojure.math.combinatorics&nbsp;:as&nbsp;combo]
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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] 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]))
</span><br/> </span><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
008&nbsp;&nbsp; 004&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 6 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[p&nbsp;(v&#x2F;ensure3d&nbsp;(:start&nbsp;e)) 008&nbsp;&nbsp;&nbsp;&nbsp;([n1&nbsp;n2]
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <span class="covered" title="11 out of 11 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q&nbsp;(v&#x2F;ensure3d&nbsp;v) 009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(and&nbsp;(number?&nbsp;n1)&nbsp;(number?&nbsp;n2))
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 5 forms covered"> <span class="covered" title="7 out of 7 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r&nbsp;(v&#x2F;ensure3d&nbsp;(:end&nbsp;e))] 010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[m&nbsp;(m&#x2F;abs&nbsp;(min&nbsp;n1&nbsp;n2))
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 25 forms covered"> <span class="covered" title="9 out of 9 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and 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><br/>
<span class="not-covered" title="0 out of 5 forms covered"> <span class="covered" title="5 out of 5 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(e&#x2F;collinear?&nbsp;p&nbsp;q&nbsp;r) 012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=ish&nbsp;n1&nbsp;n2&nbsp;t))
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 13 forms covered"> <span class="covered" title="4 out of 4 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))) 013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;n1&nbsp;n2)))
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 13 forms covered"> <span class="not-tracked" title="0 out of 0 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))) 014&nbsp;&nbsp;&nbsp;&nbsp;([n1&nbsp;n2&nbsp;tolerance]
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 13 forms covered"> <span class="covered" title="11 out of 11 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))) 015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(and&nbsp;(number?&nbsp;n1)&nbsp;(number?&nbsp;n2))
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 13 forms covered"> <span class="covered" title="9 out of 9 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))) 016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;&nbsp;(m&#x2F;abs&nbsp;(-&nbsp;n1&nbsp;n2))&nbsp;tolerance)
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 13 forms covered"> <span class="covered" title="4 out of 4 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))) 017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;n1&nbsp;n2))))
</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><br/> </span><br/>
</body> </body>
</html> </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 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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;defined&nbsp;in&nbsp;`walkmap.vertex`.&quot; 012&nbsp;&nbsp;&nbsp;&nbsp;defined&nbsp;in&nbsp;`walkmap.vertex`.&quot;
@ -47,7 +47,7 @@
014&nbsp;&nbsp;&nbsp;&nbsp;(let 014&nbsp;&nbsp;&nbsp;&nbsp;(let
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 22 forms covered"> <span class="not-covered" title="0 out of 22 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and 016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
@ -86,7 +86,7 @@
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;vertex?&nbsp;vertices) 027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;vertex?&nbsp;vertices)
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 11 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <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;)))) 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) 040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(polygon?&nbsp;o)
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 21 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <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;)))) 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"> <span class="not-covered" title="0 out of 2 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons 057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons
</span><br/> </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"> <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><br/>
<span class="not-covered" title="0 out of 5 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 5 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
065&nbsp;&nbsp; 067&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 1 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 9 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <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/> </span><br/>
</body> </body>
</html> </html>

View file

@ -37,7 +37,7 @@
<span class="covered" title="3 out of 3 forms covered"> <span class="covered" title="3 out of 3 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[v&nbsp;(:vertices&nbsp;o)] 011&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[v&nbsp;(:vertices&nbsp;o)]
</span><br/> </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 012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/> </span><br/>
<span class="covered" title="3 out of 3 forms covered"> <span class="covered" title="3 out of 3 forms covered">
@ -49,14 +49,17 @@
<span class="covered" title="4 out of 4 forms covered"> <span class="covered" title="4 out of 4 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;vertex?&nbsp;v) 015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;vertex?&nbsp;v)
</span><br/> </span><br/>
<span class="covered" title="9 out of 9 forms covered"> <span class="covered" title="3 out of 3 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))))) 016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:id&nbsp;o)
</span><br/> </span><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="covered" title="9 out of 9 forms covered">
017&nbsp;&nbsp; 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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
018&nbsp;&nbsp; 018&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="blank" title="0 out of 0 forms covered">
019&nbsp;&nbsp;
</span><br/>
</body> </body>
</html> </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]] 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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
012&nbsp;&nbsp; 014&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
018&nbsp;&nbsp; 020&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="covered" title="4 out of 4 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="partial" title="20 out of 26 forms covered"> <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><br/>
<span class="covered" title="3 out of 3 forms covered"> <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><br/>
<span class="covered" title="3 out of 3 forms covered"> <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><br/>
<span class="covered" title="6 out of 6 forms covered"> <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><br/>
<span class="partial" title="9 out of 10 forms covered"> <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><br/>
<span class="partial" title="9 out of 10 forms covered"> <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><br/>
<span class="partial" title="14 out of 15 forms covered"> <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><br/>
<span class="partial" title="1 out of 11 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
032&nbsp;&nbsp; 034&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="covered" title="8 out of 8 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
039&nbsp;&nbsp; 041&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="covered" title="6 out of 6 forms covered"> <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><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="covered" title="4 out of 4 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
046&nbsp;&nbsp; 048&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="covered" title="6 out of 6 forms covered"> <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><br/>
<span class="covered" title="5 out of 5 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="covered" title="3 out of 3 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
053&nbsp;&nbsp; 055&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="partial" title="4 out of 5 forms covered"> <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><br/>
<span class="partial" title="15 out of 16 forms covered"> <span class="partial" title="19 out of 20 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) 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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="covered" title="10 out of 10 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="partial" title="11 out of 12 forms covered"> <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;))) 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="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?`
</span><br/> </span><br/>
<span class="covered" title="6 out of 6 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 1 forms covered"> <span class="covered" title="5 out of 5 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;o)) 096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:vertices&nbsp;o)&nbsp;(centre
</span><br/> </span><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="covered" title="3 out of 3 forms covered">
073&nbsp;&nbsp; 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><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 4 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 6 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(canonicalise&nbsp;(b&#x2F;decode&nbsp;binary-stl&nbsp;in)))) 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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
083&nbsp;&nbsp; 126&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="2 out of 2 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 16 forms covered"> <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;)) 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">
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))))
</span><br/> </span><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
129&nbsp;&nbsp; 129&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <span class="covered" title="2 out of 2 forms covered">
130&nbsp;&nbsp;(defn&nbsp;binary-stl-to-ascii 130&nbsp;&nbsp;(defn-&nbsp;facet2str&nbsp;[tri]
</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><br/> </span><br/>
<span class="not-covered" title="0 out of 4 forms covered"> <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)] 131&nbsp;&nbsp;&nbsp;&nbsp;(str
</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]
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 6 forms covered"> <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/> </span><br/>
</body> </body>
</html> </html>

View file

@ -28,203 +28,236 @@
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
008&nbsp;&nbsp; 008&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;(defn&nbsp;index-vertex 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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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. 033&nbsp;&nbsp;&nbsp;&nbsp;[s&nbsp;o&nbsp;v]
</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]
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 6 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 4 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 4 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 9 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 10 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 15 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 4 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 10 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
036&nbsp;&nbsp; 047&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
040&nbsp;&nbsp; 051&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 2 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 1 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 5 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
053&nbsp;&nbsp; 064&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
059&nbsp;&nbsp; 070&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
061&nbsp;&nbsp; 072&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 4 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 4 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 18 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 10 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 14 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 4 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 13 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
074&nbsp;&nbsp; 085&nbsp;&nbsp;
</span><br/> </span><br/>
</body> </body>
</html> </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, 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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;thrown)&nbsp;if 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; 002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Miscellaneous&nbsp;utility&nbsp;functions.&quot;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
006&nbsp;&nbsp; 007&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 5 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 5 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
014&nbsp;&nbsp; 015&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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 018&nbsp;&nbsp;&nbsp;&nbsp;[o]
</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]
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 4 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 6 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 6 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 6 forms covered"> <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/> </span><br/>
</body> </body>
</html> </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 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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
006&nbsp;&nbsp; 009&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="partial" title="2 out of 3 forms covered"> <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><br/>
<span class="partial" title="32 out of 34 forms covered"> <span class="partial" title="15 out of 17 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;)) 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="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><br/> </span><br/>
<span class="covered" title="14 out of 14 forms covered"> <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><br/>
<span class="covered" title="9 out of 9 forms covered"> <span class="partial" title="9 out of 10 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;(:kind&nbsp;o))&nbsp;(=&nbsp;(:kind&nbsp;o)&nbsp;:vertex)))) 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><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
034&nbsp;&nbsp; 031&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;([x&nbsp;y] 037&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;a&nbsp;number.
</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)))
</span><br/> </span><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
045&nbsp;&nbsp; 038&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
046&nbsp;&nbsp;(defn&nbsp;canonicalise
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="covered" title="1 out of 1 forms covered"> <span class="partial" title="23 out of 26 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;(if 042&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="partial" title="13 out of 17 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/> </span><br/>
<span class="covered" title="3 out of 3 forms covered"> <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><br/>
<span class="covered" title="5 out of 5 forms covered"> <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><br/>
<span class="covered" title="5 out of 5 forms covered"> <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><br/>
<span class="covered" title="9 out of 9 forms covered"> <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><br/>
<span class="covered" title="9 out of 9 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <span class="covered" title="7 out of 7 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;)))) 067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;v&nbsp;:id&nbsp;(vertex-key&nbsp;v)))))
</span><br/> </span><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
058&nbsp;&nbsp; 068&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <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. 072&nbsp;&nbsp;&nbsp;&nbsp;[o]
</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
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <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><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="partial" title="13 out of 17 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;([o] 074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/> </span><br/>
<span class="covered" title="4 out of 4 forms covered"> <span class="covered" title="3 out of 3 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ensure3d&nbsp;o&nbsp;0.0)) 075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map?&nbsp;o)
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="covered" title="5 out of 5 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;([o&nbsp;dflt] 076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:x&nbsp;o))
</span><br/> </span><br/>
<span class="partial" title="2 out of 3 forms covered"> <span class="covered" title="5 out of 5 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond 077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:y&nbsp;o))
</span><br/> </span><br/>
<span class="partial" title="5 out of 8 forms covered"> <span class="covered" title="9 out of 9 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;)) 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><br/>
<span class="covered" title="4 out of 4 forms covered"> <span class="covered" title="9 out of 9 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:z&nbsp;o)&nbsp;o 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 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><br/> </span><br/>
<span class="not-covered" title="0 out of 1 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <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><br/>
<span class="not-covered" title="0 out of 5 forms covered"> <span class="not-covered" title="0 out of 6 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;o&nbsp;:z&nbsp;0.0) 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><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(IllegalArgumentException.&nbsp;&quot;Not&nbsp;a&nbsp;vertex!&quot;)))))) 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/> </span><br/>
</body> </body>
</html> </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 "" <!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> <ol>
<li><code>s</code> is not a map;</li> <li><code>s</code> is not a map;</li>
<li><code>o</code> is not a map, or a sequence of maps.</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> <ol>
<li><code>s</code> is not a map;</li> <li><code>s</code> is not a map;</li>
<li><code>o</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>o</code> does not have a value for the key <code>:id</code>;</li>
<li><code>v</code> is not a vertex.</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> <ol>
<li><code>s</code> is not a map;</li> <li><code>s</code> is not a map;</li>
<li><code>o</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>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." nodes."
(:require [clojure.math.numeric-tower :as m] (:require [clojure.math.numeric-tower :as m]
[walkmap.polygon :refer [polygon?]] [walkmap.polygon :refer [polygon?]]
[walkmap.vertex :refer [ensure3d vertex?]])) [walkmap.vertex :refer [ensure2d ensure3d vertex vertex= vertex?]]))
(defn edge (defn edge
"Return an edge between vertices `v1` and `v2`." "Return an edge between vertices `v1` and `v2`."
@ -36,6 +36,16 @@
#(m/expt (- (% end) (% start)) 2) #(m/expt (- (% end) (% start)) 2)
[:x :y :z]))))) [: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 (defn unit-vector
"Return an vertex parallel to `e` starting from the coordinate origin. Two "Return an vertex parallel to `e` starting from the coordinate origin. Two
edges which are parallel will have the same unit vector." edges which are parallel will have the same unit vector."
@ -52,12 +62,10 @@
(defn parallel? (defn parallel?
"True if all `edges` passed are parallel with one another." "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] [& edges]
(let [uvs (map unit-vector edges)] (let [uvs (map unit-vector edges)]
(every? (every?
#(= % (first uvs)) #(vertex= % (first uvs))
(rest uvs)))) (rest uvs))))
(defn collinear? (defn collinear?
@ -66,5 +74,116 @@
(parallel? (parallel?
e1 e1
e2 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 (ns walkmap.geometry
(:require [clojure.math.combinatorics :as combo] (:require [clojure.math.combinatorics :as combo]
[clojure.math.numeric-tower :as m] [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))))))
(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? (defn path?
"True if `o` satisfies the conditions for a path. A path shall be a map "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`." defined in `walkmap.vertex`."
[o] [o]
(let (let
[v (:nodes o)] [v (:vertices o)]
(and (and
(seq? v) (seq? v)
(> (count v) 2) (> (count v) 2)
@ -25,7 +25,7 @@
[& vertices] [& vertices]
(if (if
(every? vertex? vertices) (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.")))) (throw (IllegalArgumentException. "Each item on path must be a vertex."))))
(defn polygon->path (defn polygon->path
@ -38,7 +38,7 @@
[o] [o]
(if (if
(polygon? o) (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!")))) (throw (IllegalArgumentException. "Not a polygon!"))))
(defn path->edges (defn path->edges
@ -60,7 +60,7 @@
(e/edge (first o) (rest o)) (e/edge (first o) (rest o))
(path->edges (rest o)))) (path->edges (rest o))))
(path? o) (path? o)
(path->edges (:nodes o)) (path->edges (:vertices o))
:else :else
(throw (IllegalArgumentException. (throw (IllegalArgumentException.
"Not a path or sequence of vertices!")))) "Not a path or sequence of vertices!"))))

View file

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

View file

@ -5,7 +5,9 @@
[me.raynes.fs :as fs] [me.raynes.fs :as fs]
[org.clojars.smee.binary.core :as b] [org.clojars.smee.binary.core :as b]
[taoensso.timbre :as l :refer [info error spy]] [taoensso.timbre :as l :refer [info error spy]]
[walkmap.edge :as e]
[walkmap.polygon :refer [polygon?]] [walkmap.polygon :refer [polygon?]]
[walkmap.tag :refer [tag]]
[walkmap.vertex :as v]) [walkmap.vertex :as v])
(:import org.clojars.smee.binary.core.BinaryIO (:import org.clojars.smee.binary.core.BinaryIO
java.io.DataInput)) java.io.DataInput))
@ -51,35 +53,76 @@
:count :uint-le :count :uint-le
:facets (b/repeated facet))) :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 (defn canonicalise
"Objects read in from STL won't have all the keys/values we need them to have." "Objects read in from STL won't have all the keys/values we need them to have.
[o] `o` may be a map (representing a facet or a vertex), or a sequence of such maps;
(cond if it isn't recognised it is at present just returned unchanged. `map-kind`, if
(and (coll? o) (not (map? o))) (map canonicalise o) passed, must be a keyword indicating the value represented by the `z` axis
;; if it has :facets it's an STL structure, but it doesn't yet conform to `stl?` (defaults to `:height`). It is an error, and an exception will be thrown, if
(:facets o) (assoc o `map-kind` is not a keyword."
:kind :stl ([o] (canonicalise o :height))
:id (or (:id o) (keyword (gensym "stl"))) ([o map-kind]
:facets (canonicalise (:facets o))) (when-not
;; if it has :vertices it's a polygon, but it doesn't yet conform to `polygon?` (keyword? map-kind)
(:vertices o) (assoc o (throw (IllegalArgumentException.
:id (or (:id o) (keyword (gensym "poly"))) (subs (str "Must be a keyword: " (or map-kind "nil")) 0 80))))
:kind :polygon (cond
:vertices (canonicalise (:vertices o))) (and (coll? o) (not (map? o))) (map #(canonicalise % map-kind) o)
;; if it has a value for :x it's a vertex, but it doesn't yet conform to `vertex?` ;; if it has :facets it's an STL structure, but it doesn't yet conform to `stl?`
(:x o) (v/canonicalise o) (:facets o) (assoc o
;; shouldn't happen :kind :stl
:else o)) :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 (defn decode-binary-stl
"Parse a binary STL file from this `filename` and return an STL structure "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 **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." data, if it is not this will run but will return garbage."
[filename] ([filename]
(let [in (io/input-stream filename)] (decode-binary-stl filename :height))
(canonicalise (b/decode binary-stl in)))) ([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] (defn- vect->str [prefix v]
(str prefix " " (:x v) " " (:y v) " " (:z v) "\n")) (str prefix " " (:x v) " " (:y v) " " (:z v) "\n"))

View file

@ -6,6 +6,22 @@
[walkmap.utils :as u] [walkmap.utils :as u]
[walkmap.vertex :as v])) [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 (defn index-vertex
"Return a superstructure like `s` in which object `o` is indexed by 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 `v`. It is an error (and an exception may be thrown) if
@ -14,11 +30,6 @@
2. `o` is not a map; 2. `o` is not a map;
3. `o` does not have a value for the key `:id`; 3. `o` does not have a value for the key `:id`;
4. `v` is not a vertex." 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] [s o v]
(if-not (v/vertex? o) (if-not (v/vertex? o)
(if (:id o) (if (:id o)

View file

@ -26,7 +26,7 @@
(defn tag (defn tag
"Return an object like this `object` but with these `tags` added to its tags, "Return an object like this `object` but with these `tags` added to its tags,
if they are not already present.It is an error (and an exception will be if they are not already present. It is an error (and an exception will be
thrown) if thrown) if
1. `object` is not a map; 1. `object` is not a map;

View file

@ -1,6 +1,7 @@
(ns walkmap.utils (ns walkmap.utils
"Miscellaneous utility functions." "Miscellaneous utility functions."
(:require [walkmap.path :as p] (:require [clojure.math.numeric-tower :as m]
[walkmap.path :as p]
[walkmap.polygon :as q] [walkmap.polygon :as q]
[walkmap.vertex :as v])) [walkmap.vertex :as v]))
@ -14,13 +15,9 @@
(defn vertices (defn vertices
"If `o` is an object with vertices, return those vertices, else nil." "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] [o]
(cond (cond
(v/vertex? o) (list o) (v/vertex? o) (list o)
(q/polygon? o) (:vertices 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. "Essentially the specification for things we shall consider to be vertices.
Note that there's no `distance` function here; to find the distance between 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 (defn vertex-key
"Making sure we get the same key everytime we key a vertex with the same "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 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] [o]
(cond (keyword
(and (:x o) (:y o) (:z o)) (keyword (str "vert{" (:x o) "|" (:y o) "|" (:z o) "}")) (s/replace
(and (:x o) (:y o)) (keyword (str "vert{" (:x o) "|" (:y o) "}")) (cond
:else (throw (IllegalArgumentException. "Not a vertex.")))) (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? (defn vertex?
"True if `o` satisfies the conditions for a vertex. That is, essentially, "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? (:z o)) (number? (:z o)))
(or (nil? (:kind o)) (= (:kind o) :vertex)))) (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 (defn vertex
"Make a vertex with this `x`, `y` and (if provided) `z` values. Returns a map "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`. 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}] (let [v {:x x :y y :kind :vertex}]
(assoc v :id (vertex-key v)))) (assoc v :id (vertex-key v))))
([x y z] ([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 (defn canonicalise
"If `o` is a map with numeric values for `:x`, `:y` and optionally `:z`, "If `o` is a map with numeric values for `:x`, `:y` and optionally `:z`,
@ -54,7 +77,12 @@
(number? (:y o)) (number? (:y o))
(or (nil? (:z o)) (number? (:z o)))) (or (nil? (:z o)) (number? (:z o))))
(assoc o :kind :vertex :id (vertex-key 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 (def ensure3d
"Given a vertex `o`, if `o` has a `:z` value, just return `o`; otherwise "Given a vertex `o`, if `o` has a `:z` value, just return `o`; otherwise
@ -68,7 +96,9 @@
(ensure3d o 0.0)) (ensure3d o 0.0))
([o dflt] ([o dflt]
(cond (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 (:z o) o
:else (assoc o :z dflt)))))) :else (assoc o :z dflt))))))
@ -79,4 +109,6 @@
(if (if
(vertex? o) (vertex? o)
(assoc o :z 0.0) (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 (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.edge :refer :all]
[walkmap.vertex :refer [vertex]])) [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") :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."))) (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 (deftest construction-test
(testing "Construction of edges." (testing "Construction of edges."
(is (edge? (edge (vertex 1.0 2.0 3.0) (vertex 4.0 8.0 12.0))) (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")) (is (thrown? IllegalArgumentException (edge (vertex 1 2) "Not a vertex"))
"If second argument is not a vertex, we should get an exception."))) "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 (deftest length-test
(testing "length of an edge" (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)))) (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 (deftest minimad-test
(testing "deriving the unit vector" (testing "finding minimum and maximum coordinates of edges."
(is (= (is (= (minimaxd (edge (vertex 1.0 2.0 3.0) (vertex 4.0 8.0 12.0)) :x min) 1.0))
(unit-vector {:start {:x 0.0 :y 0.0 :z 0.0 :id 'foo} :end {:x 3 :y 4 :z 0.0 :id 'bar}}) (is (= (minimaxd (edge (vertex 1.0 2.0 3.0) (vertex 4.0 8.0 12.0)) :y max) 8.0))))
{: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 parallel-test (deftest parallel-test
(testing "parallelism" (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}})) {: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!"))) "Should not be!")))
(deftest collinear-test (deftest overlaps2d-test
(testing "collinearity" (testing "whether two edges are in the same area of the x,y plane."
(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}} (is (false? (overlaps2d? (edge (vertex 1 1) (vertex 4 4)) (edge (vertex 5 5) (vertex 8 8)))))
{:start {:x 3.0 :y 4.0 :z 0.0 :id 'foo} :end {:x 9.0 :y 12.0 :z 0.0 :id 'bar}}) (is (overlaps2d? (edge (vertex 1 1) (vertex 4 4)) (edge (vertex 4 4) (vertex 1 1))))))
"Should be")
(is (not (deftest unit-vector-test
(collinear? {:start {:x 0.0 :y 0.0 :z 0.0 :id 'foo} :end {:x 3 :y 4 :z 0.0 :id 'bar}} (testing "deriving the 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}})) (is (=
"Should not be!"))) (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.")))