'use strict';
const Vector2 = require('./vector2');
const Polygon = require('./polygon');
/**
* Rect Class
* @extends Polygon
* @property {Vector2} position
* @property {Vector2} size
*/
class Rect extends Polygon {
/**
* @param {Vector2|Object|Number} [p1] Vector2 like object of the start position | position.x
* @param {Vector2|Object|Number} [p2] Vector2 like object of the size | position.y
* @param {Number} [p3] size.x
* @param {Number} [p4] size.y
*/
constructor(...args) {
super();
this._position = Vector2.zero;
this._size = Vector2.zero;
this._checkParams(args);
}
/**
* Wrapper for checking if point is inside a rect
* @param {Vector2} point Point to check
* @returns {boolean}
* @override
*/
pointIsInside(point) {
return this.pointIsInsideRect(point);
}
/**
* Check if a point is inside a Rect
* @param {Vector2} point The Vector2 like object
* @returns {Boolean}
*/
pointIsInsideRect(point) {
const ps = this._position;
const pe = this._position.clone.add(this._size);
const pmin = new Vector2(
Math.min(ps.x, pe.x),
Math.min(ps.y, pe.y)
);
const pmax = new Vector2(
Math.max(ps.x, pe.x),
Math.max(ps.y, pe.y)
);
if (
point.x >= pmin.x &&
point.x <= pmax.x &&
point.y >= pmin.y &&
point.y <= pmax.y
) {
return true;
}
return false;
}
/**
* The start position of the rect
* @type {Vector2}
*/
get position() {
return this._position;
}
/**
* The size of the rect
* @type {Vector2}
*/
get size() {
return this._size;
}
set position(value) {
this._position = value;
this._calcPoly();
}
set size(value) {
this._size = value;
this._calcPoly();
}
_checkParams(args) {
const p1 = Vector2.IsVector2Like(args[0]) || args[0];
const p2 = Vector2.IsVector2Like(args[1]) || args[1];
const p3 = args[2];
const p4 = args[3];
if (
p1 && typeof p1 === 'object' &&
p2 && typeof p2 === 'object'
) { // (Vector2 position, Vector2 size)
this._position = p1;
this._size = p2;
} else if (
p1 && typeof p1 !== 'undefined' && typeof p1 !== 'object' &&
p2 && typeof p2 !== 'undefined' && typeof p2 !== 'object' &&
p3 && typeof p3 !== 'undefined' && typeof p3 !== 'object' &&
p4 && typeof p4 !== 'undefined' && typeof p4 !== 'object'
) { // (Vector2 position, Vector2 size)
this._position.x = p1;
this._position.y = p2;
this._size.x = p3;
this._size.y = p4;
}
this._calcPoly();
}
_calcPoly() {
this.setVertexes([
this._position,
this._position.clone.add(new Vector2(this._size.x, 0)),
this._position.clone.add(this._size),
this._position.clone.add(new Vector2(0, this._size.y))
]);
}
/**
* Get the box around a polygon or around points
* @param {Polygon|Vector2[]} p The polygon, or array of Vector2
* @returns {Rect}
*/
static Box(p) {
if (p && typeof p === 'object') {
if (p instanceof Polygon) {
p = p.points;
}
if (p instanceof Array && p.length) {
const xs = p.map(_ => _.x);
const ys = p.map(_ => _.y);
const position = new Vector2(Math.min(...xs), Math.min(...ys));
const size = new Vector2(Math.max(...xs) - Math.min(...xs), Math.max(...ys) - Math.min(...ys));
return new Rect(position, size);
}
}
return null;
}
}
module.exports = Rect;