refactor bounds into a proper class

This commit is contained in:
Stewart Allen 2022-01-31 10:07:06 -05:00
commit d29ba1dc9e

View file

@ -5,43 +5,28 @@
// dep: geo.base // dep: geo.base
(function() { (function() {
if (self.base.Bounds) return; let base = self.base;
if (base.Bounds) return;
/** let { config, util } = base;
*
* @constructor class Bounds {
*/ constructor() {
function Bounds() {
this.minx = 10e7; this.minx = 10e7;
this.miny = 10e7; this.miny = 10e7;
this.maxx = -10e7; this.maxx = -10e7;
this.maxy = -10e7; this.maxy = -10e7;
} }
const BASE = self.base, set(minx, maxx, miny, maxy) {
UTIL = BASE.util, this.minx = minx;
CONF = BASE.config, this.miny = miny;
PRO = Bounds.prototype; this.maxx = maxx;
this.maxy = maxy;
return this;
}
BASE.Bounds = Bounds; clone() {
BASE.newBounds = newBounds;
/** ******************************************************************
* Bounds Prototype Functions
******************************************************************* */
PRO.set = function(minx, maxx, miny, maxy) {
this.minx = minx;
this.miny = miny;
this.maxx = maxx;
this.maxy = maxy;
return this;
};
/**
* @returns {Bounds}
*/
PRO.clone = function() {
let b = new Bounds(); let b = new Bounds();
b.minx = this.minx; b.minx = this.minx;
b.miny = this.miny; b.miny = this.miny;
@ -49,113 +34,107 @@
b.maxy = this.maxy; b.maxy = this.maxy;
b.maxy = this.maxy; b.maxy = this.maxy;
return b; return b;
}; }
PRO.equals = function(bounds, margin) { equals(bounds, margin) {
if (!margin) margin = BASE.config.precision_offset; if (!margin) margin = config.precision_offset;
return UTIL.isCloseTo(this.minx, bounds.minx, margin) && return util.isCloseTo(this.minx, bounds.minx, margin) &&
UTIL.isCloseTo(this.miny, bounds.miny, margin) && util.isCloseTo(this.miny, bounds.miny, margin) &&
UTIL.isCloseTo(this.maxx, bounds.maxx, margin) && util.isCloseTo(this.maxx, bounds.maxx, margin) &&
UTIL.isCloseTo(this.maxy, bounds.maxy, margin); util.isCloseTo(this.maxy, bounds.maxy, margin);
}; }
/** /**
* @returns {Number} absolute delta in x,y coordinate space * @returns {Number} absolute delta in x,y coordinate space
*/ */
PRO.delta = function(bounds) { delta(bounds) {
return 0 + return 0 +
Math.abs(this.minx - bounds.minx) + Math.abs(this.minx - bounds.minx) +
Math.abs(this.miny - bounds.miny) + Math.abs(this.miny - bounds.miny) +
Math.abs(this.maxx - bounds.maxx) + Math.abs(this.maxx - bounds.maxx) +
Math.abs(this.maxy - bounds.maxy); Math.abs(this.maxy - bounds.maxy);
}; }
/** /**
* @param {Bounds} b * @param {Bounds} b
*/ */
PRO.merge = function(b) { merge(b) {
this.minx = Math.min(this.minx, b.minx); this.minx = Math.min(this.minx, b.minx);
this.maxx = Math.max(this.maxx, b.maxx); this.maxx = Math.max(this.maxx, b.maxx);
this.miny = Math.min(this.miny, b.miny); this.miny = Math.min(this.miny, b.miny);
this.maxy = Math.max(this.maxy, b.maxy); this.maxy = Math.max(this.maxy, b.maxy);
return this; return this;
}; }
/** /**
* @param {Point} p * @param {Point} p
*/ */
PRO.update = function(p) { update(p) {
this.minx = Math.min(this.minx, p.x); this.minx = Math.min(this.minx, p.x);
this.maxx = Math.max(this.maxx, p.x); this.maxx = Math.max(this.maxx, p.x);
this.miny = Math.min(this.miny, p.y); this.miny = Math.min(this.miny, p.y);
this.maxy = Math.max(this.maxy, p.y); this.maxy = Math.max(this.maxy, p.y);
return this; return this;
}; }
PRO.contains = function(bounds) { contains(bounds) {
return bounds.isNested(this); return bounds.isNested(this);
}; }
PRO.containsXY = function(x,y) { containsXY(x, y) {
return x >= this.minx && x <= this.maxx && y >= this.miny && y <= this.maxy; return x >= this.minx && x <= this.maxx && y >= this.miny && y <= this.maxy;
}; }
PRO.containsOffsetXY = function(x,y,offset) { containsOffsetXY(x, y, offset) {
return x >= this.minx-offset && x <= this.maxx+offset && y >= this.miny-offset && y <= this.maxy+offset; return x >= this.minx - offset && x <= this.maxx + offset && y >= this.miny - offset && y <= this.maxy + offset;
}; }
/** /**
* @param {Bounds} parent * @param {Bounds} parent
* @returns {boolean} true if fully inside parent bounds * @returns {boolean} true if fully inside parent bounds
*/ */
PRO.isNested = function(parent, tolerance) { isNested(parent, precision = config.precision_bounds) {
let grace = tolerance || CONF.precision_bounds;
return ( return (
this.minx >= parent.minx - grace && // min-x this.minx >= parent.minx - precision && // min-x
this.maxx <= parent.maxx + grace && // max-x this.maxx <= parent.maxx + precision && // max-x
this.miny >= parent.miny - grace && // min-y this.miny >= parent.miny - precision && // min-y
this.maxy <= parent.maxy + grace // max-y this.maxy <= parent.maxy + precision // max-y
); );
}; }
/** /**
* @param {Bounds} b * @param {Bounds} b
* @param {number} precision * @param {number} precision
* @returns {boolean} * @returns {boolean}
*/ */
PRO.overlaps = function(b, precision) { overlaps(b, precision = config.precision_bounds) {
return ( return (
Math.abs(this.centerx() - b.centerx()) * 2 - precision < this.width() + b.width() && Math.abs(this.centerx() - b.centerx()) * 2 - precision < this.width() + b.width() &&
Math.abs(this.centery() - b.centery()) * 2 - precision < this.height() + b.height() Math.abs(this.centery() - b.centery()) * 2 - precision < this.height() + b.height()
); );
};
PRO.width = function() {
return this.maxx - this.minx;
};
PRO.height = function() {
return this.maxy - this.miny;
};
PRO.center = function(z) {
return BASE.newPoint(this.centerx(), this.centery(), z);
};
PRO.centerx = function() {
return this.minx + this.width() / 2;
};
PRO.centery = function() {
return this.miny + this.height() / 2;
};
/** ******************************************************************
* Connect to base and Helpers
******************************************************************* */
function newBounds() {
return new Bounds();
} }
width() {
return this.maxx - this.minx;
}
height() {
return this.maxy - this.miny;
}
center(z) {
return base.newPoint(this.centerx(), this.centery(), z);
}
centerx() {
return this.minx + this.width() / 2;
}
centery() {
return this.miny + this.height() / 2;
}}
base.Bounds = Bounds;
base.newBounds = function() { return new Bounds() };
})(); })();