Geometry isn't working at all, but my head is spinning!

This commit is contained in:
Simon Brooke 2020-05-24 16:05:04 +01:00
parent 8a2cb942e6
commit 223bf1ce77
No known key found for this signature in database
GPG key ID: A7A4F18D1D4DF987
21 changed files with 212 additions and 75 deletions

View file

@ -39,7 +39,6 @@
(stl->svg (cull-ocean-facets (decode-binary-stl in-filename))))
([in-filename out-filename]
(let [s (binary-stl-file->svg in-filename)]
;; (svg/render-svg s out-filename)
(spit out-filename (html s))
s)))

37
src/walkmap/edge.clj Normal file
View file

@ -0,0 +1,37 @@
(ns walkmap.edge
"Essentially the specification for things we shall consider to be an edge.
An edge is a line segment having just a start and an end, with no intervening
nodes."
(:require [walkmap.path :refer [path? polygon->path]]
[walkmap.polygon :refer [polygon?]]
[walkmap.vertex :refer [vertex?]]))
(defn edge?
"True if `o` satisfies the conditions for a path. A path shall be a map
having the keys `:start` and `:end`, such that the values of each of those
keys shall be a vertex."
[o]
(and
(map? o)
(vertex? (:start o))
(vertex? (:end o))))
(defn path->edges
"if `o` is a path, a polygon, or a sequence of vertices, return a sequence of
edges representing that path, polygon or sequence."
[o]
(cond
(seq? o)
(when
(and
(vertex? (first o))
(vertex? (first (rest o))))
(cons
{:start (first o)
:end (first (rest o))}
(path->edges (rest o))))
(path? o)
(path->edges (:nodes o))
(polygon? o)
(path->edges (polygon->path o))))

57
src/walkmap/geometry.clj Normal file
View file

@ -0,0 +1,57 @@
(ns walkmap.geometry
(:require [clojure.math.combinatorics :as combo]
[clojure.math.numeric-tower :as m]
[walkmap.edge :as edge]
[walkmap.path :refer [path? polygon->path]]
[walkmap.polygon :refer [polygon?]]
[walkmap.vertex :as vertex]))
(defn collinear?
"True if these vertices `v1`, `v2`, `v3` are colinear; false otherwise."
;; This is failing...
;; see http://www.ambrsoft.com/TrigoCalc/Line3D/LineColinear.htm
[v1 v2 v3]
(let [a (m/sqrt (+ (- (:x v2) (:x v1)) (- (:y v2) (:y v1)) (- (:z v2) (:z v1))))
b (m/sqrt (+ (- (:x v3) (:x v1)) (- (:y v3) (:y v1)) (- (:z v3) (:z v1))))
c (m/sqrt (+ (- (:x v3) (:x v2)) (- (:y v3) (:y v2)) (- (:z v3) (:z v2))))]
(not
(and
(> (+ a b) c)
(> (+ a c) b)
(> (+ b c) a)))))
;; (collinear? {:x 0 :y 0 :z 0} {:x 1 :y 1 :z 1} {:x 7 :y 7 :z 7})
;; (collinear? {:x 0 :y 0 :z 0} {:x 1 :y 2 :z 1} {:x 7 :y 7 :z 7})
;; (collinear? {:x 0 :y 0 :z 0} {:x 0 :y 2 :z 0} {:x 0 :y 3 :z 0})
;; (def v1 {:x 0 :y 0 :z 0})
;; (def v2 {:x 0 :y 2 :z 0})
;; (def v3 {:x 0 :y 7 :z 0})
;; (def a (m/sqrt (+ (- (:x v2) (:x v1)) (- (:y v2) (:y v1)) (- (:z v2) (:z v1)))))
;; a
;; (def b (m/sqrt (+ (- (:x v3) (:x v1)) (- (:y v3) (:y v1)) (- (:z v3) (:z v1)))))
;; b
;; (def c (m/sqrt (+ (- (:x v3) (:x v2)) (- (:y v3) (:y v2)) (- (:z v3) (:z v2)))))
;; c
;; (> (+ b c) a)
;; (> (+ a c) b)
;; (> (+ a c) c)
(defn on?
"True if the vertex `v` is on the edge `e`."
[e v]
(let [p (vertex/ensure3d (:start e))
q (vertex/ensure3d v)
r (vertex/ensure3d (:end e))]
(and
(collinear? p q r)
(<= (:x q) (max (:x p) (:x r)))
(>= (:x q) (min (:x p) (:x r)))
(<= (:y q) (max (:y p) (:y r)))
(>= (:y q) (min (:y p) (:y r)))
(<= (:z q) (max (:z p) (:z r)))
(>= (:z q) (min (:z p) (:z r))))))

