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.0KB

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