New developed Isle of Man maps; work on intersections.

This commit is contained in:
Simon Brooke 2020-06-29 21:36:23 +01:00
parent 48d9aacb69
commit 4161f4f04a
No known key found for this signature in database
GPG key ID: A7A4F18D1D4DF987
12 changed files with 58 additions and 40 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

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

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -115,14 +115,21 @@
(defn overlaps2d?
"True if the recangle in the x,y plane bisected by edge `e1` overlaps that
bisected by edge `e2`. It is an error if either `e1` or `e2` is not an edge."
[e1 e2]
bisected by edge `e2`. It is an error if either `e1` or `e2` is not an edge.
If `c1` is passed it should be the first coordinate of the plane of
projection on which the overlap is sought (default: `:x`); similarly `c2`
should be the second such coordinate (default: `:y`)."
([e1 e2]
(overlaps2d? e1 e2 :x :y))
([e1 e2 c1 c2]
(when (and (edge? e1) (edge? e2))
(and
(> (minimaxd e1 :x max) (minimaxd e2 :x min))
(< (minimaxd e1 :x min) (minimaxd e2 :x max))
(> (minimaxd e1 :y max) (minimaxd e2 :y min))
(< (minimaxd e1 :y min) (minimaxd e2 :y max)))))
(> (minimaxd e1 c1 max) (minimaxd e2 c1 min))
(< (minimaxd e1 c1 min) (minimaxd e2 c1 max))
(> (minimaxd e1 c2 max) (minimaxd e2 c2 min))
(< (minimaxd e1 c2 min) (minimaxd e2 c2 max))))))
(defn intersection2d
"The probability of two lines intersecting in 3d space is low, and actually
@ -140,38 +147,40 @@
It is an error, and an exception will be thrown, if either `e1` or `e2` is
not an edge."
[e1 e2]
(if (and (edge? e1) (edge? e2))
(when
(overlaps2d? e1 e2) ;; relatively cheap check
(if
(collinear2d? e1 e2)
;; any point within the overlap will do, but we'll pick the end of e1
;; which is on e2
(if (on2d? e2 (:start e1)) (:start e1) (:end e1))
;; blatantly stolen from
;; https://gist.github.com/cassiel/3e725b49670356a9b936
(let [x1 (:x (:start e1))
x2 (:x (:end e1))
x3 (:x (:start e2))
x4 (:x (:end e2))
y1 (:y (:start e1))
y2 (:y (:end e1))
y3 (:y (:start e2))
y4 (:y (:end e2))
denom (- (* (- x1 x2) (- y3 y4))
(* (- y1 y2) (- x3 x4)))
x1y2-y1x2 (- (* x1 y2) (* y1 x2))
x3y4-y3x4 (- (* x3 y4) (* y3 x4))
px-num (- (* x1y2-y1x2 (- x3 x4))
(* (- x1 x2) x3y4-y3x4))
py-num (- (* x1y2-y1x2 (- y3 y4))
(* (- y1 y2) x3y4-y3x4))
result (when-not (zero? denom)
(vertex (/ px-num denom) (/ py-num denom)))]
(when (and result (on2d? e1 result) (on2d? e2 result)) result))))
(throw (IllegalArgumentException.
(str
"Both `e1` and `e2` must be edges."
(map #(or (:kind %) (type %)) [e1 e2]))))))
([e1 e2]
(intersection2d e1 e2 :x :y :z))
([e1 e2 c1 c2 c3]
(if (and (edge? e1) (edge? e2))
(when
(overlaps2d? e1 e2) ;; relatively cheap check
(if
(collinear2d? e1 e2)
;; any point within the overlap will do, but we'll pick the end of e1
;; which is on e2
(if (on2d? e2 (:start e1)) (:start e1) (:end e1))
;; blatantly stolen from
;; https://gist.github.com/cassiel/3e725b49670356a9b936
(let [x1 (c1 (:start e1))
x2 (c1 (:end e1))
x3 (c1 (:start e2))
x4 (c1 (:end e2))
y1 (c2 (:start e1))
y2 (c2 (:end e1))
y3 (c2 (:start e2))
y4 (c2 (:end e2))
denom (- (* (- x1 x2) (- y3 y4))
(* (- y1 y2) (- x3 x4)))
x1y2-y1x2 (- (* x1 y2) (* y1 x2))
x3y4-y3x4 (- (* x3 y4) (* y3 x4))
px-num (- (* x1y2-y1x2 (- x3 x4))
(* (- x1 x2) x3y4-y3x4))
py-num (- (* x1y2-y1x2 (- y3 y4))
(* (- y1 y2) x3y4-y3x4))
result (when-not (zero? denom)
(vertex (/ px-num denom) (/ py-num denom)))]
(when (and result (on2d? e1 result) (on2d? e2 result)) result))))
(throw (IllegalArgumentException.
(str
"Both `e1` and `e2` must be edges."
(map #(or (:kind %) (type %)) [e1 e2])))))))