View file

@ -1,6 +1,7 @@
(ns walkmap.path
"Essentially the specification for things we shall consider to be path."
(:require [walkmap.polygon :refer [polygon? vertex?]]))
(:require [walkmap.polygon :refer [polygon?]]
[walkmap.vertex :refer [vertex?]]))
(defn path?
"True if `o` satisfies the conditions for a path. A path shall be a map

View file

@ -1,21 +1,6 @@
(ns walkmap.polygon
"Essentially the specification for things we shall consider to be polygons.")
(defn vertex?
"True if `o` satisfies the conditions for a vertex. That is, essentially,
that it must rerpresent a two- or three- dimensional vector. A vertex is
shall be a map having at least the keys `:x` and `:y`, where the value of
those keys is a number. If the key `:z` is also present, its value must also
be a number.
The name `vector?` was not used as that would clash with a function of that
name in `clojure.core` whose semantics are entirely different."
[o]
(and
(map? o)
(number? (:x o))
(number? (:y o))
(or (nil? (:z o)) (number? (:z o)))))
"Essentially the specification for things we shall consider to be polygons."
(:require [walkmap.vertex :refer [vertex?]]))
(defn polygon?
"True if `o` satisfies the conditions for a polygon. A polygon shall be a

View file

@ -1,7 +1,7 @@
(ns walkmap.stl
"Utility functions dealing with stereolithography (STL) files. Not a stable API yet!"
(:require [clojure.java.io :as io :refer [file output-stream input-stream]]
;; [clojure.string :as s]
[clojure.string :as s]
[me.raynes.fs :as fs]
[org.clojars.smee.binary.core :as b]
[taoensso.timbre :as l :refer [info error spy]]

View file

@ -1,10 +1,11 @@
(ns walkmap.stl
(ns walkmap.svg
"Utility functions for writing stereolithography (STL) files (and possibly,
later, other geometry files of interest to us) as scalable vector graphics
(SVG)."
(:require [clojure.string :as s]
[taoensso.timbre :as l :refer [info error spy]]
[walkmap.polygon :refer [polygon? vertex?]]))
[walkmap.polygon :refer [polygon?]]
[walkmap.vertex :refer [vertex?]]))
(defn- facet->svg-poly
[facet]

40
src/walkmap/vertex.clj Normal file
View file

@ -0,0 +1,40 @@
(ns walkmap.vertex
"Essentially the specification for things we shall consider to be vertices.")
(defn vertex?
"True if `o` satisfies the conditions for a vertex. That is, essentially,
that it must rerpresent a two- or three- dimensional vector. A vertex is
shall be a map having at least the keys `:x` and `:y`, where the value of
those keys is a number. If the key `:z` is also present, its value must also
be a number.
The name `vector?` was not used as that would clash with a function of that
name in `clojure.core` whose semantics are entirely different."
[o]
(and
(map? o)
(number? (:x o))
(number? (:y o))
(or (nil? (:z o)) (number? (:z o)))))
(defn 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
`: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."
([o]
(ensure3d o 0.0))
([o dflt]
(cond
(not (vertex? o)) (throw (Exception. "Not a vertex!"))
(:z o) o
:else (assoc o :z dflt))))
(defn ensure2d
"If `o` is a vertex, set its `:z` value to zero; else throw an exception."
[o]
(if
(vertex? o)
(assoc o :z 0.0)
(throw (Exception. "Not a vertex!"))))