474 lines
30 KiB
HTML
474 lines
30 KiB
HTML
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<link rel="stylesheet" href="../coverage.css"/> <title> walkmap/polygon.clj </title>
|
|
</head>
|
|
<body>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
001 (ns walkmap.polygon
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
002 "Essentially the specification for things we shall consider to be polygons."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
003 (:require [clojure.string :as s]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
004 [walkmap.edge :as e]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
005 [walkmap.tag :as t]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
006 [walkmap.utils :refer [check-kind-type
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
007 check-kind-type-seq
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
008 kind-type
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
009 not-yet-implemented]]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
010 [walkmap.vertex :refer [check-vertex check-vertices vertex vertex?]]))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
011
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
012 (defn polygon?
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
013 "True if `o` satisfies the conditions for a polygon. A polygon shall be a
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
014 map which has a value for the key `:vertices`, where that value is a sequence
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
015 of vertices."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
016 [o]
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
017 (let
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
018 [v (:vertices o)]
|
|
</span><br/>
|
|
<span class="partial" title="18 out of 22 forms covered">
|
|
019 (and
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
020 (coll? v)
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
021 (> (count v) 2)
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
022 (every? vertex? v)
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
023 (:walkmap.id/id o)
|
|
</span><br/>
|
|
<span class="covered" title="9 out of 9 forms covered">
|
|
024 (or (nil? (:kind o)) (= (:kind o) :polygon)))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
025
|
|
</span><br/>
|
|
<span class="covered" title="22 out of 22 forms covered">
|
|
026 (defmacro check-polygon
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
027 "If `o` is not a polygon, throw an `IllegalArgumentException` with an
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
028 appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
029 from the calling function."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
030 [o]
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
031 `(check-kind-type ~o polygon? :polygon))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
032
|
|
</span><br/>
|
|
<span class="covered" title="21 out of 21 forms covered">
|
|
033 (defmacro check-polygons
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
034 "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">
|
|
035 appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
036 from the calling function."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
037 [o]
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
038 `(check-kind-type-seq ~o polygon? :polygon))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
039
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
040 (defn triangle?
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
041 "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">
|
|
042 polygon with exactly three vertices."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
043 [o]
|
|
</span><br/>
|
|
<span class="partial" title="5 out of 6 forms covered">
|
|
044 (and
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
045 (coll? o)
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
046 (= (count (:vertices o)) 3)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
047
|
|
</span><br/>
|
|
<span class="partial" title="25 out of 33 forms covered">
|
|
048 (defmacro check-triangle
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
049 "If `o` is not a triangle, throw an `IllegalArgumentException` with an
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
050 appropriate message; otherwise, returns `o`. Macro, so exception is thrown
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 2 forms covered">
|
|
051 from the calling function."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
052 [o]
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
053 `(check-kind-type ~o triangle? :triangle))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
054
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
055 (defn polygon
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
056 "Return a polygon constructed from these `vertices`."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
057 [& vertices]
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
058 (if
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
059 (> (count vertices) 2)
|
|
</span><br/>
|
|
<span class="covered" title="30 out of 30 forms covered">
|
|
060 {:vertices (check-vertices vertices)
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
061 :walkmap.id/id (keyword (gensym "poly"))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
062 :kind :polygon}
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
063 (throw (IllegalArgumentException.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
064 "A polygon must have at least 3 vertices."))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
065
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
066 (defn rectangle
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
067 "Return a rectangle, with edges aligned east-west and north-south, whose
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
068 south-west corner is the vertex `vsw` and whose north-east corner is the
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
069 vertex `vne`."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
070 [vsw vne]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
071 ;; we can actually create any rectangle in the xy plane based on two opposite
|
|
</span><br/>
|
|
<span class="covered" title="9 out of 9 forms covered">
|
|
072 ;; corners, but the maths are a bit to advanced for me today. TODO: do it!
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 21 forms covered">
|
|
073 (let [vnw (vertex (:x (check-vertex vsw))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 18 forms covered">
|
|
074 (:y (check-vertex vne))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 20 forms covered">
|
|
075 (/ (reduce + (map #(or (:z %) 0) [vsw vne])) 2))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
076 vse (vertex (:x vne)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
077 (:y vsw)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 20 forms covered">
|
|
078 (/ (reduce + (map #(or (:z %) 0) [vsw vne])) 2))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 6 forms covered">
|
|
079 height-order (sort-by :z [vsw vne])]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
080 (t/tag
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
081 (assoc
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 6 forms covered">
|
|
082 (polygon vsw vnw vne vse)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
083 :gradient
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 10 forms covered">
|
|
084 (e/unit-vector (e/edge (first height-order) (last height-order)))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
085 :centre
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 18 forms covered">
|
|
086 (vertex (+ (:x vsw) (/ (- (:x vne) (:x vsw)) 2))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 16 forms covered">
|
|
087 (+ (:x vsw) (/ (- (:y vne) (:y vsw)) 2))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
088 (:z vse)))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
089 :rectangle)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
090
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
091 ;; (rectangle (vertex 1 2 3) (vertex 7 9 4))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
092
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
093 (defn gradient
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
094 "Return a polygon like `triangle` but with a key `:gradient` whose value is a
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
095 unit vector representing the gradient across `triangle`."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
096 [triangle]
|
|
</span><br/>
|
|
<span class="covered" title="12 out of 12 forms covered">
|
|
097 (let [order (sort #(max (:z %1) (:z %2))
|
|
</span><br/>
|
|
<span class="partial" title="8 out of 18 forms covered">
|
|
098 (:vertices (check-triangle triangle)))
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
099 highest (first order)
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
100 lowest (last order)]
|
|
</span><br/>
|
|
<span class="covered" title="10 out of 10 forms covered">
|
|
101 (assoc triangle :gradient (e/unit-vector (e/edge lowest highest)))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
102
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
103 (defn triangle-centre
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
104 "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">
|
|
105 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">
|
|
106 dimensions. This only works for triangles, so is here not in
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
107 `walkmap.polygon`. It is an error (although no exception is currently
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
108 thrown) if the object past is not a triangular polygon."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
109 [facet]
|
|
</span><br/>
|
|
<span class="partial" title="9 out of 19 forms covered">
|
|
110 (let [vs (:vertices (check-triangle facet))
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
111 v1 (first vs)
|
|
</span><br/>
|
|
<span class="covered" title="10 out of 10 forms covered">
|
|
112 opposite (e/edge (nth vs 1) (nth vs 2))
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
113 oc (e/centre opposite)]
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
114 (assoc
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
115 facet
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
116 :centre
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
117 (vertex
|
|
</span><br/>
|
|
<span class="covered" title="16 out of 16 forms covered">
|
|
118 (+ (:x v1) (* (- (:x oc) (:x v1)) 2/3))
|
|
</span><br/>
|
|
<span class="covered" title="16 out of 16 forms covered">
|
|
119 (+ (:y v1) (* (- (:y oc) (:y v1)) 2/3))
|
|
</span><br/>
|
|
<span class="covered" title="16 out of 16 forms covered">
|
|
120 (+ (:z v1) (* (- (:z oc) (:z v1)) 2/3))))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
121
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
122 (defn centre
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
123 [poly]
|
|
</span><br/>
|
|
<span class="covered" title="22 out of 22 forms covered">
|
|
124 (case (count (:vertices (check-polygon poly)))
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
125 3 (triangle-centre poly)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
126 ;; else
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
127 (throw
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
128 (UnsupportedOperationException.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
129 "The general case of centre for polygons is not yet implemented."))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
130
|
|
</span><br/>
|
|
<span class="partial" title="4 out of 16 forms covered">
|
|
131 (defmacro on2dtriangle?
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
132 "Is the projection of this `vertex` on the x, y plane within the
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
133 projection of this triangle on that plane?"
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
134 [vertex poly]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
135 `(not-yet-implemented "on2d? for triangles."))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
136
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
137 (defn on2drectangle?
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
138 "Is the projection of this `vertex` on the x, y plane within the
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
139 projection of this rectangle on that plane?"
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
140 [vertex rectangle]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 7 forms covered">
|
|
141 (let [xo (sort-by :x (:vertices rectangle))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 6 forms covered">
|
|
142 yo (sort-by :x (:vertices rectangle))]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
143 (and
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 15 forms covered">
|
|
144 (< (:x (first xo)) (:x vertex) (:x (last xo)))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 14 forms covered">
|
|
145 (< (:y (first yo)) (:y vertex) (:y (last yo))))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
146
|
|
</span><br/>
|
|
<span class="partial" title="4 out of 86 forms covered">
|
|
147 (defmacro on2d?
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
148 "Is the projection of this `vertex` on the x, y plane within the
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
149 projection of this polygon `poly` on that plane?"
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
150 [vertex poly]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
151 `(cond
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
152 (rectangle? ~poly) (on2drectangle? ~vertex ~poly)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
153 (triangle? ~poly) (on2dtriangle? ~vertex ~poly)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
154 :else
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
155 (not-yet-implemented "general case of on2d? for polygons.")))
|
|
</span><br/>
|
|
</body>
|
|
</html>
|