aboutsummaryrefslogtreecommitdiffhomepage
path: root/wheelwork.lisp
diff options
context:
space:
mode:
authorColin Okay <colin@cicadas.surf>2022-06-28 12:19:43 -0500
committerColin Okay <colin@cicadas.surf>2022-06-28 12:19:43 -0500
commit6533563b384ac194f7a57dcfbdebb8c668bc7b71 (patch)
tree2bd3c08ed31ae16154be1d960a97304f95124864 /wheelwork.lisp
parentab8fd2b7778044612576ff39896be8ae08c4ec1d (diff)
[modify] contains-point-p to factor in rotation;
Diffstat (limited to 'wheelwork.lisp')
-rw-r--r--wheelwork.lisp46
1 files changed, 42 insertions, 4 deletions
diff --git a/wheelwork.lisp b/wheelwork.lisp
index fe6914e..cdfec40 100644
--- a/wheelwork.lisp
+++ b/wheelwork.lisp
@@ -454,10 +454,48 @@ TARGET is FOCUSABLEP"
(sdl2:scancode sdl-keysym)
(sdl2:mod-keywords (sdl2:mod-value sdl-keysym)))))))
+(defun get-rect (unit)
+ (with-accessors ((x unit-x) (y unit-y) (w unit-width) (h unit-height) (r unit-rotation)) unit
+ (let ((m
+ (mat:meye 4))
+ (tr
+ (vec:vec (+ x (* 0.5 w)) (+ y (* 0.5 h)) 0.0)))
+ (mat:nmtranslate m tr)
+ (mat:nmrotate m vec:+vz+ r)
+ (mat:nmtranslate m (vec:v* -1.0 tr))
+
+ (list (mat:m* m (vec:vec x y 0.0 1.0))
+ (mat:m* m (vec:vec x (+ y h) 0.0 1.0))
+ (mat:m* m (vec:vec (+ x w) (+ y h) 0.0 1.0))
+ (mat:m* m (vec:vec (+ x w) y 0.0 1.0))
+ (mat:m* m (vec:vec x y 0.0 1.0))))))
+
+(defun counterclockwisep (a b c)
+ (> (* (- (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)
+ (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 contains-point-p (unit px py)
- (with-accessors ((x unit-x) (y unit-y) (width unit-width) (height unit-height)) unit
- (and (<= x px (+ x width))
- (<= y py (+ y height)))))
+ (let ((pt
+ (vec:vec px py 0.0 1.0))
+ (corner
+ (vec:vec 0.0 0.0 0.0 1.0))
+ (poly
+ (get-rect unit)))
+ (loop for (p1 p2 . more) on poly
+ while p2
+ when (intersectp p1 p2 pt corner)
+ count 1 into intersection-count
+ finally
+ (progn
+ (return (oddp intersection-count))))))
(defun unit-under (app x y)
(labels
@@ -466,7 +504,7 @@ TARGET is FOCUSABLEP"
(container
(find-if #'finder (container-units thing) :from-end t))
(unit
- (when (contains-point-p thing x y)
+ (when (contains-point-p thing x y)
(return-from unit-under thing))))))
(finder app)))