/
intervalSorted.ts
149 lines (137 loc) · 4.07 KB
/
intervalSorted.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import { Interval } from '../index';
/**
* A special [[Interval]] where T0 is always the smallest value and T1 is always the largest.
* As a result, [[isIncreasing]] will always return `true`.
*
* ### Example
* ```js
* import { IntervalSorted } from 'shapetypes'
*
* // Create sorted interval
* const interval = new IntervalSorted(5, 10);
*
* // Get properties of the interval
* console.log(interval.length);
* // => 5
* console.log(interval.mid);
* // => 7.5
* console.log(interval.contains(8));
* // => True
* console.log(interval.isIncreasing);
* // => True
*
* ```
*
*/
export class IntervalSorted extends Interval {
// -----------------------
// STATIC
// -----------------------
/**
* Creates an interval of a given length, centered on a value.
*
* @category Create
* @param center The middle value of the interval.
* @param width The length of the interval.
*/
public static fromCenter(center: number, width: number): IntervalSorted {
if (width < 0) {
throw new RangeError('Width must be greater than 0');
}
return new IntervalSorted(center - width / 2, center + width / 2);
}
// -----------------------
// CONSTRUCTOR
// -----------------------
/***
* Creates a sorted interval from two values.
* The values don't need to be provided in order as they are sorted when the interval is constructed.
* This means that the T0 value may be reassigned to T1 if it's the largest value, and vice versa.
* @param T0 One end of the interval. This value may be assigned to T1 if it is the largest parameter.
* @param T1 The other end of the interval. This value may be assigned to T0 if it is the smallest parameter.
*/
constructor(T0: number, T1: number) {
if (T0 < T1) {
super(T0, T1);
} else {
super(T1, T0);
}
}
// -----------------------
// GET & SET
// -----------------------
/**
* A sorted interval is always increasing, so this will return false.
*/
get isDecreasing(): boolean {
return false;
}
/**
* A sorted interval is always increasing, so this will return true.
*/
get isIncreasing(): boolean {
return true;
}
/**
* Gets [[T0]], which is always the min value in a sorted interval.
*/
get min(): number {
return this.T0;
}
/**
* Gets [[T1]], which is always the min value in a sorted interval.
*/
get max(): number {
return this.T1;
}
// -----------------------
// PUBLIC
// -----------------------
/**
* Moves the min and max apart by a set amount. Returns the enlarged interval.
*
* ### Example
* ```js
* const interval = new IntervalSorted(5, 10);
* const expanded = interval.inflate(2);
* console.log(expanded.min);
* // => 3
* console.log(expanded.max);
* // => 12
* ```
* @param amount The distance to move the min and max values. If positive, the overall length of the interval will grow. If negative, the overall length will shrink.
*/
public inflate(amount: number): IntervalSorted {
if (amount * -2 > this.length) {
// Will deflate in on itself.
const mid = this.mid;
return new IntervalSorted(mid, mid);
} else {
return new IntervalSorted(this.min - amount, this.max + amount);
}
}
/**
* Creates a copy of this interval with a different min value.
*
* @param newMin New min value for the new interval
* @note Throws an error if the new minimum is greater than the current maximum.
*/
public withMin(newMin: number): IntervalSorted {
if (newMin > this.max) {
throw new RangeError('Min must be smaller than max');
}
return new IntervalSorted(newMin, this.max);
}
/**
* Creates a copy of this interval with a different max value.
*
* @param newMax New max value for the new interval
* @note Throws an error if the new maximum is less than the current minimum.
*/
public withMax(newMax: number): IntervalSorted {
if (newMax < this.min) {
throw new RangeError('Max must be larger than min');
}
return new IntervalSorted(this.min, newMax);
}
}