001  (ns walkmap.vertex
002    "Essentially the specification for things we shall consider to be vertices.")
003  
004  (defn vertex?
005    "True if `o` satisfies the conditions for a vertex. That is, essentially,
006    that it must rerpresent a two- or three- dimensional vector. A vertex is
007    shall be a map having at least the keys `:x` and `:y`, where the value of
008    those keys is a number. If the key `:z` is also present, its value must also
009    be a number.
010  
011    The name  `vector?` was not used as that would clash with a function of that
012    name in `clojure.core` whose semantics are entirely different."
013    [o]
014    (and
015      (map? o)
016      (number? (:x o))
017      (number? (:y o))
018      (or (nil? (:z o)) (number? (:z o)))))
019  
020  (def ensure3d
021    "Given a vertex `o`, if `o` has a `:z` value, just return `o`; otherwise
022    return a vertex like `o` but having thie `dflt` value as the value of its
023    `:z` key, or zero as the value of its `:z` key if `dflt` is not specified.
024  
025    If `o` is not a vertex, throws an exception."
026    (memoize
027      (fn
028        ([o]
029         (ensure3d o 0.0))
030        ([o dflt]
031         (cond
032           (not (vertex? o)) (throw (Exception. "Not a vertex!"))
033           (:z o) o
034           :else (assoc o :z dflt))))))
035  
036  (def ensure2d
037    "If `o` is a vertex, set its `:z` value to zero; else throw an exception."
038    (memoize
039      (fn [o]
040        (if
041          (vertex? o)
042          (assoc o :z 0.0)
043          (throw (Exception. "Not a vertex!"))))))