plotboilerplate
Version:
A simple javascript plotting boilerplate for 2d stuff.
158 lines • 5.21 kB
JavaScript
/**
* @classdesc A circular interval set.
*
* @author Ikaros Kappler
* @date 2020-10-02
* @modified 2020-10-18 Ported to Typescript from vanilla JS.
* @modified 2020-10-22 Added the removeAt funcion.
* @version 1.0.1
* @name CircularIntervalSet
**/
export class CircularIntervalSet {
/**
* Create a new CircularIntervalSet with the given lower and upperBound (start and end).
*
* The intervals inside lower and upper bound will initially be added to this set (full range).
*
* @param {number} start
* @param {number} end
* @method clear
* @memberof CircularIntervalSet
**/
constructor(start, end) {
this.start = start;
this.end = end;
this.intervals = [[start, end]];
}
;
/**
* Clear this set (will be empty after this operation).
*
* @method clear
* @instance
* @memberof CircularIntervalSet
* @return {void}
**/
clear() {
this.intervals = [];
}
;
/**
* Remove the interval at given index.
*
* @param {number} index
* @method removeAt
* @instance
* @memberof CircularIntervalSet
* @return {void}
**/
// Todo: remove? (not in use any more?)
removeAt(index) {
if (index < 0 || index >= this.intervals.length)
return;
this.intervals.splice(index, 1);
}
;
/**
* Intersect all sub intervalls with the given range (must be inside bounds).
*
* @param {number} start
* @param {number} end
* @method intersect
* @instance
* @memberof CircularIntervalSet
* @return {void}
**/
intersect(start, end) {
for (var i = 0; i < this.intervals.length;) {
if (start <= end) {
if ((this.intervals[i][0] >= end || this.intervals[i][1] <= start)) {
// Current interval is fully outside range.
// REMOVE
this.intervals.splice(i, 1);
}
else if (this.intervals[i][0] >= start && this.intervals[i][1] <= end) {
// Current interval is fully inside.
// KEEP
i++;
}
else if (this.intervals[i][0] <= start && this.intervals[i][1] >= end) {
// Desired range lies inside current interval.
// CUT OFF LEFT AND RIGHT.
this.intervals.splice(i, 1, [start, end]);
i++;
}
else if (this.intervals[i][0] <= start && this.intervals[i][1] < end) {
// Right end is inside range.
// CUT OFF LEFT.
this.intervals[i][0] = start;
i++;
}
else if (this.intervals[i][0] > start && this.intervals[i][1] >= end) {
// LEFT end is inside range.
// CUT OFF RIGHT.
this.intervals[i][1] = end;
i++;
}
else {
// NOOP
i++;
}
}
else {
// start > end
if (this.intervals[i][0] >= end && this.intervals[i][1] <= start) {
// Current interval is fully outside range.
// REMOVE
this.intervals.splice(i, 1);
}
else if (this.intervals[i][0] >= start) {
// Full inside (right range).
// Keep.
i++;
}
else if (this.intervals[i][1] <= end) {
// Full inside (left range).
// Keep.
i++;
}
else if (this.intervals[i][0] >= end && this.intervals[i][1] > start) {
// Right part inside.
// Cut off left part.
this.intervals.splice(i, 1, [start, this.intervals[i][1]]);
i++;
}
else if (this.intervals[i][0] <= end && this.intervals[i][1] < start) {
// Left part inside.
// Cut off right part.
this.intervals.splice(i, 1, [this.intervals[i][0], end]);
i++;
}
else if (this.intervals[i][0] <= end && this.intervals[i][1] >= start) {
// Start and end inside, inner part is not.
// Cut into two.
this.intervals.splice(i, 1, [this.intervals[i][0], end], [start, this.intervals[i][1]]);
i += 2;
}
else {
// NOOP
i++;
}
}
}
}
;
/**
* Convert this set to a human readable string.
*
* @method toString
* @instance
* @memberof CircularIntervalSet
* @return {string}
**/
toString() {
return JSON.stringify(this.intervals);
}
;
}
//# sourceMappingURL=CircularIntervalSet.js.map