![](https://secure.gravatar.com/avatar/dd96164c5d53152f67978152ffc74f7a.jpg?s=120&d=mm&r=g)
Update of /project/cells/cvsroot/cells-gtk3/ph-maths In directory clnet:/tmp/cvs-serv5005/ph-maths Added Files: ph-maths.asd ph-maths.lisp Log Message: cells-gtk3 initial. --- /project/cells/cvsroot/cells-gtk3/ph-maths/ph-maths.asd 2008/04/13 10:59:24 NONE +++ /project/cells/cvsroot/cells-gtk3/ph-maths/ph-maths.asd 2008/04/13 10:59:24 1.1 (asdf:defsystem :ph-maths :name "ph-maths" :components ((:file "ph-maths"))) --- /project/cells/cvsroot/cells-gtk3/ph-maths/ph-maths.lisp 2008/04/13 10:59:24 NONE +++ /project/cells/cvsroot/cells-gtk3/ph-maths/ph-maths.lisp 2008/04/13 10:59:24 1.1 ;;; ;;; Linear algebra 2d (defpackage :ph-maths-2d (:use :cl) (:nicknames :2d) (:export :v :x :y :v+ :v- :v* :min-abs :max-abs :v-polar :r :phi :polar-coords :polar-radius :polar-angle :cartesian-coords :abs-angle :deg->rad :rad->deg :v0 :vp :p :<> :intersect-line-circle :distance-point-line :point-in-box-p :to-decimal :to-rgb :to-rgb-vector :~=)) (in-package :ph-maths-2d) (declaim (optimize (speed 1) (debug 3) (space 0))) (defun denil (lst) (loop for val in lst if val collect val)) ;;; represent 2d vector as cons (declaim (inline v x y)) (defun v (x y) (cons x y)) (defun x (v) (car v)) (defun y (v) (cdr v)) ;;; basic linear algebra (declaim (inline v-reduce v+ v- v*)) (defun v-reduce (fn vectors) (declare (function fn)) (reduce #'(lambda (v1 v2) (v (funcall fn (x v1) (x v2)) (funcall fn (y v1) (y v2)))) (denil vectors))) (defun v+ (&rest vectors) (v-reduce #'+ vectors)) (defun v- (&rest vectors) (v-reduce #'- vectors)) (defun v* (lambda vector) (v (* (x vector) lambda) (* (y vector) lambda))) ;;; min/max (declaim (inline abs-reduce min-abs max-abs)) (defun abs-reduce (fn vals) (reduce fn (denil vals) :key #'abs)) (defun min-abs (&rest vals) (abs-reduce #'min vals)) (defun max-abs (&rest vals) (abs-reduce #'max vals)) ; polar coordinates (declaim (inline v-polar phi r polar-radius polar-angle polar-coords)) (defun v-polar (phi r) (cons phi r)) (defun phi (v) (car v)) (defun r (v) (cdr v)) (defun polar-radius (v) "return radius of cartesian vector v" (sqrt (+ (* (x v) (x v)) (* (y v) (y v))))) (defun polar-angle (v) "return angle of cartesian vector v" (if (zerop (x v)) (if (>= (y v) 0) #.(* pi -0.5) #.(* pi 0.5)) (atan (- (y v)) (x v)))) (defun polar-coords (v) "return a polar representation of cartesian vector v" (v-polar (polar-angle v) (polar-radius v))) ; cartesian coords (declaim (inline cartesian-coords)) (defun cartesian-coords (v-polar) "returns a cartesian representation of polar vector v-polar" (v (* (r v-polar) (cos (phi v-polar))) (* -1 (r v-polar) (sin (phi v-polar))))) ; degrees (declaim (inline deg->rad rad->deg abs-angle)) (defun deg->rad (degs) (/ (* degs pi) 180.0)) (defun rad->deg (rads) (* (/ rads pi) 180.0)) (defun abs-angle (phi) "returns a positive angle 0 <= phi <= 2pi" (cond ((or (= phi #.(* 2 pi)) (= phi #.(* -2 pi))) phi) (t (mod phi #.(* 2 pi))))) ; albegra -- 2d (declaim (inline v0 vp <> p)) (defun v0 (v) "returns a vector with the same direction as v and unit length" (let ((r (polar-radius v))) (if (plusp r) (v* (/ 1 r) v) (v 0 0)))) (defun vp (v) "returns a unit vector perpendicular to v" (let ((u (v0 v))) (v (- (y u)) (x u)))) (defun <> (v1 v2) "returns the scalar product <v1, v2>" (+ (* (x v1) (x v2)) (* (y v1) (y v2)))) (defun p (v1 v2) "returns the projection of v1 onto v2. Second return value is the length of the projection." (let* ((v2_0 (v0 v2)) (len (<> v2_0 v1))) (values (v* len v2_0) len))) (declaim (inline distance-point-line intersect-line-circle point-in-box-p)) (defun distance-point-line (point p1 p2) "returns the shortest distance from point to the line p1,p2." (abs (second (multiple-value-list (p (v- p1 point) (vp (v- p2 p1))))))) (defun intersect-line-circle (p1 p2 r) "returns the intersection of a line through p1 and p2 and a circle around p2 with radius r" (v+ p2 (v* r (v0 (v- p1 p2))))) (defun point-in-box-p (p p1 p2 &key (tol 0)) "returns true if p is inside the box given by p1,p2" (and (< (- (min (x p1) (x p2)) tol) (x p) (+ (max (x p1) (x p2)) tol)) (< (- (min (y p1) (y p2)) tol) (y p) (+ (max (y p1) (y p2)) tol)))) ;; base conversion (defun to-decimal (val &key (base 16)) "converts val (a value in base base as a string) to an integer" (loop for p from 0 to (1- (length val)) for x downfrom (1- (length val)) summing (* (let ((c (char-code (char val p)))) (cond ((< 47 c 58) (- c 48)) ((< 64 c 91) (- c 55)) ((< 96 c 123) (- c 87)) (t (warn "Illegal character in hex argument to to-decimal") 0))) (expt base x)))) (defun to-rgb (html-color) "parses an html color code like #A204B2 to '(.8 .01 .7 4)" (loop for val from 0 to 2 for pos = (1+ (* val 2)) collecting (/ (to-decimal (subseq html-color pos (+ pos 2))) 256))) (defun to-rgb-vector (html-color) "parses an html color code like #A204B2 to #(.8 .01 .7 4)" (coerce (loop for val from 0 to 2 for pos = (1+ (* val 2)) collecting (/ (to-decimal (subseq html-color pos (+ pos 2))) 256)) 'vector)) ; fuzzy comparison (defun ~= (&rest params) (if (cdr params) (let ((max (apply #'max params)) (min (apply #'min params))) (> .05 (abs (/ (- max min) (max (abs max) (abs min) 1d-8))))) t))
participants (1)
-
phildebrandt