UNPKG

plotboilerplate

Version:

A simple javascript plotting boilerplate for 2d stuff.

179 lines (161 loc) 4.63 kB
/** * @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 { /** * @member {number} start * @memberof CircularIntervalSet * @type {number} * @instance */ readonly start:number; /** * @member {number} end * @memberof CircularIntervalSet * @type {number} * @instance */ readonly end:number; /** * @member {Array<Array<number>>} intervals * @memberof CircularIntervalSet * @type {Array<Array<number>>} * @instance */ public intervals:Array<Array<number>>; /** * 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:number, end:number ) { 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:number) : void { 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:number, end:number ) { 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 ); }; }