You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bounds.ts 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import { Bounds } from "types"
  2. import {
  3. intersectPolygonBounds,
  4. intersectPolylineBounds,
  5. } from "./intersections"
  6. /**
  7. * Get whether two bounds collide.
  8. * @param a Bounds
  9. * @param b Bounds
  10. * @returns
  11. */
  12. export function boundsCollide(a: Bounds, b: Bounds) {
  13. return !(
  14. a.maxX < b.minX ||
  15. a.minX > b.maxX ||
  16. a.maxY < b.minY ||
  17. a.minY > b.maxY
  18. )
  19. }
  20. /**
  21. * Get whether the bounds of A contain the bounds of B. A perfect match will return true.
  22. * @param a Bounds
  23. * @param b Bounds
  24. * @returns
  25. */
  26. export function boundsContain(a: Bounds, b: Bounds) {
  27. return (
  28. a.minX < b.minX && a.minY < b.minY && a.maxY > b.maxY && a.maxX > b.maxX
  29. )
  30. }
  31. /**
  32. * Get whether the bounds of A are contained by the bounds of B.
  33. * @param a Bounds
  34. * @param b Bounds
  35. * @returns
  36. */
  37. export function boundsContained(a: Bounds, b: Bounds) {
  38. return boundsContain(b, a)
  39. }
  40. /**
  41. * Get whether a set of points are all contained by a bounding box.
  42. * @returns
  43. */
  44. export function boundsContainPolygon(a: Bounds, points: number[][]) {
  45. return points.every((point) => pointInBounds(point, a))
  46. }
  47. /**
  48. * Get whether a polygon collides a bounding box.
  49. * @param points
  50. * @param b
  51. */
  52. export function boundsCollidePolygon(a: Bounds, points: number[][]) {
  53. return intersectPolygonBounds(points, a).length > 0
  54. }
  55. /**
  56. * Get whether two bounds are identical.
  57. * @param a Bounds
  58. * @param b Bounds
  59. * @returns
  60. */
  61. export function boundsAreEqual(a: Bounds, b: Bounds) {
  62. return !(
  63. b.maxX !== a.maxX ||
  64. b.minX !== a.minX ||
  65. b.maxY !== a.maxY ||
  66. b.minY !== a.minY
  67. )
  68. }
  69. /**
  70. * Get whether a point is inside of a bounds.
  71. * @param A
  72. * @param b
  73. * @returns
  74. */
  75. export function pointInBounds(A: number[], b: Bounds) {
  76. return !(A[0] < b.minX || A[0] > b.maxX || A[1] < b.minY || A[1] > b.maxY)
  77. }
  78. export function getRotatedEllipseBounds(
  79. x: number,
  80. y: number,
  81. rx: number,
  82. ry: number,
  83. rotation: number
  84. ) {
  85. const c = Math.cos(rotation)
  86. const s = Math.sin(rotation)
  87. const w = Math.hypot(rx * c, ry * s)
  88. const h = Math.hypot(rx * s, ry * c)
  89. return {
  90. minX: x + rx - w,
  91. minY: y + ry - h,
  92. maxX: x + rx + w,
  93. maxY: y + ry + h,
  94. width: w * 2,
  95. height: h * 2,
  96. }
  97. }