diff options
author | Colin Okay <colin@cicadas.surf> | 2022-07-06 09:33:14 -0500 |
---|---|---|
committer | Colin Okay <colin@cicadas.surf> | 2022-07-06 09:33:14 -0500 |
commit | fda1d9d08349dfe103b7af3ef8f305c1701933f6 (patch) | |
tree | 5cb896cf87d140df5bd05cb1f56566cfb0f17407 /src/utils.lisp | |
parent | 8c94460d8c8f8b44ca9bcdebbf2906e84c969b19 (diff) |
[refactor] containers have render bounds
Diffstat (limited to 'src/utils.lisp')
-rw-r--r-- | src/utils.lisp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/utils.lisp b/src/utils.lisp index 3598ec3..7024a8d 100644 --- a/src/utils.lisp +++ b/src/utils.lisp @@ -14,3 +14,51 @@ (slot-value object slot))) val default)) + +(defun counterclockwisep (a b c) + "A B and C are vectors created by 3d-vectors:vec, each representing +a 2d point. Returns T if the three are supplied in counterclockwise +order, nil if not." + (> (* (- (vec:vx b) (vec:vx a)) + (- (vec:vy c) (vec:vy a))) + (* (- (vec:vy b) (vec:vy a)) + (- (vec:vx c) (vec:vx a))))) + + +(defun intersectp (a b c d) + "A B C and D are vectors of the sort created by 3d-vectors:vec, +each representing a 2d point. Returns T if the line segment between A +and B intersects the linesegment between C and D, NIL otherwise." + (or (vec:v= a c) (vec:v= a d) (vec:v= b c) (vec:v= b d) + (and (not (eq (counterclockwisep a c d) (counterclockwisep b c d))) + (not (eq (counterclockwisep a b c) (counterclockwisep a b d)))))) + +(defun path-bounds (path) + "Path is a list of vectors representing 2d points. Returns the +bounds and width and height as a plist of the form + +(:top N :left N :right N :bottom N :width N :height N) + +This is the smallest UNROTATED RECTANGLE that contains the points in +the path." + (loop + with max-x = nil + and max-y = nil + and min-x = nil + and min-y = nil + for vec in path + for x = (vec:vx vec) + for y = (vec:vy vec) + when (or (null max-x) (< max-x x)) + do (setf max-x x) + when (or (null min-x) (< x min-x)) + do (setf min-x x) + when (or (null max-y) (< max-y y)) + do (setf max-y y) + when (or (null min-y) (< y min-y)) + do (setf min-y y) + finally + (return (list :top max-y :left min-x :right max-x :bottom min-y + :width (- max-x min-x) + :height (- max-y min-y))))) + |