Changeset 2834
- Timestamp:
- 03/31/08 14:06:10 (9 months ago)
- Files:
-
- trunk/projects/bos/m2/geometry.lisp (modified) (4 diffs)
- trunk/projects/bos/m2/m2.lisp (modified) (2 diffs)
- trunk/projects/bos/m2/packages.lisp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/projects/bos/m2/geometry.lisp
r2644 r2834 3 3 ;; a point in this package is represented 4 4 ;; as a list (x y) 5 6 ;; a rectangle is represented 7 ;; as a list (left top width height) 5 8 6 9 (defmacro with-point (point &body body) … … 18 21 ,@body)))) 19 22 23 (defmacro with-rectangle (rectangle &body body) 24 (destructuring-bind (rectangle &key suffix) (ensure-list rectangle) 25 (flet ((add-suffix (symbol) 26 (if suffix 27 (intern (format nil "~a-~a" (symbol-name symbol) (string-upcase suffix)) 28 (symbol-package symbol)) 29 symbol))) 30 `(destructuring-bind (,(add-suffix 'left) 31 ,(add-suffix 'top) 32 ,(add-suffix 'width) 33 ,(add-suffix 'height)) 34 ,rectangle 35 ,@body)))) 36 20 37 (defun distance (point-a point-b) 21 38 (with-points (point-a point-b) … … 23 40 (expt (- point-a-y point-b-y) 2))))) 24 41 25 (defmacro dorect ((point (left top width height) &key test row-change) &body body) 26 "Iterate with POINT over all points in rect row per row. The list 27 containing x and y is intended for only extracting those 28 and not to be stored away (it will be modified). 29 30 BODY is only executed, if TEST of the current point is true. 31 32 For convenience, a null arg function ROW-CHANGE can be given 33 that will be called between the rows." 34 (check-type point symbol) 35 (rebinding (left top) 36 `(iter 37 (with ,point = (list nil nil)) 38 (for y from ,top to (1- (+ ,top ,height))) 39 ,(when row-change 40 `(unless (first-time-p) 41 (funcall ,row-change))) 42 (iter 43 (for x from ,left to (1- (+ ,left ,width))) 44 (setf (first ,point) x 45 (second ,point) y) 46 (when ,(if test 47 `(funcall ,test ,point) 48 t) 49 ,@body))))) 50 51 (defun rect-center (left top width height &key roundp) 52 (let ((x (+ left (/ width 2))) 53 (y (+ top (/ height 2)))) 54 (if roundp 55 (list (round x) (round y)) 56 (list x y)))) 42 ;; (defmacro dorect ((point rectangle &key test row-change) &body body) 43 ;; "Iterate with POINT over all points in rect row per row. The list 44 ;; containing x and y is intended for only extracting those 45 ;; and not to be stored away (it will be modified). 46 47 ;; BODY is only executed, if TEST of the current point is true. 48 49 ;; For convenience, a null arg function ROW-CHANGE can be given 50 ;; that will be called between the rows." 51 ;; (check-type point symbol) 52 ;; (with-rectangle rectangle 53 ;; (rebinding (left top) 54 ;; `(iter 55 ;; (with ,point = (list nil nil)) 56 ;; (for y from ,top to (1- (+ ,top ,height))) 57 ;; ,(when row-change 58 ;; `(unless (first-time-p) 59 ;; (funcall ,row-change))) 60 ;; (iter 61 ;; (for x from ,left to (1- (+ ,left ,width))) 62 ;; (setf (first ,point) x 63 ;; (second ,point) y) 64 ;; (when ,(if test 65 ;; `(funcall ,test ,point) 66 ;; t) 67 ;; ,@body)))))) 68 69 (defun rectangle-center (rectangle &key roundp) 70 (with-rectangle rectangle 71 (let ((x (+ left (/ width 2))) 72 (y (+ top (/ height 2)))) 73 (if roundp 74 (list (round x) (round y)) 75 (list x y))))) 76 77 (defun rectangle-intersects-p (a b) 78 (with-rectangle (a :suffix a) 79 (with-rectangle (b :suffix b) 80 (let* ((right-a (+ left-a width-a)) 81 (bottom-a (+ top-a height-a)) 82 (right-b (+ left-b width-b)) 83 (bottom-b (+ top-b height-b)) 84 (left (max left-a left-b)) 85 (top (max top-a top-b)) 86 (right (min right-a right-b)) 87 (bottom (min bottom-a bottom-b))) 88 (and (> right left) (> bottom top)))))) 57 89 58 90 ;; maybe change this function to take a … … 77 109 (<= (distance point center) radius)) 78 110 79 (defun point-in-rect-p (point left top width height)111 (defun point-in-rect-p (point rectangle) 80 112 (with-point point 81 (and (<= left point-x (1- (+ left width))) 82 (<= top point-y (1- (+ top height)))))) 113 (with-rectangle rectangle 114 (and (<= left point-x (1- (+ left width))) 115 (<= top point-y (1- (+ top height))))))) 83 116 84 117 ;;; for fun... 85 (defun point-in-circle-p-test ()86 (let ((center (list 4 4)))87 (dorect (p (0 0 10 10) :row-change #'terpri)88 (if (point-in-circle-p p center 3)89 (princ "x")90 (princ ".")))))118 ;; (defun point-in-circle-p-test () 119 ;; (let ((center (list 4 4))) 120 ;; (dorect (p (0 0 10 10) :row-change #'terpri) 121 ;; (if (point-in-circle-p p center 3) 122 ;; (princ "x") 123 ;; (princ "."))))) 91 124 92 125 (defun bounding-box (objects &key (key #'identity)) trunk/projects/bos/m2/m2.lisp
r2725 r2834 354 354 (destructuring-bind (left top width height) 355 355 (contract-bounding-box contract) 356 (let ((center (rect -center left top width height:roundp t))356 (let ((center (rectangle-center (list left top width height) :roundp t)) 357 357 (diameter (* 2 radius)) 358 358 (contracts (make-hash-table :test #'eq))) … … 369 369 (destructuring-bind (left top width height) 370 370 (contract-bounding-box contract) 371 (rect -center left top width height:roundp t)))371 (rectangle-center (list left top width height) :roundp t))) 372 372 373 373 (defun contract-center-lon-lat (contract) trunk/projects/bos/m2/packages.lisp
r2775 r2834 6 6 #:distance 7 7 #:dorect 8 #:rect-center 8 #:rectangle-center 9 #:rectangle-intersects-p 9 10 #:point-in-polygon-p 10 11 #:point-in-circle-p
