Work on test coverage. Tedious, but useful.
This commit is contained in:
parent
e07dc7098c
commit
5328e89c96
|
@ -16,18 +16,18 @@
|
|||
</tr></thead>
|
||||
<tr>
|
||||
<td><a href="walkmap/edge.clj.html">walkmap.edge</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:98.31697054698458%;
|
||||
float:left;"> 701 </div><div class="not-covered"
|
||||
style="width:1.6830294530154277%;
|
||||
style="width:98.32167832167832%;
|
||||
float:left;"> 703 </div><div class="not-covered"
|
||||
style="width:1.6783216783216783%;
|
||||
float:left;"> 12 </div></td>
|
||||
<td class="with-number">98.32 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:95.1923076923077%;
|
||||
float:left;"> 99 </div><div class="partial"
|
||||
style="width:4.8076923076923075%;
|
||||
style="width:95.23809523809524%;
|
||||
float:left;"> 100 </div><div class="partial"
|
||||
style="width:4.761904761904762%;
|
||||
float:left;"> 5 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">175</td><td class="with-number">17</td><td class="with-number">104</td>
|
||||
<td class="with-number">177</td><td class="with-number">17</td><td class="with-number">105</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/id.clj.html">walkmap.id</a></td><td class="with-bar"><div class="covered"
|
||||
|
@ -42,52 +42,46 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/ocean.clj.html">walkmap.ocean</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:64.28571428571429%;
|
||||
float:left;"> 18 </div><div class="not-covered"
|
||||
style="width:35.714285714285715%;
|
||||
float:left;"> 10 </div></td>
|
||||
<td class="with-number">64.29 %</td>
|
||||
style="width:100.0%;
|
||||
float:left;"> 28 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:87.5%;
|
||||
float:left;"> 7 </div><div class="not-covered"
|
||||
style="width:12.5%;
|
||||
float:left;"> 1 </div></td>
|
||||
<td class="with-number">87.50 %</td>
|
||||
<td class="with-number">24</td><td class="with-number">4</td><td class="with-number">8</td>
|
||||
style="width:100.0%;
|
||||
float:left;"> 8 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">25</td><td class="with-number">4</td><td class="with-number">8</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/path.clj.html">walkmap.path</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:12.041884816753926%;
|
||||
float:left;"> 23 </div><div class="not-covered"
|
||||
style="width:87.95811518324608%;
|
||||
float:left;"> 168 </div></td>
|
||||
<td class="with-number">12.04 %</td>
|
||||
style="width:93.60902255639098%;
|
||||
float:left;"> 249 </div><div class="not-covered"
|
||||
style="width:6.390977443609023%;
|
||||
float:left;"> 17 </div></td>
|
||||
<td class="with-number">93.61 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:17.94871794871795%;
|
||||
float:left;"> 7 </div><div class="partial"
|
||||
style="width:89.74358974358974%;
|
||||
float:left;"> 35 </div><div class="partial"
|
||||
style="width:7.6923076923076925%;
|
||||
float:left;"> 3 </div><div class="not-covered"
|
||||
style="width:2.5641025641025643%;
|
||||
float:left;"> 1 </div><div class="not-covered"
|
||||
style="width:79.48717948717949%;
|
||||
float:left;"> 31 </div></td>
|
||||
<td class="with-number">20.51 %</td>
|
||||
<td class="with-number">84</td><td class="with-number">7</td><td class="with-number">39</td>
|
||||
float:left;"> 1 </div></td>
|
||||
<td class="with-number">97.44 %</td>
|
||||
<td class="with-number">94</td><td class="with-number">9</td><td class="with-number">39</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/polygon.clj.html">walkmap.polygon</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:72.42647058823529%;
|
||||
float:left;"> 197 </div><div class="not-covered"
|
||||
style="width:27.573529411764707%;
|
||||
float:left;"> 75 </div></td>
|
||||
<td class="with-number">72.43 %</td>
|
||||
style="width:91.85393258426966%;
|
||||
float:left;"> 327 </div><div class="not-covered"
|
||||
style="width:8.146067415730338%;
|
||||
float:left;"> 29 </div></td>
|
||||
<td class="with-number">91.85 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:64.0%;
|
||||
float:left;"> 32 </div><div class="partial"
|
||||
style="width:10.0%;
|
||||
float:left;"> 5 </div><div class="not-covered"
|
||||
style="width:26.0%;
|
||||
float:left;"> 13 </div></td>
|
||||
<td class="with-number">74.00 %</td>
|
||||
<td class="with-number">87</td><td class="with-number">8</td><td class="with-number">50</td>
|
||||
style="width:89.58333333333333%;
|
||||
float:left;"> 43 </div><div class="partial"
|
||||
style="width:10.416666666666666%;
|
||||
float:left;"> 5 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">97</td><td class="with-number">11</td><td class="with-number">48</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/read_svg.clj.html">walkmap.read-svg</a></td><td class="with-bar"><div class="covered"
|
||||
|
@ -117,11 +111,11 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/stl.clj.html">walkmap.stl</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:49.07216494845361%;
|
||||
style="width:50.638297872340424%;
|
||||
float:left;"> 238 </div><div class="not-covered"
|
||||
style="width:50.92783505154639%;
|
||||
float:left;"> 247 </div></td>
|
||||
<td class="with-number">49.07 %</td>
|
||||
style="width:49.361702127659576%;
|
||||
float:left;"> 232 </div></td>
|
||||
<td class="with-number">50.64 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:40.56603773584906%;
|
||||
float:left;"> 43 </div><div class="partial"
|
||||
|
@ -134,11 +128,11 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/superstructure.clj.html">walkmap.superstructure</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:71.76781002638522%;
|
||||
float:left;"> 272 </div><div class="not-covered"
|
||||
style="width:28.232189973614776%;
|
||||
style="width:70.6043956043956%;
|
||||
float:left;"> 257 </div><div class="not-covered"
|
||||
style="width:29.395604395604394%;
|
||||
float:left;"> 107 </div></td>
|
||||
<td class="with-number">71.77 %</td>
|
||||
<td class="with-number">70.60 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:71.26436781609195%;
|
||||
float:left;"> 62 </div><div class="partial"
|
||||
|
@ -151,11 +145,11 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/svg.clj.html">walkmap.svg</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:3.7542662116040955%;
|
||||
style="width:4.21455938697318%;
|
||||
float:left;"> 11 </div><div class="not-covered"
|
||||
style="width:96.24573378839591%;
|
||||
float:left;"> 282 </div></td>
|
||||
<td class="with-number">3.75 %</td>
|
||||
style="width:95.78544061302682%;
|
||||
float:left;"> 250 </div></td>
|
||||
<td class="with-number">4.21 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:12.121212121212121%;
|
||||
float:left;"> 8 </div><div class="not-covered"
|
||||
|
@ -167,7 +161,7 @@
|
|||
<tr>
|
||||
<td><a href="walkmap/tag.clj.html">walkmap.tag</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 181 </div></td>
|
||||
float:left;"> 162 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
|
@ -177,43 +171,43 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/utils.clj.html">walkmap.utils</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:76.66666666666667%;
|
||||
float:left;"> 92 </div><div class="not-covered"
|
||||
style="width:23.333333333333332%;
|
||||
float:left;"> 28 </div></td>
|
||||
<td class="with-number">76.67 %</td>
|
||||
style="width:52.91005291005291%;
|
||||
float:left;"> 400 </div><div class="not-covered"
|
||||
style="width:47.08994708994709%;
|
||||
float:left;"> 356 </div></td>
|
||||
<td class="with-number">52.91 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:80.0%;
|
||||
float:left;"> 16 </div><div class="partial"
|
||||
style="width:5.0%;
|
||||
float:left;"> 1 </div><div class="not-covered"
|
||||
style="width:15.0%;
|
||||
float:left;"> 3 </div></td>
|
||||
<td class="with-number">85.00 %</td>
|
||||
<td class="with-number">43</td><td class="with-number">4</td><td class="with-number">20</td>
|
||||
style="width:63.888888888888886%;
|
||||
float:left;"> 23 </div><div class="partial"
|
||||
style="width:8.333333333333334%;
|
||||
float:left;"> 3 </div><div class="not-covered"
|
||||
style="width:27.77777777777778%;
|
||||
float:left;"> 10 </div></td>
|
||||
<td class="with-number">72.22 %</td>
|
||||
<td class="with-number">101</td><td class="with-number">9</td><td class="with-number">36</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="walkmap/vertex.clj.html">walkmap.vertex</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:66.52078774617068%;
|
||||
float:left;"> 304 </div><div class="not-covered"
|
||||
style="width:33.479212253829324%;
|
||||
float:left;"> 153 </div></td>
|
||||
<td class="with-number">66.52 %</td>
|
||||
style="width:69.0909090909091%;
|
||||
float:left;"> 380 </div><div class="not-covered"
|
||||
style="width:30.90909090909091%;
|
||||
float:left;"> 170 </div></td>
|
||||
<td class="with-number">69.09 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:59.75609756097561%;
|
||||
float:left;"> 49 </div><div class="partial"
|
||||
style="width:10.975609756097562%;
|
||||
float:left;"> 9 </div><div class="not-covered"
|
||||
style="width:29.26829268292683%;
|
||||
float:left;"> 24 </div></td>
|
||||
<td class="with-number">70.73 %</td>
|
||||
<td class="with-number">148</td><td class="with-number">13</td><td class="with-number">82</td>
|
||||
style="width:63.013698630136986%;
|
||||
float:left;"> 46 </div><div class="partial"
|
||||
style="width:20.54794520547945%;
|
||||
float:left;"> 15 </div><div class="not-covered"
|
||||
style="width:16.438356164383563%;
|
||||
float:left;"> 12 </div></td>
|
||||
<td class="with-number">83.56 %</td>
|
||||
<td class="with-number">149</td><td class="with-number">15</td><td class="with-number">73</td>
|
||||
</tr>
|
||||
<tr><td>Totals:</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">60.81 %</td>
|
||||
<td class="with-number">66.22 %</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">62.17 %</td>
|
||||
<td class="with-number">70.05 %</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
|
|
|
@ -20,514 +20,520 @@
|
|||
005 (:require [clojure.math.numeric-tower :as m]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 [walkmap.vertex :refer [ensure2d ensure3d vertex vertex= vertex?]]))
|
||||
006 [walkmap.utils :as u]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 [walkmap.vertex :refer [canonicalise ensure2d ensure3d vertex vertex= vertex?]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
007
|
||||
008
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
008 (defn edge
|
||||
009 (defn edge
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 "Return an edge between vertices `v1` and `v2`."
|
||||
010 "Return an edge between vertices `v1` and `v2`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 [v1 v2]
|
||||
011 [v1 v2]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
011 (if
|
||||
012 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
012 (and (vertex? v1) (vertex? v2))
|
||||
013 (and (vertex? v1) (vertex? v2))
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
013 {:kind :edge :walkmap.id/id (keyword (gensym "edge")) :start v1 :end v2}
|
||||
014 {:kind :edge :walkmap.id/id (keyword (gensym "edge")) :start v1 :end v2}
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
014 (throw (IllegalArgumentException. "Must be vertices."))))
|
||||
015 (throw (IllegalArgumentException. "Must be vertices."))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
015
|
||||
016
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
016 (defn edge?
|
||||
017 (defn edge?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 "True if `o` satisfies the conditions for a edge. An edge shall be a map
|
||||
018 "True if `o` satisfies the conditions for a edge. An edge shall be a map
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 having the keys `:start` and `:end`, such that the values of each of those
|
||||
019 having the keys `:start` and `:end`, such that the values of each of those
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 keys shall be a vertex."
|
||||
020 keys shall be a vertex."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 [o]
|
||||
021 [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
021 (and
|
||||
022 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
022 (map? o)
|
||||
023 (map? o)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
023 (vertex? (:start o))
|
||||
024 (vertex? (:start o))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
024 (vertex? (:end o))))
|
||||
025 (vertex? (:end o))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
025
|
||||
026
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
026 (defn length
|
||||
027 (defn length
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 "Return the length of the edge `e`."
|
||||
028 "Return the length of the edge `e`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 [e]
|
||||
029 [e]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
029 (let [start (ensure3d (:start e))
|
||||
030 (let [start (ensure3d (:start e))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
030 end (ensure3d (:end e))]
|
||||
031 end (ensure3d (:end e))]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
031 (m/sqrt
|
||||
032 (m/sqrt
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
032 (reduce
|
||||
033 (reduce
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
033 +
|
||||
034 +
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
034 (map
|
||||
035 (map
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
035 #(m/expt (- (% end) (% start)) 2)
|
||||
036 #(m/expt (- (% end) (% start)) 2)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
036 [:x :y :z])))))
|
||||
037 [:x :y :z])))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
037
|
||||
038
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
038 (defn centre
|
||||
039 (defn centre
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 "Return the vertex that represents the centre of this `edge`."
|
||||
040 "Return the vertex that represents the centre of this `edge`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 [edge]
|
||||
041 [edge]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
041 (let [s (ensure3d (:start edge))
|
||||
042 (let [s (ensure3d (:start edge))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
042 e (ensure3d (:end edge))]
|
||||
043 e (ensure3d (:end edge))]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
043 (vertex
|
||||
044 (vertex
|
||||
</span><br/>
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
044 (+ (:x s) (/ (- (:x e) (:x s)) 2))
|
||||
045 (+ (:x s) (/ (- (:x e) (:x s)) 2))
|
||||
</span><br/>
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
045 (+ (:y s) (/ (- (:y e) (:y s)) 2))
|
||||
046 (+ (:y s) (/ (- (:y e) (:y s)) 2))
|
||||
</span><br/>
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
046 (+ (:z s) (/ (- (:z e) (:z s)) 2)))))
|
||||
047 (+ (:z s) (/ (- (:z e) (:z s)) 2)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
047
|
||||
048
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
048 (defn unit-vector
|
||||
049 (defn unit-vector
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 "Return an vertex parallel to `e` starting from the coordinate origin. Two
|
||||
050 "Return an vertex parallel to `e` starting from the coordinate origin. Two
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050 edges which are parallel will have the same unit vector."
|
||||
051 edges which are parallel will have the same unit vector."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 [e]
|
||||
052 [e]
|
||||
</span><br/>
|
||||
<span class="covered" title="14 out of 14 forms covered">
|
||||
052 (let [e' {:start (ensure3d (:start e)) :end (ensure3d (:end e))}
|
||||
053 (let [e' {:start (ensure3d (:start e)) :end (ensure3d (:end e))}
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
053 l (length e')]
|
||||
054 l (length e')]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
054 (reduce
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
055 merge
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
056 {}
|
||||
055 (canonicalise
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
057 (map
|
||||
056 (reduce
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
058 (fn [k]
|
||||
057 merge
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
058 {}
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
059 (map
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
060 (fn [k]
|
||||
</span><br/>
|
||||
<span class="covered" title="17 out of 17 forms covered">
|
||||
059 {k (/ (- (k (:end e')) (k (:start e'))) l)})
|
||||
061 {k (/ (- (k (:end e')) (k (:start e'))) l)})
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
060 [:x :y :z]))))
|
||||
062 [:x :y :z])))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
061
|
||||
063
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
062 (defn parallel?
|
||||
064 (defn parallel?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
063 "True if all `edges` passed are parallel with one another."
|
||||
065 "True if all `edges` passed are parallel with one another."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
064 [& edges]
|
||||
066 [& edges]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
065 (let [uvs (map unit-vector edges)]
|
||||
067 (let [uvs (map unit-vector edges)]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
066 (every?
|
||||
068 (every?
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
067 #(vertex= % (first uvs))
|
||||
069 #(vertex= % (first uvs))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
068 (rest uvs))))
|
||||
070 (rest uvs))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
069
|
||||
071
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
070 (defn collinear?
|
||||
072 (defn collinear?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 "True if edges `e1` and `e2` are collinear with one another."
|
||||
073 "True if edges `e1` and `e2` are collinear with one another."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
072 [e1 e2]
|
||||
074 [e1 e2]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
073 (parallel?
|
||||
075 (parallel?
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
074 e1
|
||||
076 e1
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
075 e2
|
||||
077 e2
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
076 (if (vertex= (:start e1) (:start e2))
|
||||
078 (if (vertex= (:start e1) (:start e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
077 {:start (:start e1) :end (:end e2)}
|
||||
079 {:start (:start e1) :end (:end e2)}
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
078 {:start (:start e1) :end (:start e2)})))
|
||||
080 {:start (:start e1) :end (:start e2)})))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
079
|
||||
081
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
080 (defn collinear2d?
|
||||
082 (defn collinear2d?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
081 "True if the projections of edges `e1`, `e2` onto the x, y plane are
|
||||
083 "True if the projections of edges `e1`, `e2` onto the x, y plane are
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
082 collinear."
|
||||
084 collinear."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
083 [e1 e2]
|
||||
085 [e1 e2]
|
||||
</span><br/>
|
||||
<span class="covered" title="15 out of 15 forms covered">
|
||||
084 (collinear? {:start (ensure2d (:start e1)) :end (ensure2d (:end e1))}
|
||||
086 (collinear? {:start (ensure2d (:start e1)) :end (ensure2d (:end e1))}
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
085 {:start (ensure2d (:start e2)) :end (ensure2d (:end e2))}))
|
||||
087 {:start (ensure2d (:start e2)) :end (ensure2d (:end e2))}))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
086
|
||||
088
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
087 (defn minimaxd
|
||||
089 (defn minimaxd
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
088 "Apply function `f` to `coord` of the vertices at start and end of `edge`
|
||||
090 "Apply function `f` to `coord` of the vertices at start and end of `edge`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
089 and return the result. Intended use case is `f` = `min` or `max`, `coord`
|
||||
091 and return the result. Intended use case is `f` = `min` or `max`, `coord`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 is `:x`, `:y` or `:z`. No checks are made for sane arguments."
|
||||
092 is `:x`, `:y` or `:z`. No checks are made for sane arguments."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
091 [edge coord f]
|
||||
093 [edge coord f]
|
||||
</span><br/>
|
||||
<span class="covered" title="15 out of 15 forms covered">
|
||||
092 (apply f (list (coord (:start edge)) (coord (:end edge)))))
|
||||
094 (apply f (list (coord (:start edge)) (coord (:end edge)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
093
|
||||
095
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
094 (defn on?
|
||||
096 (defn on?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
095 "True if the vertex `v` is on the edge `e`."
|
||||
097 "True if the vertex `v` is on the edge `e`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
096 [e v]
|
||||
098 [e v]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
097 (let [p (ensure3d (:start e))
|
||||
099 (let [p (ensure3d (:start e))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
098 q (ensure3d v)
|
||||
100 q (ensure3d v)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
099 r (ensure3d (:end e))]
|
||||
101 r (ensure3d (:end e))]
|
||||
</span><br/>
|
||||
<span class="partial" title="20 out of 25 forms covered">
|
||||
100 (and
|
||||
102 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
101 (collinear? (edge p q) (edge q r))
|
||||
103 (collinear? (edge p q) (edge q r))
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
102 (<= (:x q) (max (:x p) (:x r)))
|
||||
104 (<= (:x q) (max (:x p) (:x r)))
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
103 (>= (:x q) (min (:x p) (:x r)))
|
||||
105 (>= (:x q) (min (:x p) (:x r)))
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
104 (<= (:y q) (max (:y p) (:y r)))
|
||||
106 (<= (:y q) (max (:y p) (:y r)))
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
105 (>= (:y q) (min (:y p) (:y r)))
|
||||
107 (>= (:y q) (min (:y p) (:y r)))
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
106 (<= (:z q) (max (:z p) (:z r)))
|
||||
108 (<= (:z q) (max (:z p) (:z r)))
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
107 (>= (:z q) (min (:z p) (:z r))))))
|
||||
109 (>= (:z q) (min (:z p) (:z r))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
108
|
||||
110
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
109 (defn on2d?
|
||||
111 (defn on2d?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
110 "True if vertex `v` is on edge `e` when projected onto the x, y plane."
|
||||
112 "True if vertex `v` is on edge `e` when projected onto the x, y plane."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
111 [e v]
|
||||
113 [e v]
|
||||
</span><br/>
|
||||
<span class="covered" title="15 out of 15 forms covered">
|
||||
112 (on? (edge (ensure2d (:start e)) (ensure2d (:end e))) v))
|
||||
114 (on? (edge (ensure2d (:start e)) (ensure2d (:end e))) v))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
113
|
||||
115
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
114 (defn overlaps2d?
|
||||
116 (defn overlaps2d?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
115 "True if the recangle in the x,y plane bisected by edge `e1` overlaps that
|
||||
117 "True if the recangle in the x,y plane bisected by edge `e1` overlaps that
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
116 bisected by edge `e2`. It is an error if either `e1` or `e2` is not an edge."
|
||||
118 bisected by edge `e2`. It is an error if either `e1` or `e2` is not an edge."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
117 [e1 e2]
|
||||
119 [e1 e2]
|
||||
</span><br/>
|
||||
<span class="partial" title="11 out of 12 forms covered">
|
||||
118 (when (and (edge? e1) (edge? e2))
|
||||
120 (when (and (edge? e1) (edge? e2))
|
||||
</span><br/>
|
||||
<span class="partial" title="11 out of 13 forms covered">
|
||||
119 (and
|
||||
121 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
120 (> (minimaxd e1 :x max) (minimaxd e2 :x min))
|
||||
122 (> (minimaxd e1 :x max) (minimaxd e2 :x min))
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
121 (< (minimaxd e1 :x min) (minimaxd e2 :x max))
|
||||
123 (< (minimaxd e1 :x min) (minimaxd e2 :x max))
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
122 (> (minimaxd e1 :y max) (minimaxd e2 :y min))
|
||||
124 (> (minimaxd e1 :y max) (minimaxd e2 :y min))
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
123 (< (minimaxd e1 :y min) (minimaxd e2 :y max)))))
|
||||
125 (< (minimaxd e1 :y min) (minimaxd e2 :y max)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
124
|
||||
126
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
125 (defn intersection2d
|
||||
127 (defn intersection2d
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
126 "The probability of two lines intersecting in 3d space is low, and actually
|
||||
128 "The probability of two lines intersecting in 3d space is low, and actually
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
127 that is mostly not something we're interested in. We're interested in
|
||||
129 that is mostly not something we're interested in. We're interested in
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
128 intersection in the `x,y` plane. This function returns a vertex representing
|
||||
130 intersection in the `x,y` plane. This function returns a vertex representing
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
129 a point vertically over the intersection of edges `e1`, `e2` in the `x,y`
|
||||
131 a point vertically over the intersection of edges `e1`, `e2` in the `x,y`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
130 plane, whose `z` coordinate is
|
||||
132 plane, whose `z` coordinate is
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
131
|
||||
133
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
132 * 0 if both edges are 2d (i.e. have missing or zero `z` coordinates);
|
||||
134 * 0 if both edges are 2d (i.e. have missing or zero `z` coordinates);
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
133 * if one edge is 2d, then the point on the other edge over the intersection;
|
||||
135 * if one edge is 2d, then the point on the other edge over the intersection;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
134 * otherwise, the average of the z coordinates of the points on the two
|
||||
136 * otherwise, the average of the z coordinates of the points on the two
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
135 edges over the intersection.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
136
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
137 If no such intersection exists, `nil` is returned.
|
||||
137 edges over the intersection.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
138
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
139 It is an error, and an exception will be thrown, if either `e1` or `e2` is
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
140 not an edge."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
141 [e1 e2]
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
142 (if (and (edge? e1) (edge? e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
143 (when
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
144 (overlaps2d? e1 e2) ;; relatively cheap check
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
145 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
146 (collinear2d? e1 e2)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
147 ;; any point within the overlap will do, but we'll pick the end of e1
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
148 ;; which is on e2
|
||||
</span><br/>
|
||||
<span class="partial" title="10 out of 13 forms covered">
|
||||
149 (if (on2d? e2 (:start e1)) (:start e1) (:end e1))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
150 ;; blatantly stolen from
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
151 ;; https://gist.github.com/cassiel/3e725b49670356a9b936
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
152 (let [x1 (:x (:start e1))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
153 x2 (:x (:end e1))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
154 x3 (:x (:start e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
155 x4 (:x (:end e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
156 y1 (:y (:start e1))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
157 y2 (:y (:end e1))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
158 y3 (:y (:start e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
159 y4 (:y (:end e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
160 denom (- (* (- x1 x2) (- y3 y4))
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
161 (* (- y1 y2) (- x3 x4)))
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
162 x1y2-y1x2 (- (* x1 y2) (* y1 x2))
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
163 x3y4-y3x4 (- (* x3 y4) (* y3 x4))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
164 px-num (- (* x1y2-y1x2 (- x3 x4))
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
165 (* (- x1 x2) x3y4-y3x4))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
166 py-num (- (* x1y2-y1x2 (- y3 y4))
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
167 (* (- y1 y2) x3y4-y3x4))
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
168 result (when-not (zero? denom)
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
169 (vertex (/ px-num denom) (/ py-num denom)))]
|
||||
</span><br/>
|
||||
<span class="partial" title="19 out of 20 forms covered">
|
||||
170 (when (and result (on2d? e1 result) (on2d? e2 result)) result))))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
171 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
172 (str
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
173 "Both `e1` and `e2` must be edges."
|
||||
</span><br/>
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
174 (map #(or (:kind %) (type %)) [e1 e2]))))))
|
||||
139 If no such intersection exists, `nil` is returned.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
175
|
||||
140
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
141 It is an error, and an exception will be thrown, if either `e1` or `e2` is
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
142 not an edge."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
143 [e1 e2]
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
144 (if (and (edge? e1) (edge? e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
145 (when
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
146 (overlaps2d? e1 e2) ;; relatively cheap check
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
147 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
148 (collinear2d? e1 e2)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
149 ;; any point within the overlap will do, but we'll pick the end of e1
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
150 ;; which is on e2
|
||||
</span><br/>
|
||||
<span class="partial" title="10 out of 13 forms covered">
|
||||
151 (if (on2d? e2 (:start e1)) (:start e1) (:end e1))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
152 ;; blatantly stolen from
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
153 ;; https://gist.github.com/cassiel/3e725b49670356a9b936
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
154 (let [x1 (:x (:start e1))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
155 x2 (:x (:end e1))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
156 x3 (:x (:start e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
157 x4 (:x (:end e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
158 y1 (:y (:start e1))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
159 y2 (:y (:end e1))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
160 y3 (:y (:start e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
161 y4 (:y (:end e2))
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
162 denom (- (* (- x1 x2) (- y3 y4))
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
163 (* (- y1 y2) (- x3 x4)))
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
164 x1y2-y1x2 (- (* x1 y2) (* y1 x2))
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
165 x3y4-y3x4 (- (* x3 y4) (* y3 x4))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
166 px-num (- (* x1y2-y1x2 (- x3 x4))
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
167 (* (- x1 x2) x3y4-y3x4))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
168 py-num (- (* x1y2-y1x2 (- y3 y4))
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
169 (* (- y1 y2) x3y4-y3x4))
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
170 result (when-not (zero? denom)
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
171 (vertex (/ px-num denom) (/ py-num denom)))]
|
||||
</span><br/>
|
||||
<span class="partial" title="19 out of 20 forms covered">
|
||||
172 (when (and result (on2d? e1 result) (on2d? e2 result)) result))))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
173 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
174 (str
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
175 "Both `e1` and `e2` must be edges."
|
||||
</span><br/>
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
176 (map #(or (:kind %) (type %)) [e1 e2]))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
177
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -8,73 +8,76 @@
|
|||
001 (ns walkmap.ocean
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Deal with (specifically, at this stage, cull) ocean areas")
|
||||
002 "Deal with (specifically, at this stage, cull) ocean areas"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 (:require [walkmap.utils :refer [=ish]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
003
|
||||
004
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
004 (def ^:dynamic *sea-level*
|
||||
005 (def ^:dynamic *sea-level*
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 "The sea level on heightmaps we're currently handling. If characters are to
|
||||
006 "The sea level on heightmaps we're currently handling. If characters are to
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 be able to swin in the sea, we must model the sea bottom, so we need
|
||||
007 be able to swin in the sea, we must model the sea bottom, so we need
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 heightmaps which cover at least the continental shelf. However, the sea
|
||||
008 heightmaps which cover at least the continental shelf. However, the sea
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 bottom is not walkable territory and can be culled from walkmaps.
|
||||
009 bottom is not walkable territory and can be culled from walkmaps.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
009
|
||||
010
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 **Note** must be a floating point number. `(= 0 0.0)` returns `false`!"
|
||||
011 **Note** must be a floating point number. `(= 0 0.0)` returns `false`!"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 0.0)
|
||||
012 0.0)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
012
|
||||
013
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
013 (defn ocean?
|
||||
014 (defn ocean?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 "Of a `facet`, is the altitude of every vertice equal to `*sea-level*`?"
|
||||
015 "Of a `facet`, is the altitude of every vertice equal to `*sea-level*`?"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 [facet]
|
||||
016 [facet]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
016 (every?
|
||||
017 (every?
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
017 #(= % *sea-level*)
|
||||
018 #(=ish % *sea-level*)
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
018 (map :z (:vertices facet))))
|
||||
019 (map :z (:vertices facet))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
019
|
||||
020
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
020 (defn cull-ocean-facets
|
||||
021 (defn cull-ocean-facets
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 "Ye cannae walk on water. Remove all facets from this `stl` structure which
|
||||
022 "Ye cannae walk on water. Remove all facets from this `stl` structure which
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 are at sea level."
|
||||
023 are at sea level."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 [stl]
|
||||
024 [stl]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
024 (assoc stl :facets (remove ocean? (:facets stl))))
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
025 (assoc stl :facets (remove ocean? (:facets stl))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -23,238 +23,268 @@
|
|||
006 [walkmap.edge :as e]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 [walkmap.polygon :refer [polygon?]]
|
||||
007 [walkmap.polygon :refer [check-polygon polygon?]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 [walkmap.utils :refer [kind-type]]
|
||||
008 [walkmap.tag :refer [tag tags]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 [walkmap.vertex :refer [vertex?]]))
|
||||
009 [walkmap.utils :refer [check-kind-type check-kind-type-seq kind-type]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 [walkmap.vertex :refer [vertex?]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
010
|
||||
011
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
011 (defn path?
|
||||
012 (defn path?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 "True if `o` satisfies the conditions for a path. A path shall be a map
|
||||
013 "True if `o` satisfies the conditions for a path. A path shall be a map
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 having the key `:vertices`, whose value shall be a sequence of vertices as
|
||||
014 having the key `:vertices`, whose value shall be a sequence of vertices as
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 defined in `walkmap.vertex`."
|
||||
015 defined in `walkmap.vertex`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 [o]
|
||||
016 [o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
016 (let
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
017 (let
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
017 [v (:vertices o)]
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
018 [v (:vertices o)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 22 forms covered">
|
||||
018 (and
|
||||
<span class="partial" title="18 out of 22 forms covered">
|
||||
019 (and
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
019 (seq? v)
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
020 (seq? v)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
020 (> (count v) 2)
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
021 (> (count v) 1)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
021 (every? vertex? v)
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
022 (every? vertex? v)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
022 (:walkmap.id/id o)
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
023 (:walkmap.id/id o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
023 (or (nil? (:kind o)) (= (:kind o) :path)))))
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
024 (or (nil? (:kind o)) (= (:kind o) :path)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
024
|
||||
025
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
025 (defn path
|
||||
026 (defn path
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 "Return a path constructed from these `vertices`."
|
||||
027 "Return a path constructed from these `vertices`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 [& vertices]
|
||||
028 [& vertices]
|
||||
</span><br/>
|
||||
<span class="partial" title="6 out of 7 forms covered">
|
||||
028 (when-not (every? vertex? vertices)
|
||||
<span class="covered" title="26 out of 26 forms covered">
|
||||
029 (check-kind-type-seq vertices vertex? :vertex)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
029 (throw (IllegalArgumentException.
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
030 (if
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
030 (str
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 "Each item on path must be a vertex: "
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
032 (s/join " " (map kind-type (remove vertex? vertices)))))))
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
031 (> (count vertices) 1)
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
033 {:vertices vertices :walkmap.id/id (keyword (gensym "path")) :kind :path})
|
||||
032 {:vertices vertices :walkmap.id/id (keyword (gensym "path")) :kind :path}
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
033 (throw (IllegalArgumentException. "Path must have more than one vertex."))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
034
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
035 (defn polygon->path
|
||||
<span class="covered" title="22 out of 22 forms covered">
|
||||
035 (defmacro check-path
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 "If `o` is a polygon, return an equivalent path. What's different about
|
||||
036 "If `o` is not a path, throw an `IllegalArgumentException` with an
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 a path is that in polygons there is an implicit edge between the first
|
||||
037 appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 vertex and the last. In paths, there isn't, so we need to add that
|
||||
038 from the calling function."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 edge explicitly.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
040
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
041 If `o` is not a polygon, will throw an exception."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
042 [o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
043 (when-not (polygon? o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
044 (throw (IllegalArgumentException. (str "Not a polygon: " (kind-type o)))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
045 (assoc (dissoc o :vertices)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 :kind :path
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 ;; `concat` rather than `conj` because order matters.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 12 forms covered">
|
||||
048 :vertices (concat (:vertices o) (list (first (:vertices o))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
049
|
||||
039 [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
050 (defn path->edges
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 "if `o` is a path, a polygon, or a sequence of vertices, return a sequence of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 edges representing that path, polygon or sequence.
|
||||
040 `(check-kind-type ~o path? :path))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
053
|
||||
041
|
||||
</span><br/>
|
||||
<span class="covered" title="21 out of 21 forms covered">
|
||||
042 (defmacro check-paths
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 Throws `IllegalArgumentException` if `o` is not a path, a polygon, or
|
||||
043 "If `o` is not a sequence of paths, throw an `IllegalArgumentException` with an
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
055 sequence of vertices."
|
||||
044 appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 from the calling function."
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
046 [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
047 `(check-kind-type-seq ~o path? :path))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
048
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
049 (defn polygon->path
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050 "If `o` is a polygon, return an equivalent path. What's different about
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 a path is that in polygons there is an implicit edge between the first
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 vertex and the last. In paths, there isn't, so we need to add that
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 edge explicitly.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
054
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
055 If `o` is not a polygon, will throw an exception."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
056 [o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
057 (cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
058 (seq? o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
059 (when
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
060 (and
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
061 (vertex? (first o))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
062 (vertex? (first (rest o))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
063 (cons
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
057 ;; this is breaking, but I have NO IDEA why!
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
064 ;; TODO: think about: when constructing an edge from a path, should the
|
||||
058 ;; (check-polygon o polygon? :polygon)
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
059 (assoc (dissoc o :vertices)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
065 ;; constructed edge be tagged with the tags of the path?
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
066 (e/edge (first o) (rest o))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
067 (path->edges (rest o))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
068 (path? o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
069 (path->edges (:vertices o))
|
||||
060 :kind :path
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
070 :else
|
||||
061 ;; `concat` rather than `conj` because order matters.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
071 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
072 "Not a path or sequence of vertices!"))))
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
062 :vertices (concat (:vertices o) (list (first (:vertices o))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
073
|
||||
063
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
074 (defn length
|
||||
064 (defn path->edges
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
075 "Return the length of this path, in metres. **Note that**
|
||||
065 "if `o` is a path, a polygon, or a sequence of vertices, return a sequence of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076 1. This is not the same as the distance from the start to the end of the
|
||||
066 edges representing that path, polygon or sequence.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
067
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
077 path, which, except for absolutely straight paths, will be shorter;
|
||||
068 Throws `IllegalArgumentException` if `o` is not a path, a polygon, or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
078 2. It is not even quite the same as the length of the path *as rendered*,
|
||||
069 sequence of vertices."
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
070 [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
071 (cond
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
072 (seq? o) (when
|
||||
</span><br/>
|
||||
<span class="partial" title="4 out of 5 forms covered">
|
||||
073 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
074 (vertex? (first o))
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
075 (vertex? (first (rest o))))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
076 (cons
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
079 since paths will generally be rendered as spline curves."
|
||||
077 ;; TODO: think about: when constructing an edge from a path, should the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
080 [path]
|
||||
078 ;; constructed edge be tagged with the tags of the path?
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
081 (if
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
079 (e/edge (first o) (first (rest o)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
082 (path? path)
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
080 (path->edges (rest o))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
083 (reduce + (map e/length (path->edges path)))
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
081 (path? o) (path->edges (:vertices o))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
084 (throw (IllegalArgumentException. "Not a path!"))))
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
082 (polygon? o) (path->edges (polygon->path o))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
083 :else
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
084 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
085 "Not a path or sequence of vertices!"))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
086
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
087 (defn length
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
088 "Return the length of this path, in metres. **Note that**
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
089 1. This is not the same as the distance from the start to the end of the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 path, which, except for absolutely straight paths, will be shorter;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
091 2. It is not even quite the same as the length of the path *as rendered*,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
092 since paths will generally be rendered as spline curves."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
093 [path]
|
||||
</span><br/>
|
||||
<span class="partial" title="14 out of 24 forms covered">
|
||||
094 (reduce + (map e/length (path->edges (check-path path)))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
005 [walkmap.tag :as t]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 [walkmap.utils :refer [kind-type]]
|
||||
006 [walkmap.utils :refer [check-kind-type check-kind-type-seq kind-type]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 [walkmap.vertex :refer [vertex vertex?]]))
|
||||
007 [walkmap.vertex :refer [check-vertices vertex vertex?]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
008
|
||||
|
@ -49,7 +49,7 @@
|
|||
<span class="covered" title="3 out of 3 forms covered">
|
||||
015 [v (:vertices o)]
|
||||
</span><br/>
|
||||
<span class="partial" title="17 out of 22 forms covered">
|
||||
<span class="partial" title="18 out of 22 forms covered">
|
||||
016 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
|
@ -70,200 +70,230 @@
|
|||
<span class="blank" title="0 out of 0 forms covered">
|
||||
022
|
||||
</span><br/>
|
||||
<span class="covered" title="22 out of 22 forms covered">
|
||||
023 (defmacro check-polygon
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 "If `o` is not a polygon, throw an `IllegalArgumentException` with an
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 from the calling function."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
023 (defn triangle?
|
||||
028 `(check-kind-type ~o polygon? :polygon))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
029
|
||||
</span><br/>
|
||||
<span class="covered" title="21 out of 21 forms covered">
|
||||
030 (defmacro check-polygons
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 "True if `o` satisfies the conditions for a triangle. A triangle shall be a
|
||||
031 "If `o` is not a sequence of polygons, throw an `IllegalArgumentException` with an
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 polygon with exactly three vertices."
|
||||
032 appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 [o]
|
||||
033 from the calling function."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
035 `(check-kind-type-seq ~o polygon? :polygon))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
036
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
037 (defn triangle?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 "True if `o` satisfies the conditions for a triangle. A triangle shall be a
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 polygon with exactly three vertices."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 [o]
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 6 forms covered">
|
||||
027 (and
|
||||
041 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
028 (coll? o)
|
||||
042 (coll? o)
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
029 (= (count (:vertices o)) 3)))
|
||||
043 (= (count (:vertices o)) 3)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
030
|
||||
044
|
||||
</span><br/>
|
||||
<span class="covered" title="23 out of 23 forms covered">
|
||||
045 (defmacro check-triangle
|
||||
</span><br/>
|
||||
<span class="partial" title="2 out of 6 forms covered">
|
||||
046 "If `o` is not a triangle, throw an `IllegalArgumentException` with an
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
048 from the calling function."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
031 (defn polygon
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 "Return a polygon constructed from these `vertices`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 [vertices]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
034 (when-not (every? vertex? vertices)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
035 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
036 (str
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 "Each item on vertices must be a vertex: "
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
038 (s/join " " (map kind-type (remove vertex? vertices)))))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
039 {:vertices vertices :walkmap.id/id (keyword (gensym "poly")) :kind :polygon})
|
||||
050 `(check-kind-type ~o triangle? :triangle))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
040
|
||||
051
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
041 (defn gradient
|
||||
052 (defn polygon
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
042 "Return a polygon like `triangle` but with a key `:gradient` whose value is a
|
||||
053 "Return a polygon constructed from these `vertices`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043 unit vector representing the gradient across `triangle`."
|
||||
054 [& vertices]
|
||||
</span><br/>
|
||||
<span class="covered" title="30 out of 30 forms covered">
|
||||
055 {:vertices (check-vertices vertices)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
056 :walkmap.id/id (keyword (gensym "poly"))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044 [triangle]
|
||||
057 :kind :polygon})
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 6 forms covered">
|
||||
045 (when-not (triangle? triangle)
|
||||
<span class="blank" title="1 out of 1 forms covered">
|
||||
058
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
046 (throw (IllegalArgumentException.
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
059 (defn gradient
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
047 (s/join " " ["Must be a triangle:" (kind-type triangle)]))))
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
060 "Return a polygon like `triangle` but with a key `:gradient` whose value is a
|
||||
</span><br/>
|
||||
<span class="covered" title="15 out of 15 forms covered">
|
||||
048 (let [order (sort #(max (:z %1) (:z %2)) (:vertices triangle))
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
061 unit vector representing the gradient across `triangle`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
062 [triangle]
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
063 (let [order (sort #(max (:z %1) (:z %2))
|
||||
</span><br/>
|
||||
<span class="partial" title="8 out of 18 forms covered">
|
||||
064 (:vertices (check-triangle triangle)))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
049 highest (first order)
|
||||
065 highest (first order)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
050 lowest (last order)]
|
||||
066 lowest (last order)]
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
051 (assoc triangle :gradient (e/unit-vector (e/edge lowest highest)))))
|
||||
067 (assoc triangle :gradient (e/unit-vector (e/edge lowest highest)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
052
|
||||
068
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
053 (defn triangle-centre
|
||||
069 (defn triangle-centre
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
070 "Return a canonicalised `facet` (i.e. a triangular polygon) with an added
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 "Return a canonicalised `facet` (i.e. a triangular polygon) with an added
|
||||
071 key `:centre` whose value represents the centre of this facet in 3
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
055 key `:centre` whose value represents the centre of this facet in 3
|
||||
072 dimensions. This only works for triangles, so is here not in
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
056 dimensions. This only works for triangles, so is here not in
|
||||
073 `walkmap.polygon`. It is an error (although no exception is currently
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
057 `walkmap.polygon`. It is an error (although no exception is currently
|
||||
074 thrown) if the object past is not a triangular polygon."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 thrown) if the object past is not a triangular polygon."
|
||||
075 [facet]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059 [facet]
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 6 forms covered">
|
||||
060 (when-not (triangle? facet)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
061 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
062 (s/join " " ["Must be a triangle:" (kind-type facet)]))))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
063 (let [vs (:vertices facet)
|
||||
<span class="partial" title="9 out of 19 forms covered">
|
||||
076 (let [vs (:vertices (check-triangle facet))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
064 v1 (first vs)
|
||||
077 v1 (first vs)
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
065 opposite (e/edge (nth vs 1) (nth vs 2))
|
||||
078 opposite (e/edge (nth vs 1) (nth vs 2))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
066 oc (e/centre opposite)]
|
||||
079 oc (e/centre opposite)]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
067 (assoc
|
||||
080 (assoc
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
068 facet
|
||||
081 facet
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
069 :centre
|
||||
082 :centre
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
070 (vertex
|
||||
083 (vertex
|
||||
</span><br/>
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
071 (+ (:x v1) (* (- (:x oc) (:x v1)) 2/3))
|
||||
084 (+ (:x v1) (* (- (:x oc) (:x v1)) 2/3))
|
||||
</span><br/>
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
072 (+ (:y v1) (* (- (:y oc) (:y v1)) 2/3))
|
||||
085 (+ (:y v1) (* (- (:y oc) (:y v1)) 2/3))
|
||||
</span><br/>
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
073 (+ (:z v1) (* (- (:z oc) (:z v1)) 2/3))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
074
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
075 (defn centre
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076 [poly]
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 6 forms covered">
|
||||
077 (when-not (polygon? poly)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
078 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
079 (s/join " " ["Must be a polygon:" (kind-type poly)]))))
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
080 (case (count (:vertices poly))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
081 3 (triangle-centre poly)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
082 ;; else
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
083 (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
084 (UnsupportedOperationException.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
085 "The general case of centre for polygons is not yet implemented."))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
086
|
||||
086 (+ (:z v1) (* (- (:z oc) (:z v1)) 2/3))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
087
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
088 (defn centre
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
089 [poly]
|
||||
</span><br/>
|
||||
<span class="covered" title="22 out of 22 forms covered">
|
||||
090 (case (count (:vertices (check-polygon poly)))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
091 3 (triangle-centre poly)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
092 ;; else
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
093 (throw
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
094 (UnsupportedOperationException.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
095 "The general case of centre for polygons is not yet implemented."))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
096
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
097
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -550,7 +550,7 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
182 ([filename stl solidname]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 16 forms covered">
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
183 (l/debug "Solid name is " solidname)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
|
|
|
@ -355,7 +355,7 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
117 ([o s]
|
||||
</span><br/>
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
118 (l/debug "Finding objects in:" o)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
|
|
|
@ -274,7 +274,7 @@
|
|||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
090 (:facets stl)))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 17 forms covered">
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
091 (l/info "Generating SVG for " *preferred-svg-render* " renderer")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
|
@ -316,7 +316,7 @@
|
|||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
104 (let [s (binary-stl-file->svg in-filename)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 17 forms covered">
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
105 (l/info "Emitting SVG with " *preferred-svg-render* " renderer")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 [object & tags]
|
||||
</span><br/>
|
||||
<span class="covered" title="20 out of 20 forms covered">
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
039 (l/debug "Tagging" (kind-type object) "with" tags)
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
|
|
|
@ -11,127 +11,301 @@
|
|||
002 "Miscellaneous utility functions."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 (:require [clojure.math.numeric-tower :as m]))
|
||||
003 (:require [clojure.math.numeric-tower :as m]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 [clojure.string :as s]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
004
|
||||
005
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
005 (defn deep-merge
|
||||
006 (defn deep-merge
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 "Recursively merges maps. If vals are not maps, the last value wins."
|
||||
007 "Recursively merges maps. If vals are not maps, the last value wins."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 ;; TODO: not my implementation, not sure I entirely trust it.
|
||||
008 ;; TODO: not my implementation, not sure I entirely trust it.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 ;; TODO TODO: if we are to successfully merge walkmap objects, we must
|
||||
009 ;; TODO TODO: if we are to successfully merge walkmap objects, we must
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 ;; return, on each object, the union of its tags if any.
|
||||
010 ;; return, on each object, the union of its tags if any.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 [& vals]
|
||||
011 [& vals]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
011 (if (every? map? vals)
|
||||
012 (if (every? map? vals)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
012 (apply merge-with deep-merge vals)
|
||||
013 (apply merge-with deep-merge vals)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
013 (last vals)))
|
||||
014 (last vals)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
014
|
||||
015
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
015 (defn truncate
|
||||
016 (defn truncate
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 "If string `s` is more than `n` characters long, return the first `n`
|
||||
017 "If string `s` is more than `n` characters long, return the first `n`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 characters; otherwise, return `s`."
|
||||
018 characters; otherwise, return `s`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 [s n]
|
||||
019 [s n]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 21 forms covered">
|
||||
019 (if (and (string? s) (number? n) (> (count s) n))
|
||||
020 (if (and (string? s) (number? n) (> (count s) n))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
020 (subs s 0 n)
|
||||
021 (subs s 0 n)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
021 s))
|
||||
022 s))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
022
|
||||
023
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
023 (defn kind-type
|
||||
024 (defn kind-type
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 "Identify the type of an `object`, e.g. for logging. If it has a `:kind` key,
|
||||
025 "Identify the type of an `object`, e.g. for logging. If it has a `:kind` key,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 it's one of ours, and that's what we want. Otherwise, we want its type; but
|
||||
026 it's one of ours, and that's what we want. Otherwise, we want its type; but
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 the type of `nil` is `nil`, which doesn't get printed when assembling error
|
||||
027 the type of `nil` is `nil`, which doesn't get printed when assembling error
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 ,essages, so return \"nil\"."
|
||||
028 ,essages, so return \"nil\"."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 [object]
|
||||
029 [object]
|
||||
</span><br/>
|
||||
<span class="partial" title="14 out of 15 forms covered">
|
||||
029 (or (:kind object) (type object) "nil"))
|
||||
030 (or (:kind object) (type object) "nil"))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
030
|
||||
031
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
031 (defn =ish
|
||||
032 (defn =ish
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 "True if numbers `n1`, `n2` are roughly equal; that is to say, equal to
|
||||
033 "True if numbers `n1`, `n2` are roughly equal; that is to say, equal to
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 within `tolerance` (defaults to one part in a million)."
|
||||
034 within `tolerance` (defaults to one part in a million)."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 ([n1 n2]
|
||||
035 ([n1 n2]
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
035 (if (and (number? n1) (number? n2))
|
||||
036 (if (and (number? n1) (number? n2))
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
036 (let [m (m/abs (min n1 n2))
|
||||
037 (let [m (m/abs (min n1 n2))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
037 t (if (zero? m) 0.000001 (* 0.000001 m))]
|
||||
038 t (if (zero? m) 0.000001 (* 0.000001 m))]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
038 (=ish n1 n2 t))
|
||||
039 (=ish n1 n2 t))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
039 (= n1 n2)))
|
||||
040 (= n1 n2)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 ([n1 n2 tolerance]
|
||||
041 ([n1 n2 tolerance]
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
041 (if (and (number? n1) (number? n2))
|
||||
042 (if (and (number? n1) (number? n2))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
042 (< (m/abs (- n1 n2)) tolerance)
|
||||
043 (< (m/abs (- n1 n2)) tolerance)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
043 (= n1 n2))))
|
||||
044 (= n1 n2))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
045
|
||||
</span><br/>
|
||||
<span class="partial" title="94 out of 198 forms covered">
|
||||
046 (defmacro check-kind-type
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 "If `object` is not of kind-type `expected`, throws an
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
048 IllegalArgumentException with an appropriate message; otherwise, returns
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 `object`. If `checkfn` is supplied, it should be a function which tests
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050 whether the object is of the expected kind-type.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
051
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 Macro, so that the exception is thrown from the calling function."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 ([object expected]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
054 `(if-not (= (kind-type ~object) ~expected)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
055 (throw
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
056 (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
057 (s/join
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 " "
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
059 ["Expected" ~expected "but found" (kind-type ~object)])))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
060 ~object))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
061 ([object checkfn expected]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
062 `(if-not (~checkfn ~object)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
063 (throw
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
064 (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
065 (s/join
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 " "
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
067 ["Expected" ~expected "but found" (kind-type ~object)])))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
068 ~object)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
069
|
||||
</span><br/>
|
||||
<span class="partial" title="203 out of 416 forms covered">
|
||||
070 (defmacro check-kind-type-seq
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 "If some item on sequence `s` is not of the `expected` kind-type, throws an
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
072 IllegalArgumentException with an appropriate message; otherwise, returns
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
073 `object`. If `checkfn` is supplied, it should be a function which tests
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
074 whether the object is of the expected kind-type.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
075
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076 Macro, so that the exception is thrown from the calling function."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
077 ([s expected]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
078 `(if-not (every? #(= (kind-type %) ~expected) ~s)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
079 (throw
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
080 (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
081 (s/join
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
082 " "
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
083 ["Expected sequence of"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
084 ~expected
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
085 "but found ("
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
086 (s/join ", " (remove #(= ~expected %) (map kind-type ~s)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
087 ")"])))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
088 ~s))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
089 ([s checkfn expected]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
090 `(if-not (every? #(~checkfn %) ~s)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
091 (throw
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
092 (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
093 (s/join
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
094 " "
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
095 ["Expected sequence of"
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
096 ~expected
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
097 "but found ("
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
098 (s/join ", " (remove #(= ~expected %) (map kind-type ~s)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
099 ")"])))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
100 ~s)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
101
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
008 [taoensso.timbre :as l]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 [walkmap.utils :refer [=ish kind-type truncate]]))
|
||||
009 [walkmap.utils :refer [=ish check-kind-type check-kind-type-seq kind-type truncate]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
010
|
||||
|
@ -139,7 +139,7 @@
|
|||
<span class="covered" title="3 out of 3 forms covered">
|
||||
045 (:walkmap.id/id o)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
<span class="partial" title="7 out of 17 forms covered">
|
||||
046 (number? (:x o))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
|
@ -154,299 +154,302 @@
|
|||
<span class="blank" title="0 out of 0 forms covered">
|
||||
050
|
||||
</span><br/>
|
||||
<span class="covered" title="27 out of 27 forms covered">
|
||||
051 (defmacro check-vertex
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 "If `o` is not a vertex, throw an `IllegalArgumentException` with an
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 from the calling function."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
055 [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
051 (defn vertex=
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 "True if vertices `v1`, `v2` represent the same vertex."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 [v1 v2]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
054 (every?
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
055 #(=ish (% v1) (% v2))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
056 [:x :y :z]))
|
||||
056 `(check-kind-type ~o vertex? :vertex))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
057
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
058 (defn vertex*
|
||||
<span class="partial" title="21 out of 22 forms covered">
|
||||
058 (defmacro check-vertices
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059 "Return a vertex like `v1`, but with each of its coordinates multiplied
|
||||
059 "If `o` is not a sequence of vertices, throw an `IllegalArgumentException` with an
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
060 by the equivalent vertex in `v2`."
|
||||
060 appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
061 [v1 v2]
|
||||
061 from the calling function."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
062 [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
062 (if
|
||||
</span><br/>
|
||||
<span class="partial" title="9 out of 10 forms covered">
|
||||
063 (and (vertex? v1) (vertex? v2))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
064 (let [f (fn [v1 v2 coord]
|
||||
</span><br/>
|
||||
<span class="partial" title="9 out of 10 forms covered">
|
||||
065 (* (or (coord v1) 0)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 ;; one here is deliberate!
|
||||
</span><br/>
|
||||
<span class="partial" title="7 out of 8 forms covered">
|
||||
067 (or (coord v2) 1)))]
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
068 (assoc v1 :x (f v1 v2 :x)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
069 :y (f v1 v2 :y)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
070 :z (f v1 v2 :z)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 15 forms covered">
|
||||
071 (do (l/warn
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
072 (s/join
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
073 " "
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
074 ["in `vertex-multiply`, both must be vectors. v1:" v1 "v2:" v2]))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
075 v1)))
|
||||
063 `(check-kind-type-seq ~o vertex? :vertex))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
076
|
||||
064
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
077 (defn vertex
|
||||
065 (defn vertex=
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
078 "Make a vertex with this `x`, `y` and (if provided) `z` values. Returns a map
|
||||
066 "True if vertices `v1`, `v2` represent the same vertex."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
079 with those values, plus a unique `:walkmap.id/id` value, and `:kind` set to `:vertex`.
|
||||
067 [v1 v2]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
080 It's not necessary to use this function to create a vertex, but the `:walkmap.id/id`
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
068 (check-vertex v1)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
081 must be present and must be unique."
|
||||
<span class="partial" title="6 out of 16 forms covered">
|
||||
069 (check-vertex v2)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
082 ([x y]
|
||||
<span class="partial" title="3 out of 12 forms covered">
|
||||
070 (every?
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
083 (let [v {:x x :y y :kind :vertex}]
|
||||
071 #(=ish (% v1) (% v2))
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
084 (assoc v :walkmap.id/id (vertex-key v))))
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
072 [:x :y :z]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
073
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
074 (defn vertex*
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
085 ([x y z]
|
||||
075 "Return a vertex like `v1`, but with each of its coordinates multiplied
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
086 (let [v (assoc (vertex x y) :z z)]
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076 by the equivalent vertex in `v2`. It is an error, and an exception will
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
087 (assoc v :walkmap.id/id (vertex-key v)))))
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
077 be thrown, if either `v1` or `v2` is not a vertex."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
078 [v1 v2]
|
||||
</span><br/>
|
||||
<span class="partial" title="6 out of 16 forms covered">
|
||||
079 (check-vertex v1)
|
||||
</span><br/>
|
||||
<span class="partial" title="6 out of 16 forms covered">
|
||||
080 (check-vertex v2)
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
081 (let [f (fn [v1 v2 coord]
|
||||
</span><br/>
|
||||
<span class="partial" title="9 out of 10 forms covered">
|
||||
082 (* (or (coord v1) 0)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
083 ;; one here is deliberate!
|
||||
</span><br/>
|
||||
<span class="partial" title="7 out of 8 forms covered">
|
||||
084 (or (coord v2) 1)))]
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
085 (assoc v1 :x (f v1 v2 :x)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
086 :y (f v1 v2 :y)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
087 :z (f v1 v2 :z))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
088
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
089 (defn canonicalise
|
||||
089 (defn vertex
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 "If `o` is a map with numeric values for `:x`, `:y` and optionally `:z`,
|
||||
090 "Make a vertex with this `x`, `y` and (if provided) `z` values. Returns a map
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
091 upgrade it to something we will recognise as a vertex."
|
||||
091 with those values, plus a unique `:walkmap.id/id` value, and `:kind` set to `:vertex`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
092 [o]
|
||||
092 It's not necessary to use this function to create a vertex, but the `:walkmap.id/id`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
093 must be present and must be unique."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
094 ([x y]
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
095 (let [v {:x x :y y :kind :vertex}]
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
096 (assoc v :walkmap.id/id (vertex-key v))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
097 ([x y z]
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
098 (let [v {:x x :y y :z z :kind :vertex}]
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
099 (assoc v :walkmap.id/id (vertex-key v)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
100
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
093 (if
|
||||
101 (defn canonicalise
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
102 "If `o` is a map with numeric values for `:x`, `:y` and optionally `:z`,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
103 upgrade it to something we will recognise as a vertex."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
104 [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
105 (if
|
||||
</span><br/>
|
||||
<span class="partial" title="13 out of 17 forms covered">
|
||||
094 (and
|
||||
106 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
095 (map? o)
|
||||
107 (map? o)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
096 (number? (:x o))
|
||||
108 (number? (:x o))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
097 (number? (:y o))
|
||||
109 (number? (:y o))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
098 (or (nil? (:z o)) (number? (:z o))))
|
||||
110 (or (nil? (:z o)) (number? (:z o))))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
099 (assoc o :kind :vertex :walkmap.id/id (vertex-key o))
|
||||
111 (assoc o :kind :vertex :walkmap.id/id (vertex-key o))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
100 (throw
|
||||
112 (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
101 (IllegalArgumentException.
|
||||
113 (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
102 (truncate
|
||||
114 (truncate
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
103 (str "Not a proto-vertex: must have numeric `:x` and `:y`: "
|
||||
115 (str "Not a proto-vertex: must have numeric `:x` and `:y`: "
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
104 (or o "nil"))
|
||||
116 (or o "nil"))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
105 80)))))
|
||||
117 80)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
106
|
||||
118
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
107 (def ensure3d
|
||||
119 (def ensure3d
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
108 "Given a vertex `o`, if `o` has a `:z` value, just return `o`; otherwise
|
||||
120 "Given a vertex `o`, if `o` has a `:z` value, just return `o`; otherwise
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
109 return a vertex like `o` but having thie `dflt` value as the value of its
|
||||
121 return a vertex like `o` but having this `dflt` value as the value of its
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
110 `:z` key, or zero as the value of its `:z` key if `dflt` is not specified.
|
||||
122 `:z` key, or zero as the value of its `:z` key if `dflt` is not specified.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
111
|
||||
123
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
112 If `o` is not a vertex, throws an exception."
|
||||
124 If `o` is not a vertex, throws an exception."
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
113 (memoize
|
||||
125 (memoize
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
114 (fn
|
||||
126 (fn
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
115 ([o]
|
||||
127 ([o]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
116 (ensure3d o 0.0))
|
||||
128 (ensure3d o 0.0))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
117 ([o dflt]
|
||||
129 ([o dflt]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
118 (cond
|
||||
<span class="partial" title="9 out of 19 forms covered">
|
||||
130 (if (:z (check-vertex o))
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 6 forms covered">
|
||||
119 (not (vertex? o)) (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
120 (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 12 forms covered">
|
||||
121 (truncate (str "Not a vertex: " (or o "nil")) 80)))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
122 (:z o) o
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
131 o
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
123 :else (assoc o :z dflt))))))
|
||||
132 (assoc o :z dflt))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
124
|
||||
133
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
125 (def ensure2d
|
||||
134 (def ensure2d
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
126 "If `o` is a vertex, set its `:z` value to zero; else throw an exception."
|
||||
135 "If `o` is a vertex, set its `:z` value to zero; else throw an exception."
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
127 (memoize
|
||||
136 (memoize
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
128 (fn [o]
|
||||
137 (fn [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
129 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
130 (vertex? o)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
131 (assoc o :z 0.0)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
132 (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
133 (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 12 forms covered">
|
||||
134 (truncate (str "Not a vertex: " (or o "nil")) 80)))))))
|
||||
<span class="partial" title="10 out of 20 forms covered">
|
||||
138 (assoc (check-vertex o) :z 0.0))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
135
|
||||
139
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
136 (defn within-box?
|
||||
140 (defn within-box?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
137 "True if `target` is within the box defined by `minv` and `maxv`. All
|
||||
141 "True if `target` is within the box defined by `minv` and `maxv`. All
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
138 arguments must be vertices; additionally, both `minv` and `maxv` must
|
||||
142 arguments must be vertices; additionally, both `minv` and `maxv` must
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
139 have `:z` coordinates."
|
||||
143 have `:z` coordinates."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
140 [target minv maxv]
|
||||
144 [target minv maxv]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 20 forms covered">
|
||||
141 (when-not (and (vertex? target) (vertex? minv) (vertex? maxv))
|
||||
<span class="not-covered" title="0 out of 34 forms covered">
|
||||
145 (check-vertices [target minv maxv])
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
142 (throw (IllegalArgumentException.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
143 (s/join " " ["Arguments to `within-box?` must be vertices:"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
144 (map kind-type [target minv maxv])]))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
145 (every?
|
||||
146 (every?
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
146 (map
|
||||
147 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 16 forms covered">
|
||||
147 #(< (% minv) (or (% target) 0) (% maxv))
|
||||
148 #(< (% minv) (or (% target) 0) (% maxv))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
148 [:x :y :z])))
|
||||
149 [:x :y :z])))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>Dali performance</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="dali-performance.html"><div class="inner"><span>Dali performance</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.ocean.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ocean</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.superstructure.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>superstructure</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.tag.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>tag</span></div></a></li><li class="depth-2 branch"><a href="walkmap.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#dali-performance" name="dali-performance"></a>Dali performance</h1>
|
||||
<html><head><meta charset="UTF-8" /><title>Dali performance</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="dali-performance.html"><div class="inner"><span>Dali performance</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.id.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>id</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.read-svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read-svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.routing.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>routing</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.superstructure.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>superstructure</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.tag.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>tag</span></div></a></li><li class="depth-2 branch"><a href="walkmap.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#dali-performance" name="dali-performance"></a>Dali performance</h1>
|
||||
<p>Notes written while trying to characterise the performance problem in Dali.</p>
|
||||
<h2><a href="#hypothesis-one-its-the-way-i-format-the-polygons-thats-the-issue" name="hypothesis-one-its-the-way-i-format-the-polygons-thats-the-issue"></a>Hypothesis one: it’s the way I format the polygons that’s the issue</h2>
|
||||
<p>Firstly, with both versions of <code>stl->svg</code> using the same version of <code>facet->svg-poly</code>, i.e. this one:</p>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>Introduction to walkmap</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="dali-performance.html"><div class="inner"><span>Dali performance</span></div></a></li><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.geometry.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>geometry</span></div></a></li><li class="depth-2 branch"><a href="walkmap.ocean.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ocean</span></div></a></li><li class="depth-2 branch"><a href="walkmap.path.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>path</span></div></a></li><li class="depth-2 branch"><a href="walkmap.polygon.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>polygon</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.superstructure.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>superstructure</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.tag.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>tag</span></div></a></li><li class="depth-2 branch"><a href="walkmap.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#introduction-to-walkmap" name="introduction-to-walkmap"></a>Introduction to walkmap</h1>
|
||||
<html><head><meta charset="UTF-8" /><title>Introduction to walkmap</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Walkmap</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="dali-performance.html"><div class="inner"><span>Dali performance</span></div></a></li><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>Introduction to walkmap</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>walkmap</span></div></div></li><li class="depth-2 branch"><a href="walkmap.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.id.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>id</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.read-svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read-svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.routing.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>routing</span></div></a></li><li class="depth-2 branch"><a href="walkmap.stl.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>stl</span></div></a></li><li class="depth-2 branch"><a href="walkmap.superstructure.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>superstructure</span></div></a></li><li class="depth-2 branch"><a href="walkmap.svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.tag.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>tag</span></div></a></li><li class="depth-2 branch"><a href="walkmap.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="walkmap.vertex.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>vertex</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#introduction-to-walkmap" name="introduction-to-walkmap"></a>Introduction to walkmap</h1>
|
||||
<p>This library is written in support of work on <a href="https://simon-brooke.github.io/the-great-game/codox/Pathmaking.html">The Great Game</a>, but is separate because it may be of some use in other settings.</p>
|
||||
<h2><a href="#usage" name="usage"></a>Usage</h2>
|
||||
<p>What works:</p>
|
||||
|
|
File diff suppressed because one or more lines are too long
3
docs/codox/walkmap.id.html
Normal file
3
docs/codox/walkmap.id.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>walkmap.id 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.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.id.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>id</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.read-svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read-svg</span></div></a></li><li class="depth-2 branch"><a href="walkmap.routing.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>routing</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.id.html#var-id"><div class="inner"><span>id</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">walkmap.id</h1><div class="doc"><div class="markdown"><p>The namespace within which the privileged keyword <code>:walkmap.id/id</code> is defined.</p></div></div><div class="public anchor" id="var-id"><h3>id</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>The magic id key walkmap uses, to distinguish it from all other uses of the unprotected keyword.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/walkmap/blob/master/src/walkmap/id.clj#L4">view source</a></div></div></div></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
docs/codox/walkmap.read-svg.html
Normal file
3
docs/codox/walkmap.read-svg.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/codox/walkmap.routing.html
Normal file
3
docs/codox/walkmap.routing.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>walkmap.routing 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.edge.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>edge</span></div></a></li><li class="depth-2 branch"><a href="walkmap.id.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>id</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.read-svg.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read-svg</span></div></a></li><li class="depth-2 branch current"><a href="walkmap.routing.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>routing</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.routing</h1><div class="doc"><div class="markdown"><p>Finding optimal routes to traverse a map.</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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -4,7 +4,8 @@
|
|||
:doc/format :markdown}
|
||||
:output-path "docs/codox"
|
||||
:source-uri "https://github.com/simon-brooke/walkmap/blob/master/{filepath}#L{line}"}
|
||||
:dependencies [[org.clojure/clojure "1.8.0"]
|
||||
:dependencies [[org.clojure/algo.generic "0.1.3"]
|
||||
[org.clojure/clojure "1.8.0"]
|
||||
[org.clojure/data.zip "1.0.0"]
|
||||
[org.clojure/math.numeric-tower "0.0.4"]
|
||||
[org.clojure/math.combinatorics "0.1.6"]
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
An edge is a line segment having just a start and an end, with no intervening
|
||||
nodes."
|
||||
(:require [clojure.math.numeric-tower :as m]
|
||||
[walkmap.vertex :refer [ensure2d ensure3d vertex vertex= vertex?]]))
|
||||
[walkmap.utils :as u]
|
||||
[walkmap.vertex :refer [canonicalise ensure2d ensure3d vertex vertex= vertex?]]))
|
||||
|
||||
(defn edge
|
||||
"Return an edge between vertices `v1` and `v2`."
|
||||
|
@ -51,13 +52,14 @@
|
|||
[e]
|
||||
(let [e' {:start (ensure3d (:start e)) :end (ensure3d (:end e))}
|
||||
l (length e')]
|
||||
(reduce
|
||||
merge
|
||||
{}
|
||||
(map
|
||||
(fn [k]
|
||||
{k (/ (- (k (:end e')) (k (:start e'))) l)})
|
||||
[:x :y :z]))))
|
||||
(canonicalise
|
||||
(reduce
|
||||
merge
|
||||
{}
|
||||
(map
|
||||
(fn [k]
|
||||
{k (/ (- (k (:end e')) (k (:start e'))) l)})
|
||||
[:x :y :z])))))
|
||||
|
||||
(defn parallel?
|
||||
"True if all `edges` passed are parallel with one another."
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(ns walkmap.ocean
|
||||
"Deal with (specifically, at this stage, cull) ocean areas")
|
||||
"Deal with (specifically, at this stage, cull) ocean areas"
|
||||
(:require [walkmap.utils :refer [=ish]]))
|
||||
|
||||
(def ^:dynamic *sea-level*
|
||||
"The sea level on heightmaps we're currently handling. If characters are to
|
||||
|
@ -14,7 +15,7 @@
|
|||
"Of a `facet`, is the altitude of every vertice equal to `*sea-level*`?"
|
||||
[facet]
|
||||
(every?
|
||||
#(= % *sea-level*)
|
||||
#(=ish % *sea-level*)
|
||||
(map :z (:vertices facet))))
|
||||
|
||||
(defn cull-ocean-facets
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
feature, where such features specifically include watercourses."
|
||||
(:require [clojure.string :as s]
|
||||
[walkmap.edge :as e]
|
||||
[walkmap.polygon :refer [polygon?]]
|
||||
[walkmap.utils :refer [kind-type]]
|
||||
[walkmap.polygon :refer [check-polygon polygon?]]
|
||||
[walkmap.tag :refer [tag tags]]
|
||||
[walkmap.utils :refer [check-kind-type check-kind-type-seq kind-type]]
|
||||
[walkmap.vertex :refer [vertex?]]))
|
||||
|
||||
(defn path?
|
||||
|
@ -17,7 +18,7 @@
|
|||
[v (:vertices o)]
|
||||
(and
|
||||
(seq? v)
|
||||
(> (count v) 2)
|
||||
(> (count v) 1)
|
||||
(every? vertex? v)
|
||||
(:walkmap.id/id o)
|
||||
(or (nil? (:kind o)) (= (:kind o) :path)))))
|
||||
|
@ -25,12 +26,25 @@
|
|||
(defn path
|
||||
"Return a path constructed from these `vertices`."
|
||||
[& vertices]
|
||||
(when-not (every? vertex? vertices)
|
||||
(throw (IllegalArgumentException.
|
||||
(str
|
||||
"Each item on path must be a vertex: "
|
||||
(s/join " " (map kind-type (remove vertex? vertices)))))))
|
||||
{:vertices vertices :walkmap.id/id (keyword (gensym "path")) :kind :path})
|
||||
(check-kind-type-seq vertices vertex? :vertex)
|
||||
(if
|
||||
(> (count vertices) 1)
|
||||
{:vertices vertices :walkmap.id/id (keyword (gensym "path")) :kind :path}
|
||||
(throw (IllegalArgumentException. "Path must have more than one vertex."))))
|
||||
|
||||
(defmacro check-path
|
||||
"If `o` is not a path, throw an `IllegalArgumentException` with an
|
||||
appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
from the calling function."
|
||||
[o]
|
||||
`(check-kind-type ~o path? :path))
|
||||
|
||||
(defmacro check-paths
|
||||
"If `o` is not a sequence of paths, throw an `IllegalArgumentException` with an
|
||||
appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
from the calling function."
|
||||
[o]
|
||||
`(check-kind-type-seq ~o path? :path))
|
||||
|
||||
(defn polygon->path
|
||||
"If `o` is a polygon, return an equivalent path. What's different about
|
||||
|
@ -40,8 +54,8 @@
|
|||
|
||||
If `o` is not a polygon, will throw an exception."
|
||||
[o]
|
||||
(when-not (polygon? o)
|
||||
(throw (IllegalArgumentException. (str "Not a polygon: " (kind-type o)))))
|
||||
;; this is breaking, but I have NO IDEA why!
|
||||
;; (check-polygon o polygon? :polygon)
|
||||
(assoc (dissoc o :vertices)
|
||||
:kind :path
|
||||
;; `concat` rather than `conj` because order matters.
|
||||
|
@ -55,18 +69,17 @@
|
|||
sequence of vertices."
|
||||
[o]
|
||||
(cond
|
||||
(seq? o)
|
||||
(when
|
||||
(and
|
||||
(vertex? (first o))
|
||||
(vertex? (first (rest o))))
|
||||
(cons
|
||||
;; TODO: think about: when constructing an edge from a path, should the
|
||||
;; constructed edge be tagged with the tags of the path?
|
||||
(e/edge (first o) (rest o))
|
||||
(path->edges (rest o))))
|
||||
(path? o)
|
||||
(path->edges (:vertices o))
|
||||
(seq? o) (when
|
||||
(and
|
||||
(vertex? (first o))
|
||||
(vertex? (first (rest o))))
|
||||
(cons
|
||||
;; TODO: think about: when constructing an edge from a path, should the
|
||||
;; constructed edge be tagged with the tags of the path?
|
||||
(e/edge (first o) (first (rest o)))
|
||||
(path->edges (rest o))))
|
||||
(path? o) (path->edges (:vertices o))
|
||||
(polygon? o) (path->edges (polygon->path o))
|
||||
:else
|
||||
(throw (IllegalArgumentException.
|
||||
"Not a path or sequence of vertices!"))))
|
||||
|
@ -78,7 +91,4 @@
|
|||
2. It is not even quite the same as the length of the path *as rendered*,
|
||||
since paths will generally be rendered as spline curves."
|
||||
[path]
|
||||
(if
|
||||
(path? path)
|
||||
(reduce + (map e/length (path->edges path)))
|
||||
(throw (IllegalArgumentException. "Not a path!"))))
|
||||
(reduce + (map e/length (path->edges (check-path path)))))
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
(:require [clojure.string :as s]
|
||||
[walkmap.edge :as e]
|
||||
[walkmap.tag :as t]
|
||||
[walkmap.utils :refer [kind-type]]
|
||||
[walkmap.vertex :refer [vertex vertex?]]))
|
||||
[walkmap.utils :refer [check-kind-type check-kind-type-seq kind-type]]
|
||||
[walkmap.vertex :refer [check-vertices vertex vertex?]]))
|
||||
|
||||
(defn polygon?
|
||||
"True if `o` satisfies the conditions for a polygon. A polygon shall be a
|
||||
|
@ -20,6 +20,20 @@
|
|||
(:walkmap.id/id o)
|
||||
(or (nil? (:kind o)) (= (:kind o) :polygon)))))
|
||||
|
||||
(defmacro check-polygon
|
||||
"If `o` is not a polygon, throw an `IllegalArgumentException` with an
|
||||
appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
from the calling function."
|
||||
[o]
|
||||
`(check-kind-type ~o polygon? :polygon))
|
||||
|
||||
(defmacro check-polygons
|
||||
"If `o` is not a sequence of polygons, throw an `IllegalArgumentException` with an
|
||||
appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
from the calling function."
|
||||
[o]
|
||||
`(check-kind-type-seq ~o polygon? :polygon))
|
||||
|
||||
(defn triangle?
|
||||
"True if `o` satisfies the conditions for a triangle. A triangle shall be a
|
||||
polygon with exactly three vertices."
|
||||
|
@ -28,24 +42,26 @@
|
|||
(coll? o)
|
||||
(= (count (:vertices o)) 3)))
|
||||
|
||||
(defmacro check-triangle
|
||||
"If `o` is not a triangle, throw an `IllegalArgumentException` with an
|
||||
appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
from the calling function."
|
||||
[o]
|
||||
`(check-kind-type ~o triangle? :triangle))
|
||||
|
||||
(defn polygon
|
||||
"Return a polygon constructed from these `vertices`."
|
||||
[vertices]
|
||||
(when-not (every? vertex? vertices)
|
||||
(throw (IllegalArgumentException.
|
||||
(str
|
||||
"Each item on vertices must be a vertex: "
|
||||
(s/join " " (map kind-type (remove vertex? vertices)))))))
|
||||
{:vertices vertices :walkmap.id/id (keyword (gensym "poly")) :kind :polygon})
|
||||
[& vertices]
|
||||
{:vertices (check-vertices vertices)
|
||||
:walkmap.id/id (keyword (gensym "poly"))
|
||||
:kind :polygon})
|
||||
|
||||
(defn gradient
|
||||
"Return a polygon like `triangle` but with a key `:gradient` whose value is a
|
||||
unit vector representing the gradient across `triangle`."
|
||||
[triangle]
|
||||
(when-not (triangle? triangle)
|
||||
(throw (IllegalArgumentException.
|
||||
(s/join " " ["Must be a triangle:" (kind-type triangle)]))))
|
||||
(let [order (sort #(max (:z %1) (:z %2)) (:vertices triangle))
|
||||
(let [order (sort #(max (:z %1) (:z %2))
|
||||
(:vertices (check-triangle triangle)))
|
||||
highest (first order)
|
||||
lowest (last order)]
|
||||
(assoc triangle :gradient (e/unit-vector (e/edge lowest highest)))))
|
||||
|
@ -57,10 +73,7 @@
|
|||
`walkmap.polygon`. It is an error (although no exception is currently
|
||||
thrown) if the object past is not a triangular polygon."
|
||||
[facet]
|
||||
(when-not (triangle? facet)
|
||||
(throw (IllegalArgumentException.
|
||||
(s/join " " ["Must be a triangle:" (kind-type facet)]))))
|
||||
(let [vs (:vertices facet)
|
||||
(let [vs (:vertices (check-triangle facet))
|
||||
v1 (first vs)
|
||||
opposite (e/edge (nth vs 1) (nth vs 2))
|
||||
oc (e/centre opposite)]
|
||||
|
@ -74,10 +87,7 @@
|
|||
|
||||
(defn centre
|
||||
[poly]
|
||||
(when-not (polygon? poly)
|
||||
(throw (IllegalArgumentException.
|
||||
(s/join " " ["Must be a polygon:" (kind-type poly)]))))
|
||||
(case (count (:vertices poly))
|
||||
(case (count (:vertices (check-polygon poly)))
|
||||
3 (triangle-centre poly)
|
||||
;; else
|
||||
(throw
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns walkmap.utils
|
||||
"Miscellaneous utility functions."
|
||||
(:require [clojure.math.numeric-tower :as m]))
|
||||
(:require [clojure.math.numeric-tower :as m]
|
||||
[clojure.string :as s]))
|
||||
|
||||
(defn deep-merge
|
||||
"Recursively merges maps. If vals are not maps, the last value wins."
|
||||
|
@ -41,3 +42,60 @@
|
|||
(if (and (number? n1) (number? n2))
|
||||
(< (m/abs (- n1 n2)) tolerance)
|
||||
(= n1 n2))))
|
||||
|
||||
(defmacro check-kind-type
|
||||
"If `object` is not of kind-type `expected`, throws an
|
||||
IllegalArgumentException with an appropriate message; otherwise, returns
|
||||
`object`. If `checkfn` is supplied, it should be a function which tests
|
||||
whether the object is of the expected kind-type.
|
||||
|
||||
Macro, so that the exception is thrown from the calling function."
|
||||
([object expected]
|
||||
`(if-not (= (kind-type ~object) ~expected)
|
||||
(throw
|
||||
(IllegalArgumentException.
|
||||
(s/join
|
||||
" "
|
||||
["Expected" ~expected "but found" (kind-type ~object)])))
|
||||
~object))
|
||||
([object checkfn expected]
|
||||
`(if-not (~checkfn ~object)
|
||||
(throw
|
||||
(IllegalArgumentException.
|
||||
(s/join
|
||||
" "
|
||||
["Expected" ~expected "but found" (kind-type ~object)])))
|
||||
~object)))
|
||||
|
||||
(defmacro check-kind-type-seq
|
||||
"If some item on sequence `s` is not of the `expected` kind-type, throws an
|
||||
IllegalArgumentException with an appropriate message; otherwise, returns
|
||||
`object`. If `checkfn` is supplied, it should be a function which tests
|
||||
whether the object is of the expected kind-type.
|
||||
|
||||
Macro, so that the exception is thrown from the calling function."
|
||||
([s expected]
|
||||
`(if-not (every? #(= (kind-type %) ~expected) ~s)
|
||||
(throw
|
||||
(IllegalArgumentException.
|
||||
(s/join
|
||||
" "
|
||||
["Expected sequence of"
|
||||
~expected
|
||||
"but found ("
|
||||
(s/join ", " (remove #(= ~expected %) (map kind-type ~s)))
|
||||
")"])))
|
||||
~s))
|
||||
([s checkfn expected]
|
||||
`(if-not (every? #(~checkfn %) ~s)
|
||||
(throw
|
||||
(IllegalArgumentException.
|
||||
(s/join
|
||||
" "
|
||||
["Expected sequence of"
|
||||
~expected
|
||||
"but found ("
|
||||
(s/join ", " (remove #(= ~expected %) (map kind-type ~s)))
|
||||
")"])))
|
||||
~s)))
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
(:require [clojure.math.numeric-tower :as m]
|
||||
[clojure.string :as s]
|
||||
[taoensso.timbre :as l]
|
||||
[walkmap.utils :refer [=ish kind-type truncate]]))
|
||||
[walkmap.utils :refer [=ish check-kind-type check-kind-type-seq kind-type truncate]]))
|
||||
|
||||
(defn vertex-key
|
||||
"Making sure we get the same key everytime we key a vertex with the same
|
||||
|
@ -48,31 +48,43 @@
|
|||
(or (nil? (:z o)) (number? (:z o)))
|
||||
(or (nil? (:kind o)) (= (:kind o) :vertex))))
|
||||
|
||||
(defmacro check-vertex
|
||||
"If `o` is not a vertex, throw an `IllegalArgumentException` with an
|
||||
appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
from the calling function."
|
||||
[o]
|
||||
`(check-kind-type ~o vertex? :vertex))
|
||||
|
||||
(defmacro check-vertices
|
||||
"If `o` is not a sequence of vertices, throw an `IllegalArgumentException` with an
|
||||
appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
||||
from the calling function."
|
||||
[o]
|
||||
`(check-kind-type-seq ~o vertex? :vertex))
|
||||
|
||||
(defn vertex=
|
||||
"True if vertices `v1`, `v2` represent the same vertex."
|
||||
[v1 v2]
|
||||
(check-vertex v1)
|
||||
(check-vertex v2)
|
||||
(every?
|
||||
#(=ish (% v1) (% v2))
|
||||
[:x :y :z]))
|
||||
|
||||
(defn vertex*
|
||||
"Return a vertex like `v1`, but with each of its coordinates multiplied
|
||||
by the equivalent vertex in `v2`."
|
||||
by the equivalent vertex in `v2`. It is an error, and an exception will
|
||||
be thrown, if either `v1` or `v2` is not a vertex."
|
||||
[v1 v2]
|
||||
(if
|
||||
(and (vertex? v1) (vertex? v2))
|
||||
(let [f (fn [v1 v2 coord]
|
||||
(* (or (coord v1) 0)
|
||||
;; one here is deliberate!
|
||||
(or (coord v2) 1)))]
|
||||
(assoc v1 :x (f v1 v2 :x)
|
||||
:y (f v1 v2 :y)
|
||||
:z (f v1 v2 :z)))
|
||||
(do (l/warn
|
||||
(s/join
|
||||
" "
|
||||
["in `vertex-multiply`, both must be vectors. v1:" v1 "v2:" v2]))
|
||||
v1)))
|
||||
(check-vertex v1)
|
||||
(check-vertex v2)
|
||||
(let [f (fn [v1 v2 coord]
|
||||
(* (or (coord v1) 0)
|
||||
;; one here is deliberate!
|
||||
(or (coord v2) 1)))]
|
||||
(assoc v1 :x (f v1 v2 :x)
|
||||
:y (f v1 v2 :y)
|
||||
:z (f v1 v2 :z))))
|
||||
|
||||
(defn vertex
|
||||
"Make a vertex with this `x`, `y` and (if provided) `z` values. Returns a map
|
||||
|
@ -83,7 +95,7 @@
|
|||
(let [v {:x x :y y :kind :vertex}]
|
||||
(assoc v :walkmap.id/id (vertex-key v))))
|
||||
([x y z]
|
||||
(let [v (assoc (vertex x y) :z z)]
|
||||
(let [v {:x x :y y :z z :kind :vertex}]
|
||||
(assoc v :walkmap.id/id (vertex-key v)))))
|
||||
|
||||
(defn canonicalise
|
||||
|
@ -106,7 +118,7 @@
|
|||
|
||||
(def ensure3d
|
||||
"Given a vertex `o`, if `o` has a `:z` value, just return `o`; otherwise
|
||||
return a vertex like `o` but having thie `dflt` value as the value of its
|
||||
return a vertex like `o` but having this `dflt` value as the value of its
|
||||
`:z` key, or zero as the value of its `:z` key if `dflt` is not specified.
|
||||
|
||||
If `o` is not a vertex, throws an exception."
|
||||
|
@ -115,33 +127,22 @@
|
|||
([o]
|
||||
(ensure3d o 0.0))
|
||||
([o dflt]
|
||||
(cond
|
||||
(not (vertex? o)) (throw
|
||||
(IllegalArgumentException.
|
||||
(truncate (str "Not a vertex: " (or o "nil")) 80)))
|
||||
(:z o) o
|
||||
:else (assoc o :z dflt))))))
|
||||
(if (:z (check-vertex o))
|
||||
o
|
||||
(assoc o :z dflt))))))
|
||||
|
||||
(def ensure2d
|
||||
"If `o` is a vertex, set its `:z` value to zero; else throw an exception."
|
||||
(memoize
|
||||
(fn [o]
|
||||
(if
|
||||
(vertex? o)
|
||||
(assoc o :z 0.0)
|
||||
(throw
|
||||
(IllegalArgumentException.
|
||||
(truncate (str "Not a vertex: " (or o "nil")) 80)))))))
|
||||
(assoc (check-vertex o) :z 0.0))))
|
||||
|
||||
(defn within-box?
|
||||
"True if `target` is within the box defined by `minv` and `maxv`. All
|
||||
arguments must be vertices; additionally, both `minv` and `maxv` must
|
||||
have `:z` coordinates."
|
||||
[target minv maxv]
|
||||
(when-not (and (vertex? target) (vertex? minv) (vertex? maxv))
|
||||
(throw (IllegalArgumentException.
|
||||
(s/join " " ["Arguments to `within-box?` must be vertices:"
|
||||
(map kind-type [target minv maxv])]))))
|
||||
(check-vertices [target minv maxv])
|
||||
(every?
|
||||
(map
|
||||
#(< (% minv) (or (% target) 0) (% maxv))
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
(:require [clojure.math.numeric-tower :as m]
|
||||
[clojure.test :refer :all]
|
||||
[walkmap.edge :refer :all]
|
||||
[walkmap.vertex :refer [vertex]]))
|
||||
[walkmap.vertex :refer [vertex vertex=]]))
|
||||
|
||||
(deftest edge-test
|
||||
(testing "identification of edges."
|
||||
|
@ -98,12 +98,12 @@
|
|||
|
||||
(deftest parallel-test
|
||||
(testing "parallelism"
|
||||
(is (parallel? {:start {:x 0.0 :y 0.0 :z 0.0 :walkmap.id/id 'foo} :end {:x 3 :y 4 :z 0.0 :walkmap.id/id 'bar}}
|
||||
{:start {:x 1.0 :y 2.0 :z 3.5 :walkmap.id/id 'foo} :end {:x 4.0 :y 6.0 :z 3.5 :walkmap.id/id 'bar}})
|
||||
(is (parallel? (edge (vertex 0.0 0.0 0.0) (vertex 3 4 0.0))
|
||||
(edge (vertex 1.0 2.0 3.5) (vertex 4.0 6.0 3.5)))
|
||||
"Should be")
|
||||
(is (not
|
||||
(parallel? {:start {:x 0.0 :y 0.0 :z 0.0 :walkmap.id/id 'foo} :end {:x 3 :y 4 :z 0.0 :walkmap.id/id 'bar}}
|
||||
{:start {:x 1.0 :y 2.0 :z 3.5 :walkmap.id/id 'foo} :end {:x 4.0 :y 6.0 :z 3.49 :walkmap.id/id 'bar}}))
|
||||
(parallel? (edge (vertex 0.0 0.0 0.0) (vertex 3 4 0.0))
|
||||
(edge (vertex 1.0 2.0 3.5) (vertex 4.0 6.0 3.49))))
|
||||
"Should not be!")))
|
||||
|
||||
(deftest overlaps2d-test
|
||||
|
@ -113,9 +113,9 @@
|
|||
|
||||
(deftest unit-vector-test
|
||||
(testing "deriving the unit vector"
|
||||
(is (=
|
||||
(unit-vector {:start {:x 0.0 :y 0.0 :z 0.0 :walkmap.id/id 'foo} :end {:x 3 :y 4 :z 0.0 :walkmap.id/id 'bar}})
|
||||
{:x 0.6, :y 0.8, :z 0.0}))
|
||||
(is (=
|
||||
(unit-vector {:start {:x 1.0 :y 2.0 :z 3.5 :walkmap.id/id 'foo} :end {:x 4.0 :y 6.0 :z 3.5 :walkmap.id/id 'bar}})
|
||||
{:x 0.6, :y 0.8, :z 0.0}))))
|
||||
(is (vertex=
|
||||
(unit-vector (edge (vertex 0.0 0.0 0.0) (vertex 3 4 0.0)))
|
||||
(vertex 0.6 0.8 0.0)))
|
||||
(is (vertex=
|
||||
(unit-vector (edge (vertex 1.0 2.0 3.5) (vertex 4.0 6.0 3.5)))
|
||||
(vertex 0.6 0.8 0.0)))))
|
||||
|
|
53
test/walkmap/ocean_test.clj
Normal file
53
test/walkmap/ocean_test.clj
Normal file
|
@ -0,0 +1,53 @@
|
|||
(ns walkmap.ocean-test
|
||||
(:require [clojure.test :refer :all]
|
||||
[walkmap.ocean :refer :all]
|
||||
[walkmap.polygon :refer [polygon]]
|
||||
[walkmap.vertex :refer [vertex vertex=]]))
|
||||
|
||||
(deftest ocean-tests
|
||||
(testing "Identification of polygons at sea level"
|
||||
(is (ocean? (polygon (vertex 0 0 0) (vertex 0 1 0) (vertex 1 0 0)))
|
||||
"All `:z` coordinates are zero, and default binding for `*sea-level*`
|
||||
=> ocean.")
|
||||
(is (false? (ocean? (polygon (vertex 0 0 1) (vertex 0 1 0) (vertex 1 0 0))))
|
||||
"Not all `:z` coordinates are zero, and default binding for `*sea-level*`
|
||||
=> not ocean.")
|
||||
(is (false? (ocean? (polygon (vertex 0 0 5) (vertex 0 1 5) (vertex 1 0 5))))
|
||||
"Not all `:z` coordinates are five, and default binding for `*sea-level*`
|
||||
=> not ocean.")
|
||||
(binding [*sea-level* 5]
|
||||
(is (false? (ocean? (polygon (vertex 0 0 0) (vertex 0 1 0) (vertex 1 0 0))))
|
||||
"All `:z` coordinates are zero, and `*sea-level*` rebound to five
|
||||
=> not ocean.")
|
||||
(is (false? (ocean? (polygon (vertex 0 0 1) (vertex 0 1 0) (vertex 1 0 0))))
|
||||
"Not all `:z` coordinates are zero, and `*sea-level*` rebound to five
|
||||
=> not ocean.")
|
||||
(is (ocean? (polygon (vertex 0 0 5) (vertex 0 1 5) (vertex 1 0 5)))
|
||||
"Not all `:z` coordinates are five, and `*sea-level*` rebound to five
|
||||
=> ocean."))))
|
||||
|
||||
(deftest cull-ocean-facets-tests
|
||||
(testing "Culling of ocean facets (not currently used)."
|
||||
(let [stl {:facets [(polygon (vertex 0 0 0) (vertex 0 1 0) (vertex 1 0 0))
|
||||
(polygon (vertex 0 0 1) (vertex 0 1 0) (vertex 1 0 0))
|
||||
(polygon (vertex 0 0 5) (vertex 0 1 5) (vertex 1 0 5))]}
|
||||
expected {:facets
|
||||
[(polygon (vertex 0 0 1) (vertex 0 1 0) (vertex 1 0 0))
|
||||
(polygon (vertex 0 0 5) (vertex 0 1 5) (vertex 1 0 5))]}
|
||||
actual (cull-ocean-facets stl)]
|
||||
(map
|
||||
#(is (vertex= (nth (:facets expected) %) (nth (:facets actual) %))
|
||||
(str "Facet " % " did not match."))
|
||||
(range (max (count (:facets expected)) (count (:facets actual))))))
|
||||
(binding [*sea-level* 5]
|
||||
(let [stl {:facets [(polygon (vertex 0 0 0) (vertex 0 1 0) (vertex 1 0 0))
|
||||
(polygon (vertex 0 0 1) (vertex 0 1 0) (vertex 1 0 0))
|
||||
(polygon (vertex 0 0 5) (vertex 0 1 5) (vertex 1 0 5))]}
|
||||
expected {:facets
|
||||
[(polygon (vertex 0 0 0) (vertex 0 1 0) (vertex 1 0 0))
|
||||
(polygon (vertex 0 0 1) (vertex 0 1 0) (vertex 1 0 0))]}
|
||||
actual (cull-ocean-facets stl)]
|
||||
(map
|
||||
#(is (vertex= (nth (:facets expected) %) (nth (:facets actual) %))
|
||||
(str "Facet " % " did not match."))
|
||||
(range (max (count (:facets expected)) (count (:facets actual)))))))))
|
109
test/walkmap/path_test.clj
Normal file
109
test/walkmap/path_test.clj
Normal file
|
@ -0,0 +1,109 @@
|
|||
(ns walkmap.path-test
|
||||
(:require [clojure.test :refer :all]
|
||||
[walkmap.edge :refer [edge?]]
|
||||
[walkmap.path :refer :all]
|
||||
[walkmap.polygon :refer [polygon]]
|
||||
[walkmap.utils :refer [kind-type]]
|
||||
[walkmap.vertex :refer [vertex vertex=]]))
|
||||
|
||||
(deftest path-tests
|
||||
(testing "Path instantiation"
|
||||
(is (= (kind-type (path (vertex 0 0 0) (vertex 1 1 1))) :path)
|
||||
"Paths should be identified as paths.")
|
||||
(is (path? (path (vertex 0 0 0) (vertex 1 1 1)))
|
||||
"Paths should test as paths.")
|
||||
(is (check-path (path (vertex 0 0 0) (vertex 1 1 1)))
|
||||
"No exception should be thrown when checking a valid path.")
|
||||
(is (thrown?
|
||||
IllegalArgumentException
|
||||
(check-path
|
||||
(update-in
|
||||
(path (vertex 0 0 0) (vertex 1 1 1))
|
||||
:vertices
|
||||
conj
|
||||
"Not a vertex")))
|
||||
"Checking an invalid path should throw an exception.")
|
||||
(is (thrown?
|
||||
IllegalArgumentException
|
||||
(path (vertex 0 0 0)))
|
||||
"Too short.")
|
||||
(is (thrown?
|
||||
IllegalArgumentException
|
||||
(path (vertex 0 0 0) (vertex 1 1 1) "Not a vertex"))
|
||||
"Non-vertex included.")
|
||||
(is (thrown?
|
||||
IllegalArgumentException
|
||||
(path (vertex 0 0 0) (vertex 1 1 1) "Not a vertex."))
|
||||
"Passing something which is not a vertex when constructing a path whould
|
||||
cause an exception to be thrown.")))
|
||||
|
||||
(deftest conversion-tests
|
||||
(testing "Converting polygons to paths"
|
||||
(let [poly (polygon (vertex 0 0 0) (vertex 1 0 0) (vertex 1 1 0) (vertex 0 1 0))
|
||||
p (polygon->path poly)]
|
||||
(is (path? p) "Should be a path.")
|
||||
(is (vertex= (first p) (last p))
|
||||
"First and last vertices of the generated path should be equal to
|
||||
one another.")
|
||||
(is (= (count (:vertices path)) (inc (count (:vertices poly))))
|
||||
"The generated path should have one more vertex than the polygon.")
|
||||
(map
|
||||
#(is (vertex= (nth (:vertices poly) %) (nth (:vertices p) %))
|
||||
(str "Vertex " % " from each set of vertices should be the same."))
|
||||
(range (count (:vertices poly))))))
|
||||
(testing "Converting polygons and paths to edges."
|
||||
(let [poly (polygon (vertex 0 0 0) (vertex 1 0 0) (vertex 1 1 0) (vertex 0 1 0))
|
||||
edges (path->edges poly)]
|
||||
(is (every? edge? edges)
|
||||
"Every returned edge should be an edge.")
|
||||
(is (= (count (:vertices poly)) (count edges))
|
||||
"There should be the same number of edges as the vertices of the polygon")
|
||||
(map
|
||||
#(is
|
||||
(vertex= (nth (:vertices poly) %) (:start (nth edges %)))
|
||||
(str
|
||||
"Each edge should start from the same place as the corresponding
|
||||
vertex: " %))
|
||||
(range (count (:vertices poly))))
|
||||
(map
|
||||
#(is
|
||||
(vertex= (nth (:vertices poly) (mod (inc %) (count (:vertices poly))))
|
||||
(:end (nth edges %)))
|
||||
(str
|
||||
"Each edge should end at the same place as the subsequent
|
||||
vertex: " %))
|
||||
(range (count (:vertices poly)))))
|
||||
(is (thrown? IllegalArgumentException
|
||||
(path->edges "Not a legal argument.")))))
|
||||
|
||||
(deftest check-paths-tests
|
||||
(testing "Checking multiple paths."
|
||||
(is (thrown? IllegalArgumentException
|
||||
(check-paths [(path (vertex 0 0 0)
|
||||
(vertex 1 0 0)
|
||||
(vertex 1 1 0)
|
||||
(vertex 0 1 0)
|
||||
(vertex 0 0 0))
|
||||
(path (vertex 0 0 1)
|
||||
(vertex 1 0 1)
|
||||
(vertex 1 1 1)
|
||||
(vertex 0 1 1)
|
||||
(vertex 0 0 1))
|
||||
(vertex 0 0 0)]))
|
||||
"Not all elements are paths")
|
||||
(is (check-paths [(path (vertex 0 0 0)
|
||||
(vertex 1 0 0)
|
||||
(vertex 1 1 0)
|
||||
(vertex 0 1 0)
|
||||
(vertex 0 0 0))
|
||||
(path (vertex 0 0 1)
|
||||
(vertex 1 0 1)
|
||||
(vertex 1 1 1)
|
||||
(vertex 0 1 1)
|
||||
(vertex 0 0 1))])
|
||||
"All elements are paths")))
|
||||
|
||||
(deftest length-tests
|
||||
(testing "length of paths"
|
||||
(let [p (path (vertex 0 0 0) (vertex 1 0 0) (vertex 1 1 0) (vertex 0 1 0) (vertex 0 0 0))]
|
||||
(is (= (length p) 4) "By inspection."))))
|
81
test/walkmap/polygon_test.clj
Normal file
81
test/walkmap/polygon_test.clj
Normal file
|
@ -0,0 +1,81 @@
|
|||
(ns walkmap.polygon-test
|
||||
(:require [clojure.test :refer :all]
|
||||
;; [clojure.algo.generic.math-functions :as m]
|
||||
;; [walkmap.edge :refer [edge?]]
|
||||
;; [walkmap.path :refer :all]
|
||||
[walkmap.polygon :refer :all]
|
||||
[walkmap.utils :refer [kind-type]]
|
||||
[walkmap.vertex :refer [vertex vertex? vertex=]])
|
||||
)
|
||||
|
||||
(deftest polygon-tests
|
||||
(testing "Constructing polygons"
|
||||
(let [square (polygon (vertex 0 0 0) (vertex 1 0 0)
|
||||
(vertex 1 1 0) (vertex 0 1 0))
|
||||
triangle (polygon (vertex 0 0 0) (vertex 0 3 0)
|
||||
(vertex 4 0 0))]
|
||||
(is (= (kind-type square) :polygon)
|
||||
"Square should have `:kind` = `:polygon`.")
|
||||
(is (= (kind-type triangle) :polygon)
|
||||
"Triangle should have `:kind` = `:polygon`.")
|
||||
(is (polygon? square) "Square should be a polygon.")
|
||||
(is (polygon? triangle) "Triangle should be a polygon.")
|
||||
(is (false? (triangle? square)) "Square is not a triangle.")
|
||||
(is (triangle? triangle) "Triangle is a triangle.")
|
||||
(is (check-polygon square) "No exception should be thrown.")
|
||||
(is (check-polygon triangle) "No exception should be thrown.")
|
||||
(is (check-triangle triangle) "No exception should be thrown.")
|
||||
(is (check-polygons [square triangle])
|
||||
"No exception should be thrown.")
|
||||
(is (thrown?
|
||||
IllegalArgumentException
|
||||
(check-polygon "Not a polygon")) "Not a polygon")
|
||||
(is (thrown?
|
||||
IllegalArgumentException
|
||||
(check-polygons [square triangle "Not a polygon"]))
|
||||
"One value is not a polygon.")
|
||||
(is (thrown?
|
||||
IllegalArgumentException (check-triangle square))
|
||||
"Not a triangle.")
|
||||
(is (thrown?
|
||||
IllegalArgumentException (polygon (vertex 0 0 0) (vertex 1 0 0)))
|
||||
"Too few vertices.")
|
||||
(is (thrown?
|
||||
IllegalArgumentException (polygon (vertex 0 0 0) (vertex 1 0 0)
|
||||
(vertex 1 1 0) "Not a vertex"
|
||||
(vertex 0 1 0)))
|
||||
"Non-vertex included.")
|
||||
)
|
||||
))
|
||||
|
||||
(deftest gradient-tests
|
||||
(testing "Finding the gradient across a triangle."
|
||||
(let [tri (polygon (vertex 0 0 1) (vertex 1 0 0) (vertex 1 1 0.5))
|
||||
gra (gradient tri)]
|
||||
(is (nil? (:gradient tri)) "Basic trangle should not have a gradient.")
|
||||
(is (vertex? (:gradient gra))
|
||||
"After passing through gradient function, it should have a gradient.")
|
||||
;; TODO: I need to check that the gradient is being computed correclt,
|
||||
;; but my brain isn't up to the trigonometry just now.
|
||||
)))
|
||||
|
||||
(deftest centre-tests
|
||||
(testing "Finding the centres of polygons."
|
||||
(let [square (polygon (vertex 0 0 0) (vertex 1 0 0)
|
||||
(vertex 1 1 0) (vertex 0 1 0))
|
||||
triangle (polygon (vertex 0 0 0) (vertex 0 3 0)
|
||||
(vertex 4 0 0))
|
||||
centred (centre triangle)]
|
||||
(is (vertex= (:centre centred) (vertex 1.3333333 1.0 0.0))
|
||||
"By inspection (check this maths!).")
|
||||
(is (thrown?
|
||||
UnsupportedOperationException
|
||||
(centre square))
|
||||
"We can't yet find the centre of a quadrilateral, but we should be
|
||||
able to do so, so it isn't an illegal argument, it just doesn't
|
||||
work.")
|
||||
(is (thrown?
|
||||
IllegalArgumentException
|
||||
(centre "Not a polygon"))
|
||||
"Anything else that isn't a polygon, though, is an illegal argument."))))
|
||||
|
45
test/walkmap/vertex_test.clj
Normal file
45
test/walkmap/vertex_test.clj
Normal file
|
@ -0,0 +1,45 @@
|
|||
(ns walkmap.utils-test
|
||||
(:require [clojure.test :refer :all]
|
||||
[walkmap.vertex :refer :all]))
|
||||
|
||||
(deftest vertex-equal-tests
|
||||
(testing "Equality of vertices"
|
||||
(is (vertex= (vertex 0 0 0) (vertex 0 0 0))
|
||||
"should be equal")
|
||||
(is (vertex= (vertex 0 0 0) (vertex 0.0000001 0 0))
|
||||
"differences less than one part in a million should be ignored")
|
||||
(is (vertex= (vertex 0 0 0) (vertex 0 0 1))
|
||||
"should not be equal")
|
||||
(is (thrown? IllegalArgumentException
|
||||
(vertex= (vertex 0 0 0) "Not a vertex"))
|
||||
"Exception should be thrown: not a vertex.")))
|
||||
|
||||
(deftest vertex-multiply-tests
|
||||
(testing "multiplication of vertices"
|
||||
(let [v (vertex (rand) (rand) (rand))
|
||||
u (vertex 1 1 1)
|
||||
v' (vertex* v u)]
|
||||
(is (vertex= v v')
|
||||
"Multiplication by {:x 1 :y 1 :z 1} should not change the vertex"))
|
||||
(let [v (vertex 0.333333 0.25 0.2)
|
||||
d (vertex 3 4 5)
|
||||
v' (vertex* v d)
|
||||
expected (vertex 1 1 1)]
|
||||
(is (vertex= expected v')
|
||||
"Multiplication by values other than {:x 1 :y 1 :z 1} should change
|
||||
the vertex"))
|
||||
(let [v (vertex 0.333333 0.25 0.2)
|
||||
d (vertex 3 4)
|
||||
v' (vertex* v d)
|
||||
expected (vertex 1 1 0.2)]
|
||||
(is (vertex= expected v')
|
||||
"Multiplication by a 2D vertex should not change `:z`"))
|
||||
(let [v (vertex 0.333333 0.25)
|
||||
d (vertex 3 4)
|
||||
v' (vertex* v d)
|
||||
expected (vertex 1 1 0)]
|
||||
(is (vertex= expected v')
|
||||
"Multiplication of a 2D vertex should result in `:z` = zero"))
|
||||
(is (thrown? IllegalArgumentException
|
||||
(vertex* (vertex 0 0 0) "Not a vertex"))
|
||||
"Exception should be thrown: not a vertex.")))
|
Loading…
Reference in a new issue