@pacem/pacem-numerical 1.0.0-bessel → 1.0.0-dirac
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/dist/browser/pacem-numerical.js +360 -1
- package/dist/browser/pacem-numerical.js.map +1 -1
- package/dist/browser/pacem-numerical.min.js +1 -1
- package/dist/bundle/pacem-numerical.min.mjs +1 -1
- package/dist/bundle/pacem-numerical.mjs +311 -1
- package/dist/bundle/pacem-numerical.mjs.map +2 -2
- package/dist/docs/pacem-numerical.json +13706 -0
- package/dist/esm/index-geometry-linearalgebra.js +1 -1
- package/dist/esm/index-geometry.js +1 -1
- package/dist/esm/index-iife.js +1 -1
- package/dist/esm/index-mathematics-dataanalysis.js +1 -1
- package/dist/esm/index-mathematics.js +1 -1
- package/dist/esm/index.js +1 -1
- package/package.json +2 -1
- package/typings/index.d.ts +541 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @pacem/pacem-numerical v1.0.0-
|
|
2
|
+
* @pacem/pacem-numerical v1.0.0-dirac (https://js.pacem.it)
|
|
3
3
|
* Pacem (https://pacem.it)
|
|
4
4
|
* Licensed under Apache-2.0
|
|
5
5
|
*/
|
|
@@ -33,9 +33,17 @@ var Vector = class _Vector {
|
|
|
33
33
|
this.normalize(clone);
|
|
34
34
|
return clone;
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns the squared magnitude (length) of the vector. Cheaper than {@link mag} since it avoids the square root.
|
|
38
|
+
* @param v
|
|
39
|
+
*/
|
|
36
40
|
static magSqr(v) {
|
|
37
41
|
return v.x * v.x + v.y * v.y;
|
|
38
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Returns the magnitude (length) of the vector.
|
|
45
|
+
* @param v
|
|
46
|
+
*/
|
|
39
47
|
static mag(v) {
|
|
40
48
|
return Math.sqrt(_Vector.magSqr(v));
|
|
41
49
|
}
|
|
@@ -199,6 +207,13 @@ function delaunayTriangulation(vertices) {
|
|
|
199
207
|
return indices;
|
|
200
208
|
}
|
|
201
209
|
var Delaunay = class {
|
|
210
|
+
/**
|
|
211
|
+
* Computes the Delaunay triangulation of the given points.
|
|
212
|
+
* @param vertices Points to triangulate.
|
|
213
|
+
* @returns A flat array of triangle indices into {@link vertices} (each consecutive group of 3
|
|
214
|
+
* entries identifies one triangle), in the same "vertices + triangle indices" format used by
|
|
215
|
+
* most graphics/meshing libraries. Returns an empty array if fewer than 3 points are provided.
|
|
216
|
+
*/
|
|
202
217
|
static triangulate(vertices) {
|
|
203
218
|
return delaunayTriangulation(vertices);
|
|
204
219
|
}
|
|
@@ -258,6 +273,11 @@ var Utils = class _Utils {
|
|
|
258
273
|
return null;
|
|
259
274
|
}
|
|
260
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Computes the axis-aligned bounding box of a set of points.
|
|
278
|
+
* @param vertices Points to enclose.
|
|
279
|
+
* @returns The smallest rect containing all provided points.
|
|
280
|
+
*/
|
|
261
281
|
static boundingBox(vertices) {
|
|
262
282
|
let xmin = Number.MAX_VALUE, ymin = Number.MAX_VALUE, xmax = -Number.MAX_VALUE, ymax = -Number.MAX_VALUE;
|
|
263
283
|
const l = vertices.length;
|
|
@@ -269,6 +289,15 @@ var Utils = class _Utils {
|
|
|
269
289
|
}
|
|
270
290
|
return { x: xmin, y: ymin, width: xmax - xmin, height: ymax - ymin };
|
|
271
291
|
}
|
|
292
|
+
/**
|
|
293
|
+
* Combines two polygons using a boolean set operator (union, intersection or difference).
|
|
294
|
+
* Internally triangulates the merged vertex set (via {@link mesh}) and filters the resulting
|
|
295
|
+
* triangles by whether their barycenter falls inside either source polygon.
|
|
296
|
+
* @param polygon1 First polygon.
|
|
297
|
+
* @param polygon2 Second polygon.
|
|
298
|
+
* @param operator Boolean operator to apply.
|
|
299
|
+
* @returns The resulting polygon(s), plus the underlying triangulation mesh and triangles used to compute them; or `null` if the operation yields no polygon.
|
|
300
|
+
*/
|
|
272
301
|
static combinePolygons(polygon1, polygon2, operator) {
|
|
273
302
|
return _Utils._mergePolygons(polygon1, polygon2, operator);
|
|
274
303
|
}
|
|
@@ -622,6 +651,12 @@ var Utils = class _Utils {
|
|
|
622
651
|
const minx = Math.min(segment[0].x, segment[1].x), maxx = Math.max(segment[0].x, segment[1].x), miny = Math.min(segment[0].y, segment[1].y), maxy = Math.max(segment[0].y, segment[1].y);
|
|
623
652
|
return p.x >= minx && p.x <= maxx && p.y >= miny && p.y <= maxy && _Utils.inLine(p, segment, precision);
|
|
624
653
|
}
|
|
654
|
+
/**
|
|
655
|
+
* Checks whether a point lies inside (or on the boundary of) a triangle, by verifying that it
|
|
656
|
+
* is on the same rotational side of all three edges.
|
|
657
|
+
* @param p Point to test.
|
|
658
|
+
* @param triangle Triangle vertices.
|
|
659
|
+
*/
|
|
625
660
|
static inTriangle(p, triangle) {
|
|
626
661
|
let last;
|
|
627
662
|
for (let j = 0; j < 3; j++) {
|
|
@@ -740,22 +775,49 @@ var Polygon = class _Polygon {
|
|
|
740
775
|
static {
|
|
741
776
|
this._eps = 1e-12;
|
|
742
777
|
}
|
|
778
|
+
/**
|
|
779
|
+
* Type guard checking whether the provided value is a valid {@link Polygon} (has at least 3 point vertices).
|
|
780
|
+
* @param obj
|
|
781
|
+
*/
|
|
743
782
|
static isPolygon(obj) {
|
|
744
783
|
return isPolygon(obj);
|
|
745
784
|
}
|
|
785
|
+
/**
|
|
786
|
+
* Builds a polygon from the provided vertices, in order.
|
|
787
|
+
* @param points Vertices of the polygon.
|
|
788
|
+
*/
|
|
746
789
|
static from(...points) {
|
|
747
790
|
return { vertices: Array.from(points) };
|
|
748
791
|
}
|
|
792
|
+
/**
|
|
793
|
+
* Checks whether a point lies inside the polygon.
|
|
794
|
+
* @param polygon
|
|
795
|
+
* @param p Point to test.
|
|
796
|
+
*/
|
|
749
797
|
static contains(polygon, p) {
|
|
750
798
|
return Utils.inPolygon(p, polygon.vertices, 12);
|
|
751
799
|
}
|
|
800
|
+
/**
|
|
801
|
+
* Returns the center of the polygon's bounding box.
|
|
802
|
+
* Note: this is not the geometric centroid (center of mass) for non-symmetric polygons.
|
|
803
|
+
* @param polygon
|
|
804
|
+
*/
|
|
752
805
|
static centroid(polygon) {
|
|
753
806
|
const bbox = _Polygon.boundingBox(polygon);
|
|
754
807
|
return { x: bbox.x + bbox.width / 2, y: bbox.y + bbox.height / 2 };
|
|
755
808
|
}
|
|
809
|
+
/**
|
|
810
|
+
* Computes the axis-aligned bounding box of the polygon.
|
|
811
|
+
* @param polygon
|
|
812
|
+
*/
|
|
756
813
|
static boundingBox(polygon) {
|
|
757
814
|
return Utils.boundingBox(polygon.vertices);
|
|
758
815
|
}
|
|
816
|
+
/**
|
|
817
|
+
* Returns the polygon's edges as an ordered list of segments, each joining a vertex to the next
|
|
818
|
+
* (the last one wrapping back to the first).
|
|
819
|
+
* @param polygon
|
|
820
|
+
*/
|
|
759
821
|
static sides(polygon) {
|
|
760
822
|
const { vertices } = polygon;
|
|
761
823
|
const retval = [];
|
|
@@ -765,6 +827,10 @@ var Polygon = class _Polygon {
|
|
|
765
827
|
}
|
|
766
828
|
return retval;
|
|
767
829
|
}
|
|
830
|
+
/**
|
|
831
|
+
* Checks whether the polygon is convex, i.e. all its interior angles turn in the same rotational direction.
|
|
832
|
+
* @param polygon
|
|
833
|
+
*/
|
|
768
834
|
static isConvex(polygon) {
|
|
769
835
|
const { vertices } = polygon, l = vertices.length;
|
|
770
836
|
if (l <= 3) {
|
|
@@ -853,6 +919,12 @@ var Polygon = class _Polygon {
|
|
|
853
919
|
static area(polygon) {
|
|
854
920
|
return Utils.area(polygon.vertices);
|
|
855
921
|
}
|
|
922
|
+
/**
|
|
923
|
+
* Computes the intersection area(s) between two polygons.
|
|
924
|
+
* @param polygon1
|
|
925
|
+
* @param polygon2
|
|
926
|
+
* @returns The overlapping area(s) as one or more polygons.
|
|
927
|
+
*/
|
|
856
928
|
static intersect(polygon1, polygon2) {
|
|
857
929
|
return Utils.intersect(polygon1, polygon2);
|
|
858
930
|
}
|
|
@@ -872,6 +944,11 @@ import { parseAsNumericalArray } from "@pacem/pacem-foundation";
|
|
|
872
944
|
var RAD2DEG2 = 180 / Math.PI;
|
|
873
945
|
var DEG2RAD = 1 / RAD2DEG2;
|
|
874
946
|
var Vector3D = class _Vector3D {
|
|
947
|
+
/**
|
|
948
|
+
* Builds a {@link Vector3D} from its x, y, z components, in that order.
|
|
949
|
+
* @param args Exactly 3 numbers: x, y, z.
|
|
950
|
+
* @throws If the number of arguments is not exactly 3.
|
|
951
|
+
*/
|
|
875
952
|
static from(...args) {
|
|
876
953
|
const l = 3;
|
|
877
954
|
if (args.length !== l) {
|
|
@@ -879,6 +956,11 @@ var Vector3D = class _Vector3D {
|
|
|
879
956
|
}
|
|
880
957
|
return { x: args[0], y: args[1], z: args[2] };
|
|
881
958
|
}
|
|
959
|
+
/**
|
|
960
|
+
* Parses a string representation (e.g. `"1 2 3"` or `"1,2,3"`) into a {@link Vector3D}.
|
|
961
|
+
* @param input String to parse.
|
|
962
|
+
* @throws If the input cannot be parsed as exactly 3 numbers.
|
|
963
|
+
*/
|
|
882
964
|
static parse(input) {
|
|
883
965
|
const arr = parseAsNumericalArray(input);
|
|
884
966
|
if (arr && arr.length === 3) {
|
|
@@ -887,15 +969,19 @@ var Vector3D = class _Vector3D {
|
|
|
887
969
|
throw new Error(`Cannot parse "${input}" as a valid Vector3D.`);
|
|
888
970
|
}
|
|
889
971
|
// notable vectors
|
|
972
|
+
/** Returns the unit vector along the x axis: `(1, 0, 0)`. */
|
|
890
973
|
static i() {
|
|
891
974
|
return { x: 1, y: 0, z: 0 };
|
|
892
975
|
}
|
|
976
|
+
/** Returns the unit vector along the y axis: `(0, 1, 0)`. */
|
|
893
977
|
static j() {
|
|
894
978
|
return { x: 0, y: 1, z: 0 };
|
|
895
979
|
}
|
|
980
|
+
/** Returns the unit vector along the z axis: `(0, 0, 1)`. */
|
|
896
981
|
static k() {
|
|
897
982
|
return { x: 0, y: 0, z: 1 };
|
|
898
983
|
}
|
|
984
|
+
/** Returns the zero vector: `(0, 0, 0)`. */
|
|
899
985
|
static zero() {
|
|
900
986
|
return { x: 0, y: 0, z: 0 };
|
|
901
987
|
}
|
|
@@ -943,6 +1029,10 @@ var Vector3D = class _Vector3D {
|
|
|
943
1029
|
static scale(v, fx, fy = fx, fz = fx) {
|
|
944
1030
|
return { x: v.x * fx, y: v.y * fy, z: v.z * fz };
|
|
945
1031
|
}
|
|
1032
|
+
/**
|
|
1033
|
+
* Returns the squared magnitude (length) of the vector. Cheaper than {@link mag} since it avoids the square root.
|
|
1034
|
+
* @param v
|
|
1035
|
+
*/
|
|
946
1036
|
static magSqr(v) {
|
|
947
1037
|
return v.x * v.x + v.y * v.y + v.z * v.z;
|
|
948
1038
|
}
|
|
@@ -955,9 +1045,17 @@ var Vector3D = class _Vector3D {
|
|
|
955
1045
|
static areClose(v1, v2) {
|
|
956
1046
|
return (v2.x - v1.x).isCloseTo(0) && (v2.y - v1.y).isCloseTo(0) && (v2.z - v1.z).isCloseTo(0);
|
|
957
1047
|
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Returns the magnitude (length) of the vector.
|
|
1050
|
+
* @param v
|
|
1051
|
+
*/
|
|
958
1052
|
static mag(v) {
|
|
959
1053
|
return Math.sqrt(_Vector3D.magSqr(v));
|
|
960
1054
|
}
|
|
1055
|
+
/**
|
|
1056
|
+
* Returns the opposite vector (each component negated).
|
|
1057
|
+
* @param v
|
|
1058
|
+
*/
|
|
961
1059
|
static negate(v) {
|
|
962
1060
|
return { x: -v.x, y: -v.y, z: -v.z };
|
|
963
1061
|
}
|
|
@@ -1028,6 +1126,10 @@ var Spherical = class _Spherical {
|
|
|
1028
1126
|
const theta = Math.atan2(v.x, v.z), phi = Math.acos((v.y / rho).clamp(-1, 1));
|
|
1029
1127
|
return _Spherical.from(rho, theta * RAD2DEG2, phi * RAD2DEG2);
|
|
1030
1128
|
}
|
|
1129
|
+
/**
|
|
1130
|
+
* Converts {@link Spherical} coordinates back into cartesian {@link Vector3D} coordinates.
|
|
1131
|
+
* @param coords
|
|
1132
|
+
*/
|
|
1031
1133
|
static toVector(coords) {
|
|
1032
1134
|
const { rho, theta: thetaDeg, phi: phiDeg } = coords;
|
|
1033
1135
|
const phi = phiDeg * DEG2RAD;
|
|
@@ -1114,6 +1216,11 @@ var Matrix3D = class _Matrix3D {
|
|
|
1114
1216
|
};
|
|
1115
1217
|
}
|
|
1116
1218
|
//#endregion
|
|
1219
|
+
/**
|
|
1220
|
+
* Builds a {@link Matrix3D} from its 16 components, in row-major order.
|
|
1221
|
+
* @param args Exactly 16 numbers.
|
|
1222
|
+
* @throws If the number of arguments is not exactly 16.
|
|
1223
|
+
*/
|
|
1117
1224
|
static from(...args) {
|
|
1118
1225
|
const l = 16;
|
|
1119
1226
|
if (args.length !== l) {
|
|
@@ -1138,9 +1245,17 @@ var Matrix3D = class _Matrix3D {
|
|
|
1138
1245
|
m44: args[15]
|
|
1139
1246
|
};
|
|
1140
1247
|
}
|
|
1248
|
+
/**
|
|
1249
|
+
* Returns the transpose of the given matrix (rows and columns swapped).
|
|
1250
|
+
* @param m
|
|
1251
|
+
*/
|
|
1141
1252
|
static transpose(m) {
|
|
1142
1253
|
return _Matrix3D.from(m.m11, m.m21, m.m31, m.offsetX, m.m12, m.m22, m.m32, m.offsetY, m.m13, m.m23, m.m33, m.offsetZ, m.m14, m.m24, m.m34, m.m44);
|
|
1143
1254
|
}
|
|
1255
|
+
/**
|
|
1256
|
+
* Flattens the matrix into a 16-number array, in row-major order (the same order accepted by {@link from}).
|
|
1257
|
+
* @param m
|
|
1258
|
+
*/
|
|
1144
1259
|
static toArray(m) {
|
|
1145
1260
|
return [
|
|
1146
1261
|
m.m11,
|
|
@@ -1179,6 +1294,11 @@ var Matrix3D = class _Matrix3D {
|
|
|
1179
1294
|
s.m33 *= z;
|
|
1180
1295
|
});
|
|
1181
1296
|
}
|
|
1297
|
+
/**
|
|
1298
|
+
* Returns a copy of the matrix translated (offset) by the given vector.
|
|
1299
|
+
* @param m
|
|
1300
|
+
* @param offset
|
|
1301
|
+
*/
|
|
1182
1302
|
static translate(m, offset) {
|
|
1183
1303
|
return Matrix3DUtils.modify(m, (s) => {
|
|
1184
1304
|
s.offsetX += offset.x;
|
|
@@ -1186,6 +1306,11 @@ var Matrix3D = class _Matrix3D {
|
|
|
1186
1306
|
s.offsetZ += offset.z;
|
|
1187
1307
|
});
|
|
1188
1308
|
}
|
|
1309
|
+
/**
|
|
1310
|
+
* Parses a string representation of a matrix (16 numbers) into a {@link Matrix3D}.
|
|
1311
|
+
* @param input String to parse.
|
|
1312
|
+
* @throws If the input cannot be parsed as exactly 16 numbers.
|
|
1313
|
+
*/
|
|
1189
1314
|
static parse(input) {
|
|
1190
1315
|
const arr = parseAsNumericalArray(input);
|
|
1191
1316
|
if (arr && arr.length === 16) {
|
|
@@ -1193,12 +1318,25 @@ var Matrix3D = class _Matrix3D {
|
|
|
1193
1318
|
}
|
|
1194
1319
|
throw new Error(`Cannot parse "${input}" as a valid Matrix3D.`);
|
|
1195
1320
|
}
|
|
1321
|
+
/**
|
|
1322
|
+
* Checks whether the matrix is the identity matrix.
|
|
1323
|
+
* @param m
|
|
1324
|
+
*/
|
|
1196
1325
|
static isIdentity(m) {
|
|
1197
1326
|
return m.m11 == 1 && m.m12 == 0 && m.m13 == 0 && m.m14 == 0 && m.m21 == 0 && m.m22 == 1 && m.m23 == 0 && m.m24 == 0 && m.m31 == 0 && m.m32 == 0 && m.m33 == 1 && m.m34 == 0 && m.offsetX == 0 && m.offsetY == 0 && m.offsetZ == 0 && m.m44 == 1;
|
|
1198
1327
|
}
|
|
1328
|
+
/**
|
|
1329
|
+
* Checks whether the matrix represents a pure affine transform, i.e. it has no perspective
|
|
1330
|
+
* component (its 4th column is `(0, 0, 0, 1)`).
|
|
1331
|
+
* @param m
|
|
1332
|
+
*/
|
|
1199
1333
|
static isAffine(m) {
|
|
1200
1334
|
return m.m14 == 0 && m.m24 == 0 && m.m34 == 0 && m.m44 == 1;
|
|
1201
1335
|
}
|
|
1336
|
+
/**
|
|
1337
|
+
* Computes the determinant of the matrix.
|
|
1338
|
+
* @param m
|
|
1339
|
+
*/
|
|
1202
1340
|
static determinant(m) {
|
|
1203
1341
|
if (_Matrix3D.isIdentity(m)) {
|
|
1204
1342
|
return 1;
|
|
@@ -1235,6 +1373,12 @@ var Matrix3D = class _Matrix3D {
|
|
|
1235
1373
|
}
|
|
1236
1374
|
return m;
|
|
1237
1375
|
}
|
|
1376
|
+
/**
|
|
1377
|
+
* Computes the inverse of the matrix, using the cofactor/adjugate method (with a specialized,
|
|
1378
|
+
* cheaper path for affine matrices).
|
|
1379
|
+
* @param m
|
|
1380
|
+
* @returns The inverse matrix, or `null` if the matrix is singular (determinant is 0).
|
|
1381
|
+
*/
|
|
1238
1382
|
static invert(m) {
|
|
1239
1383
|
if (_Matrix3D.isAffine(m)) {
|
|
1240
1384
|
const determinant = _Matrix3D.determinant(m);
|
|
@@ -1337,9 +1481,15 @@ var Matrix3D = class _Matrix3D {
|
|
|
1337
1481
|
}
|
|
1338
1482
|
};
|
|
1339
1483
|
var Quaternion = class _Quaternion {
|
|
1484
|
+
/** Returns the identity quaternion (no rotation). */
|
|
1340
1485
|
static identity() {
|
|
1341
1486
|
return _Quaternion.from(0, 0, 0, 1);
|
|
1342
1487
|
}
|
|
1488
|
+
/**
|
|
1489
|
+
* Builds a {@link Quaternion} from its x, y, z, w components, in that order.
|
|
1490
|
+
* @param args Exactly 4 numbers: x, y, z, w.
|
|
1491
|
+
* @throws If the number of arguments is not exactly 4.
|
|
1492
|
+
*/
|
|
1343
1493
|
static from(...args) {
|
|
1344
1494
|
const l = 4;
|
|
1345
1495
|
if (args.length !== l) {
|
|
@@ -1352,6 +1502,11 @@ var Quaternion = class _Quaternion {
|
|
|
1352
1502
|
w: args[3]
|
|
1353
1503
|
};
|
|
1354
1504
|
}
|
|
1505
|
+
/**
|
|
1506
|
+
* Parses a string representation of a quaternion (4 numbers) into a {@link Quaternion}.
|
|
1507
|
+
* @param input String to parse.
|
|
1508
|
+
* @throws If the input cannot be parsed as exactly 4 numbers.
|
|
1509
|
+
*/
|
|
1355
1510
|
static parse(input) {
|
|
1356
1511
|
const arr = parseAsNumericalArray(input);
|
|
1357
1512
|
if (arr && arr.length === 4) {
|
|
@@ -1359,6 +1514,12 @@ var Quaternion = class _Quaternion {
|
|
|
1359
1514
|
}
|
|
1360
1515
|
throw new Error(`Cannot parse "${input}" as a valid Quaternion.`);
|
|
1361
1516
|
}
|
|
1517
|
+
/**
|
|
1518
|
+
* Builds the (shortest-arc) quaternion representing the rotation that takes one unit vector onto another.
|
|
1519
|
+
* Normalizes both input vectors in place as a side effect.
|
|
1520
|
+
* @param from Source direction.
|
|
1521
|
+
* @param to Target direction.
|
|
1522
|
+
*/
|
|
1362
1523
|
static fromVectors(from, to) {
|
|
1363
1524
|
Vector3D.normalize(from);
|
|
1364
1525
|
Vector3D.normalize(to);
|
|
@@ -1471,6 +1632,11 @@ var Quaternion = class _Quaternion {
|
|
|
1471
1632
|
}
|
|
1472
1633
|
}
|
|
1473
1634
|
}
|
|
1635
|
+
/**
|
|
1636
|
+
* Returns the conjugate of the quaternion (vector part negated). For a unit quaternion, this
|
|
1637
|
+
* represents the inverse rotation.
|
|
1638
|
+
* @param q
|
|
1639
|
+
*/
|
|
1474
1640
|
static conjugate(q) {
|
|
1475
1641
|
return _Quaternion.from(-q.x, -q.y, -q.z, q.w);
|
|
1476
1642
|
}
|
|
@@ -1481,15 +1647,29 @@ var Quaternion = class _Quaternion {
|
|
|
1481
1647
|
static mag(q) {
|
|
1482
1648
|
return Math.sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w);
|
|
1483
1649
|
}
|
|
1650
|
+
/**
|
|
1651
|
+
* Returns the squared magnitude of the vector (imaginary) part of the quaternion.
|
|
1652
|
+
* @param q
|
|
1653
|
+
*/
|
|
1484
1654
|
static norm(q) {
|
|
1485
1655
|
return q.x * q.x + q.y * q.y + q.z * q.z;
|
|
1486
1656
|
}
|
|
1657
|
+
/**
|
|
1658
|
+
* Returns the (unit) rotation axis represented by the quaternion, defaulting to the y axis
|
|
1659
|
+
* when the quaternion has no vector part (i.e. represents no rotation).
|
|
1660
|
+
* @param q
|
|
1661
|
+
*/
|
|
1487
1662
|
static axis(q) {
|
|
1488
1663
|
if (q.x == 0 && q.y == 0 && q.z == 0) {
|
|
1489
1664
|
return Vector3D.j();
|
|
1490
1665
|
}
|
|
1491
1666
|
return Vector3D.unit(q);
|
|
1492
1667
|
}
|
|
1668
|
+
/**
|
|
1669
|
+
* Rotates a vector by the given quaternion (normalizes the quaternion in place as a side effect).
|
|
1670
|
+
* @param v Vector to rotate.
|
|
1671
|
+
* @param q Rotation quaternion.
|
|
1672
|
+
*/
|
|
1493
1673
|
static transform(v, q) {
|
|
1494
1674
|
_Quaternion.normalize(q);
|
|
1495
1675
|
const cross = Vector3D.cross(q, v);
|
|
@@ -1518,6 +1698,10 @@ var Quaternion = class _Quaternion {
|
|
|
1518
1698
|
}
|
|
1519
1699
|
return Math.atan2(y, x) * 114.59155902616465;
|
|
1520
1700
|
}
|
|
1701
|
+
/**
|
|
1702
|
+
* Builds the rotation matrix equivalent to the given quaternion.
|
|
1703
|
+
* @param q
|
|
1704
|
+
*/
|
|
1521
1705
|
static toRotationMatrix(q) {
|
|
1522
1706
|
var m = Matrix3D.identity();
|
|
1523
1707
|
var X = q.x;
|
|
@@ -1535,6 +1719,10 @@ var Quaternion = class _Quaternion {
|
|
|
1535
1719
|
m.m33 = 1 - 2 * X * X - 2 * Y * Y;
|
|
1536
1720
|
return m;
|
|
1537
1721
|
}
|
|
1722
|
+
/**
|
|
1723
|
+
* Returns the inverse rotation of the given quaternion (the conjugate of its normalized form).
|
|
1724
|
+
* @param q
|
|
1725
|
+
*/
|
|
1538
1726
|
static invert(q) {
|
|
1539
1727
|
const n = _Quaternion.unit(q);
|
|
1540
1728
|
return _Quaternion.conjugate(n);
|
|
@@ -1642,14 +1830,29 @@ var Complex = class {
|
|
|
1642
1830
|
}
|
|
1643
1831
|
return buildComplex(real, img || 0);
|
|
1644
1832
|
}
|
|
1833
|
+
/**
|
|
1834
|
+
* Adds two complex numbers (real numbers are treated as having a zero imaginary part).
|
|
1835
|
+
* @param a First addend.
|
|
1836
|
+
* @param b Second addend.
|
|
1837
|
+
*/
|
|
1645
1838
|
static add(a, b) {
|
|
1646
1839
|
const ac = complex(a), bc = complex(b);
|
|
1647
1840
|
return buildComplex(ac.real + bc.real, ac.img + bc.img);
|
|
1648
1841
|
}
|
|
1842
|
+
/**
|
|
1843
|
+
* Subtracts one complex number from another.
|
|
1844
|
+
* @param from Minuend.
|
|
1845
|
+
* @param what Subtrahend.
|
|
1846
|
+
*/
|
|
1649
1847
|
static subtract(from, what) {
|
|
1650
1848
|
const ac = complex(from), bc = complex(what);
|
|
1651
1849
|
return buildComplex(ac.real - bc.real, ac.img - bc.img);
|
|
1652
1850
|
}
|
|
1851
|
+
/**
|
|
1852
|
+
* Multiplies two complex numbers.
|
|
1853
|
+
* @param a First factor.
|
|
1854
|
+
* @param b Second factor.
|
|
1855
|
+
*/
|
|
1653
1856
|
static multiply(a, b) {
|
|
1654
1857
|
const ac = complex(a), bc = complex(b);
|
|
1655
1858
|
return buildComplex(
|
|
@@ -1659,6 +1862,12 @@ var Complex = class {
|
|
|
1659
1862
|
ac.real * bc.img + ac.img * bc.real
|
|
1660
1863
|
);
|
|
1661
1864
|
}
|
|
1865
|
+
/**
|
|
1866
|
+
* Divides one complex number by another.
|
|
1867
|
+
* @param a Dividend.
|
|
1868
|
+
* @param b Divisor.
|
|
1869
|
+
* @returns The quotient, or {@link Complex.NaC} if the divisor is (close to) zero.
|
|
1870
|
+
*/
|
|
1662
1871
|
static divide(a, b) {
|
|
1663
1872
|
const ac = complex(a), bc = complex(b);
|
|
1664
1873
|
const div = this.absSquare(bc).roundoff();
|
|
@@ -1673,20 +1882,42 @@ var Complex = class {
|
|
|
1673
1882
|
inv_div * (ac.img * bc.real - ac.real * bc.img)
|
|
1674
1883
|
);
|
|
1675
1884
|
}
|
|
1885
|
+
/**
|
|
1886
|
+
* Returns the squared modulus (|z|²) of the complex number, i.e. real² + img².
|
|
1887
|
+
* Cheaper than {@link modulus} since it avoids the square root.
|
|
1888
|
+
* @param c
|
|
1889
|
+
*/
|
|
1676
1890
|
static absSquare(c) {
|
|
1677
1891
|
const ac = complex(c);
|
|
1678
1892
|
return Math.pow(ac.real, 2) + Math.pow(ac.img, 2);
|
|
1679
1893
|
}
|
|
1894
|
+
/**
|
|
1895
|
+
* Returns the modulus (magnitude) of the complex number.
|
|
1896
|
+
* @param c
|
|
1897
|
+
*/
|
|
1680
1898
|
static modulus(c) {
|
|
1681
1899
|
return Math.sqrt(this.absSquare(c));
|
|
1682
1900
|
}
|
|
1901
|
+
/**
|
|
1902
|
+
* Type guard checking whether the provided value is a {@link Complex} number.
|
|
1903
|
+
* @param c
|
|
1904
|
+
*/
|
|
1683
1905
|
static isComplex(c) {
|
|
1684
1906
|
return c != null && typeof c === "object" && "real" in c && "img" in c && typeof c.real === "number" && typeof c.img === "number";
|
|
1685
1907
|
}
|
|
1908
|
+
/**
|
|
1909
|
+
* Returns the complex conjugate: same real part, negated imaginary part.
|
|
1910
|
+
* @param a
|
|
1911
|
+
*/
|
|
1686
1912
|
static conjugate(a) {
|
|
1687
1913
|
a = complex(a);
|
|
1688
1914
|
return buildComplex(a.real, Math.abs(a.img) == 0 ? 0 : -a.img);
|
|
1689
1915
|
}
|
|
1916
|
+
/**
|
|
1917
|
+
* Checks whether two complex numbers have the same real and imaginary parts.
|
|
1918
|
+
* @param c1
|
|
1919
|
+
* @param c2
|
|
1920
|
+
*/
|
|
1690
1921
|
static equals(c1, c2) {
|
|
1691
1922
|
const c_1 = this.build(c1), c_2 = this.build(c2);
|
|
1692
1923
|
if (!this.isComplex(c1) || !this.isComplex(c2)) {
|
|
@@ -1706,6 +1937,7 @@ var Complex = class {
|
|
|
1706
1937
|
// if (!this.isComplex( c)
|
|
1707
1938
|
// }
|
|
1708
1939
|
//}
|
|
1940
|
+
/** The "Not a Complex" sentinel value (`NaN + NaNi`), returned by operations on invalid input. */
|
|
1709
1941
|
static get NaC() {
|
|
1710
1942
|
return nac();
|
|
1711
1943
|
}
|
|
@@ -1817,11 +2049,17 @@ function erfc(x) {
|
|
|
1817
2049
|
return x >= 0 ? ans : 2 - ans;
|
|
1818
2050
|
}
|
|
1819
2051
|
var Gaussian = class {
|
|
2052
|
+
/**
|
|
2053
|
+
* Creates a new {@link Gaussian} distribution with the given mean and standard deviation.
|
|
2054
|
+
* @param mean Mean (μ) of the distribution.
|
|
2055
|
+
* @param stdev Standard deviation (σ) of the distribution (its absolute value is used).
|
|
2056
|
+
*/
|
|
1820
2057
|
constructor(mean2, stdev2) {
|
|
1821
2058
|
this.mean = mean2;
|
|
1822
2059
|
this.stdev = Math.abs(stdev2);
|
|
1823
2060
|
this.variance = Math.pow(stdev2, 2);
|
|
1824
2061
|
}
|
|
2062
|
+
/** The standard normal distribution (mean 0, standard deviation 1). */
|
|
1825
2063
|
static get normal() {
|
|
1826
2064
|
return _normal;
|
|
1827
2065
|
}
|
|
@@ -1856,6 +2094,7 @@ var _normal = new Gaussian(0, 1);
|
|
|
1856
2094
|
|
|
1857
2095
|
// packages/numerical/dist/esm/math/interpolation.js
|
|
1858
2096
|
var Lagrange = class _Lagrange {
|
|
2097
|
+
/** Use {@link Lagrange.create} to build an instance. */
|
|
1859
2098
|
constructor(points) {
|
|
1860
2099
|
this.#set = points;
|
|
1861
2100
|
}
|
|
@@ -1924,6 +2163,11 @@ var Lagrange = class _Lagrange {
|
|
|
1924
2163
|
}
|
|
1925
2164
|
// Iterative/global Lagrange computation removed — barycentric is used
|
|
1926
2165
|
// exclusively for interpolation.
|
|
2166
|
+
/**
|
|
2167
|
+
* Evaluates the Lagrange interpolating polynomial at the given x, using barycentric weights.
|
|
2168
|
+
* @param x Input value.
|
|
2169
|
+
* @returns The interpolated y value (the exact node y if x coincides with a node).
|
|
2170
|
+
*/
|
|
1927
2171
|
interpolate(x) {
|
|
1928
2172
|
return this._computeBarycentric(x);
|
|
1929
2173
|
}
|
|
@@ -1944,6 +2188,7 @@ var Lagrangian = {
|
|
|
1944
2188
|
create: Lagrange.create
|
|
1945
2189
|
};
|
|
1946
2190
|
var Pchip = class _Pchip {
|
|
2191
|
+
/** Use {@link Pchip.create} to build an instance. */
|
|
1947
2192
|
constructor(points) {
|
|
1948
2193
|
if (!points || points.length < 2)
|
|
1949
2194
|
throw new Error("Need at least 2 points");
|
|
@@ -1990,6 +2235,12 @@ var Pchip = class _Pchip {
|
|
|
1990
2235
|
}
|
|
1991
2236
|
return m;
|
|
1992
2237
|
}
|
|
2238
|
+
/**
|
|
2239
|
+
* Evaluates the PCHIP curve at the given x, using cubic Hermite interpolation on the enclosing segment.
|
|
2240
|
+
* Values outside the node range are linearly extrapolated using the boundary derivative.
|
|
2241
|
+
* @param x Input value.
|
|
2242
|
+
* @returns The interpolated y value.
|
|
2243
|
+
*/
|
|
1993
2244
|
interpolate(x) {
|
|
1994
2245
|
const xs = this.xs, ys = this.ys, ms = this.ms;
|
|
1995
2246
|
const n = xs.length;
|
|
@@ -2032,6 +2283,7 @@ var Pchip = class _Pchip {
|
|
|
2032
2283
|
}
|
|
2033
2284
|
};
|
|
2034
2285
|
var Newton = class _Newton {
|
|
2286
|
+
/** Use {@link Newton.create} to build an instance. */
|
|
2035
2287
|
constructor(points) {
|
|
2036
2288
|
if (!points || points.length === 0)
|
|
2037
2289
|
throw new Error("Need at least 1 point");
|
|
@@ -2049,6 +2301,11 @@ var Newton = class _Newton {
|
|
|
2049
2301
|
}
|
|
2050
2302
|
this.coeffs = a;
|
|
2051
2303
|
}
|
|
2304
|
+
/**
|
|
2305
|
+
* Evaluates the Newton form of the interpolating polynomial at the given x, via nested multiplication.
|
|
2306
|
+
* @param x Input value.
|
|
2307
|
+
* @returns The interpolated y value (`NaN` if the interpolator has no points).
|
|
2308
|
+
*/
|
|
2052
2309
|
interpolate(x) {
|
|
2053
2310
|
const xs = this.xs, a = this.coeffs;
|
|
2054
2311
|
const n = a.length;
|
|
@@ -2285,6 +2542,12 @@ import { Numbers, NullChecker as NullChecker3 } from "@pacem/pacem-foundation";
|
|
|
2285
2542
|
var ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
2286
2543
|
var OUT_OF_RANGE = `Radix out of range: possible values go between positive 1 exclusive and ${ALPHABET.length} inclusive`;
|
|
2287
2544
|
var Utils3 = class _Utils {
|
|
2545
|
+
/**
|
|
2546
|
+
* Computes the least common multiple (LCM) of the given numbers (each rounded to the nearest integer).
|
|
2547
|
+
* @param args Two or more numbers.
|
|
2548
|
+
* @returns The least common multiple.
|
|
2549
|
+
* @throws If fewer than two numbers are provided.
|
|
2550
|
+
*/
|
|
2288
2551
|
static lcd(...args) {
|
|
2289
2552
|
if (NullChecker3.isNullOrEmpty(args) || args.length <= 1) {
|
|
2290
2553
|
throw "Insufficient set of numbers.";
|
|
@@ -2303,6 +2566,12 @@ var Utils3 = class _Utils {
|
|
|
2303
2566
|
}
|
|
2304
2567
|
return result;
|
|
2305
2568
|
}
|
|
2569
|
+
/**
|
|
2570
|
+
* Computes the greatest common divisor (GCD) of two numbers (each rounded to the nearest integer)
|
|
2571
|
+
* using the Euclidean algorithm.
|
|
2572
|
+
* @param a
|
|
2573
|
+
* @param b
|
|
2574
|
+
*/
|
|
2306
2575
|
static gcd(a, b) {
|
|
2307
2576
|
a = Math.round(a), b = Math.round(b);
|
|
2308
2577
|
if (a === 0) {
|
|
@@ -2310,9 +2579,26 @@ var Utils3 = class _Utils {
|
|
|
2310
2579
|
}
|
|
2311
2580
|
return _Utils.gcd(b % a, a);
|
|
2312
2581
|
}
|
|
2582
|
+
/**
|
|
2583
|
+
* Converts an integer value from one numeric base (radix) to another.
|
|
2584
|
+
* @param v Value to convert, in the source radix.
|
|
2585
|
+
* @param from Source radix.
|
|
2586
|
+
* @param to Target radix.
|
|
2587
|
+
* @returns The value re-expressed in the target radix, as a string.
|
|
2588
|
+
*/
|
|
2313
2589
|
static rebaseInt(v, from, to) {
|
|
2314
2590
|
return Numbers.rebase(v, from, to);
|
|
2315
2591
|
}
|
|
2592
|
+
/**
|
|
2593
|
+
* Converts a (possibly fractional) numeric value from one radix to another, dispatching to the
|
|
2594
|
+
* appropriate specialized conversion routine depending on whether base-10 is the source, the
|
|
2595
|
+
* target, or neither.
|
|
2596
|
+
* @param v Value to convert, in the source radix.
|
|
2597
|
+
* @param fromRadix Source radix.
|
|
2598
|
+
* @param toRadix Target radix.
|
|
2599
|
+
* @param precision Maximum number of digits to compute for the fractional part (default 12).
|
|
2600
|
+
* @returns The converted value: a number when converting to base 10, otherwise a string.
|
|
2601
|
+
*/
|
|
2316
2602
|
static rebaseFloat(v, fromRadix, toRadix, precision = 12) {
|
|
2317
2603
|
const from10 = _Utils.rebaseFloat10ToN, to10 = _Utils.rebaseFloatNTo10;
|
|
2318
2604
|
if (fromRadix === 10) {
|
|
@@ -2328,6 +2614,14 @@ var Utils3 = class _Utils {
|
|
|
2328
2614
|
const _10 = to10(v.toString(), fromRadix, precision + 1);
|
|
2329
2615
|
return from10(_10, toRadix, precision);
|
|
2330
2616
|
}
|
|
2617
|
+
/**
|
|
2618
|
+
* Converts a numeric string expressed in the given radix into its base-10 (decimal) value.
|
|
2619
|
+
* @param v Value to convert, expressed in the source radix (digits from `0-9a-z`).
|
|
2620
|
+
* @param radix Source radix (must be greater than 1 and no larger than the size of the digit alphabet).
|
|
2621
|
+
* @param precision Unused for the integer part; reserved for symmetry with the sibling conversion methods.
|
|
2622
|
+
* @returns The base-10 numeric value, or `NaN` if the input contains invalid digits.
|
|
2623
|
+
* @throws If radix is out of range.
|
|
2624
|
+
*/
|
|
2331
2625
|
static rebaseFloatNTo10(v, radix, precision = 12) {
|
|
2332
2626
|
const alphabet = ALPHABET;
|
|
2333
2627
|
if (radix <= 1 || radix > alphabet.length) {
|
|
@@ -2353,6 +2647,14 @@ var Utils3 = class _Utils {
|
|
|
2353
2647
|
}
|
|
2354
2648
|
return sign * retval;
|
|
2355
2649
|
}
|
|
2650
|
+
/**
|
|
2651
|
+
* Converts a base-10 number into its representation in another **integer** radix.
|
|
2652
|
+
* @param v Base-10 value to convert.
|
|
2653
|
+
* @param radix Target integer radix (must be greater than 1 and no larger than the size of the digit alphabet).
|
|
2654
|
+
* @param precision Maximum number of digits to compute for the fractional part (default 12).
|
|
2655
|
+
* @returns The value re-expressed in the target radix, as a string.
|
|
2656
|
+
* @throws If radix is out of range.
|
|
2657
|
+
*/
|
|
2356
2658
|
static rebaseFloat10ToNIntBase(v, radix, precision = 12) {
|
|
2357
2659
|
const alphabet = ALPHABET;
|
|
2358
2660
|
if (radix <= 1 || radix > alphabet.length) {
|
|
@@ -2401,6 +2703,14 @@ var Utils3 = class _Utils {
|
|
|
2401
2703
|
}
|
|
2402
2704
|
return (Math.sign(v) < 0 ? "-" : "") + output + "." + rebasedFrac.replace(/0+$/, "");
|
|
2403
2705
|
}
|
|
2706
|
+
/**
|
|
2707
|
+
* Converts a base-10 number into its representation in another (possibly non-integer) radix.
|
|
2708
|
+
* @param v Base-10 value to convert.
|
|
2709
|
+
* @param radix Target radix, possibly fractional (must be greater than 1 and no larger than the size of the digit alphabet).
|
|
2710
|
+
* @param precision Maximum number of digits to compute for the fractional part (default 12).
|
|
2711
|
+
* @returns The value re-expressed in the target radix, as a string.
|
|
2712
|
+
* @throws If radix is out of range.
|
|
2713
|
+
*/
|
|
2404
2714
|
static rebaseFloat10ToN(v, radix, precision = 12) {
|
|
2405
2715
|
const alphabet = ALPHABET;
|
|
2406
2716
|
if (radix <= 1 || radix > alphabet.length) {
|