poly.scm 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. (define-module (basket poly)
  2. #:use-module (basket vec)
  3. #:use-module (basket rect)
  4. #:use-module (basket))
  5. (export
  6. make-regular-poly
  7. poly->path
  8. poly->cpath
  9. poly-center
  10. poly-add
  11. poly-sub
  12. poly-rotate-around
  13. poly-rotate-center
  14. poly-scale
  15. poly-bounds
  16. triangle-contains)
  17. (define (make-regular-poly center radius sides)
  18. (map (lambda (x)
  19. (let ((angle (* tau (/ x sides))))
  20. (vec-add center (vec-mult (make-vec (sin angle) (cos angle)) radius))))
  21. (iota sides)))
  22. (define (poly->path p)
  23. (append p (list (car p))))
  24. (define (poly->cpath p)
  25. (cons 'cpath p))
  26. (define (poly-center p)
  27. "Returns the center of a polygon."
  28. (if (null? p)
  29. '(0 . 0)
  30. (vec-div (apply vec-add p) (length p))))
  31. (define (poly-add p . vs)
  32. "Adds any number of vectors to the points of a polygon."
  33. (map (lambda (v) (apply vec-add v vs)) p))
  34. (define (poly-sub p . vs)
  35. "Subtracts any number of vectors to the points of a polygon."
  36. (map (lambda (v) (apply vec-sub v vs)) p))
  37. (define (poly-rotate-around p v t)
  38. "Rotates a polygon around a point."
  39. (poly-add
  40. (map (lambda (x) (vec-rotate x t))
  41. (poly-sub p v))
  42. v))
  43. (define (poly-rotate-center p t)
  44. "Rotates a polygon around its center."
  45. (poly-rotate-around p (poly-center p) t))
  46. (define (poly-scale p x)
  47. "Scales a polygon (around its center)."
  48. (map (lambda (v) (vec-lerp (poly-center p) v x)) p))
  49. (define (poly-bounds p)
  50. "Returns the bounding box of a polygon as a rectangle."
  51. (let ((xs (map vec-x p))
  52. (ys (map vec-y p)))
  53. (make-rect (make-vec (apply min xs) (apply min ys))
  54. (make-vec (apply max xs) (apply max ys)))))
  55. (define (triangle-contains t v)
  56. "Tests for a point being contained in a triangle."
  57. ; this uses the Barycentric coordinate system, whatever that means.
  58. (let* ((b (vec-sub (cadr t) (car t)))
  59. (c (vec-sub (caddr t) (car t)))
  60. (v (vec-sub v (car t)))
  61. (bb (vec-dot b b))
  62. (bc (vec-dot b c))
  63. (bv (vec-dot b v))
  64. (cc (vec-dot c c))
  65. (cv (vec-dot c v))
  66. (id (/ (- (* bb cc) (* bc bc))))
  67. (u (* id (- (* bb cv) (* bc bv))))
  68. (v (* id (- (* cc bv) (* bc cv)))))
  69. (and (>= u 0) (>= v 0) (<= (+ u v) 1))))