-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmath.ts
114 lines (108 loc) · 3.1 KB
/
math.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
/**
* Define a ranging function to calculate the number bound by `min` and `max`
* and a percent or fraction (0 through 1).
*
* **Note**: `percent`s (fractions) less than 0 or greater than 1 will return
* values outside of the `min`–`max` range.
* @example
* ```ts
* import { range } from '@resolute/std/math';
* const ranger = range(0, 10);
* ranger(0.5); // 5
* ranger(1.5); // 15
* ranger(-0.5); // -5
* ```
* @param min lower bound
* @param max upper bound
*/
export const range = (min: number, max: number) =>
/**
* Calculate the number in the defined range (`min`, `max`) specified by
* `percent`.
*
* **Note**: `percent`s (fractions) less than 0 or greater than 1 will return
* values outside of the `min`–`max` range.
* @param percent fraction
*/
(percent: number) => min + (max - min) * percent;
/**
* Define a scaling function to calculate the percentage of `value` relative to
* `min` and `max`.
* @example
* ```ts
* import { scale } from '@resolute/std/math';
* const scaler = scale(0, 10);
* scaler(5); // 0.5
* scaler(15); // 1.5
* scaler(-5); // -0.5
* ```
* @param min lower bound
* @param max upper bound
*/
export const scale = (min: number, max: number) =>
/**
* Calculate the percentage of `value` relative to `min` and `max`.
* @param value relative to `min` and `max`
*/
(value: number) => (value - min) / (max - min);
/**
* Define a clamping function to keep a `value` bound to the `min` and
* `max`.
* @example
* ```ts
* import { clamp } from '@resolute/std/math';
* clamp(0, 1)(0.5); // 0.5
* clamp(0, 1)(5); // 1
* clamp(0, 1)(-5); // 0
* ```
* @param min optional lower bound. Default 0
* @param max optional upper bound. Default 1
*/
export const clamp = (min = 0, max = 1) =>
/**
* Clamp a `value` to the bounds defined by `min` and `max`
* @param value to be bounded to `min` and `max`
*/
(value: number) => Math.min(max, Math.max(min, value));
export const clamp01 = clamp();
/**
* Generate a scale for each member of an array with (optional) `overlap`.
* @example
* ```ts
* import { divide } from '@resolute/std/math';
* [1, 2, 3]
* .map(divide())
* .map(([value, scaler]) => [
* scaler(0), // 0%
* scaler(1 / 3), // 33%
* scaler(2 / 3), // 66%
* scaler(3 / 3), // 100%
* ]);
* // [
* // [ 0, 1, 2, 3 ], // 1
* // [ -1, 0, 1, 2 ], // 2
* // [ -2, -1, 0, 1 ] // 3
* // ]
* ```
* @param overlap multiplier factor of overlap (1 means no overlap)
*/
export const divide = (overlap = 1) =>
/**
* Use with array.map() to generate the divided scales.
*/
<T>(value: T, index: number, array: T[]) => {
const unit = 1 / array.length;
const min = index * unit;
const max = min + unit * overlap;
return [value, scale(min, max)] as const;
};
/**
* Generate a random number **inclusively** between `min` and `max`.
*/
export const randomIntInclusive = (min: number, max: number) =>
Math.floor(Math.random() * (max - min + 1) + min);
/**
* Generate a random number **exclusively** between `min` and `max`.
*/
export const randomIntExclusiveMax = (min: number, max: number) =>
Math.floor(Math.random() * (max - min) + min);