@jarenjs/core 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +800 -0
- package/LICENSE +21 -0
- package/README.md +68 -0
- package/dist/types/array.d.ts +28 -0
- package/dist/types/bigint.d.ts +5 -0
- package/dist/types/dates.d.ts +79 -0
- package/dist/types/float.d.ts +32 -0
- package/dist/types/function.d.ts +22 -0
- package/dist/types/index.d.ts +119 -0
- package/dist/types/integer.d.ts +24 -0
- package/dist/types/math/float64.d.ts +121 -0
- package/dist/types/math/index.d.ts +5 -0
- package/dist/types/math/int32.d.ts +41 -0
- package/dist/types/math/vec2f64.d.ts +346 -0
- package/dist/types/math/vec2i32.d.ts +43 -0
- package/dist/types/math/vec3f64.d.ts +61 -0
- package/dist/types/number.d.ts +39 -0
- package/dist/types/object.d.ts +44 -0
- package/dist/types/scan.d.ts +64 -0
- package/dist/types/string.d.ts +65 -0
- package/dist/types/text/base64.d.ts +4 -0
- package/dist/types/text/basic.d.ts +5 -0
- package/dist/types/text/email.d.ts +3 -0
- package/dist/types/text/host.d.ts +14 -0
- package/dist/types/text/i18n.d.ts +13 -0
- package/dist/types/text/identifiers.d.ts +5 -0
- package/dist/types/text/index.d.ts +8 -0
- package/dist/types/text/iregexp.d.ts +36 -0
- package/dist/types/text/misc.d.ts +4 -0
- package/dist/types/text/punycode.d.ts +86 -0
- package/package.json +101 -0
- package/src/array.js +57 -0
- package/src/bigint.js +30 -0
- package/src/dates.js +371 -0
- package/src/float.js +107 -0
- package/src/function.js +56 -0
- package/src/index.js +223 -0
- package/src/integer.js +77 -0
- package/src/math/float64.js +316 -0
- package/src/math/index.js +5 -0
- package/src/math/int32.js +235 -0
- package/src/math/vec2f64.js +706 -0
- package/src/math/vec2i32.js +250 -0
- package/src/math/vec3f64.js +225 -0
- package/src/number.js +63 -0
- package/src/object.js +240 -0
- package/src/scan.js +96 -0
- package/src/string.js +194 -0
- package/src/text/base64.js +54 -0
- package/src/text/basic.js +23 -0
- package/src/text/email.js +61 -0
- package/src/text/host.js +335 -0
- package/src/text/i18n.js +294 -0
- package/src/text/identifiers.js +27 -0
- package/src/text/index.js +11 -0
- package/src/text/iregexp.js +308 -0
- package/src/text/misc.js +19 -0
- package/src/text/punycode.js +407 -0
package/src/index.js
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
//@ts-check
|
|
2
|
+
export function isFn(data) {
|
|
3
|
+
return typeof data === 'function';
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
//#region Scalar Tests
|
|
7
|
+
function isScalarTypeEx(typeName) {
|
|
8
|
+
switch (typeName) {
|
|
9
|
+
case 'string':
|
|
10
|
+
case 'number':
|
|
11
|
+
case 'boolean':
|
|
12
|
+
case 'integer':
|
|
13
|
+
case 'bigint':
|
|
14
|
+
return true;
|
|
15
|
+
default:
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function isScalarType(data) {
|
|
21
|
+
return data != null && isScalarTypeEx(typeof data);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function isStringType(data) {
|
|
25
|
+
return typeof data === 'string';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Checks if the given data is of boolean type.
|
|
30
|
+
* @param {any} data - The data to check.
|
|
31
|
+
* @returns {boolean} - True if the data is a boolean, otherwise false.
|
|
32
|
+
*/
|
|
33
|
+
export function isBooleanType(data) {
|
|
34
|
+
return data === true || data === false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Checks if the given data is of number type.
|
|
39
|
+
* @param {any} data - The data to check.
|
|
40
|
+
* @returns {boolean} - True if the data is a number, otherwise false.
|
|
41
|
+
*/
|
|
42
|
+
export function isNumberType(data) {
|
|
43
|
+
return data != null && typeof data === 'number';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Checks if the given data is an integer type.
|
|
48
|
+
* @param {any} data - The data to check.
|
|
49
|
+
* @returns {boolean} - True if the data is an integer, otherwise false.
|
|
50
|
+
*/
|
|
51
|
+
export function isIntegerType(data) {
|
|
52
|
+
return Number.isInteger(data);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function isBigIntType(data) {
|
|
56
|
+
return typeof data === 'bigint';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
|
|
61
|
+
//#region Scalar Getters
|
|
62
|
+
/**
|
|
63
|
+
* Returns the string type of the input object if it is a string; otherwise, returns the default value.
|
|
64
|
+
*
|
|
65
|
+
* @param {any} obj - The input object to check its type.
|
|
66
|
+
* @param {string|undefined} [def=undefined] - The default value to return if the input object is not a string.
|
|
67
|
+
* @returns {string} The string type of the input object or the default value.
|
|
68
|
+
*/
|
|
69
|
+
export function getStringType(obj, def = undefined) {
|
|
70
|
+
return isStringType(obj) ? obj : def;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Checks if the given object is a boolean type and returns it, otherwise returns the default value.
|
|
75
|
+
* @param {any} obj - The object to check.
|
|
76
|
+
* @param {boolean|undefined} [def=undefined] - The default value to return if the object is not a boolean.
|
|
77
|
+
* @returns {boolean|undefined} - The boolean value or the default value.
|
|
78
|
+
*/
|
|
79
|
+
export function getBooleanType(obj, def = undefined) {
|
|
80
|
+
return isBooleanType(obj) ? obj : def;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Checks if the given object is a number type and returns it, otherwise returns the default value.
|
|
85
|
+
* @param {any} obj - The object to check.
|
|
86
|
+
* @param {number|undefined} [def=undefined] - The default value to return if the object is not a number.
|
|
87
|
+
* @returns {number|undefined} - The number value or the default value.
|
|
88
|
+
*/
|
|
89
|
+
export function getNumberType(obj, def = undefined) {
|
|
90
|
+
return isNumberType(obj) ? obj : def;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Checks if the given object is an integer type and returns it, otherwise returns the default value.
|
|
95
|
+
* @param {any} obj - The object to check.
|
|
96
|
+
* @param {number|undefined} [def=undefined] - The default value to return if the object is not an integer.
|
|
97
|
+
* @returns {number|undefined} - The integer value or the default value.
|
|
98
|
+
*/
|
|
99
|
+
export function getIntegerType(obj, def = undefined) {
|
|
100
|
+
return isIntegerType(obj) ? obj : def;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Checks if the given object is a bigint type and returns it, otherwise returns the default value.
|
|
105
|
+
* @param {any} obj - The object to check.
|
|
106
|
+
* @param {bigint|undefined} [def=undefined] - The default value to return if the object is not a bigint.
|
|
107
|
+
* @returns {bigint|undefined} - The bigint value or the default value.
|
|
108
|
+
*/
|
|
109
|
+
export function getBigIntType(obj, def = undefined) {
|
|
110
|
+
return isBigIntType(obj)
|
|
111
|
+
? obj
|
|
112
|
+
: def;
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
|
|
116
|
+
//#region Object Tests
|
|
117
|
+
/**
|
|
118
|
+
* Checks if the input data is null.
|
|
119
|
+
*
|
|
120
|
+
* @param {any} data - The data to be checked.
|
|
121
|
+
* @returns {boolean} - Returns true if the data is null, otherwise false.
|
|
122
|
+
*/
|
|
123
|
+
export function isNullValue(data) {
|
|
124
|
+
return data === null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Checks if the given data is an object of a specific class.
|
|
129
|
+
*
|
|
130
|
+
* @param {any} data - The data to check.
|
|
131
|
+
* @param {Function} type - The class type to compare against.
|
|
132
|
+
* @returns {boolean} Returns true if the data is an object of the specified class; otherwise, false.
|
|
133
|
+
*/
|
|
134
|
+
export function isObjectOfClass(data, type) {
|
|
135
|
+
return data != null && data.constructor === type;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @brief test if data is an object literal
|
|
140
|
+
* @param {*} data the data to test
|
|
141
|
+
* @returns boolean
|
|
142
|
+
*/
|
|
143
|
+
export function isObjectClass(data) {
|
|
144
|
+
return isObjectOfClass(data, Object);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Checks if the input data is of type Map.
|
|
149
|
+
*
|
|
150
|
+
* @param {any} data - The data to be checked.
|
|
151
|
+
* @returns {boolean} - Returns true if the data is an instance of the Map class, otherwise false.
|
|
152
|
+
*/
|
|
153
|
+
export function isMapClass(data) {
|
|
154
|
+
return isObjectOfClass(data, Map);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @brief test if data is typeof object but not an Array
|
|
159
|
+
* @param {*} data the data to test
|
|
160
|
+
* @returns boolean
|
|
161
|
+
*/
|
|
162
|
+
export function isObjectType(data) {
|
|
163
|
+
return data != null
|
|
164
|
+
&& typeof data === 'object'
|
|
165
|
+
&& data.constructor !== Array;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Checks if the input data is of type Array.
|
|
170
|
+
*
|
|
171
|
+
* @param {any} data - The data to be checked.
|
|
172
|
+
* @returns {boolean} - Returns true if the data is an instance of the Array class, otherwise false.
|
|
173
|
+
*/
|
|
174
|
+
export function isArrayClass(data) {
|
|
175
|
+
return isObjectOfClass(data, Array);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Checks if the input data is of type Set.
|
|
180
|
+
*
|
|
181
|
+
* @param {any} data - The data to be checked.
|
|
182
|
+
* @returns {boolean} - Returns true if the data is an instance of the Set class, otherwise false.
|
|
183
|
+
*/
|
|
184
|
+
export function isSetClass(data) {
|
|
185
|
+
return isObjectOfClass(data, Set);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export const TypedArray = Object.getPrototypeOf(Uint8Array);
|
|
189
|
+
export function isTypedArray(data) {
|
|
190
|
+
if (data == null)
|
|
191
|
+
return false;
|
|
192
|
+
const proto = data.__proto__.__proto__;
|
|
193
|
+
return proto != null && proto.constructor === TypedArray;
|
|
194
|
+
}
|
|
195
|
+
//#endregion
|
|
196
|
+
|
|
197
|
+
//#region Object Getters
|
|
198
|
+
export function getObjectType(obj, def = undefined) {
|
|
199
|
+
return isObjectType(obj) ? obj : def;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export function getArrayClass(obj, def = undefined) {
|
|
203
|
+
return isArrayClass(obj) ? obj : def;
|
|
204
|
+
}
|
|
205
|
+
//#endregion
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Calculates the inclusive and exclusive bounds based on the provided parameters.
|
|
209
|
+
*
|
|
210
|
+
* @param {function} getType - A function to determine the type of the inclusive and exclusive bounds.
|
|
211
|
+
* @param {number|string|undefined} inclusive - The inclusive bound value.
|
|
212
|
+
* @param {number|string|boolean|undefined} exclusive - The exclusive bound value.
|
|
213
|
+
* @returns {Array} An array containing the inclusive and exclusive bounds.
|
|
214
|
+
*/
|
|
215
|
+
export function getInclusiveExclusiveBounds(getType, inclusive, exclusive) {
|
|
216
|
+
const includes = getType(inclusive);
|
|
217
|
+
const excludes = exclusive === true
|
|
218
|
+
? includes
|
|
219
|
+
: getType(exclusive);
|
|
220
|
+
return (excludes === undefined)
|
|
221
|
+
? [includes, undefined]
|
|
222
|
+
: [undefined, excludes];
|
|
223
|
+
}
|
package/src/integer.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//@ts-check
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
isIntegerType,
|
|
5
|
+
} from './index.js';
|
|
6
|
+
|
|
7
|
+
export const INT8_MIN = -128;
|
|
8
|
+
export const INT8_MAX = 127;
|
|
9
|
+
|
|
10
|
+
export function isValidInt8(value) {
|
|
11
|
+
return isIntegerType(value)
|
|
12
|
+
&& value >= INT8_MIN
|
|
13
|
+
&& value <= INT8_MAX;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const UINT8_MIN = 0;
|
|
17
|
+
export const UINT8_MAX = 255;
|
|
18
|
+
|
|
19
|
+
export function isValidUInt8(value) {
|
|
20
|
+
return isIntegerType(value)
|
|
21
|
+
&& value >= UINT8_MIN
|
|
22
|
+
&& value <= UINT8_MAX;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const INT16_MIN = -32768;
|
|
26
|
+
export const INT16_MAX = 32767;
|
|
27
|
+
|
|
28
|
+
export function isValidInt16(value) {
|
|
29
|
+
return isIntegerType(value)
|
|
30
|
+
&& value >= INT16_MIN
|
|
31
|
+
&& value <= INT16_MAX;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const UINT16_MIN = 0;
|
|
35
|
+
export const UINT16_MAX = 65535;
|
|
36
|
+
|
|
37
|
+
export function isValidUInt16(value) {
|
|
38
|
+
return isIntegerType(value)
|
|
39
|
+
&& value >= UINT16_MIN
|
|
40
|
+
&& value <= UINT16_MAX;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const INT32_MIN = -(2 ** 31);
|
|
44
|
+
export const INT32_MAX = (2 ** 31) - 1;
|
|
45
|
+
|
|
46
|
+
export function isValidInt32(value) {
|
|
47
|
+
return isIntegerType(value)
|
|
48
|
+
&& value >= INT32_MIN
|
|
49
|
+
&& value <= INT32_MAX;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const UINT32_MIN = 0;
|
|
53
|
+
export const UINT32_MAX = (2 ** 32) - 1;
|
|
54
|
+
|
|
55
|
+
export function isValidUInt32(value) {
|
|
56
|
+
return isIntegerType(value)
|
|
57
|
+
&& value >= UINT32_MIN
|
|
58
|
+
&& value <= UINT32_MAX;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const INT64_MIN = Number.MIN_SAFE_INTEGER;
|
|
62
|
+
export const INT64_MAX = Number.MAX_SAFE_INTEGER;
|
|
63
|
+
|
|
64
|
+
export function isValidInt64(value) {
|
|
65
|
+
return isIntegerType(value)
|
|
66
|
+
&& value >= INT64_MIN
|
|
67
|
+
&& value <= INT64_MAX;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const UINT64_MIN = 0;
|
|
71
|
+
export const UINT64_MAX = Number.MAX_SAFE_INTEGER;
|
|
72
|
+
|
|
73
|
+
export function isValidUInt64(value) {
|
|
74
|
+
return isIntegerType(value)
|
|
75
|
+
&& value >= UINT64_MIN
|
|
76
|
+
&& value <= UINT64_MAX;
|
|
77
|
+
}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
//@ts-check
|
|
2
|
+
|
|
3
|
+
export const mathf64_abs = Math.abs;
|
|
4
|
+
|
|
5
|
+
export const mathf64_sqrt = Math.sqrt;
|
|
6
|
+
export const mathf64_pow = Math.pow;
|
|
7
|
+
export const mathf64_sin = Math.sin;
|
|
8
|
+
export const mathf64_cos = Math.cos;
|
|
9
|
+
export const mathf64_atan2 = Math.atan2;
|
|
10
|
+
export const mathf64_asin = Math.asin;
|
|
11
|
+
|
|
12
|
+
export const mathf64_ceil = Math.ceil;
|
|
13
|
+
export const mathf64_floor = Math.floor;
|
|
14
|
+
export const mathf64_round = Math.round;
|
|
15
|
+
export const mathf64_min = Math.min;
|
|
16
|
+
export const mathf64_max = Math.max;
|
|
17
|
+
|
|
18
|
+
export const mathf64_random = Math.random;
|
|
19
|
+
|
|
20
|
+
export const mathf64_EPSILON = +0.000001;
|
|
21
|
+
|
|
22
|
+
export const mathf64_SQRTFIVE = +mathf64_sqrt(5);
|
|
23
|
+
|
|
24
|
+
export const mathf64_PI = +Math.PI;
|
|
25
|
+
export const mathf64_PI2 = +(mathf64_PI * 2);
|
|
26
|
+
export const mathf64_PI1H = +(mathf64_PI / 2);
|
|
27
|
+
export const mathf64_PI41 = +(4 / mathf64_PI);
|
|
28
|
+
export const mathf64_PI42 = +(4 / (mathf64_PI * mathf64_PI));
|
|
29
|
+
|
|
30
|
+
const _isqrt = (function float64_isqrt_oncompile() {
|
|
31
|
+
const f = new Float32Array(1);
|
|
32
|
+
const i = new Int32Array(f.buffer);
|
|
33
|
+
return function float64_isqrt_impl(n = 0.0) {
|
|
34
|
+
n = +n;
|
|
35
|
+
const n2 = +(n * 0.5);
|
|
36
|
+
f[0] = +n;
|
|
37
|
+
i[0] = (0x5f375a86 - ((i[0] | 0) >> 1)) | 0;
|
|
38
|
+
n = +f[0];
|
|
39
|
+
return +(+n * +(1.5 - (+n2 * +n * +n)));
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
|
|
43
|
+
export class Float64 {
|
|
44
|
+
|
|
45
|
+
static gcd(a = 0.0, b = 0.0) {
|
|
46
|
+
a = +a; b = +b;
|
|
47
|
+
// For example, a 1024x768 monitor has a GCD of 256.
|
|
48
|
+
// When you divide both values by that you get 4x3 or 4: 3.
|
|
49
|
+
return +((b === 0.0) ? +a : +Float64.gcd(b, a % b));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static sqrt(n = 0.0) {
|
|
53
|
+
return +mathf64_sqrt(+n);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* The Cross Product Magnitude
|
|
59
|
+
* a × b of two vectors is another vector that is at right angles to both:
|
|
60
|
+
* The magnitude (length) of the cross product equals the area
|
|
61
|
+
* of a parallelogram with vectors a and b for sides:
|
|
62
|
+
*
|
|
63
|
+
* We can calculate the Cross Product this way:
|
|
64
|
+
*
|
|
65
|
+
* a × b = |a| |b| sin(θ) n
|
|
66
|
+
*
|
|
67
|
+
* or as
|
|
68
|
+
*
|
|
69
|
+
* a × b = ax × by - bx × ay
|
|
70
|
+
*
|
|
71
|
+
* Another useful property of the cross product is,
|
|
72
|
+
* that its magnitude is related to the sine of
|
|
73
|
+
* the angle between the two vectors:
|
|
74
|
+
*
|
|
75
|
+
* | a x b | = |a| . |b| . sine(theta)
|
|
76
|
+
*
|
|
77
|
+
* or
|
|
78
|
+
*
|
|
79
|
+
* sine(theta) = | a x b | / (|a| . |b|)
|
|
80
|
+
*
|
|
81
|
+
* So, in implementation 1 above, if a and b are known in advance
|
|
82
|
+
* to be unit vectors then the result of that function is exactly that sine() value.
|
|
83
|
+
* @param {number} ax
|
|
84
|
+
* @param {number} ay
|
|
85
|
+
* @param {number} bx
|
|
86
|
+
* @param {number} by
|
|
87
|
+
*/
|
|
88
|
+
static cross(ax = 0.0, ay = 0.0, bx = 0.0, by = 0.0) {
|
|
89
|
+
return +(+(+ax * +by) - +(+bx * +ay));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
*
|
|
95
|
+
* We can calculate the Dot Product of two vectors this way:
|
|
96
|
+
*
|
|
97
|
+
* a · b = |a| × |b| × cos(θ)
|
|
98
|
+
*
|
|
99
|
+
* or in this implementation as:
|
|
100
|
+
*
|
|
101
|
+
* a · b = ax × bx + ay × by
|
|
102
|
+
*
|
|
103
|
+
* When two vectors are at right angles to each other the dot product is zero.
|
|
104
|
+
*
|
|
105
|
+
* @param {number} ax vector A x velocity
|
|
106
|
+
* @param {number} ay vector A y velocity
|
|
107
|
+
* @param {number} bx vector B x velocity
|
|
108
|
+
* @param {number} by vector B y velocity
|
|
109
|
+
* @returns {number} scalar of the dot product
|
|
110
|
+
*/
|
|
111
|
+
static dot(ax = 0.0, ay = 0.0, bx = 0.0, by = 0.0) {
|
|
112
|
+
return +(+(+ax * +bx) + +(+ay * +by));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
static mag2(dx = 0.0, dy = 0.0) {
|
|
116
|
+
return +Float64.dot(dx, dy, dx, dy);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
static mag(dx = 0.0, dy = 0.0) {
|
|
120
|
+
return +mathf64_sqrt(+Float64.mag2(dx, dy));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static isqrt(n = 0.0) {
|
|
124
|
+
return +_isqrt(n);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
static fib(n = 0.0) {
|
|
128
|
+
n = +mathf64_floor(+n);
|
|
129
|
+
if (!(n >= 1.0)) return 0.0;
|
|
130
|
+
let c = 0.0;
|
|
131
|
+
let x = 1.0;
|
|
132
|
+
let i = 1.0;
|
|
133
|
+
for (; i !== n; i += 1.0) {
|
|
134
|
+
const t = +(+c + +x);
|
|
135
|
+
c = +x;
|
|
136
|
+
x = +t;
|
|
137
|
+
}
|
|
138
|
+
return +x;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// https://gist.github.com/geraldyeo/988116export
|
|
142
|
+
static fib2(value = 0.0) {
|
|
143
|
+
value = +value;
|
|
144
|
+
const fh = +(1.0 / +mathf64_SQRTFIVE * +mathf64_pow(+(+(1.0 + mathf64_SQRTFIVE) / 2.0), +value));
|
|
145
|
+
const sh = +(1.0 / +mathf64_SQRTFIVE * +mathf64_pow(+(+(1.0 - mathf64_SQRTFIVE) / 2.0), +value));
|
|
146
|
+
return +mathf64_round(+(fh - sh));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static norm(value = 0.0, min = 0.0, max = 0.0) {
|
|
150
|
+
value = +value; min = +min; max = +max;
|
|
151
|
+
return +((value - min) / (max - min));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
static lerp(norm = 0.0, min = 0.0, max = 0.0) {
|
|
155
|
+
norm = +norm; min = +min; max = +max;
|
|
156
|
+
return +((max - min) * (norm + min));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static map(value = 0.0, smin = 0.0, smax = 0.0, dmin = 0.0, dmax = 0.0) {
|
|
160
|
+
value = +value; smin = +smin; smax = +smax; dmin = +dmin; dmax = +dmax;
|
|
161
|
+
return +Float64.lerp(+Float64.norm(value, smin, smax), dmin, dmax);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Clamps a value between a checked boundary.
|
|
166
|
+
* and can therefor handle swapped min/max arguments
|
|
167
|
+
*
|
|
168
|
+
* @param {number} value input value
|
|
169
|
+
* @param {number} min minimum bounds
|
|
170
|
+
* @param {number} max maximum bounds
|
|
171
|
+
* @returns {number} clamped value
|
|
172
|
+
*/
|
|
173
|
+
static clamp(value = 0.0, min = 0.0, max = 0.0) {
|
|
174
|
+
return +mathf64_min(+mathf64_max(+value, +mathf64_min(+min, +max)), +mathf64_max(+min, +max));
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Clamps a value between an unchecked boundary
|
|
178
|
+
* this function needs min < max!!
|
|
179
|
+
* (see Float64.clamp for a checked boundary)
|
|
180
|
+
*
|
|
181
|
+
* @param {number} value input value
|
|
182
|
+
* @param {number} min minimum bounds
|
|
183
|
+
* @param {number} max maximum bounds
|
|
184
|
+
* @returns {number} clamped value
|
|
185
|
+
*/
|
|
186
|
+
static clampu(value = 0.0, min = 0.0, max = 0.0) {
|
|
187
|
+
return +mathf64_min(+mathf64_max(+value, +min), +max);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
static inRange(value = 0.0, min = 0.0, max = 0.0) {
|
|
191
|
+
return +(+value >= +mathf64_min(+min, +max) && +value <= +mathf64_max(+min, +max));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
static intersectsRange(smin = 0.0, smax = 0.0, dmin = 0.0, dmax = 0.0) {
|
|
195
|
+
return +(+mathf64_max(+smin, +smax) >= +mathf64_min(+dmin, +dmax)
|
|
196
|
+
&& +mathf64_min(+smin, +smax) <= +mathf64_max(+dmin, +dmax));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
static intersectsRect(
|
|
200
|
+
ax = 0.0, ay = 0.0, aw = 0.0, ah = 0.0,
|
|
201
|
+
bx = 0.0, by = 0.0, bw = 0.0, bh = 0.0,
|
|
202
|
+
) {
|
|
203
|
+
return +(+(+Float64.intersectsRange(+ax, +(+ax + +aw), +bx, +(+bx + +bw)) > 0.0
|
|
204
|
+
&& +Float64.intersectsRange(+ay, +(+ay + +ah), +by, +(+by + +bh)) > 0.0));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
//#region trigonometry
|
|
208
|
+
|
|
209
|
+
static toRadian(degrees = 0.0) {
|
|
210
|
+
return +(+degrees * +Math.PI / 180.0);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
static toDegrees(radians = 0.0) {
|
|
214
|
+
return +(+radians * 180.0 / +Math.PI);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
static wrapRadians(r = 0.0) {
|
|
218
|
+
r = +r;
|
|
219
|
+
if (+r > Math.PI) return +(+r - +mathf64_PI2);
|
|
220
|
+
else if (+r < -Math.PI) return +(+r + +mathf64_PI2);
|
|
221
|
+
return +r;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
static sinLpEx(r = 0.0) {
|
|
225
|
+
r = +r;
|
|
226
|
+
return +((r < 0.0)
|
|
227
|
+
? +(+mathf64_PI41 * +r + +mathf64_PI42 * +r * +r)
|
|
228
|
+
: +(+mathf64_PI41 * +r - +mathf64_PI42 * +r * +r));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
static sinLp(r = 0.0) {
|
|
232
|
+
//always wrap input angle between -PI and PI
|
|
233
|
+
return +Float64.sinLpEx(+Float64.wrapRadians(+r));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
static cosLp(r = 0.0) {
|
|
237
|
+
//compute cosine: sin(x + PI/2) = cos(x)
|
|
238
|
+
return +Float64.sinLp(+(+r + +mathf64_PI1H));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
static cosHp(r = 0.0) {
|
|
242
|
+
// template<typename T>
|
|
243
|
+
// inline T cos(T x) noexcept
|
|
244
|
+
// {
|
|
245
|
+
// constexpr T tp = 1./(2.*M_PI);
|
|
246
|
+
// x *= tp;
|
|
247
|
+
// x -= T(.25) + std::floor(x + T(.25));
|
|
248
|
+
// x *= T(16.) * (std::abs(x) - T(.5));
|
|
249
|
+
// #if EXTRA_PRECISION
|
|
250
|
+
// x += T(.225) * x * (std::abs(x) - T(1.));
|
|
251
|
+
// #endif
|
|
252
|
+
// return x;
|
|
253
|
+
// }
|
|
254
|
+
throw new Error('float64_cosHp is not implemented! r=' + String(r));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
static sinMpEx(r = 0.0) {
|
|
258
|
+
r = +r;
|
|
259
|
+
const sin = +((r < 0.0)
|
|
260
|
+
? +(mathf64_PI41 * r + mathf64_PI42 * r * r)
|
|
261
|
+
: +(mathf64_PI41 * r - mathf64_PI42 * r * r));
|
|
262
|
+
return +((sin < 0.0)
|
|
263
|
+
? +(0.225 * (sin * -sin - sin) + sin)
|
|
264
|
+
: +(0.225 * (sin * sin - sin) + sin));
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
static sinMp(r = 0.0) {
|
|
268
|
+
return +Float64.sinMpEx(+Float64.wrapRadians(+r));
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
static cosMp(r = 0.0) {
|
|
272
|
+
//compute cosine: sin(x + PI/2) = cos(x)
|
|
273
|
+
return +Float64.sinMp(+(+r + +mathf64_PI1H));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
static theta(x = 0.0, y = 0.0) {
|
|
277
|
+
return +mathf64_atan2(+y, +x);
|
|
278
|
+
/*
|
|
279
|
+
// alternative was faster, but not anymore.
|
|
280
|
+
// error < 0.005
|
|
281
|
+
y = +y;
|
|
282
|
+
x = +x;
|
|
283
|
+
if (x == 0.0) {
|
|
284
|
+
if (y > 0.0) return +(Math.PI / 2.0);
|
|
285
|
+
if (y == 0.0) return 0.0;
|
|
286
|
+
return +(-Math.PI / 2.0);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const z = +(y / x);
|
|
290
|
+
var atan = 0.0;
|
|
291
|
+
if (+Math.abs(z) < 1.0) {
|
|
292
|
+
atan = +(z / (1.0 + 0.28 * z * z));
|
|
293
|
+
if (x < 0.0) {
|
|
294
|
+
if (y < 0.0) return +(atan - Math.PI);
|
|
295
|
+
return +(atan + Math.PI);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
atan = +(Math.PI / 2.0 - z / (z * z + 0.28));
|
|
300
|
+
if (y < 0.0) return +(atan - Math.PI);
|
|
301
|
+
}
|
|
302
|
+
return +(atan);
|
|
303
|
+
*/
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
static angle(x = 0.0, y = 0.0) {
|
|
307
|
+
return +Float64.theta(x, y);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
static phi(y = 0.0, len = 0.0) {
|
|
311
|
+
return +mathf64_asin(+y / +len);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
//#endregion
|
|
315
|
+
|
|
316
|
+
}
|