dotfiles/vscode/.vscode/extensions/randomfractalsinc.vscode-data-preview-2.3.0/node_modules/rectangular/index.js
Errol Sancaktar ff17c17e23 vscode
2024-06-14 09:31:58 -06:00

553 lines
18 KiB
JavaScript

'use strict';
/* eslint-env node, browser */
/**
* Creates a new read-only property and attaches it to the provided context.
* @private
* @param {string} name - Name for new property.
* @param {*} [value] - Value of new property.
*/
function addReadOnlyProperty(name, value) {
Object.defineProperty(this, name, {
value: value,
writable: false,
enumerable: true,
configurable: false
});
}
/**
* @constructor Point
*
* @desc This object represents a single point in an abstract 2-dimensional matrix.
*
* The unit of measure is typically pixels.
* (If used to model computer graphics, vertical coordinates are typically measured downwards
* from the top of the window. This convention however is not inherent in this object.)
*
* Note: This object should be instantiated with the `new` keyword.
*
* @param {number} x - the new point's `x` property
* @param {number} y - the new point's `y` property
*/
function Point(x, y) {
/**
* @name x
* @type {number}
* @summary This point's horizontal coordinate.
* @desc Created upon instantiation by the {@link Point|constructor}.
* @memberOf Point.prototype
* @abstract
*/
addReadOnlyProperty.call(this, 'x', Number(x) || 0);
/**
* @name y
* @type {number}
* @summary This point's vertical coordinate.
* @desc Created upon instantiation by the {@link Point|constructor}.
* @memberOf Point.prototype
* @abstract
*/
addReadOnlyProperty.call(this, 'y', Number(y) || 0);
}
Point.prototype = {
/**
* @returns {Point} A new point which is this point's position increased by coordinates of given `offset`.
* @param {Point} offset - Horizontal and vertical values to add to this point's coordinates.
* @memberOf Point.prototype
*/
plus: function(offset) {
return new Point(
this.x + offset.x,
this.y + offset.y
);
},
/**
* @returns {Point} A new point which is this point's position increased by given offsets.
* @param {number} [offsetX=0] - Value to add to this point's horizontal coordinate.
* @param {number} [offsetY=0] - Value to add to this point's horizontal coordinate.
* @memberOf Point.prototype
*/
plusXY: function(offsetX, offsetY) {
return new Point(
this.x + (offsetX || 0),
this.y + (offsetY || 0)
);
},
/**
* @returns {Point} A new point which is this point's position decreased by coordinates of given `offset`.
* @param {Point} offset - Horizontal and vertical values to subtract from this point's coordinates.
* @memberOf Point.prototype
*/
minus: function(offset) {
return new Point(
this.x - offset.x,
this.y - offset.y
);
},
/**
* @returns {Point} A new `Point` positioned to least x and least y of this point and given `offset`.
* @param {Point} point - A point to compare to this point.
* @memberOf Point.prototype
*/
min: function(point) {
return new Point(
Math.min(this.x, point.x),
Math.min(this.y, point.y)
);
},
/**
* @returns {Point} A new `Point` positioned to greatest x and greatest y of this point and given `point`.
* @param {Point} point - A point to compare to this point.
* @memberOf Point.prototype
*/
max: function(point) {
return new Point(
Math.max(this.x, point.x),
Math.max(this.y, point.y)
);
},
/**
* @returns {number} Distance between given `point` and this point using Pythagorean Theorem formula.
* @param {Point} point - A point from which to compute the distance to this point.
* @memberOf Point.prototype
*/
distance: function(point) {
var deltaX = point.x - this.x,
deltaY = point.y - this.y;
return Math.sqrt(
deltaX * deltaX +
deltaY * deltaY
);
},
/**
* _(Formerly: `equal`.)_
* @returns {boolean} `true` iff _both_ coordinates of this point are exactly equal to those of given `point`.
* @param {Point} point - A point to compare to this point.
* @memberOf Point.prototype
*/
equals: function(point) {
var result = false;
if (point) {
result =
this.x === point.x &&
this.y === point.y;
}
return result;
},
/**
* @returns {boolean} `true` iff _both_ coordinates of this point are greater than those of given `point`.
* @param {Point} point - A point to compare to this point
* @memberOf Point.prototype
*/
greaterThan: function(point) {
return (
this.x > point.x &&
this.y > point.y
);
},
/**
* @returns {boolean} `true` iff _both_ coordinates of this point are less than those of given `point`.
* @param {Point} point - A point to compare to this point
* @memberOf Point.prototype
*/
lessThan: function(point) {
return (
this.x < point.x &&
this.y < point.y
);
},
/**
* _(Formerly `greaterThanEqualTo`.)_
* @returns {boolean} `true` iff _both_ coordinates of this point are greater than or equal to those of given `point`.
* @param {Point} point - A point to compare to this point
* @memberOf Point.prototype
*/
greaterThanOrEqualTo: function(point) {
return (
this.x >= point.x &&
this.y >= point.y
);
},
/**
* _(Formerly `lessThanEqualTo`.)_
* @returns {boolean} `true` iff _both_ coordinates of this point are less than or equal to those of given `point`.
* @param {Point} point - A point to compare to this point.
* @memberOf Point.prototype
*/
lessThanOrEqualTo: function(point) {
return (
this.x <= point.x &&
this.y <= point.y
);
},
/**
* _(Formerly `isContainedWithinRectangle`.)_
* @param rect {Rectangle} - Rectangle to test this point against.
* @returns {boolean} `true` iff this point is within given `rect`.
* @memberOf Point.prototype
*/
within: function(rect) {
var minX = rect.origin.x,
maxX = minX + rect.extent.x;
var minY = rect.origin.y,
maxY = minY + rect.extent.y;
if (rect.extent.x < 0) {
minX = maxX;
maxX = rect.origin.x;
}
if (rect.extent.y < 0) {
minY = maxY;
maxY = rect.origin.y;
}
return (
minX <= this.x && this.x < maxX &&
minY <= this.y && this.y < maxY
);
}
};
Point.prototype.EQ = Point.prototype.equals;
Point.prototype.GT = Point.prototype.greaterThan;
Point.prototype.LT = Point.prototype.lessThan;
Point.prototype.GE = Point.prototype.greaterThanOrEqualTo;
Point.prototype.LE = Point.prototype.lessThanOrEqualTo;
/**
* @constructor Rectangle
*
* @desc This object represents a rectangular area within an abstract 2-dimensional matrix.
*
* The unit of measure is typically pixels.
* (If used to model computer graphics, vertical coordinates are typically measured downwards
* from the top of the window. This convention however is not inherent in this object.)
*
* Normally, the `x` and `y` parameters to the constructor describe the upper left corner of the rect.
* However, negative values of `width` and `height` will be added to the given `x` and `y`. That is,
* a negative value of the `width` parameter will extend the rect to the left of the given `x` and
* a negative value of the `height` parameter will extend the rect above the given `y`.
* In any case, after instantiation the following are guaranteed to always be true:
* * The `extent`, `width`, and `height` properties _always_ give positive values.
* * The `origin`, `top`, and `left` properties _always_ reflect the upper left corner.
* * The `corner`, `bottom`, and `right` properties _always_ reflect the lower right corner.
*
* Note: This object should be instantiated with the `new` keyword.
*
* @param {number} [x=0] - Horizontal coordinate of some corner of the rect.
* @param {number} [y=0] - Vertical coordinate of some corner of the rect.
* @param {number} [width=0] - Width of the new rect. May be negative (see above).
* @param {number} [height=0] - Height of the new rect. May be negative (see above).
*/
function Rectangle(x, y, width, height) {
x = Number(x) || 0;
y = Number(y) || 0;
width = Number(width) || 0;
height = Number(height) || 0;
if (width < 0) {
x += width;
width = -width;
}
if (height < 0) {
y += height;
height = -height;
}
/**
* @name origin
* @type {Point}
* @summary Upper left corner of this rect.
* @desc Created upon instantiation by the {@linkplain Rectangle|constructor}.
* @memberOf Rectangle.prototype
* @abstract
*/
addReadOnlyProperty.call(this, 'origin', new Point(x, y));
/**
* @name extent
* @type {Point}
* @summary this rect's width and height.
* @desc Unlike the other `Point` properties, `extent` is not a global coordinate pair; rather it consists of a _width_ (`x`, always positive) and a _height_ (`y`, always positive).
*
* This object might be more legitimately typed as something like `Area` with properties `width` and `height`; however we wanted it to be able to use it efficiently with a point's `plus` and `minus` methods (that is, without those methods having to check and branch on the type of its parameter).
*
* Created upon instantiation by the {@linkplain Rectangle|constructor}.
* @see The {@link Rectangle#corner|corner} method.
* @memberOf Rectangle.prototype
* @abstract
*/
addReadOnlyProperty.call(this, 'extent', new Point(width, height));
/**
* @name corner
* @type {Point}
* @summary Lower right corner of this rect.
* @desc This is a calculated value created upon instantiation by the {@linkplain Rectangle|constructor}. It is `origin` offset by `extent`.
*
* **Note:** These coordinates actually point to the pixel one below and one to the right of the rect's actual lower right pixel.
* @memberOf Rectangle.prototype
* @abstract
*/
addReadOnlyProperty.call(this, 'corner', new Point(x + width, y + height));
/**
* @name center
* @type {Point}
* @summary Center of this rect.
* @desc Created upon instantiation by the {@linkplain Rectangle|constructor}.
* @memberOf Rectangle.prototype
* @abstract
*/
addReadOnlyProperty.call(this, 'center', new Point(x + (width / 2), y + (height / 2)));
}
Rectangle.prototype = {
/**
* @type {number}
* @desc _(Formerly a function; now a getter.)_
* @summary Minimum vertical coordinate of this rect.
* @memberOf Rectangle.prototype
*/
get top() {
return this.origin.y;
},
/**
* @type {number}
* @desc _(Formerly a function; now a getter.)_
* @summary Minimum horizontal coordinate of this rect.
* @memberOf Rectangle.prototype
*/
get left() {
return this.origin.x;
},
/**
* @type {number}
* @desc _(Formerly a function; now a getter.)_
* @summary Maximum vertical coordinate of this rect + 1.
* @memberOf Rectangle.prototype
*/
get bottom() {
return this.corner.y;
},
/**
* @type {number}
* @desc _(Formerly a function; now a getter.)_
* @summary Maximum horizontal coordinate of this rect + 1.
* @memberOf Rectangle.prototype
*/
get right() {
return this.corner.x;
},
/**
* @type {number}
* @desc _(Formerly a function; now a getter.)_
* @summary Width of this rect (always positive).
* @memberOf Rectangle.prototype
*/
get width() {
return this.extent.x;
},
/**
* @type {number}
* @desc _(Formerly a function; now a getter.)_
* @summary Height of this rect (always positive).
* @memberOf Rectangle.prototype
*/
get height() {
return this.extent.y;
},
/**
* @type {number}
* @desc _(Formerly a function; now a getter.)_
* @summary Area of this rect.
* @memberOf Rectangle.prototype
*/
get area() {
return this.width * this.height;
},
/**
* @returns {Rectangle} A copy of this rect but with horizontal position reset to given `x` and no width.
* @param {number} x - Horizontal coordinate of the new rect.
* @memberOf Rectangle.prototype
*/
flattenXAt: function(x) {
return new Rectangle(x, this.origin.y, 0, this.extent.y);
},
/**
* @returns {Rectangle} A copy of this rect but with vertical position reset to given `y` and no height.
* @param {number} y - Vertical coordinate of the new rect.
* @memberOf Rectangle.prototype
*/
flattenYAt: function(y) {
return new Rectangle(this.origin.x, y, this.extent.x, 0);
},
/**
* @returns {boolean} `true` iff given `point` entirely contained within this rect.
* @param {Point} pointOrRect - The point or rect to test for containment.
* @memberOf Rectangle.prototype
*/
contains: function(pointOrRect) {
return pointOrRect.within(this);
},
/**
* _(Formerly `isContainedWithinRectangle`.)_
* @returns {boolean} `true` iff `this` rect is entirely contained within given `rect`.
* @param {Rectangle} rect - Rectangle to test against this rect.
* @memberOf Rectangle.prototype
*/
within: function(rect) {
return (
rect.origin.lessThanOrEqualTo(this.origin) &&
rect.corner.greaterThanOrEqualTo(this.corner)
);
},
/**
* _(Formerly: `insetBy`.)_
* @returns {Rectangle} That is enlarged/shrunk by given `padding`.
* @param {number} padding - Amount by which to increase (+) or decrease (-) this rect
* @see The {@link Rectangle#shrinkBy|shrinkBy} method.
* @memberOf Rectangle.prototype
*/
growBy: function(padding) {
return new Rectangle(
this.origin.x + padding,
this.origin.y + padding,
this.extent.x - padding - padding,
this.extent.y - padding - padding);
},
/**
* @returns {Rectangle} That is enlarged/shrunk by given `padding`.
* @param {number} padding - Amount by which to decrease (+) or increase (-) this rect.
* @see The {@link Rectangle#growBy|growBy} method.
* @memberOf Rectangle.prototype
*/
shrinkBy: function(padding) {
return this.growBy(-padding);
},
/**
* @returns {Rectangle} Bounding rect that contains both this rect and the given `rect`.
* @param {Rectangle} rect - The rectangle to union with this rect.
* @memberOf Rectangle.prototype
*/
union: function(rect) {
var origin = this.origin.min(rect.origin),
corner = this.corner.max(rect.corner),
extent = corner.minus(origin);
return new Rectangle(
origin.x, origin.y,
extent.x, extent.y
);
},
/**
* iterate over all points within this rect, invoking `iteratee` for each.
* @param {function(number,number)} iteratee - Function to call for each point.
* Bound to `context` when given; otherwise it is bound to this rect.
* Each invocation of `iteratee` is called with two arguments:
* the horizontal and vertical coordinates of the point.
* @param {object} [context=this] - Context to bind to `iteratee` (when not `this`).
* @memberOf Rectangle.prototype
*/
forEach: function(iteratee, context) {
context = context || this;
for (var x = this.origin.x, x2 = this.corner.x; x < x2; x++) {
for (var y = this.origin.y, y2 = this.corner.y; y < y2; y++) {
iteratee.call(context, x, y);
}
}
},
/**
* @returns {Rectangle} One of:
* * _If this rect intersects with the given `rect`:_
* a new rect representing that intersection.
* * _If it doesn't intersect and `ifNoneAction` defined:_
* result of calling `ifNoneAction`.
* * _If it doesn't intersect and `ifNoneAction` undefined:_
* `null`.
* @param {Rectangle} rect - The rectangle to intersect with this rect.
* @param {function(Rectangle)} [ifNoneAction] - When no intersection, invoke and return result.
* Bound to `context` when given; otherwise bound to this rect.
* Invoked with `rect` as sole parameter.
* @param {object} [context=this] - Context to bind to `ifNoneAction` (when not `this`).
* @memberOf Rectangle.prototype
*/
intersect: function(rect, ifNoneAction, context) {
var result = null,
origin = this.origin.max(rect.origin),
corner = this.corner.min(rect.corner),
extent = corner.minus(origin);
if (extent.x > 0 && extent.y > 0) {
result = new Rectangle(
origin.x, origin.y,
extent.x, extent.y
);
} else if (typeof ifNoneAction === 'function') {
result = ifNoneAction.call(context || this, rect);
}
return result;
},
/**
* @returns {boolean} `true` iff this rect overlaps with given `rect`.
* @param {Rectangle} rect - The rectangle to intersect with this rect.
* @memberOf Rectangle.prototype
*/
intersects: function(rect) {
return (
rect.corner.x > this.origin.x &&
rect.corner.y > this.origin.y &&
rect.origin.x < this.corner.x &&
rect.origin.y < this.corner.y
);
}
};
// Interface
exports.Point = Point;
exports.Rectangle = Rectangle;