rect.scm 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. (define-module (basket rect)
  2. #:use-module (basket vec)
  3. #:use-module (basket poly)
  4. #:use-module (basket)
  5. #:use-module (srfi srfi-1))
  6. (export
  7. make-rect
  8. rect-ul rect-dr
  9. rect-l rect-u rect-r rect-d
  10. rect-width rect-height
  11. rect->poly
  12. rect->path rect->cpath
  13. rect-contains
  14. rect-intersects
  15. rect->vecss rect->rectss
  16. rect-lerp)
  17. (define make-rect list)
  18. (define rect-ul car)
  19. (define rect-dr cadr)
  20. (define rect-u cdar)
  21. (define rect-l caar)
  22. (define rect-d cdadr)
  23. (define rect-r caadr)
  24. (define (rect-width r)
  25. (- (rect-r r) (rect-l r)))
  26. (define (rect-height r)
  27. (- (rect-d r) (rect-u r)))
  28. (define (rect->poly r)
  29. (list
  30. (rect-ul r)
  31. (make-vec (rect-r r) (rect-u r))
  32. (rect-dr r)
  33. (make-vec (rect-l r) (rect-d r))))
  34. (define (rect->path r)
  35. (poly->path (rect->poly r)))
  36. (define (rect->cpath r)
  37. (poly->cpath (rect->poly r)))
  38. (define (rect-contains r v)
  39. "Tests for a vector being inside the boundaries of a rectangle."
  40. (and
  41. (>= (vec-x v) (rect-l r))
  42. (<= (vec-x v) (rect-r r))
  43. (>= (vec-y v) (rect-u r))
  44. (<= (vec-y v) (rect-d r))))
  45. (define (rect-intersects a b)
  46. "Tests for two rectangles intersecting."
  47. (and (<= (rect-l a) (rect-r b))
  48. (<= (rect-l b) (rect-r a))
  49. (<= (rect-u a) (rect-d b))
  50. (<= (rect-u b) (rect-d a))))
  51. (define (rect->vecss r n)
  52. "Turns a rectangle boundary and an element count into a grid of vectors."
  53. (let ((ul (rect-ul r))
  54. (dr (rect-dr r))
  55. (width (if (pair? n) (car n) n))
  56. (height (if (pair? n) (cdr n) n)))
  57. (map (lambda (y)
  58. (map (lambda (x)
  59. (make-vec (vec-x (vec-lerp ul dr (/ x (- width 1))))
  60. (vec-y (vec-lerp ul dr (/ y (- height 1))))))
  61. (iota width)))
  62. (iota height))))
  63. (define (rect->rectss r n)
  64. "Splits a rangle boundary and an element count into a grid of rangles."
  65. (let* ((ul (rect-ul r))
  66. (dr (rect-dr r))
  67. (width (if (pair? n) (car n) n))
  68. (height (if (pair? n) (cdr n) n))
  69. (rwidth (/ (rect-width r) width))
  70. (rheight (/ (rect-height r) height)))
  71. (map
  72. (lambda (y)
  73. (map
  74. (lambda (x)
  75. (let ((v (make-vec
  76. (vec-x (vec-lerp ul dr (/ x width)))
  77. (vec-y (vec-lerp ul dr (/ y height))))))
  78. (list v (vec-add v (make-vec rwidth rheight)))))
  79. (iota width)))
  80. (iota height))))
  81. (define (rect-lerp r v)
  82. "Interpolate a vector over a rectangle."
  83. (make-vec (lerp (rect-l r) (rect-r r) (vec-x v))
  84. (lerp (rect-u r) (rect-d r) (vec-y v))))