import Vec2 from "./vec2.js";
/**
* @module Bounds
* @fileoverview Contains bounds class.
*/
/**
* @class
* Basic bounding box.
*/
class Bounds {
/**
* Create a bounding box from width and height (centered)
* @param {number} width Width of bounding box
* @param {number} height Height of bounding box
* @returns {Bounds} Resulting bounding box
*/
static fromWidthAndHeight(width, height) {
const w2 = width / 2;
const h2 = height / 2;
return new Bounds(
new Vec2(-w2, -h2),
new Vec2(w2, h2)
);
}
/**
* Create a new bounding box (parameters do not have to necessarily be min and max).
* @param {Vec2} from First corner
* @param {Vec2} to Second corner
* @constructor
*/
constructor(from = new Vec2(), to = new Vec2()) {
this._min = Vec2.min(from, to);
this._max = Vec2.max(from, to);
}
/**
* Get a copy of the bounding box.
* @returns {Bounds} Copied bounding box
*/
copy() {
return new Bounds(this._min, this._max);
}
//
// Getters
//
/**
* Minimum (top-left) point
* @returns {Vec2} Minimum corner
*/
get min() {
return this._min.copy();
}
/**
* Maximum (bottom-right) point
* @returns {Vec2} Maximum corner
*/
get max() {
return this._max.copy();
}
/**
* Get the width of the bounding box.
* @returns {number} Width of bounds
*/
get width() {
return this._max.x - this._min.x;
}
/**
* Get the height of the bounding box.
* @returns {number} Height of bounds
*/
get height() {
return this._max.y - this._min.y;
}
/**
* Get the x value of the left side of the bounds.
* @returns {number} Left side position along x-axis
*/
get left() {
return this._min.x;
}
/**
* Get the x value of the right side of the bounds.
* @returns {number} Right side position along x-axis
*/
get right() {
return this._max.x;
}
/**
* Get the y value of the top side of the bounds.
* @returns {number} Top side position along y-axis
*/
get top() {
return this._min.y;
}
/**
* Get the y value of the bottom side of the bounds.
* @returns {number} Bottom side position along y-axis
*/
get bottom() {
return this._max.y;
}
/**
* Get the top-right corner of the bounding box.
* @returns {Vec2} Top-right corner
*/
get topRight() {
return new Vec2(this._max.x, this._min.y);
}
/**
* Get the bottom-left corner of the bounding box.
* @returns {Vec2} Bottom-left corner
*/
get bottomLeft() {
return new Vec2(this._min.x, this._max.y);
}
//
// Checks & Calculations
//
/**
* Offset the bounding box.
* @param {Vec2} offset Vector to offset by
* @returns {Bounds} Offset bounding box
*/
add(offset) {
return new Bounds(
this._min.add(offset),
this._max.add(offset)
);
}
/**
* Merge the bounds with another.
* @param {Bounds} other Other bounding box to merge with
* @returns {Bounds} Merged/combined bounding box
*/
merge(other) {
return new Bounds(
Vec2.min(this._min, other._min),
Vec2.max(this._max, other._max)
);
}
/**
* Scale the bounding box.
* @param {number|Vec2} val Value to scale bounds by
* @returns {Bounds} Scaled bounding box
*/
scale(val) {
val = Vec2.from(val);
return new Bounds(
this._min.mul(val),
this._max.mul(val)
);
}
/**
* Check if a point is within the bounding box.
* @param {Vec2} pos Point to check for
* @returns {boolean} Whether point is within bounds
*/
within(pos) {
return pos.x >= this._min.x && pos.x <= this._max.x
&& pos.y >= this._min.y && pos.y <= this._max.y;
}
/**
* Check if the bounding box overlaps another.
* @param {Bounds} other Other bounding box to check with
* @returns {boolean} Whether bounding boxes overlap
*/
overlaps(other) {
if (this.right < other.left || this.left > other.right)
return false;
return !(this.bottom < other.top || this.top > other.bottom);
}
}
export default Bounds;