Source: AABB.js

  1. import { Vector } from "./Vector.js";
  2. import { Line } from "./Line.js";
  3. /** Class representing an Axis-Aligned Bounding Box. */
  4. export class AABB {
  5. /**
  6. * Create an AABB using centre position, width, and height.
  7. * @param {number} x - The x value of the centre.
  8. * @param {number} y - The y value of the centre.
  9. * @param {number} width - The width measured from the centre.
  10. * @param {number} height - The height measured from the centre.
  11. */
  12. constructor(x, y, width, height) {
  13. this.x = x;
  14. this.y = y;
  15. this.width = width;
  16. this.height = height;
  17. }
  18. /**
  19. * Create an AABB from four corner [Vectors]{@link Vector}.
  20. * @param {Vector} topLeft
  21. * @param {Vector} topRight
  22. * @param {Vector} bottomRight
  23. * @param {Vector} bottomLeft
  24. * @returns {AABB} - A new AABB object.
  25. */
  26. static fromCorners(topLeft, topRight, bottomRight, bottomLeft) {
  27. const centre = new Vector(topRight.x - topLeft.x, bottomLeft.y - topLeft.y);
  28. const width = topRight.x - centre.x;
  29. const height = bottomRight.y - centre.y;
  30. return new AABB(centre.x, centre.y, width, height);
  31. }
  32. /**
  33. * Check if this AABB contains a {@link Vector}.
  34. * @param {Vector} point - The vector to check.
  35. * @returns {boolean}
  36. */
  37. contains(point) {
  38. return (
  39. point.x > this.x - this.width &&
  40. point.x < this.x + this.width &&
  41. point.y > this.y - this.height &&
  42. point.y < this.y + this.height
  43. );
  44. }
  45. /**
  46. * Check if this AABB intersects another AABB.
  47. * @param {AABB} range - The target AABB to check.
  48. * @returns {boolean}
  49. */
  50. intersects(range) {
  51. return !(
  52. range.x - range.width > this.x + this.width ||
  53. range.x + range.width < this.x - this.width ||
  54. range.y - range.height > this.y + this.height ||
  55. range.y + range.height < this.y - this.height
  56. );
  57. }
  58. /**
  59. * Create an array of [Lines]{@link Line} containing one line for each side of the AABB.
  60. * @param {string} [options.stroke]
  61. * @param {number} [options.strokeWidth]
  62. * @returns {Line[]} - An array of Lines that can be added
  63. * to a {@link Plot} using {@link Plot#add}.
  64. */
  65. lines(options = {}) {
  66. const topLeft = new Vector(this.x - this.width, this.y - this.height);
  67. const topRight = new Vector(this.x + this.width, this.y - this.height);
  68. const bottomLeft = new Vector(this.x - this.width, this.y + this.height);
  69. const bottomRight = new Vector(this.x + this.width, this.y + this.height);
  70. let lines = [];
  71. lines.push(
  72. new Line(topLeft, topRight, options),
  73. new Line(topRight, bottomRight, options),
  74. new Line(bottomRight, bottomLeft, options),
  75. new Line(bottomLeft, topLeft, options),
  76. );
  77. return lines;
  78. }
  79. }