Bbox = {
const RANGE_LESS_THAN = 1;
const RANGE_OVERLAPS = 0;
const RANGE_GREATER_THAN = -1;
function rangeCompare([min, max], value) {
if (value < min) return RANGE_LESS_THAN;
if (value > max) return RANGE_GREATER_THAN;
return RANGE_OVERLAPS;
}
function rangesDistance(range1, range2, wrapDistance) {
const compare1 = rangeCompare(range1, range2[0]);
const compare2 = rangeCompare(range1, range2[1]);
let compareResult = RANGE_OVERLAPS;
if (compare1 == compare2) compareResult = compare1;
if (compareResult == RANGE_OVERLAPS) return 0;
const lowRange = (compareResult == RANGE_GREATER_THAN) ? range1 : range2;
const highRange = (lowRange == range2) ? range1 : range2;
const distance = highRange[0] - lowRange[1];
if (!wrapDistance) return distance;
const lowRangeWrapped = [lowRange[0] + wrapDistance, lowRange[1] + wrapDistance];
const wrappedDistance = lowRangeWrapped[0] - highRange[1];
return Math.min(distance, wrappedDistance);
}
function getDistanceVector(bbox1, bbox2, worldSize) {
const [worldSizeX, worldSizeY] = [...(worldSize ?? []), 0, 0];
const dx = rangesDistance([bbox1[0], bbox1[2]], [bbox2[0], bbox2[2]], worldSizeX);
const dy = rangesDistance([bbox1[1], bbox1[3]], [bbox2[1], bbox2[3]], worldSizeY);
return [dx, dy];
}
class Bbox {
static getDistance(bbox1, bbox2, worldSize) {
const [dx, dy] = getDistanceVector(bbox1, bbox2, worldSize);
if (dx == 0) return dy;
if (dy == 0) return dx;
return Math.sqrt(dx**2 + dy**2);
}
static intersects(bbox1, bbox2, worldSize) {
const [dx, dy] = getDistanceVector(bbox1, bbox2, worldSize);
return dx * dy == 0;
}
static width(bbox) {
return bbox[2] - bbox[0];
}
static height(bbox) {
return bbox[3] - bbox[1];
}
static area(bbox) {
return Bbox.width(bbox) * Bbox.height(bbox);
}
static fromPoints(points) {
let x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;
for (let [x, y] of points) {
if (x < x0) x0 = x;
if (x > x1) x1 = x;
if (y < y0) y0 = y;
if (y > y1) y1 = y;
}
return [x0, y0, x1, y1];
}
}
return Bbox;
}