UNPKG

flatten-js

Version:

Javascript library for 2d geometry

195 lines (175 loc) 6.27 kB
/** * Created by Alex Bol on 3/7/2017. */ "use strict"; module.exports = function(Flatten) { /** * Class Box represent bounding box of the shape * @type {Box} */ Flatten.Box = class Box { /** * * @param {number} xmin - minimal x coordinate * @param {number} ymin - minimal y coordinate * @param {number} xmax - maximal x coordinate * @param {number} ymax - maximal y coordinate */ constructor(xmin=undefined, ymin=undefined, xmax=undefined, ymax=undefined) { /** * Minimal x coordinate * @type {number} */ this.xmin = xmin; /** * Minimal y coordinate * @type {number} */ this.ymin = ymin; /** * Maximal x coordinate * @type {number} */ this.xmax = xmax; /** * Maximal y coordinate * @type {number} */ this.ymax = ymax; } /** * Clones and returns new instance of box * @returns {Box} */ clone() { return new Box(this.xmin, this.ymin, this.xmax, this.ymax); } /** * Property low need for interval tree interface * @returns {Point} */ get low() { return new Flatten.Point(this.xmin, this.ymin); } /** * Property high need for interval tree interface * @returns {Point} */ get high() { return new Flatten.Point(this.xmax, this.ymax); } /** * Property max returns the box itself ! * @returns {Box} */ get max() { return this.clone(); } /** * Return center of the box * @returns {Point} */ get center() { return new Flatten.Point( (this.xmin + this.xmax)/2, (this.ymin + this.ymax)/2 ); } /** * Returns true if not intersected with other box * @param {Box} other_box - other box to test * @returns {boolean} */ not_intersect(other_box) { return ( this.xmax < other_box.xmin || this.xmin > other_box.xmax || this.ymax < other_box.ymin || this.ymin > other_box.ymax ); } /** * Returns true if intersected with other box * @param {Box} other_box - Query box * @returns {boolean} */ intersect(other_box) { return !this.not_intersect(other_box); } /** * Returns new box merged with other box * @param {Box} other_box - Other box to merge with * @returns {Box} */ merge(other_box) { return new Box( this.xmin === undefined ? other_box.xmin : Math.min(this.xmin, other_box.xmin), this.ymin === undefined ? other_box.ymin : Math.min(this.ymin, other_box.ymin), this.xmax === undefined ? other_box.xmax : Math.max(this.xmax, other_box.xmax), this.ymax === undefined ? other_box.ymax : Math.max(this.ymax, other_box.ymax) ); } /** * Defines predicate "less than" between two boxes. Need for interval index * @param {Box} other_box - other box * @returns {boolean} - true if this box less than other box, false otherwise */ less_than(other_box) { if (this.low.lessThan(other_box.low)) return true; if (this.low.equalTo(other_box.low) && this.high.lessThan(other_box.high)) return true; return false; } /** * Returns true if this box is equal to other box, false otherwise * @param {Box} other_box - query box * @returns {boolean} */ equal_to(other_box) { return (this.low.equalTo(other_box.low) && this.high.equalTo(other_box.high)); } output() { return this.clone(); } maximal_val(box1, box2) { // return pt1.lessThan(pt2) ? pt2.clone() : pt1.clone(); return box1.merge(box2); } val_less_than(pt1, pt2) { return pt1.lessThan(pt2); } /** * Set new values to the box object * @param {number} xmin - miminal x coordinate * @param {number} ymin - minimal y coordinate * @param {number} xmax - maximal x coordinate * @param {number} ymax - maximal y coordinate */ set(xmin, ymin, xmax, ymax) { this.xmin = xmin; this.ymin = ymin; this.xmax = xmax; this.ymax = ymax; } /** * Return string to draw circle in svg * @param {Object} attrs - an object with attributes of svg rectangle element, * like "stroke", "strokeWidth", "fill" <br/> * Defaults are stroke:"black", strokeWidth:"1", fill:"none" * @returns {string} */ svg(attrs = {}) { let {stroke, strokeWidth, fill, id, className} = attrs; // let rest_str = Object.keys(rest).reduce( (acc, key) => acc += ` ${key}="${rest[key]}"`, ""); let id_str = (id && id.length > 0) ? `id="${id}"` : ""; let class_str = (className && className.length > 0) ? `class="${className}"` : ""; let width = this.xmax - this.xmin; let height = this.ymax - this.ymin; return `\n<rect x="${this.xmin}" y="${this.ymin}" width=${width} height=${height} stroke="${stroke || "black"}" stroke-width="${strokeWidth || 1}" fill="${fill || "none"}" ${id_str} ${class_str} />`; }; }; /** * Shortcut to create new circle * @param args * @returns {Box} */ Flatten.box = (...args) => new Flatten.Box(...args); };