@pacem/pacem-numerical 1.0.3 → 1.0.5-archimedes

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @pacem/pacem-numerical v1.0.3 (https://js.pacem.it)
2
+ * @pacem/pacem-numerical v1.0.5-archimedes (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @pacem/pacem-numerical v1.0.3 (https://js.pacem.it)
2
+ * @pacem/pacem-numerical v1.0.5-archimedes (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @pacem/pacem-numerical v1.0.3 (https://js.pacem.it)
2
+ * @pacem/pacem-numerical v1.0.5-archimedes (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @pacem/pacem-numerical v1.0.3 (https://js.pacem.it)
2
+ * @pacem/pacem-numerical v1.0.5-archimedes (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../esm/index-geometry.js", "../esm/geom/geom.js", "../esm/geom/linear-algebra.js", "../esm/geom/algorithms/delaunay.js", "../esm/geom/polygon.js", "../esm/geom/geom3d.js", "../esm/geom/util3d.js", "../esm/index-geometry-linearalgebra.js", "../esm/index-mathematics.js", "../esm/math/complex.js", "../esm/index-mathematics-dataanalysis.js", "../esm/math/fourier.js", "../esm/math/gaussian.js", "../esm/math/interpolation.js", "../esm/math/statistics.js", "../esm/math/math.js"],
4
- "sourcesContent": ["export * from './geom/geom';\nexport * from './geom/polygon';\nexport * from './geom/util3d';\nexport * as LinearAlgebra from './index-geometry-linearalgebra';\n", "import { Point, Rect, NullChecker } from '@pacem/pacem-foundation';\nimport { Vector } from './linear-algebra';\nimport { Delaunay } from './algorithms/delaunay';\nconst RAD2DEG = 180.0 / Math.PI;\nconst RAD_ROUND = 2 * Math.PI;\nconst PRECISION = 12; // default epsilon 1e-12 checking proximity (not used for roundoffs)\n;\nfunction isPoint(p) {\n return Point.isPoint(p);\n}\nfunction isSegment(s) {\n return s != null && Array.isArray(s) && s.length === 2\n && isPoint(s[0]) && isPoint(s[1]);\n}\n/** Utility tools for 2D geometry: points, segments, polygons and their interactions. */\nexport class Utils {\n /**\n * Computes the slope (in radians) of the segment joining two points.\n * @param p1 Point 1\n * @param p2 Point 2\n */\n static slopeRad(p1, p2) {\n return Math.atan2(p2.y - p1.y, p2.x - p1.x);\n }\n /**\n * Computes the slope (in radians) of the segment joining two points and returns a strictly positive value (0 to 2*pi).\n * @param p1 Point 1\n * @param p2 Point 2\n */\n static slopeRad2(p1, p2) {\n return (RAD_ROUND + Utils.slopeRad(p1, p2)) % RAD_ROUND;\n }\n /**\n * Computes the slope (in degrees) of the segment joining two points.\n * @param p1 Point 1\n * @param p2 Point 2\n */\n static slopeDeg(p1, p2) {\n return Utils.slopeRad(p1, p2) * RAD2DEG;\n }\n /**\n * Computes the slope (in degrees) of the segment joining two points and returns a strictly positive value (0 to 360).\n * @param p1 Point 1\n * @param p2 Point 2\n */\n static slopeDeg2(p1, p2) {\n return (360 + Utils.slopeDeg(p1, p2)) % 360;\n }\n static intersect(arg1, arg2, ...args) {\n if (Array.isArray(arg1) && Array.isArray(arg2)) {\n return Utils._intersectSegments(arg1, arg2, true);\n }\n else if (Rect.isRect(arg1)) {\n return Utils._intersectRects(...arguments);\n }\n else if ('vertices' in arg1) {\n return Utils._mergePolygons(arg1, arg2, 'intersect')?.polygons ?? null;\n }\n else {\n return null;\n }\n }\n /**\n * Computes the axis-aligned bounding box of a set of points.\n * @param vertices Points to enclose.\n * @returns The smallest rect containing all provided points.\n */\n static boundingBox(vertices) {\n let xmin = Number.MAX_VALUE, ymin = Number.MAX_VALUE, xmax = -Number.MAX_VALUE, ymax = -Number.MAX_VALUE;\n const l = vertices.length;\n for (let v of vertices) {\n xmin = Math.min(xmin, v.x);\n ymin = Math.min(ymin, v.y);\n xmax = Math.max(xmax, v.x);\n ymax = Math.max(ymax, v.y);\n }\n return { x: xmin, y: ymin, width: xmax - xmin, height: ymax - ymin };\n }\n /**\n * Combines two polygons using a boolean set operator (union, intersection or difference).\n * Internally triangulates the merged vertex set (via {@link mesh}) and filters the resulting\n * triangles by whether their barycenter falls inside either source polygon.\n * @param polygon1 First polygon.\n * @param polygon2 Second polygon.\n * @param operator Boolean operator to apply.\n * @returns The resulting polygon(s), plus the underlying triangulation mesh and triangles used to compute them; or `null` if the operation yields no polygon.\n */\n static combinePolygons(polygon1, polygon2, operator) {\n return Utils._mergePolygons(polygon1, polygon2, operator);\n }\n static _mergePolygons(polygon1, polygon2, operator) {\n if (NullChecker.isNullOrEmpty(polygon1?.vertices) || NullChecker.isNullOrEmpty(polygon2?.vertices)) {\n return null;\n }\n // look for sudden exit\n // 2 contains 1\n const contained1 = polygon1.vertices.filter(v => Utils.inPolygon(v, polygon2.vertices));\n if (polygon1.vertices.length == contained1.length) {\n return {\n polygons: operator === 'intersect' ? [polygon1] : /* hole in difference */ [polygon2]\n };\n }\n // 1 contains 2\n const contained2 = polygon2.vertices.filter(v => Utils.inPolygon(v, polygon1.vertices));\n if (polygon2.vertices.length === contained2.length) {\n return {\n polygons: operator === 'intersect' ? [polygon2] : /* hole in difference */ [polygon1]\n };\n }\n // bboxes do not intersect\n const bbox1 = Utils.boundingBox(polygon1.vertices), bbox2 = Utils.boundingBox(polygon2.vertices);\n const rect = Utils.intersect(bbox1, bbox2);\n if (operator !== 'union' && (!Rect.isRect(rect) || !(rect.width > 0) || !(rect.height > 0))) {\n return null; // { polygons: [] };\n }\n const { vertices: vertices1 } = polygon1, { vertices: vertices2 } = polygon2;\n if (vertices1.length < 3 || vertices2.length < 3) {\n return null;\n }\n // steps:\n // 1. compute the intersection points between the two polygon's edges,\n // 2. triangulate all the vertices (original + intersection points)\n // 3. filter the triangles whose barycenter is not within both the original polygons\n // 4. return the vertices of the remaining triangles as the intersection polygon vertices\n const sideBuilderCallback = (v, j, arr) => [v, arr[(j + 1) % arr.length]];\n const verticesSortCallback = (a, b) => a.x === b.x ? a.y - b.y : a.x - b.x;\n const edges1 = vertices1.map(sideBuilderCallback), edges2 = vertices2.map(sideBuilderCallback);\n const outputVertices = vertices1.concat(vertices2);\n const memoizer = new Map();\n const ensureMemoizer = e => {\n if (!memoizer.has(e)) {\n const retval = [];\n memoizer.set(e, retval);\n }\n return memoizer.get(e);\n };\n // loop to find edge intersections\n let thereAreIntersections = false;\n for (let edge1 of edges1) {\n const additionalVertices1 = ensureMemoizer(edge1);\n for (let edge2 of edges2) {\n const additionalVertices2 = ensureMemoizer(edge2);\n const intersection = Utils.intersect(edge1, edge2);\n if (!NullChecker.isNull(intersection)) {\n // found intersection\n thereAreIntersections = true;\n outputVertices.push(intersection);\n additionalVertices1.push(intersection);\n additionalVertices2.push(intersection);\n }\n }\n }\n // if no point is contained in each other's polygon AND additionalVertices is empty AND 'intersect' => exit\n if (contained1.length === 0 && contained2.length === 0 && !thereAreIntersections) {\n switch (operator) {\n case 'union':\n return { polygons: [polygon1, polygon2] };\n default:\n return null; // { polygons: [] };\n }\n }\n const constraints = [];\n for (let edge of edges1.concat(edges2)) {\n const additionalVertices = ensureMemoizer(edge);\n if (NullChecker.isNullOrEmpty(additionalVertices)) {\n constraints.push(edge);\n }\n else {\n // split the edge into segments by the additional vertices\n const totalVertices = edge.concat(additionalVertices).sort(verticesSortCallback);\n for (let j = 0; j < totalVertices.length - 1; j++) {\n constraints.push([totalVertices[j], totalVertices[j + 1]]);\n }\n }\n }\n // simplify by removing coinciding vertices\n var dirty = false;\n var mesh;\n do {\n outputVertices.sort(verticesSortCallback);\n outputVertices.filter((v, i, arr) => { return i === 0 || !Utils.areClose(v, arr[i - 1]); });\n // triangulate\n mesh = Utils.mesh(outputVertices);\n const { vertices, triangleIndices } = mesh;\n dirty = false;\n // enforce constraints\n for (let j = 0; j < triangleIndices.length; j += 3) {\n const indexA = triangleIndices[j], indexB = triangleIndices[j + 1], indexC = triangleIndices[j + 2];\n const A = vertices[indexA], B = vertices[indexB], C = vertices[indexC];\n const sides = [[A, B], [B, C], [C, A]];\n for (let constraint of constraints) {\n for (let side of sides) {\n const consecutive = Utils.areClose(side[0], constraint[0])\n || Utils.areClose(side[1], constraint[1])\n || Utils.areClose(side[0], constraint[1])\n || Utils.areClose(side[1], constraint[0]);\n const intersection = consecutive ? null : Utils.intersect(side, constraint);\n if (!NullChecker.isNull(intersection) && outputVertices.findIndex(p => Utils.areClose(p, intersection, 4)) === -1) {\n // pick triangle adjacent to the intesected side\n dirty = true;\n outputVertices.push(intersection);\n //break;\n }\n }\n }\n }\n } while (dirty);\n const { vertices, triangleIndices } = mesh;\n // loop through triangles and filter by barycenter\n const triangles = [];\n for (let j = 0; j < triangleIndices.length; j += 3) {\n const jA = j, jB = j + 1, jC = j + 2;\n const A = vertices[triangleIndices[jA]], B = vertices[triangleIndices[jB]], C = vertices[triangleIndices[jC]];\n const O = { x: (A.x + B.x + C.x) / 3, y: (A.y + B.y + C.y) / 3 };\n const in1 = Utils.inPolygon(O, vertices1), in2 = Utils.inPolygon(O, vertices2);\n if (in1 && in2 && operator === 'intersect'\n || (in1 || in2) && operator === 'union'\n || (in1 && !in2 || !in1 && in2) && operator === 'difference') {\n triangles.push([A, B, C]);\n }\n }\n // return the unique vertices of the remaining triangles as the intersection polygon vertices\n // 1. list all edges\n const edges = triangles.flatMap(([A, B, C]) => [[A, B], [B, C], [C, A]]);\n // 2. filter by uniqueness\n const uniqueEdges = [];\n for (let j = 0; j < edges.length; j++) {\n const edge = edges[j];\n if (j == 0) {\n uniqueEdges.push(edge);\n continue;\n }\n const alreadyIn = uniqueEdges.findIndex(e => Utils.areClose(e[0], edge[0]) && Utils.areClose(e[1], edge[1]) || Utils.areClose(e[0], edge[1]) && Utils.areClose(e[1], edge[0]));\n if (alreadyIn === -1) {\n uniqueEdges.push(edge);\n }\n else {\n uniqueEdges.splice(alreadyIn, 1);\n }\n }\n if (uniqueEdges.length < 3) {\n return null;\n }\n const polygons = [];\n const cleanupPolygon = (vertices) => {\n // check that the starting vertex is not repeated\n const { length } = vertices;\n const repeated = Utils.areClose(vertices[0], vertices[length - 1]);\n const retval = vertices.slice(0, repeated ? (length - 1) : length);\n // check sneaky starting in-segment vertex\n if (retval.length > 3 && Utils.inSegment(retval[0], [retval[1], retval[retval.length - 1]])) {\n retval.shift();\n }\n return retval;\n };\n // 3. order the boundary vertices by following the edges\n const [P0, P1] = uniqueEdges.shift();\n const boundaryVertices = [P0, P1];\n while (uniqueEdges.length > 1) {\n const lastVertex = boundaryVertices[boundaryVertices.length - 1];\n const nextEdgeIndex = uniqueEdges.findIndex(e => Utils.areClose(e[0], lastVertex) || Utils.areClose(e[1], lastVertex));\n // manage to return multiple polygons in case of multiple disconnected intersections\n // nextVertex could be null but uniqueEdges not empty, then move to another polygon to yield.\n if (nextEdgeIndex === -1) {\n // check that the starting vertex is not repeated\n polygons.push({ vertices: cleanupPolygon(boundaryVertices.splice(0)) });\n // start next polygon\n const [P2, P3] = uniqueEdges.shift();\n boundaryVertices.push(P2, P3);\n }\n else {\n const [nextEdge] = uniqueEdges.splice(nextEdgeIndex, 1);\n const nextVertex = Utils.areClose(nextEdge[0], lastVertex) ? nextEdge[1] : (Utils.areClose(nextEdge[1], lastVertex) ? nextEdge[0] : null);\n // cleanup past in-segment vertices\n if (boundaryVertices.length > 1 && Utils.inSegment(boundaryVertices[boundaryVertices.length - 1], [boundaryVertices[boundaryVertices.length - 2], nextVertex])) {\n boundaryVertices.splice(boundaryVertices.length - 1, 1, nextVertex);\n }\n else {\n boundaryVertices.push(nextVertex);\n }\n }\n }\n polygons.push({ vertices: cleanupPolygon(boundaryVertices) });\n return {\n polygons, mesh, triangles: triangles.map(vertices => { return { vertices }; })\n };\n }\n static mesh(point, ...points) {\n const vertices = [].concat(point).concat(points), triangleIndices = Delaunay.triangulate(vertices);\n return { vertices, triangleIndices };\n }\n static intersectLines(segment1, segment2, m2, q2) {\n let s1, s2;\n // overload 2 => m+q in pairs, reset as overload 1\n if (Array.isArray(segment1) && Array.isArray(segment2)\n && segment1.length === 2 && segment2.length === 2\n && typeof segment1[0] === 'number' && typeof segment2[0] === 'number' && typeof segment1[1] === 'number' && typeof segment2[1] === 'number') {\n // var type switch, instructions' order matter!\n m2 = segment2[0];\n q2 = segment2[1];\n segment2 = segment1[1];\n segment1 = segment1[0];\n }\n // overload 1?\n if (typeof segment1 === 'number' && typeof segment2 === 'number') {\n const m1 = segment1, q1 = segment2;\n // dummy segments\n s1 = [\n { x: 0, y: q1 },\n { x: 1, y: m1 + q1 }\n ];\n s2 = [\n { x: 0, y: q2 },\n { x: 1, y: m2 + q2 }\n ];\n }\n // overload 0\n else {\n s1 = segment1;\n s2 = segment2;\n }\n return Utils._intersectSegments(s1, s2, false);\n }\n static cramer(l1, l2) {\n if (Array.isArray(l1)) {\n l1 = { a: l1[0], b: l1[1], c: l1[2] };\n }\n if (Array.isArray(l2)) {\n l2 = { a: l2[0], b: l2[1], c: l2[2] };\n }\n let xP = (l1.b * l2.c - l1.c * l2.b) / (l1.b * l2.a - l1.a * l2.b), yP = (l1.c * l2.a - l1.a * l2.c) / (l1.b * l2.a - l1.a * l2.b);\n return { x: -xP.roundoff(), y: -yP.roundoff() };\n }\n static mq(arg0, p2) {\n let p1;\n if (isPoint(arg0)) {\n p1 = arg0;\n }\n else {\n p1 = arg0[0];\n p2 = arg0[1];\n }\n if (p1.x === p2.x) {\n return [Number.NaN, Number.NaN];\n }\n const m = (p2.y - p1.y) / (p2.x - p1.x);\n const q = p1.y - m * p1.x;\n return [m, q];\n }\n static _intersectSegments(segment1, segment2, excludeProjection) {\n // do bounding boxes intersect?\n const A = segment1[0], B = segment1[1], C = segment2[0], D = segment2[1], xAB = Math.min(A.x, B.x), yAB = Math.min(A.y, B.y), XAB = Math.max(A.x, B.x), wAB = XAB - xAB, YAB = Math.max(A.y, B.y), hAB = YAB - yAB, xCD = Math.min(C.x, D.x), yCD = Math.min(C.y, D.y), XCD = Math.max(C.x, D.x), wCD = XCD - xCD, YCD = Math.max(C.y, D.y), hCD = YCD - yCD;\n if (wAB === 0 && wCD === 0) {\n // both vertical segments (null or infinite intersections) return null\n return null;\n }\n if (hAB === 0 && hCD === 0) {\n // both horizontal segments (null or infinite intersections) return null\n return null;\n }\n // dry\n const outOfXBounds = (p) => {\n return p.x < xCD || p.x > XCD || p.x < xAB || p.x > XAB;\n };\n const outOfYBounds = (p) => {\n return p.y < yCD || p.y > YCD || p.y < yAB || p.y > YAB;\n };\n var retval = null;\n if (wAB === 0) {\n if (excludeProjection && (xCD > xAB || XCD < XAB)) {\n return null;\n }\n const mqCD = Utils.mq(C, D);\n retval = Utils.cramer([1, 0, -xAB], [mqCD[0], -1, mqCD[1]]);\n if (excludeProjection && outOfYBounds(retval)) {\n retval = null;\n }\n }\n else if (wCD === 0) {\n if (excludeProjection && (xAB > xCD || XAB < XCD)) {\n return null;\n }\n const mqAB = Utils.mq(A, B);\n retval = Utils.cramer([mqAB[0], -1, mqAB[1]], [1, 0, -xCD]);\n if (excludeProjection && outOfYBounds(retval)) {\n retval = null;\n }\n }\n else if (hAB === 0) {\n if (excludeProjection && (yCD > yAB || YCD < YAB)) {\n return null;\n }\n const mqCD = Utils.mq(C, D);\n retval = Utils.cramer([0, 1, -yAB], [mqCD[0], -1, mqCD[1]]);\n if (excludeProjection && outOfXBounds(retval)) {\n retval = null;\n }\n }\n else if (hCD === 0) {\n if (excludeProjection && (yAB > yCD || YAB < YCD)) {\n return null;\n }\n const mqAB = Utils.mq(A, B);\n retval = Utils.cramer([mqAB[0], -1, mqAB[1]], [0, 1, -yCD]);\n if (excludeProjection && outOfXBounds(retval)) {\n retval = null;\n }\n }\n else {\n let intersection;\n if (!excludeProjection ||\n ((intersection = Utils._intersectRects({ x: xAB, y: yAB, width: wAB, height: hAB }, { x: xCD, y: yCD, width: wCD, height: hCD }))\n && intersection.width > 0\n && intersection.height > 0)) {\n // cramer's rule\n const mqAB = Utils.mq(A, B), mqCD = Utils.mq(C, D);\n const mAB = mqAB[0], mCD = mqCD[0], qAB = mqAB[1], qCD = mqCD[1];\n // parallel os superposed segments yield null\n if (mAB !== mCD) {\n retval = Utils.cramer([mAB, -1, qAB], [mCD, -1, qCD]);\n let xR = retval.x, yR = retval.y;\n if (excludeProjection\n && (xR < intersection.x || xR > (intersection.x + intersection.width)\n || yR < intersection.y || yR > (intersection.y + intersection.height))) {\n retval = null;\n }\n }\n }\n }\n if (retval === null) {\n return null;\n }\n return { x: retval.x, y: retval.y };\n }\n static _intersectRects(...args) {\n return Rect.intersect(...args);\n }\n static _areClose(p1, p2, precision = PRECISION) {\n return Math.abs(p1.x - p2.x).isCloseTo(0, precision) && Math.abs(p1.y - p2.y).isCloseTo(0, precision);\n }\n static areClose(p1, p2, precision = PRECISION) {\n return Utils._areClose(p1, p2, precision);\n }\n /**\n * Returns the dot product between two vectors/points.\n * @param v1\n * @param v2\n */\n static dot(v1, v2) {\n return Vector.dot(v1, v2);\n }\n /**\n * Returns the cross product between two vectors/points (magnitude along the z axis).\n * @param v1\n * @param v2\n */\n static cross(v1, v2) {\n return Vector.cross(v1, v2);\n }\n static distance(p1, arg2) {\n if (isSegment(p1)) {\n return Point.distance(p1[0], p1[1]);\n }\n else if (isPoint(arg2)) {\n return Point.distance(p1, arg2);\n }\n else {\n const m = arg2[0], q = arg2[1];\n return Math.abs(m * p1.x - p1.y + q) / Math.sqrt(Math.pow(m, 2) + 1);\n }\n }\n static _pointSegmentDistance(p, segment) {\n const v1 = Vector.from(segment[0], segment[1]), v2 = Vector.from(segment[0], p);\n return Utils.cross(v1, v2);\n }\n static isWithin(p, segment, clockwise, precision = PRECISION) {\n const cross = Utils._pointSegmentDistance(p, segment);\n if (cross.isCloseTo(0, precision)) {\n return false;\n }\n return clockwise ? cross < 0 : cross > 0;\n }\n static isBeyond(p, segment, clockwise, precision = PRECISION) {\n return Utils.isWithin(p, segment, !clockwise, precision);\n }\n static inLine(p, segment, precision = PRECISION) {\n const cross = Utils._pointSegmentDistance(p, segment);\n return cross.isCloseTo(0, precision);\n }\n static inSegment(p, segment, precision = PRECISION) {\n 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);\n return p.x >= minx && p.x <= maxx && p.y >= miny && p.y <= maxy && Utils.inLine(p, segment, precision);\n }\n /**\n * Checks whether a point lies inside (or on the boundary of) a triangle, by verifying that it\n * is on the same rotational side of all three edges.\n * @param p Point to test.\n * @param triangle Triangle vertices.\n */\n static inTriangle(p, triangle) {\n let last;\n for (let j = 0; j < 3; j++) {\n const p1 = triangle[j], p2 = triangle[(j + 1) % 3], v1 /* vector */ = Point.subtract(p2, p), v2 = Point.subtract(p1, p), current = Utils.cross(v1, v2);\n if (j > 0 && (current * last) <= 0) {\n // in the current 'triangle' we face a different direction,\n // then exit (:=not in polygon)\n return false;\n }\n last = current;\n }\n return true;\n }\n static inPolygon(p, vertices, precision = PRECISION) {\n if (!(vertices?.length >= 3)) {\n throw `Not enough vertices`;\n }\n const length = vertices.length;\n if (length === 3) {\n return Utils.inTriangle(p, [vertices[0], vertices[1], vertices[2]]);\n }\n if (precision > 0) {\n vertices = vertices.map(v => { return { x: v.x.roundoff(precision), y: v.y.roundoff(precision) }; });\n p = { x: p.x.roundoff(precision), y: p.y.roundoff(precision) };\n }\n // true polygon (might be concave, hulled, ...)\n // 1. preliminary bbox check\n let minx = Number.MAX_VALUE, miny = Number.MAX_VALUE, maxx = Number.MIN_VALUE, maxy = Number.MIN_VALUE;\n for (let j = 0; j < length; j++) {\n const v = vertices[j];\n minx = Math.min(minx, v.x);\n miny = Math.min(miny, v.y);\n maxx = Math.max(maxx, v.x);\n maxy = Math.max(maxy, v.y);\n }\n if (p.x < minx || p.x > maxx || p.y < miny || p.y > maxy) {\n return false;\n }\n // 2. intersections\n const /* dummy point 'left' to the left-most point of the shape and haivng the same 'y' of the target point */ outerPoint = { x: minx - 1, y: p.y }, \n /* horizontal segment that binds the provided point with the outside one */ test = [outerPoint, p];\n let intersections = 0;\n for (let j = 0; j < length; j++) {\n const p1 = vertices[j], p2 = vertices[(j + 1) % length], side = [p1, p2];\n // edge case\n if (p1.y === p.y) {\n const p0 = vertices[(j - 1 + length) % length];\n // not on the same side (above or below)? then counts as an intersection\n if (p.x > p1.x && (p0.y - p.y) * (p2.y - p.y) < 0) {\n intersections++;\n }\n }\n else if (p2.y === p.y) {\n // already handled at previous statement one loop ago, skip\n continue;\n }\n else {\n // straddle testing\n if (Utils.intersect(side, test) != null) {\n intersections++;\n }\n }\n }\n return intersections % 2 === 1;\n }\n static area(point, ...points) {\n const pts = [].concat(point).concat(points);\n // shoelace algorithm\n let retval = 0;\n const length = pts.length;\n if (length >= 3) {\n for (let j = 0; j < pts.length; j++) {\n const { x: xj, y: yj } = pts[j], next = j === (length - 1) ? 0 : j + 1, { x: xnext, y: ynext } = pts[next];\n retval += (xj * ynext - yj * xnext);\n }\n retval *= .5;\n }\n return Math.abs(retval.roundoff());\n }\n static convexHull(point, ...points) {\n const pts = [].concat(point).concat(points);\n if (!(pts?.length > 1)) {\n return pts?.slice() ?? [];\n }\n const sorted = pts\n .map(p => ({ x: p.x, y: p.y }))\n .sort((a, b) => a.x === b.x ? a.y - b.y : a.x - b.x);\n const unique = [];\n for (const p of sorted) {\n const last = unique[unique.length - 1];\n if (!last || last.x !== p.x || last.y !== p.y) {\n unique.push(p);\n }\n }\n if (unique.length <= 2) {\n return unique;\n }\n const cross = (o, a, b) => {\n return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);\n };\n const lower = [];\n for (const p of unique) {\n while (lower.length >= 2\n && cross(lower[lower.length - 2], lower[lower.length - 1], p) <= 0) {\n lower.pop();\n }\n lower.push(p);\n }\n const upper = [];\n for (let j = unique.length - 1; j >= 0; j--) {\n const p = unique[j];\n while (upper.length >= 2\n && cross(upper[upper.length - 2], upper[upper.length - 1], p) <= 0) {\n upper.pop();\n }\n upper.push(p);\n }\n lower.pop();\n upper.pop();\n return lower.concat(upper);\n }\n}\n// }\n", "import { Point } from '@pacem/pacem-foundation';\n/** 2D vector utils. */\nexport class Vector {\n /**\n * Returns the unit (normalized) vector having the same direction and sense of the provided one.\n * @param v\n */\n static unit(v) {\n const clone = { x: v.x, y: v.y };\n this.normalize(clone);\n return clone;\n }\n /**\n * Returns the squared magnitude (length) of the vector. Cheaper than {@link mag} since it avoids the square root.\n * @param v\n */\n static magSqr(v) {\n return v.x * v.x + v.y * v.y;\n }\n /**\n * Returns the magnitude (length) of the vector.\n * @param v\n */\n static mag(v) {\n return Math.sqrt(Vector.magSqr(v));\n }\n /**\n * Normalizes the provided vector in place.\n * @param v\n */\n static normalize(v) {\n const l = Vector.mag(v);\n if (l <= 0) {\n throw 'Cannot normalize a vector of length 0.';\n }\n const inv = 1 / l;\n v.x *= inv;\n v.y *= inv;\n }\n /**\n * Returns the vector joining two points.\n * @param p1 Start point\n * @param p2 End point\n */\n static from(p1, p2) {\n return Point.subtract(p1, p2);\n }\n /**\n * Returns the dot product between two vectors/points.\n * @param v1\n * @param v2\n */\n static dot(v1, v2) {\n return v1.x * v2.x + v1.y * v2.y;\n }\n /**\n * Returns the cross product between two vectors/points (magnitude along the z axis).\n * @param v1\n * @param v2\n */\n static cross(v1, v2) {\n return v1.x * v2.y - v1.y * v2.x;\n }\n /**\n * Checks if the two points are effectively the same location.\n * @param v1 The first point.\n * @param v2 The second point.\n * @returns True if the points are considered coincident within tolerance; otherwise, false.\n */\n static areClose(v1, v2) {\n return (v2.x - v1.x).isCloseTo(0)\n && (v2.y - v1.y).isCloseTo(0);\n }\n}\n", "class Vertex {\n constructor(x, y, index = -1 // original index in the input array\n ) {\n this.x = x;\n this.y = y;\n this.index = index;\n }\n equals(other) {\n return this.x === other.x && this.y === other.y;\n }\n}\n// Compute circumcircle of a triangle (center + radius)\nfunction calcCircumCirc(v0, v1, v2) {\n const ax = v0.x, ay = v0.y;\n const bx = v1.x, by = v1.y;\n const cx = v2.x, cy = v2.y;\n const d = 2 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by));\n if (Math.abs(d) < 1e-12) {\n // Degenerate (collinear) triangle\n return { c: { x: 0, y: 0 }, r: Infinity };\n }\n const ux = ((ax * ax + ay * ay) * (by - cy) +\n (bx * bx + by * by) * (cy - ay) +\n (cx * cx + cy * cy) * (ay - by)) /\n d;\n const uy = ((ax * ax + ay * ay) * (cx - bx) +\n (bx * bx + by * by) * (ax - cx) +\n (cx * cx + cy * cy) * (bx - ax)) /\n d;\n const r = Math.hypot(ux - ax, uy - ay);\n return { c: { x: ux, y: uy }, r };\n}\nclass Triangle {\n constructor(v0, v1, v2) {\n this.v0 = v0;\n this.v1 = v1;\n this.v2 = v2;\n this.circumCirc = calcCircumCirc(v0, v1, v2);\n }\n inCircumcircle(v) {\n const dx = this.circumCirc.c.x - v.x;\n const dy = this.circumCirc.c.y - v.y;\n return Math.hypot(dx, dy) <= this.circumCirc.r + 1e-9;\n }\n}\n// Create a large \"super triangle\" that encloses all points\nfunction superTriangle(vertices) {\n let minX = Infinity, minY = Infinity;\n let maxX = -Infinity, maxY = -Infinity;\n for (const v of vertices) {\n minX = Math.min(minX, v.x);\n minY = Math.min(minY, v.y);\n maxX = Math.max(maxX, v.x);\n maxY = Math.max(maxY, v.y);\n }\n const dx = (maxX - minX) * 10;\n const dy = (maxY - minY) * 10;\n const v0 = new Vertex(minX - dx, minY - dy * 3);\n const v1 = new Vertex(minX - dx, maxY + dy);\n const v2 = new Vertex(maxX + dx * 3, maxY + dy);\n return new Triangle(v0, v1, v2);\n}\n// Collect unique edges from a list of triangles (used during point insertion)\nfunction uniqueEdges(edges) {\n const unique = [];\n for (let i = 0; i < edges.length; ++i) {\n let isUnique = true;\n for (let j = 0; j < edges.length; ++j) {\n if (i !== j) {\n const e1 = edges[i];\n const e2 = edges[j];\n if ((e1.v0.equals(e2.v0) && e1.v1.equals(e2.v1)) ||\n (e1.v0.equals(e2.v1) && e1.v1.equals(e2.v0))) {\n isUnique = false;\n break;\n }\n }\n }\n if (isUnique)\n unique.push(edges[i]);\n }\n return unique;\n}\n// Insert a new vertex into the current triangulation\nfunction addVertex(vertex, triangles) {\n const edges = [];\n // 1. Remove all triangles whose circumcircle contains the new vertex\n triangles = triangles.filter((triangle) => {\n if (triangle.inCircumcircle(vertex)) {\n edges.push({ v0: triangle.v0, v1: triangle.v1 });\n edges.push({ v0: triangle.v1, v1: triangle.v2 });\n edges.push({ v0: triangle.v2, v1: triangle.v0 });\n return false;\n }\n return true;\n });\n // 2. Create new triangles from the unique polygon edges + new vertex\n const unique = uniqueEdges(edges);\n for (const edge of unique) {\n triangles.push(new Triangle(edge.v0, edge.v1, vertex));\n }\n return triangles;\n}\n// Main Delaunay triangulation (Bowyer-Watson)\nfunction triangulate(vertices) {\n if (vertices.length < 3)\n return [];\n // 1. Create super triangle\n const st = superTriangle(vertices);\n // 2. Start with the super triangle\n let triangles = [st];\n // 3. Insert each point one by one\n for (const vertex of vertices) {\n triangles = addVertex(vertex, triangles);\n }\n // 4. Remove any triangle that touches the super triangle\n triangles = triangles.filter((t) => !(t.v0 === st.v0 ||\n t.v0 === st.v1 ||\n t.v0 === st.v2 ||\n t.v1 === st.v0 ||\n t.v1 === st.v1 ||\n t.v1 === st.v2 ||\n t.v2 === st.v0 ||\n t.v2 === st.v1 ||\n t.v2 === st.v2));\n return triangles;\n}\n// Public API: Delaunay triangulation given vertices \u2192 triangle indices\nfunction delaunayTriangulation(vertices) {\n if (vertices.length < 3)\n return [];\n // Create internal vertices that remember their original index\n const vertList = vertices.map((p, idx) => new Vertex(p.x, p.y, idx));\n const triangles = triangulate(vertList);\n // Convert to flat index array: [i0, j0, k0, i1, j1, k1, ...]\n const indices = [];\n for (const t of triangles) {\n // All vertices in the final triangulation come from the original input\n indices.push(t.v0.index, t.v1.index, t.v2.index);\n }\n return indices;\n}\n// Example usage:\n/*\nconst vertices: Point[] = [\n { x: 0, y: 0 },\n { x: 10, y: 0 },\n { x: 5, y: 10 },\n { x: 15, y: 5 },\n { x: 2, y: 8 },\n // ... any number of points\n];\n\nconst triangleIndices = delaunayTriangulation(vertices);\n\n// triangleIndices is a flat array of indices, e.g. [0,1,2, 0,2,4, 1,3,2, ...]\n// Use it like this:\nfor (let i = 0; i < triangleIndices.length; i += 3) {\n const a = vertices[triangleIndices[i]];\n const b = vertices[triangleIndices[i + 1]];\n const c = vertices[triangleIndices[i + 2]];\n console.log(`Triangle: ${a.x},${a.y} \u2192 ${b.x},${b.y} \u2192 ${c.x},${c.y}`);\n}\n*/\n// This implementation is self-contained, numerically robust (small epsilon), and works with floating-point coordinates.\n// It assumes general position (no four points exactly cocircular). For production use with degenerate cases,\n// you may want to add a tiny random jitter to the points if needed.\n/**\n * Computes the (unconstrained) 2D Delaunay triangulation of a set of points, using the\n * incremental Bowyer-Watson algorithm.\n *\n * A Delaunay triangulation connects a set of points into triangles such that no point lies\n * strictly inside the circumcircle of any triangle. Among all the ways a point set can be\n * triangulated, this property makes it the one that maximizes the minimum angle of all the\n * triangles, avoiding thin \"sliver\" triangles \u2014 which is why it's the standard choice for\n * meshes, terrain modeling, and (via its dual) Voronoi diagrams.\n *\n * The Bowyer-Watson algorithm builds the triangulation incrementally: starting from a single\n * \"super triangle\" that encloses every input point, each point is inserted one at a time by\n * removing every existing triangle whose circumcircle contains it (which necessarily leaves a\n * star-shaped polygonal hole around the new point) and re-triangulating that hole by connecting\n * the new point to the hole's boundary edges. Once every point has been inserted, any triangle\n * still touching a vertex of the initial super triangle is discarded, leaving the final\n * triangulation of the original points.\n */\nexport class Delaunay {\n /**\n * Computes the Delaunay triangulation of the given points.\n * @param vertices Points to triangulate.\n * @returns A flat array of triangle indices into {@link vertices} (each consecutive group of 3\n * entries identifies one triangle), in the same \"vertices + triangle indices\" format used by\n * most graphics/meshing libraries. Returns an empty array if fewer than 3 points are provided.\n */\n static triangulate(vertices) {\n return delaunayTriangulation(vertices);\n }\n}\n//}\n", "import { Point, Matrix2D, Angle, NullChecker } from '@pacem/pacem-foundation';\n// namespace Pacem.Geometry {\nimport { Utils } from './geom';\nimport * as LinearAlgebra from './linear-algebra';\nfunction isPolygon(obj) {\n let vertices;\n return 'vertices' in obj && Array.isArray(obj.vertices)\n && (vertices = obj.vertices).length >= 3\n && vertices.every(i => Point.isPoint(i));\n}\n/** Utility tools to build and inspect {@link Polygon}s. */\nexport class Polygon {\n static { this._eps = 1e-12; }\n /**\n * Type guard checking whether the provided value is a valid {@link Polygon} (has at least 3 point vertices).\n * @param obj\n */\n static isPolygon(obj) {\n return isPolygon(obj);\n }\n /**\n * Builds a polygon from the provided vertices, in order.\n * @param points Vertices of the polygon.\n */\n static from(...points) {\n return { vertices: Array.from(points) };\n }\n /**\n * Checks whether a point lies inside the polygon.\n * @param polygon\n * @param p Point to test.\n */\n static contains(polygon, p) {\n return Utils.inPolygon(p, polygon.vertices, 12);\n }\n /**\n * Returns the center of the polygon's bounding box.\n * Note: this is not the geometric centroid (center of mass) for non-symmetric polygons.\n * @param polygon\n */\n static centroid(polygon) {\n const bbox = Polygon.boundingBox(polygon);\n return { x: bbox.x + bbox.width / 2, y: bbox.y + bbox.height / 2 };\n }\n /**\n * Computes the axis-aligned bounding box of the polygon.\n * @param polygon\n */\n static boundingBox(polygon) {\n return Utils.boundingBox(polygon.vertices);\n }\n /**\n * Returns the polygon's edges as an ordered list of segments, each joining a vertex to the next\n * (the last one wrapping back to the first).\n * @param polygon\n */\n static sides(polygon) {\n const { vertices } = polygon;\n const retval = [];\n for (let j = 1; j <= vertices.length; j++) {\n const v = vertices[j % vertices.length], v0 = vertices[j - 1];\n retval.push([v0, v]);\n }\n return retval;\n }\n /**\n * Checks whether the polygon is convex, i.e. all its interior angles turn in the same rotational direction.\n * @param polygon\n */\n static isConvex(polygon) {\n const { vertices } = polygon, l = vertices.length;\n if (l <= 3) {\n return true;\n }\n let sign = 0;\n for (let j = 0; j < vertices.length; j++) {\n const p0 = vertices[(j - 1 + l) % l], p = vertices[j], p1 = vertices[(j + 1) % l];\n const theta = Angle.angleBetween(p, p0, p1);\n //if (Math.abs(theta) > Math.PI) {\n // return false;\n //}\n if (sign === 0) {\n sign = Math.sign(theta);\n continue;\n }\n if (sign != Math.sign(theta)) {\n return false;\n }\n }\n return true;\n }\n /**\n * Check whether a polygon is a self-intersecting one.\n * @param polygon\n * @returns\n */\n static isSelfIntersecting(polygon) {\n const { vertices } = polygon;\n if (vertices.length <= 3) {\n return false;\n }\n const sides = Polygon.sides(polygon);\n for (let side of sides) {\n for (let check of sides) {\n if ( /* same */check === side || /* contiguous */ check[0] === side[1] || side[0] === check[1]) {\n continue;\n }\n const intersection = Utils.intersect(check, side);\n if (!NullChecker.isNull(intersection)) {\n return true;\n }\n }\n }\n return false;\n }\n /**\n * Returns whether the vertices of the spcified polygon have been provided in counter-clockwise order.\n * Meaningless in case of self-intersecting polygons.\n * @param polygon\n * @returns\n */\n static isCounterClockwise(polygon) {\n const { vertices: [p0, p1, p2] } = polygon;\n return Angle.angleBetween(p1, p0, p2) > 0; /* ccw angle <=> cw polygon and viceversa */\n }\n /**\n * Expands (or contracts) a polygon by a provided offset.\n * @param polygon\n * @param offset\n *\n */\n static expand(polygon, offset) {\n // TODO: https://en.wikipedia.org/wiki/Straight_skeleton\n const { vertices } = polygon, l = vertices.length, retval = [];\n for (let j = 0; j < vertices.length; j++) {\n const p0 = vertices[(j - 1 + l) % l], p = vertices[j], p1 = vertices[(j + 1) % l];\n const theta = Angle.angleBetween(p, p0, p1), scale = -offset / Math.sin(Math.abs(theta) / 2);\n const matrix = Matrix2D.scale(Matrix2D.identity, scale);\n const v0 = Point.subtract(p, p0);\n LinearAlgebra.Vector.normalize(v0);\n const v1 = Point.subtract(p, p1);\n LinearAlgebra.Vector.normalize(v1);\n const vector = Point.add(v0, v1);\n LinearAlgebra.Vector.normalize(vector);\n const pOffset = Matrix2D.multiply(vector, matrix);\n retval.push(Point.add(p, { x: pOffset.x.roundoff(), y: pOffset.y.roundoff() }));\n }\n return { vertices: retval };\n }\n /**\n * Returns the area of a polygon using the shoelace algorithm. It's meaningless in case of self-intersecting polygons.\n * @param polygon\n * @returns\n */\n static area(polygon) {\n return Utils.area(polygon.vertices);\n }\n /**\n * Computes the intersection area(s) between two polygons.\n * @param polygon1\n * @param polygon2\n * @returns The overlapping area(s) as one or more polygons.\n */\n static intersect(polygon1, polygon2) {\n return Utils.intersect(polygon1, polygon2);\n }\n /**\n * Returns the convex hull of a polygon.\n * @param polygon\n * @returns\n */\n static convexHull(polygon) {\n const vertices = Utils.convexHull(polygon.vertices);\n return { vertices };\n }\n}\n//}\n", "import { parseAsNumericalArray } from '@pacem/pacem-foundation';\n// namespace Pacem.Geometry.LinearAlgebra {\nconst RAD2DEG = 180.0 / Math.PI;\nconst DEG2RAD = 1.0 / RAD2DEG;\n/** 3D vector utils. */\nexport class Vector3D {\n /**\n * Builds a {@link Vector3D} from its x, y, z components, in that order.\n * @param args Exactly 3 numbers: x, y, z.\n * @throws If the number of arguments is not exactly 3.\n */\n static from(...args) {\n const l = 3;\n if (args.length !== l) {\n throw new RangeError(`Must provide exactly ${l} numbers`);\n }\n return { x: args[0], y: args[1], z: args[2] };\n }\n /**\n * Parses a string representation (e.g. `\"1 2 3\"` or `\"1,2,3\"`) into a {@link Vector3D}.\n * @param input String to parse.\n * @throws If the input cannot be parsed as exactly 3 numbers.\n */\n static parse(input) {\n const arr = parseAsNumericalArray(input);\n if (arr && arr.length === 3) {\n return Vector3D.from.apply(null, arr);\n }\n throw new Error(`Cannot parse \"${input}\" as a valid Vector3D.`);\n }\n // notable vectors\n /** Returns the unit vector along the x axis: `(1, 0, 0)`. */\n static i() {\n return { x: 1, y: 0, z: 0 };\n }\n /** Returns the unit vector along the y axis: `(0, 1, 0)`. */\n static j() {\n return { x: 0, y: 1, z: 0 };\n }\n /** Returns the unit vector along the z axis: `(0, 0, 1)`. */\n static k() {\n return { x: 0, y: 0, z: 1 };\n }\n /** Returns the zero vector: `(0, 0, 0)`. */\n static zero() {\n return { x: 0, y: 0, z: 0 };\n }\n /**\n * Subtracts a point p from another and returns the resulting vector.\n * @param p Point to subtract\n * @param from Point to be subtracted from\n */\n static subtract(p, from) {\n return { x: from.x - p.x, y: from.y - p.y, z: from.z - p.z };\n }\n /**\n * Adds a set of points together and returns the resulting vector.\n * @param points Points to add\n */\n static add(...points) {\n var point = { x: 0, y: 0, z: 0 };\n for (var p of points) {\n point.x += p.x;\n point.y += p.y;\n point.z += p.z;\n }\n return point;\n }\n /**\n * Returns the dot product between two vectors/points.\n * @param v1\n * @param v2\n */\n static dot(v1, v2) {\n return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;\n }\n /**\n * Returns the cross product between two vectors/points (as a vector itself).\n * @param v1\n * @param v2\n */\n static cross(v1, v2) {\n return {\n x: (v1.y * v2.z) - (v1.z * v2.y),\n y: (v1.z * v2.x) - (v1.x * v2.z),\n z: (v1.x * v2.y) - (v1.y * v2.x)\n };\n }\n static scale(v, fx, fy = fx, fz = fx) {\n return { x: v.x * fx, y: v.y * fy, z: v.z * fz };\n }\n /**\n * Returns the squared magnitude (length) of the vector. Cheaper than {@link mag} since it avoids the square root.\n * @param v\n */\n static magSqr(v) {\n return v.x * v.x + v.y * v.y + v.z * v.z;\n }\n /**\n * Checks if the two points are effectively the same location.\n * @param v1 The first point.\n * @param v2 The second point.\n * @returns True if the points are considered coincident within tolerance; otherwise, false.\n */\n static areClose(v1, v2) {\n return (v2.x - v1.x).isCloseTo(0)\n && (v2.y - v1.y).isCloseTo(0)\n && (v2.z - v1.z).isCloseTo(0);\n }\n /**\n * Returns the magnitude (length) of the vector.\n * @param v\n */\n static mag(v) {\n return Math.sqrt(Vector3D.magSqr(v));\n }\n /**\n * Returns the opposite vector (each component negated).\n * @param v\n */\n static negate(v) {\n return { x: -v.x, y: -v.y, z: -v.z };\n }\n /**\n * Returns the unit (normalized) vector having the same direction and sense of the provided one.\n * @param v\n */\n static unit(v) {\n const clone = { x: v.x, y: v.y, z: v.z };\n this.normalize(clone);\n return clone;\n }\n /**\n * Normalizes the provided vector in place.\n * @param v\n */\n static normalize(v) {\n const l = Vector3D.mag(v);\n if (l <= 0) {\n throw 'Cannot normalize a vector of length 0.';\n }\n const inv = 1 / l;\n v.x *= inv;\n v.y *= inv;\n v.z *= inv;\n }\n /**\n * Returns the angle (in degrees) between two vectors.\n * @param vector1\n * @param vector2\n */\n static angleBetween(vector1, vector2) {\n let num;\n const v1 = Vector3D.unit(vector1);\n const v2 = Vector3D.unit(vector2);\n const dot = Vector3D.dot(v1, v2);\n if (dot < 0.0) {\n const vectord = { x: -v1.x - v2.x, y: -v1.y - v2.y, z: -v1.z - v2.z };\n const length = Vector3D.mag(vectord);\n num = Math.PI - (2.0 * Math.asin(length / 2.0));\n }\n else {\n const vectord = { x: v1.x - v2.x, y: v1.y - v2.y, z: v1.z - v2.z };\n const length = Vector3D.mag(vectord);\n num = 2.0 * Math.asin(length / 2.0);\n }\n return RAD2DEG * num;\n }\n}\n/**\n * Utilities to convert between spherical coordinates (radial distance `rho`, azimuth `theta` and\n * polar angle `phi`) and their cartesian ({@link Vector3D}) or rotation-matrix ({@link Matrix3D}) equivalents.\n */\nexport class Spherical {\n /**\n * Creates a new {@link Spherical} object.\n * @param rho radius.\n * @param theta Azimuth angle in degrees.\n * @param phi Polar angle in degrees.\n * @returns\n */\n static from(rho, theta, phi) {\n return { rho: rho.clamp(0, Infinity), theta: theta.clamp(-180, 180), phi: phi.clamp(0, 360) };\n }\n static fromVector(v, y, z) {\n if (typeof v === 'number') {\n v = Vector3D.from(v, y, z);\n }\n const rho = Vector3D.mag(v);\n if (rho.isCloseTo(0)) {\n return Spherical.from(0, 0, 0);\n }\n const theta = Math.atan2(v.x, v.z), phi = Math.acos((v.y / rho).clamp(-1, 1));\n return Spherical.from(rho, theta * RAD2DEG, phi * RAD2DEG);\n }\n /**\n * Converts {@link Spherical} coordinates back into cartesian {@link Vector3D} coordinates.\n * @param coords\n */\n static toVector(coords) {\n const { rho, theta: thetaDeg, phi: phiDeg } = coords;\n const phi = phiDeg * DEG2RAD;\n const theta = thetaDeg * DEG2RAD;\n const sinPhiRho = Math.sin(phi) * rho;\n return {\n x: sinPhiRho * Math.sin(theta),\n y: Math.cos(phi) * rho,\n z: sinPhiRho * Math.cos(theta)\n };\n //const t = DEG2RAD * theta,\n // sinTheta = Math.sin(t),\n // cosTheta = Math.cos(t),\n // p = DEG2RAD * phi,\n // sinPhi = Math.sin(p),\n // cosPhi = Math.cos(p);\n //const m = Matrix3D.from(\n // sinTheta * cosPhi, cosTheta * cosPhi, -sinPhi, 0,\n // sinTheta * sinPhi, cosTheta * sinPhi, cosPhi, 0,\n // cosTheta, -sinTheta, 0, 0,\n // 0, 0, 0, 1\n //);\n //return Matrix3D.transform({ x: rho, y: t, z: p }, m);\n }\n static toRotationMatrix(coords) {\n const { theta, phi } = coords;\n const t = DEG2RAD * theta, sinTheta = Math.sin(t), cosTheta = Math.cos(t), p = DEG2RAD * phi, sinPhi = Math.sin(p), cosPhi = Math.cos(p);\n return Matrix3D.from(sinTheta * cosPhi, sinTheta * sinPhi, cosTheta, 0, cosTheta * cosPhi, cosTheta * sinPhi, -sinTheta, 0, -sinPhi, cosPhi, 0, 0, 0, 0, 0, 1);\n }\n}\nclass Matrix3DUtils {\n /**\n * Modifies the content of a provided matrix and returns it as a new matrix instance.\n * @param m Input matrix\n * @param action Content change callback\n * @returns New matrix instance.\n */\n static modify(m, action) {\n const { m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, offsetX, offsetY, offsetZ, m44 } = m;\n const retval = {\n m11, m12, m13, m14,\n m21, m22, m23, m24,\n m31, m32, m33, m34,\n offsetX, offsetY, offsetZ, m44\n };\n action(retval);\n return retval;\n }\n static clone(m) {\n return Matrix3DUtils.modify(m, _ => { });\n }\n static multiply(m1, m2) {\n if (Matrix3D.isIdentity(m1))\n return m2;\n if (Matrix3D.isIdentity(m2))\n return m1;\n return Matrix3D.from((((m1.m11 * m2.m11) + (m1.m12 * m2.m21)) + (m1.m13 * m2.m31)) + (m1.m14 * m2.offsetX), (((m1.m11 * m2.m12) + (m1.m12 * m2.m22)) + (m1.m13 * m2.m32)) + (m1.m14 * m2.offsetY), (((m1.m11 * m2.m13) + (m1.m12 * m2.m23)) + (m1.m13 * m2.m33)) + (m1.m14 * m2.offsetZ), (((m1.m11 * m2.m14) + (m1.m12 * m2.m24)) + (m1.m13 * m2.m34)) + (m1.m14 * m2.m44), (((m1.m21 * m2.m11) + (m1.m22 * m2.m21)) + (m1.m23 * m2.m31)) + (m1.m24 * m2.offsetX), (((m1.m21 * m2.m12) + (m1.m22 * m2.m22)) + (m1.m23 * m2.m32)) + (m1.m24 * m2.offsetY), (((m1.m21 * m2.m13) + (m1.m22 * m2.m23)) + (m1.m23 * m2.m33)) + (m1.m24 * m2.offsetZ), (((m1.m21 * m2.m14) + (m1.m22 * m2.m24)) + (m1.m23 * m2.m34)) + (m1.m24 * m2.m44), (((m1.m31 * m2.m11) + (m1.m32 * m2.m21)) + (m1.m33 * m2.m31)) + (m1.m34 * m2.offsetX), (((m1.m31 * m2.m12) + (m1.m32 * m2.m22)) + (m1.m33 * m2.m32)) + (m1.m34 * m2.offsetY), (((m1.m31 * m2.m13) + (m1.m32 * m2.m23)) + (m1.m33 * m2.m33)) + (m1.m34 * m2.offsetZ), (((m1.m31 * m2.m14) + (m1.m32 * m2.m24)) + (m1.m33 * m2.m34)) + (m1.m34 * m2.m44), (((m1.offsetX * m2.m11) + (m1.offsetY * m2.m21)) + (m1.offsetZ * m2.m31)) + (m1.m44 * m2.offsetX), (((m1.offsetX * m2.m12) + (m1.offsetY * m2.m22)) + (m1.offsetZ * m2.m32)) + (m1.m44 * m2.offsetY), (((m1.offsetX * m2.m13) + (m1.offsetY * m2.m23)) + (m1.offsetZ * m2.m33)) + (m1.m44 * m2.offsetZ), (((m1.offsetX * m2.m14) + (m1.offsetY * m2.m24)) + (m1.offsetZ * m2.m34)) + (m1.m44 * m2.m44));\n }\n}\n/** Utilities to build, combine and invert 4x4 transformation matrices ({@link Matrix3D}) in 3D space. */\nexport class Matrix3D {\n //#region notable matrices\n /**\n * Identity 4x4 matrix.\n * @returns\n */\n static identity() {\n return {\n m11: 1, m12: 0, m13: 0, m14: 0,\n m21: 0, m22: 1, m23: 0, m24: 0,\n m31: 0, m32: 0, m33: 1, m34: 0,\n offsetX: 0, offsetY: 0, offsetZ: 0, m44: 1\n };\n }\n //#endregion\n /**\n * Builds a {@link Matrix3D} from its 16 components, in row-major order.\n * @param args Exactly 16 numbers.\n * @throws If the number of arguments is not exactly 16.\n */\n static from(...args) {\n const l = 16;\n if (args.length !== l) {\n throw new RangeError(`Must provide exactly ${l} numbers`);\n }\n return {\n m11: args[0],\n m12: args[1],\n m13: args[2],\n m14: args[3],\n m21: args[4],\n m22: args[5],\n m23: args[6],\n m24: args[7],\n m31: args[8],\n m32: args[9],\n m33: args[10],\n m34: args[11],\n offsetX: args[12],\n offsetY: args[13],\n offsetZ: args[14],\n m44: args[15]\n };\n }\n /**\n * Returns the transpose of the given matrix (rows and columns swapped).\n * @param m\n */\n static transpose(m) {\n 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);\n }\n /**\n * Flattens the matrix into a 16-number array, in row-major order (the same order accepted by {@link from}).\n * @param m\n */\n static toArray(m) {\n return [m.m11, m.m12, m.m13, m.m14,\n m.m21, m.m22, m.m23, m.m24,\n m.m31, m.m32, m.m33, m.m34,\n m.offsetX, m.offsetY, m.offsetZ, m.m44];\n }\n static clone(m, modifier) {\n return typeof modifier === 'function' ? Matrix3DUtils.modify(m, modifier) : Matrix3DUtils.clone(m);\n }\n static scale(m, x, y, z) {\n if (typeof x === 'number') {\n y ??= x;\n z ??= x;\n }\n else {\n z = x.z;\n y = x.y;\n x = x.x;\n }\n return Matrix3DUtils.modify(m, s => {\n s.m11 *= x;\n s.m22 *= y;\n s.m33 *= z;\n });\n }\n /**\n * Returns a copy of the matrix translated (offset) by the given vector.\n * @param m\n * @param offset\n */\n static translate(m, offset) {\n return Matrix3DUtils.modify(m, s => {\n s.offsetX += offset.x;\n s.offsetY += offset.y;\n s.offsetZ += offset.z;\n });\n }\n /**\n * Parses a string representation of a matrix (16 numbers) into a {@link Matrix3D}.\n * @param input String to parse.\n * @throws If the input cannot be parsed as exactly 16 numbers.\n */\n static parse(input) {\n const arr = parseAsNumericalArray(input);\n if (arr && arr.length === 16) {\n return Matrix3D.from.apply(null, arr);\n }\n throw new Error(`Cannot parse \"${input}\" as a valid Matrix3D.`);\n }\n /**\n * Checks whether the matrix is the identity matrix.\n * @param m\n */\n static isIdentity(m) {\n return m.m11 == 1.0 && m.m12 == .0 && m.m13 == .0 && m.m14 == .0\n && m.m21 == .0 && m.m22 == 1.0 && m.m23 == .0 && m.m24 == .0\n && m.m31 == .0 && m.m32 == .0 && m.m33 == 1.0 && m.m34 == .0\n && m.offsetX == .0 && m.offsetY == .0 && m.offsetZ == .0 && m.m44 == 1.0;\n }\n /**\n * Checks whether the matrix represents a pure affine transform, i.e. it has no perspective\n * component (its 4th column is `(0, 0, 0, 1)`).\n * @param m\n */\n static isAffine(m) {\n return m.m14 == .0 && m.m24 == .0 && m.m34 == .0 && m.m44 == 1.0;\n }\n /**\n * Computes the determinant of the matrix.\n * @param m\n */\n static determinant(m) {\n if (Matrix3D.isIdentity(m)) {\n return 1.0;\n }\n else if (Matrix3D.isAffine(m)) {\n return m.m11 * (m.m22 * m.m33 - m.m32 * m.m23)\n - m.m12 * (m.m21 * m.m33 - m.m31 * m.m23)\n + m.m13 * (m.m21 * m.m32 - m.m31 * m.m22);\n }\n else {\n const num6 = (m.m13 * m.m24) - (m.m23 * m.m14);\n const num5 = (m.m13 * m.m34) - (m.m33 * m.m14);\n const num4 = (m.m13 * m.m44) - (m.offsetZ * m.m14);\n const num3 = (m.m23 * m.m34) - (m.m33 * m.m24);\n const num2 = (m.m23 * m.m44) - (m.offsetZ * m.m24);\n const num = (m.m33 * m.m44) - (m.offsetZ * m.m34);\n const num10 = ((m.m22 * num5) - (m.m32 * num6)) - (m.m12 * num3);\n const num9 = ((m.m12 * num2) - (m.m22 * num4)) + (m.offsetY * num6);\n const num8 = ((m.m32 * num4) - (m.offsetY * num5)) - (m.m12 * num);\n const num7 = ((m.m22 * num) - (m.m32 * num2)) + (m.offsetY * num3);\n const det = ((((m.offsetX * num10) + (m.m31 * num9)) + (m.m21 * num8)) + (m.m11 * num7));\n return det;\n }\n }\n /**\n * Multiplies two matrices in the provided order (i.e.: applies {@link m2} to {@link m1}).\n * @param matrices Matrices to apply one to the other, sequentially.\n * @returns Combination matrix.\n */\n static multiply(...matrices) {\n if (matrices.length === 0) {\n throw new ReferenceError('Matrix not provided.');\n }\n const arr = Array.from(matrices);\n let m = arr[0];\n for (let i = 1; i < arr.length; i++) {\n m = Matrix3DUtils.multiply(m, arr[i]);\n }\n return m;\n }\n /**\n * Computes the inverse of the matrix, using the cofactor/adjugate method (with a specialized,\n * cheaper path for affine matrices).\n * @param m\n * @returns The inverse matrix, or `null` if the matrix is singular (determinant is 0).\n */\n static invert(m) {\n if (Matrix3D.isAffine(m)) {\n // normalize affine invert\n const determinant = Matrix3D.determinant(m);\n if (determinant == 0.0) {\n return null;\n }\n const cofactor31 = (m.m12 * m.m23) - (m.m22 * m.m13);\n const cofactor21 = (m.m32 * m.m13) - (m.m12 * m.m33);\n const cofactor11 = (m.m22 * m.m33) - (m.m32 * m.m23);\n //\n const num20 = (m.m21 * m.m13) - (m.m11 * m.m23);\n const num19 = (m.m11 * m.m33) - (m.m31 * m.m13);\n const num18 = (m.m31 * m.m23) - (m.m21 * m.m33);\n const num7 = (m.m11 * m.m22) - (m.m21 * m.m12);\n const num6 = (m.m11 * m.m32) - (m.m31 * m.m12);\n const num5 = (m.m11 * m.offsetY) - (m.offsetX * m.m12);\n const num4 = (m.m21 * m.m32) - (m.m31 * m.m22);\n const num3 = (m.m21 * m.offsetY) - (m.offsetX * m.m22);\n const num2 = (m.m31 * m.offsetY) - (m.offsetX * m.m32);\n const num17 = ((m.m23 * num5) - (m.offsetZ * num7)) - (m.m13 * num3);\n const num16 = ((m.m13 * num2) - (m.m33 * num5)) + (m.offsetZ * num6);\n const num15 = ((m.m33 * num3) - (m.offsetZ * num4)) - (m.m23 * num2);\n const num14 = num7;\n const num13 = -num6;\n const num12 = num4;\n const invdet = 1.0 / determinant;\n return Matrix3D.from(cofactor11 * invdet, cofactor21 * invdet, cofactor31 * invdet, .0, num18 * invdet, num19 * invdet, num20 * invdet, .0, num12 * invdet, num13 * invdet, num14 * invdet, .0, num15 * invdet, num16 * invdet, num17 * invdet, 1.0);\n }\n else {\n const determinant = Matrix3D.determinant(m);\n if (determinant == 0.0) {\n return null;\n }\n const num1 = m.m33 * m.m44 - m.m34 * m.offsetZ;\n const num2 = m.m32 * m.m44 - m.m34 * m.offsetY;\n const num3 = m.m31 * m.m44 - m.m34 * m.offsetX;\n const num4 = m.m32 * m.offsetZ - m.m33 * m.offsetY;\n const num5 = m.m31 * m.offsetZ - m.m33 * m.offsetX;\n const num6 = m.m31 * m.offsetY - m.m32 * m.offsetX;\n const num7 = m.m33 * m.m44 - m.m34 * m.offsetZ;\n const num8 = m.m32 * m.m44 - m.m34 * m.offsetY;\n const num9 = m.m31 * m.m44 - m.m34 * m.offsetX;\n const num10 = m.m32 * m.offsetZ - m.m33 * m.offsetY;\n const num11 = m.m31 * m.offsetZ - m.m33 * m.offsetX;\n const num12 = m.m31 * m.offsetY - m.m32 * m.offsetX;\n const num13 = m.m23 * m.m44 - m.m24 * m.offsetZ;\n const num14 = m.m22 * m.m44 - m.m24 * m.offsetY;\n const num15 = m.m21 * m.m44 - m.m24 * m.offsetX;\n const num16 = m.m22 * m.offsetZ - m.m23 * m.offsetY;\n const num17 = m.m21 * m.offsetZ - m.m23 * m.offsetX;\n const num18 = m.m21 * m.offsetY - m.m22 * m.offsetX;\n const num19 = m.m23 * m.m34 - m.m24 * m.m33;\n const num20 = m.m22 * m.m34 - m.m24 * m.m32;\n const num21 = m.m21 * m.m34 - m.m24 * m.m31;\n const num22 = m.m22 * m.m33 - m.m23 * m.m32;\n const num23 = m.m21 * m.m33 - m.m23 * m.m31;\n const num24 = m.m21 * m.m32 - m.m22 * m.m31;\n const cofactor11 = (m.m22 * num1 - m.m23 * num2 + m.m24 * num4);\n const cofactor12 = -(m.m21 * num1 - m.m23 * num3 + m.m24 * num5);\n const cofactor13 = (m.m21 * num2 - m.m22 * num3 + m.m24 * num6);\n const cofactor14 = -(m.m21 * num4 - m.m22 * num5 + m.m23 * num6);\n const cofactor21 = -(m.m12 * num7 - m.m13 * num8 + m.m14 * num10);\n const cofactor22 = (m.m11 * num7 - m.m13 * num9 + m.m14 * num11);\n const cofactor23 = -(m.m11 * num8 - m.m12 * num9 + m.m14 * num12);\n const cofactor24 = (m.m11 * num10 - m.m12 * num11 + m.m13 * num12);\n const cofactor31 = (m.m12 * num13 - m.m13 * num14 + m.m14 * num16);\n const cofactor32 = -(m.m11 * num13 - m.m13 * num15 + m.m14 * num17);\n const cofactor33 = (m.m11 * num14 - m.m12 * num15 + m.m14 * num18);\n const cofactor34 = -(m.m11 * num16 - m.m12 * num17 + m.m13 * num18);\n const cofactor41 = -(m.m12 * num19 - m.m13 * num20 + m.m14 * num22);\n const cofactor42 = (m.m11 * num19 - m.m13 * num21 + m.m14 * num23);\n const cofactor43 = -(m.m11 * num20 - m.m12 * num21 + m.m14 * num24);\n const cofactor44 = (m.m11 * num22 - m.m12 * num23 + m.m13 * num24);\n const inverseDet = 1.0 / determinant;\n return Matrix3D.from(cofactor11 * inverseDet, cofactor21 * inverseDet, cofactor31 * inverseDet, cofactor41 * inverseDet, cofactor12 * inverseDet, cofactor22 * inverseDet, cofactor32 * inverseDet, cofactor42 * inverseDet, cofactor13 * inverseDet, cofactor23 * inverseDet, cofactor33 * inverseDet, cofactor43 * inverseDet, cofactor14 * inverseDet, cofactor24 * inverseDet, cofactor34 * inverseDet, cofactor44 * inverseDet);\n }\n }\n /**\n * Moves a given point in 3D space given the transformation matrix.\n * @param point\n * @param matrix\n */\n static transform(point, matrix) {\n var pt = { x: point.x, y: point.y, z: point.z };\n if (!Matrix3D.isIdentity(matrix)) {\n var x = pt.x;\n var y = pt.y;\n var z = pt.z;\n pt.x = (((x * matrix.m11) + (y * matrix.m21)) + (z * matrix.m31)) + matrix.offsetX;\n pt.y = (((x * matrix.m12) + (y * matrix.m22)) + (z * matrix.m32)) + matrix.offsetY;\n pt.z = (((x * matrix.m13) + (y * matrix.m23)) + (z * matrix.m33)) + matrix.offsetZ;\n if (!Matrix3D.isAffine(matrix)) {\n var num4 = (((x * matrix.m14) + (y * matrix.m24)) + (z * matrix.m34)) + matrix.m44;\n if (num4 != .0) {\n pt.x /= num4;\n pt.y /= num4;\n pt.z /= num4;\n }\n }\n }\n return pt;\n }\n}\n/** Utilities to build, combine and convert {@link Quaternion} rotations. */\nexport class Quaternion {\n /** Returns the identity quaternion (no rotation). */\n static identity() {\n return Quaternion.from(0, 0, 0, 1);\n }\n /**\n * Builds a {@link Quaternion} from its x, y, z, w components, in that order.\n * @param args Exactly 4 numbers: x, y, z, w.\n * @throws If the number of arguments is not exactly 4.\n */\n static from(...args) {\n const l = 4;\n if (args.length !== l) {\n throw new RangeError(`Must provide exactly ${l} numbers`);\n }\n return {\n x: args[0],\n y: args[1],\n z: args[2],\n w: args[3],\n };\n }\n /**\n * Parses a string representation of a quaternion (4 numbers) into a {@link Quaternion}.\n * @param input String to parse.\n * @throws If the input cannot be parsed as exactly 4 numbers.\n */\n static parse(input) {\n const arr = parseAsNumericalArray(input);\n if (arr && arr.length === 4) {\n return Quaternion.from.apply(null, arr);\n }\n throw new Error(`Cannot parse \"${input}\" as a valid Quaternion.`);\n }\n /**\n * Builds the (shortest-arc) quaternion representing the rotation that takes one unit vector onto another.\n * Normalizes both input vectors in place as a side effect.\n * @param from Source direction.\n * @param to Target direction.\n */\n static fromVectors(from, to) {\n // setup\n Vector3D.normalize(from);\n Vector3D.normalize(to);\n const yieldQ = (x, y, z, w) => {\n const retval = Quaternion.from(x, y, z, w);\n Quaternion.normalize(retval);\n return retval;\n };\n // process\n let r = Vector3D.dot(from, to) + 1;\n if (r.isCloseTo(0)) {\n if (Math.abs(from.x) > Math.abs(from.z)) {\n return yieldQ(-from.y, from.x, 0, /* r */ 0);\n }\n return yieldQ(0, -from.z, from.y, /* r */ 0);\n }\n else {\n return yieldQ(from.y * to.z - from.z * to.y, from.z * to.x - from.x * to.z, from.x * to.y - from.y * to.x, r);\n }\n }\n /**\n * In-place normalizarion of the provided quaternion\n * @param q {Quaternion}\n */\n static normalize(q) {\n const l = Quaternion.mag(q);\n if (l.isCloseTo(0)) {\n q.x = q.y = q.z = 0;\n q.w = 1;\n }\n else {\n const f = 1 / l;\n q.x *= f;\n q.y *= f;\n q.z *= f;\n q.w *= f;\n }\n }\n /**\n * Returns a normalized copy of the source quaternion.\n * @param q {Quaternion}\n */\n static unit(q) {\n const clone = Quaternion.from(q.x, q.y, q.z, q.w);\n Quaternion.normalize(clone);\n return clone;\n }\n /**\n * Creates a quaternion instance given the rotation axis and an angle (in degrees).\n * @param axis\n * @param angleDeg\n */\n static fromAxisAngle(axis, angleDeg) {\n angleDeg %= 360.0;\n var angleInRadians = DEG2RAD * angleDeg;\n var length = Vector3D.mag(axis);\n if (length == 0.0) {\n throw new RangeError('Invalid argument');\n }\n var factor = Math.sin(0.5 * angleInRadians) / length;\n var x = axis.x * factor;\n var y = axis.y * factor;\n var z = axis.z * factor;\n return Quaternion.from(x, y, z, Math.cos(.5 * angleInRadians));\n }\n /**\n * Creates a quaternion instance given the rotation matrix.\n * @param rotationMatrix\n */\n static fromRotationMatrix(rotationMatrix) {\n const trace = rotationMatrix.m11 + rotationMatrix.m22 + rotationMatrix.m33 + rotationMatrix.m44;\n if (trace > 0) {\n const sq = 0.5 / Math.sqrt(trace);\n const w = 0.25 / sq;\n const x = (rotationMatrix.m23 - rotationMatrix.m32) * sq;\n const y = (rotationMatrix.m31 - rotationMatrix.m13) * sq;\n const z = (rotationMatrix.m12 - rotationMatrix.m21) * sq;\n return Quaternion.from(x, y, z, w);\n }\n else {\n if (rotationMatrix.m11 > rotationMatrix.m22 && rotationMatrix.m11 > rotationMatrix.m22) {\n const sq = 0.5 / Math.sqrt(rotationMatrix.m44 + rotationMatrix.m11 - rotationMatrix.m22 - rotationMatrix.m33);\n const w = (rotationMatrix.m23 - rotationMatrix.m32) * sq;\n const x = 0.25 / sq;\n const y = (rotationMatrix.m12 + rotationMatrix.m21) * sq;\n const z = (rotationMatrix.m31 + rotationMatrix.m13) * sq;\n return Quaternion.from(x, y, z, w);\n }\n else if (rotationMatrix.m22 > rotationMatrix.m33) {\n const sq = .5 / Math.sqrt(rotationMatrix.m44 + rotationMatrix.m22 - rotationMatrix.m11 - rotationMatrix.m33);\n const z = (rotationMatrix.m23 + rotationMatrix.m32) * sq;\n const y = 0.25 / sq;\n const x = (rotationMatrix.m12 + rotationMatrix.m21) * sq;\n const w = (rotationMatrix.m31 - rotationMatrix.m13) * sq;\n return Quaternion.from(x, y, z, w);\n }\n else {\n const sq = .5 / Math.sqrt(rotationMatrix.m44 + rotationMatrix.m33 - rotationMatrix.m11 - rotationMatrix.m22);\n const y = (rotationMatrix.m23 + rotationMatrix.m32) * sq;\n const z = 0.25 / sq;\n const w = (rotationMatrix.m12 - rotationMatrix.m21) * sq;\n const x = (rotationMatrix.m31 - rotationMatrix.m13) * sq;\n return Quaternion.from(x, y, z, w);\n }\n }\n }\n /**\n * Returns the conjugate of the quaternion (vector part negated). For a unit quaternion, this\n * represents the inverse rotation.\n * @param q\n */\n static conjugate(q) {\n return Quaternion.from(-q.x, -q.y, -q.z, q.w);\n }\n /**\n * Returns the magnitude/length of the provided quaternion.\n * @param q {Quaternion}\n */\n static mag(q) {\n return Math.sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w);\n }\n /**\n * Returns the squared magnitude of the vector (imaginary) part of the quaternion.\n * @param q\n */\n static norm(q) {\n return (q.x * q.x + q.y * q.y + q.z * q.z);\n }\n /**\n * Returns the (unit) rotation axis represented by the quaternion, defaulting to the y axis\n * when the quaternion has no vector part (i.e. represents no rotation).\n * @param q\n */\n static axis(q) {\n if (q.x == .0 && q.y == .0 && q.z == .0) {\n return Vector3D.j();\n }\n return Vector3D.unit(q);\n }\n /**\n * Rotates a vector by the given quaternion (normalizes the quaternion in place as a side effect).\n * @param v Vector to rotate.\n * @param q Rotation quaternion.\n */\n static transform(v, q) {\n Quaternion.normalize(q);\n const cross = Vector3D.cross(q, v);\n const t = Vector3D.scale(cross, 2);\n const tCross = Vector3D.cross(q, t);\n return {\n x: v.x + q.w * t.x + tCross.x,\n y: v.y + q.w * t.y + tCross.y,\n z: v.z + q.w * t.z + tCross.z,\n };\n }\n /**\n * Returns the rotation angle (in degrees) of the provided quaternion.\n * @param q\n */\n static angle(q) {\n let y = Math.sqrt(q.x * q.x + q.y * q.y + q.z * q.z);\n let x = q.w;\n if (y > Number.MAX_VALUE) {\n const num = Math.max(Math.abs(q.x), Math.max(Math.abs(q.y), Math.abs(q.z)));\n const num5 = q.x / num;\n const num4 = q.y / num;\n const num3 = q.z / num;\n y = Math.sqrt(((num5 * num5) + (num4 * num4)) + (num3 * num3));\n x /= num;\n }\n return (Math.atan2(y, x) * 114.59155902616465);\n }\n /**\n * Builds the rotation matrix equivalent to the given quaternion.\n * @param q\n */\n static toRotationMatrix(q) {\n var m = Matrix3D.identity();\n var X = q.x;\n var Y = q.y;\n var Z = q.z;\n var W = q.w;\n m.m11 = 1.0 - 2.0 * Y * Y - 2.0 * Z * Z;\n m.m12 = 2.0 * X * Y + 2.0 * W * Z;\n m.m13 = 2.0 * X * Z - 2.0 * W * Y;\n m.m21 = 2.0 * X * Y - 2.0 * W * Z;\n m.m22 = 1.0 - 2.0 * X * X - 2.0 * Z * Z;\n m.m23 = 2.0 * Y * Z + 2.0 * W * X;\n m.m31 = 2.0 * W * Y + 2.0 * X * Z;\n m.m32 = 2.0 * Y * Z - 2.0 * W * X;\n m.m33 = 1.0 - 2.0 * X * X - 2.0 * Y * Y;\n return m;\n }\n /**\n * Returns the inverse rotation of the given quaternion (the conjugate of its normalized form).\n * @param q\n */\n static invert(q) {\n const n = Quaternion.unit(q);\n return Quaternion.conjugate(n);\n }\n /**\n * Combines two quaternions.\n * @param q1\n * @param q2\n */\n static multiply(q1, q2) {\n return Quaternion.from(q1.w * q2.x + q1.x + q2.w + q1.y * q2.z - q1.z * q2.y, q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x, q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w, q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z);\n }\n /**\n * Returns the dot product of two quaternions.\n * @param q1\n * @param q2\n */\n static dot(q1, q2) {\n var q = Quaternion.multiply(q1, Quaternion.conjugate(q2));\n return q.w;\n }\n}\n// #endregion\n//}\n", "//namespace Pacem.Geometry {\nimport { Vector3D } from './geom3d';\n//#region Utils\n/** Utility tools for 3D geometry: rays, triangles and their interactions. */\nexport class Utils3D {\n /**\n * Computes the intersection between a ray and a triangle in the 3D space - if any - using the M\u00F6ller\u2013Trumbore algorithm.\n * @param ray Array of two points identifying a ray.\n * @param triangle Array of three points identifying a triangle.\n * @returns Intersection point if any, otherwise null.\n */\n static intersect(ray, triangle) {\n // M\u00F6ller\u2013Trumbore algorithm\n const [start, end] = ray;\n const vector = Vector3D.subtract(start, end);\n const [a, b, c] = triangle;\n const ab = Vector3D.subtract(a, b);\n const ac = Vector3D.subtract(a, c);\n const cross = Vector3D.cross(vector, ac);\n const det = Vector3D.dot(ab, cross);\n if (det.isCloseTo(0)) {\n return null;\n }\n const invDet = 1 / det;\n const s = Vector3D.subtract(start, a);\n const u = invDet * Vector3D.dot(s, cross);\n if (u < 0 || u > 1) {\n return null;\n }\n const scross = Vector3D.cross(s, ab);\n const v = invDet * Vector3D.dot(vector, scross);\n if (v < 0 || (u + v) > 1) {\n return null;\n }\n const t = invDet * Vector3D.dot(ac, scross);\n if (t < 0 || t.isCloseTo(0)) {\n return null;\n }\n return Vector3D.add(start, Vector3D.scale(vector, t));\n }\n}\n//#endregion\n//}\n", "export * from './geom/linear-algebra';\nexport * from './geom/geom3d';\n", "export * from './math/complex';\nexport * as DataAnalysis from './index-mathematics-dataanalysis.js';\nexport * as NumberTheory from './math/math';\n", "// namespace Pacem.Mathematics {\nfunction complex(c) {\n if (typeof c === 'number') {\n c = { real: c, img: 0 };\n }\n return c;\n}\nvar NOT_A_COMPLEX;\nfunction buildComplex(real, img) {\n const c = {};\n Object.defineProperty(c, 'real', { value: real, writable: false });\n Object.defineProperty(c, 'img', { value: img, writable: false });\n return c;\n}\nfunction nac() {\n return NOT_A_COMPLEX || (NOT_A_COMPLEX = buildComplex(Number.NaN, Number.NaN));\n}\n/** Utility tools to build and operate on {@link Complex} numbers. */\nexport class Complex {\n static build(real, img) {\n if (this.isComplex(real)) {\n return real;\n }\n img ??= 0;\n if (typeof real != 'number' || typeof img != 'number') {\n return nac();\n }\n return buildComplex(real, img || 0);\n }\n /**\n * Adds two complex numbers (real numbers are treated as having a zero imaginary part).\n * @param a First addend.\n * @param b Second addend.\n */\n static add(a, b) {\n const ac = complex(a), bc = complex(b);\n return buildComplex(ac.real + bc.real, ac.img + bc.img);\n }\n /**\n * Subtracts one complex number from another.\n * @param from Minuend.\n * @param what Subtrahend.\n */\n static subtract(from, what) {\n const ac = complex(from), bc = complex(what);\n return buildComplex(ac.real - bc.real, ac.img - bc.img);\n }\n /**\n * Multiplies two complex numbers.\n * @param a First factor.\n * @param b Second factor.\n */\n static multiply(a, b) {\n const ac = complex(a), bc = complex(b);\n return buildComplex(\n /* real*/ ac.real * bc.real - ac.img * bc.img, \n /* img */ ac.real * bc.img + ac.img * bc.real);\n }\n /**\n * Divides one complex number by another.\n * @param a Dividend.\n * @param b Divisor.\n * @returns The quotient, or {@link Complex.NaC} if the divisor is (close to) zero.\n */\n static divide(a, b) {\n const ac = complex(a), bc = complex(b);\n const div = this.absSquare(bc).roundoff();\n if (div === 0) {\n return nac();\n }\n const inv_div = 1 / div;\n return buildComplex(\n /* real*/ inv_div * (ac.real * bc.real + ac.img * bc.img), \n /* img */ inv_div * (ac.img * bc.real - ac.real * bc.img));\n }\n /**\n * Returns the squared modulus (|z|\u00B2) of the complex number, i.e. real\u00B2 + img\u00B2.\n * Cheaper than {@link modulus} since it avoids the square root.\n * @param c\n */\n static absSquare(c) {\n const ac = complex(c);\n return Math.pow(ac.real, 2) + Math.pow(ac.img, 2);\n }\n /**\n * Returns the modulus (magnitude) of the complex number.\n * @param c\n */\n static modulus(c) {\n return Math.sqrt(this.absSquare(c));\n }\n /**\n * Type guard checking whether the provided value is a {@link Complex} number.\n * @param c\n */\n static isComplex(c) {\n return c != null && typeof c === 'object' && 'real' in c && 'img' in c && typeof c.real === 'number' && typeof c.img === 'number';\n }\n /**\n * Returns the complex conjugate: same real part, negated imaginary part.\n * @param a\n */\n static conjugate(a) {\n a = complex(a);\n return buildComplex(a.real, Math.abs(a.img) == 0 ? 0 : -a.img);\n }\n /**\n * Checks whether two complex numbers have the same real and imaginary parts.\n * @param c1\n * @param c2\n */\n static equals(c1, c2) {\n const c_1 = this.build(c1), c_2 = this.build(c2);\n if (!this.isComplex(c1) || !this.isComplex(c2)) {\n return false;\n }\n return c_1.real === c_2.real && c_1.img === c_2.img;\n }\n //static isNaN(c: Complex | number): boolean {\n // switch (c) {\n // case undefined:\n // // doh!\n // return true;\n // case null:\n // // doh!\n // return false;\n // default:\n // if (!this.isComplex( c)\n // }\n //}\n /** The \"Not a Complex\" sentinel value (`NaN + NaNi`), returned by operations on invalid input. */\n static get NaC() { return nac(); }\n}\n//}\n", "export * from './math/fourier';\nexport * from './math/gaussian';\n;\nexport * from './math/interpolation';\nexport * from './math/statistics';\n", "//namespace Pacem.Mathematics.DataAnalysis {\nimport { Complex } from './complex';\n// #region DFT utils\n/**\n * Unit circle Euler's formula\n * @param k partial 'slices'\n * @param N total 'slices'\n */\nfunction euler(k, N) {\n const x = 2 * Math.PI * k / N;\n return Complex.build(Math.cos(x), Math.sin(x));\n}\n/** Unit circle memoizer */\nconst unitCircle = {};\nfunction exp(k, N) {\n const memN = unitCircle[N] = unitCircle[N] || {};\n return memN[k] = memN[k] || euler(k, N);\n}\n// #endregion\nfunction isPowerOfTwo(length) {\n return length > 0 && (length & (length - 1)) === 0;\n}\n/** Cooley-Tukey */\nfunction fftRec(data) {\n const retval = [], N = data.length;\n if (N === 1) {\n return [Complex.build(data[0])];\n }\n // even/odds recursion\n const retval_2n = fftRec(data.filter((_, i) => i % 2 === 0)), retval_2n1 = fftRec(data.filter((_, i) => i % 2 === 1));\n for (var k = 0; k < N / 2; k++) {\n const t = retval_2n[k], e = Complex.multiply(exp(k, N), retval_2n1[k]);\n retval[k] = Complex.add(t, e);\n retval[k + (N / 2)] = Complex.subtract(t, e);\n }\n return retval;\n}\n/** Discrete Fourier Transform (DFT) utilities, including a Cooley-Tukey FFT fast path for power-of-two inputs. */\nexport class Fourier {\n /**\n * Checks the input vector and outputs a frequency vector using the best performing algo.\n * @param data Input vector of any size\n * @param normalize Whether to normalize the signal or not (default true)\n */\n static transform(data, normalize = true) {\n data = data || [];\n if (isPowerOfTwo(data.length)) {\n return this.fft(data, normalize);\n }\n return this.dft(data, normalize);\n }\n /**\n * Checks the input vector and applies inverted fourier transform's best performing algo.\n * @param data Input frequency vector\n */\n static invert(data, normalize = true) {\n return this.idft(data || [], normalize);\n }\n /**\n * Naive Discrete Fourier Transform implementation (O(n^2) algo).\n * @param data Input vector of any size\n * @param normalize Whether to normalize the signal or not (default true)\n */\n static dft(data, normalize = true) {\n const N = (data || [])?.length, DEN = normalize ? 1 / Math.sqrt(N) : 1, retval = [];\n for (let k = 0; k < N; k++) {\n retval.push({ real: 0, img: 0 });\n for (let j = 0; j < N; j++) {\n const e = exp(k * j, N), item = Complex.multiply(data[j], e), itemN = Complex.multiply(item, DEN);\n retval[k] = Complex.add(retval[k], itemN);\n }\n }\n return retval;\n }\n /**\n * Inverse Discrete Fourier Transform.\n * @param data Input vector data of any size\n */\n static idft(data, normalize = true) {\n const reversed = data.map(i => Complex.build(i.img, i.real)), temp = this.transform(reversed, normalize);\n return temp.map(c => Complex.build(c.img, c.real));\n }\n /**\n * FFT processing using Cooley-Tukey.\n * @param data Input vector (size MUST be power of 2)\n */\n static fft(data, normalize = true) {\n const retval = fftRec(data);\n if (!normalize) {\n return retval;\n }\n const DEN = 1 / Math.sqrt(data.length);\n return retval.map(i => Complex.multiply(i, DEN));\n }\n}\n//}\n", "//namespace Pacem.Mathematics.DataAnalysis {\nconst SQRT_PI = Math.sqrt(Math.PI);\n/**\n * Complementary Error Function as seen on Numerical Recipes in C (p.221).\n * @param x Input\n */\nfunction erfc(x) {\n const z = Math.abs(x);\n const t = 1.0 / (1.0 + 0.5 * z);\n const ans = t * Math.exp(-z * z - 1.26551223 + t * (1.00002368 + t * (0.37409196 + t * (0.09678418 +\n t * (-0.18628806 + t * (0.27886807 + t * (-1.13520398 + t * (1.48851587 +\n t * (-0.82215223 + t * 0.17087277)))))))));\n return x >= 0.0 ? ans : 2.0 - ans;\n}\n/**\n * Error Function.\n * @param x\n */\nfunction erf(x) {\n return 1 - erfc(x);\n}\n/** Represents a Gaussian (normal) distribution and exposes its density and cumulative probability functions. */\nexport class Gaussian {\n /**\n * Creates a new {@link Gaussian} distribution with the given mean and standard deviation.\n * @param mean Mean (\u03BC) of the distribution.\n * @param stdev Standard deviation (\u03C3) of the distribution (its absolute value is used).\n */\n constructor(mean, stdev) {\n this.mean = mean;\n this.stdev = Math.abs(stdev);\n this.variance = Math.pow(stdev, 2);\n }\n /** The standard normal distribution (mean 0, standard deviation 1). */\n static get normal() {\n return _normal;\n }\n /**\n * Un-normalized probability density function.\n * Can be useful as a weight function without requiring the integral w(x)dx to be 1.\n * @param x Input value\n */\n weight(x) {\n // e^(.5 *(-Z^2))\n return Math.exp(-0.5 * Math.pow(this._z(x), 2));\n }\n /**\n * Probability density function (PDF).\n * @param x Input value\n */\n probabilityDensity(x) {\n // 1/(\u03C3 \u221A2\u03C0) * e^(.5 *(-Z^2))\n const inv_coeff = this.stdev * Math.SQRT2 * SQRT_PI, exp_part = this.weight(x);\n return exp_part / inv_coeff;\n }\n _z(x) {\n // Z = (x - \u03BC)/\u03C3\n return (x - this.mean) / this.stdev;\n }\n /**\n * Returns the area under the PDF from -\u221E to x\n * @param x Input value\n */\n probability(x) {\n return 0.5 * erfc(-this._z(x) / Math.SQRT2);\n }\n}\nconst _normal = new Gaussian(0, 1);\n//}\n", "/**\n * Lagrange polynomial interpolation, evaluated using the numerically stable barycentric form.\n * Given a set of `(x, y)` points, builds the unique polynomial of minimal degree passing through\n * all of them and evaluates it at arbitrary x values.\n */\nexport class Lagrange {\n /** Use {@link Lagrange.create} to build an instance. */\n constructor(points) {\n this.#set = points;\n }\n #set;\n #weights = null;\n _prepareBarycentric() {\n if (this.#weights) {\n return;\n }\n const points = this.#set || [];\n const n = points.length;\n if (n === 0) {\n this.#weights = [];\n return;\n }\n // Compute barycentric weights in a numerically stable way.\n // Direct product of differences can overflow/underflow for large n.\n // We compute log-weights and normalize by subtracting the max log to\n // keep values in a reasonable range (scaling cancels out in evaluation).\n const logs = new Array(n);\n const signs = new Array(n);\n for (let j = 0; j < n; j++) {\n let sumLog = 0;\n let sign = 1;\n const xj = points[j].x;\n for (let m = 0; m < n; m++) {\n if (m === j)\n continue;\n const diff = xj - points[m].x;\n if (diff === 0) {\n throw new Error('Invalid function provided.');\n }\n if (diff < 0)\n sign = -sign;\n sumLog += Math.log(Math.abs(diff));\n }\n // log of weight is -sumLog\n logs[j] = -sumLog;\n signs[j] = sign;\n }\n // normalize logs to avoid underflow/overflow when exponentiating\n let maxLog = logs[0];\n for (let j = 1; j < n; j++) {\n if (logs[j] > maxLog)\n maxLog = logs[j];\n }\n const w = new Array(n);\n for (let j = 0; j < n; j++) {\n // scaled weight: sign * exp(log - maxLog)\n const scaled = Math.exp(logs[j] - maxLog);\n w[j] = signs[j] * scaled;\n }\n this.#weights = w;\n }\n _computeBarycentric(x) {\n const points = this.#set || [];\n if (!this.#weights) {\n this._prepareBarycentric();\n }\n const w = this.#weights || [];\n let numerator = 0;\n let denominator = 0;\n for (let j = 0; j < points.length; j++) {\n const xj = points[j].x;\n if (x === xj) {\n return points[j].y;\n }\n const temp = w[j] / (x - xj);\n numerator += temp * points[j].y;\n denominator += temp;\n }\n return numerator / denominator;\n }\n // Iterative/global Lagrange computation removed \u2014 barycentric is used\n // exclusively for interpolation.\n /**\n * Evaluates the Lagrange interpolating polynomial at the given x, using barycentric weights.\n * @param x Input value.\n * @returns The interpolated y value (the exact node y if x coincides with a node).\n */\n interpolate(x) {\n return this._computeBarycentric(x);\n }\n static create(...values) {\n var array = [];\n if (arguments.length > 0 && Array.isArray(arguments[0])) {\n array = arguments[0];\n }\n else {\n array = Array.from(values);\n }\n const points = array.map((y, x) => { return typeof y === 'number' ? { x, y } : y; });\n return new Lagrange(points);\n }\n}\n/**\n * @deprecated Use Lagrange instead. This alias is kept for backward compatibility.\n */\nexport const Lagrangian = {\n create: Lagrange.create\n};\n/**\n * Piecewise Cubic Hermite Interpolating Polynomial (PCHIP).\n * Builds a shape-preserving (monotonicity-respecting) piecewise-cubic curve through a set of\n * `(x, y)` points: unlike {@link Lagrange}, it does not overshoot between nodes, at the cost of\n * only being C\u00B9 (continuous first derivative, not second).\n */\nexport class Pchip {\n /** Use {@link Pchip.create} to build an instance. */\n constructor(points) {\n if (!points || points.length < 2)\n throw new Error('Need at least 2 points');\n const pts = points.slice().sort((a, b) => a.x - b.x);\n this.xs = pts.map(p => p.x);\n this.ys = pts.map(p => p.y);\n this.ms = this.computeDerivatives();\n }\n computeDerivatives() {\n const n = this.xs.length;\n const h = new Array(n - 1);\n const delta = new Array(n - 1);\n for (let i = 0; i < n - 1; i++) {\n h[i] = this.xs[i + 1] - this.xs[i];\n delta[i] = (this.ys[i + 1] - this.ys[i]) / h[i];\n }\n const m = new Array(n).fill(0);\n // endpoints: use one-sided slope\n m[0] = delta[0];\n m[n - 1] = delta[n - 2];\n // interior: weighted harmonic mean (PCHIP)\n for (let i = 1; i < n - 1; i++) {\n const d1 = delta[i - 1], d2 = delta[i];\n if (d1 === 0 || d2 === 0 || d1 * d2 <= 0) {\n m[i] = 0;\n }\n else {\n const w1 = 2 * h[i] + h[i - 1];\n const w2 = h[i] + 2 * h[i - 1];\n m[i] = (w1 + w2) / ((w1 / d1) + (w2 / d2));\n }\n }\n // (Optional) limit derivative to avoid overshoot: monotonicity constraints\n for (let i = 0; i < n - 1; i++) {\n if (delta[i] === 0) {\n m[i] = 0;\n m[i + 1] = 0;\n }\n else {\n const a = m[i] / delta[i];\n const b = m[i + 1] / delta[i];\n const s = a * a + b * b;\n if (s > 9) { // limit size, algorithm from Fritsch-Carlson/PCHIP\n const tau = 3 / Math.sqrt(s);\n m[i] = tau * a * delta[i];\n m[i + 1] = tau * b * delta[i];\n }\n }\n }\n return m;\n }\n /**\n * Evaluates the PCHIP curve at the given x, using cubic Hermite interpolation on the enclosing segment.\n * Values outside the node range are linearly extrapolated using the boundary derivative.\n * @param x Input value.\n * @returns The interpolated y value.\n */\n interpolate(x) {\n const xs = this.xs, ys = this.ys, ms = this.ms;\n const n = xs.length;\n // quick bounds\n if (x <= xs[0]) {\n // avoid dangerous extrapolation: use linear extension or return ys[0]\n const slope = ms[0];\n return ys[0] + slope * (x - xs[0]);\n }\n if (x >= xs[n - 1]) {\n const slope = ms[n - 1];\n return ys[n - 1] + slope * (x - xs[n - 1]);\n }\n // locate interval\n let i = 0, j = n - 1;\n while (j - i > 1) {\n const mid = (i + j) >> 1;\n if (xs[mid] <= x)\n i = mid;\n else\n j = mid;\n }\n const h = xs[i + 1] - xs[i];\n const t = (x - xs[i]) / h;\n const t2 = t * t, t3 = t2 * t;\n // Hermite basis\n const h00 = 2 * t3 - 3 * t2 + 1;\n const h10 = t3 - 2 * t2 + t;\n const h01 = -2 * t3 + 3 * t2;\n const h11 = t3 - t2;\n return h00 * ys[i] + h10 * (ms[i] * h) + h01 * ys[i + 1] + h11 * (ms[i + 1] * h);\n }\n static create(...values) {\n var array = [];\n if (arguments.length > 0 && Array.isArray(arguments[0])) {\n array = arguments[0];\n }\n else {\n array = Array.from(values);\n }\n const points = array.map((y, x) => { return typeof y === 'number' ? { x, y } : y; });\n return new Pchip(points);\n }\n}\n/**\n * Newton's divided-difference polynomial interpolation.\n * Builds the same interpolating polynomial as {@link Lagrange} but represents it in Newton form\n * (a nested/Horner-like product of divided differences), which is efficient to evaluate and to\n * extend incrementally as new points are added.\n */\nexport class Newton {\n /** Use {@link Newton.create} to build an instance. */\n constructor(points) {\n if (!points || points.length === 0)\n throw new Error('Need at least 1 point');\n const pts = points.slice().sort((a, b) => a.x - b.x);\n this.xs = pts.map(p => p.x);\n const n = pts.length;\n // copy y values into coefficients array and convert in-place to divided differences\n const a = pts.map(p => p.y);\n for (let j = 1; j < n; j++) {\n for (let i = n - 1; i >= j; i--) {\n const denom = this.xs[i] - this.xs[i - j];\n if (denom === 0)\n throw new Error('Invalid function provided.');\n a[i] = (a[i] - a[i - 1]) / denom;\n }\n }\n this.coeffs = a;\n }\n /**\n * Evaluates the Newton form of the interpolating polynomial at the given x, via nested multiplication.\n * @param x Input value.\n * @returns The interpolated y value (`NaN` if the interpolator has no points).\n */\n interpolate(x) {\n const xs = this.xs, a = this.coeffs;\n const n = a.length;\n if (n === 0)\n return NaN;\n // evaluate Newton form with nested multiplication (Horner-like)\n let result = a[n - 1];\n for (let i = n - 2; i >= 0; i--) {\n result = result * (x - xs[i]) + a[i];\n }\n return result;\n }\n static create(...values) {\n var array = [];\n if (arguments.length > 0 && Array.isArray(arguments[0])) {\n array = arguments[0];\n }\n else {\n array = Array.from(values);\n }\n const points = array.map((y, x) => { return typeof y === 'number' ? { x, y } : y; });\n return new Newton(points);\n }\n}\n//}\n", "import { Gaussian } from './gaussian';\nconst selfSelector = (i, _) => i;\nfunction mode(set, selector = selfSelector) {\n const groups = Object.groupBy(set, selector);\n let key, max = 0;\n for (let group in groups) {\n const l = groups[group].length;\n if (l > max) {\n key = parseInt(group);\n max = l;\n }\n }\n return key;\n}\nfunction median(set, selector = selfSelector) {\n const setCopy = set.slice(0), length = setCopy.length;\n setCopy.sort((a, b) => {\n const i = selector(a), j = selector(b);\n return i - j;\n });\n const index = Math.ceil(setCopy.length / 2) - 1;\n if (length % 2 == 1) {\n return setCopy[index];\n }\n return .5 * (setCopy[index + 1] + setCopy[index]);\n}\nfunction sum(set, selector = selfSelector) {\n return set.reduce((p, c, i) => p + selector(c, i), 0);\n}\nfunction mean(set, selector = selfSelector) {\n return sum(set, selector) / set.length;\n}\nfunction variance(set, selector = selfSelector, bessel = false) {\n const avg = mean(set, selector);\n return set.reduce((p, c) => Math.pow(c - avg, 2) + p, 0) / (set.length - (bessel ? 1 : 0));\n}\nfunction stdev(set, selector = selfSelector, bessel = false) {\n const v = variance(set, selector, bessel);\n return Math.sqrt(v);\n}\nfunction correlation(set, arg2, selector1 = selfSelector, selector2 = selfSelector) {\n const twoArrays = Array.isArray(arg2);\n if (twoArrays && arg2.length !== set.length) {\n throw new Error('Sets must be of the same length.');\n }\n const length = set.length;\n const setX = set, setY = twoArrays ? arg2 : set;\n const selectorX = twoArrays ? selector1 : arg2;\n const selectorY = twoArrays ? selector2 : selector1;\n const meanX = mean(setX, selectorX);\n const meanY = mean(setY, selectorY);\n let accNum = 0;\n let accDenXSq = 0;\n let accDenYSq = 0;\n for (let i = 0; i < length; i++) {\n const itemX = setX[i], itemY = setY[i];\n const a = selectorX(itemX, i) - meanX;\n const b = selectorY(itemY, i) - meanY;\n accNum += (a * b);\n accDenXSq += (a * a);\n accDenYSq += (b * b);\n }\n return accNum / Math.sqrt(accDenXSq * accDenYSq);\n}\nfunction linearRegression(set, arg2, selector1 = selfSelector, selector2 = selfSelector) {\n const twoArrays = Array.isArray(arg2);\n if (twoArrays && arg2.length !== set.length) {\n throw new Error('Sets must be of the same length.');\n }\n const setX = set, setY = twoArrays ? arg2 : set;\n const selectorX0 = twoArrays ? selector1 : arg2;\n const selectorY0 = twoArrays ? selector2 : selectorX0;\n const selectorX = selectorX0 ?? (p => p.x);\n const selectorY = selectorY0 ?? (p => p.y);\n const length = set.length;\n let xyAcc = 0, xAcc = 0, yAcc = 0, x2Acc = 0, y2Acc = 0;\n for (let i = 0; i < length; i++) {\n const itemX = setX[i], itemY = setY[i];\n const x = selectorX(itemX, i);\n const y = selectorY(itemY, i);\n xyAcc += x * y;\n xAcc += x;\n yAcc += y;\n x2Acc += x * x;\n y2Acc += y * y;\n }\n const m = (length * xyAcc - xAcc * yAcc) / (length * x2Acc - Math.pow(xAcc, 2));\n const q = (yAcc - m * xAcc) / length;\n return [m, q];\n}\n/** Utility tools about statistics, probability, data analysis... */\nexport class Utils {\n static sum(set, selector) {\n return sum(set, selector);\n }\n static mean(set, selector) {\n return mean(set, selector);\n }\n static median(set, selector) {\n return median(set, selector);\n }\n static mode(set, selector) {\n return mode(set, selector);\n }\n static var(set, selector) {\n return variance(set, selector, true);\n }\n static varp(set, selector) {\n return variance(set, selector, false);\n }\n static stdevp(set, selector) {\n return stdev(set, selector, false);\n }\n static stdev(set, selector) {\n return stdev(set, selector, true);\n }\n static correlation(set, arg2, selector1, selector2) {\n return correlation(set, arg2, selector1, selector2);\n }\n static linearRegression(set, arg2, selector1, selector2) {\n return linearRegression(set, arg2, selector1, selector2);\n }\n // restart from here: https://en.wikipedia.org/wiki/Multivariate_statistics#Multivariate_analysis\n /**\n * Returns a set of utilities for gaussian distribution computations.\n * @param mean\n * @param stdev\n */\n static gaussian(mean, stdev) {\n return new Gaussian(mean, stdev);\n }\n}\nfunction searchFnFactory(minAssigner, maxAssigner) {\n const fn = (left, right, f, tolerance) => {\n let min = left;\n let max = right;\n let x1 = minAssigner(min, max);\n let x2 = maxAssigner(min, max);\n let f1 = f(x1);\n let f2 = f(x2);\n while ((max - min) > tolerance) {\n if (f1 < f2) {\n max = x2;\n x2 = x1;\n f2 = f1;\n x1 = minAssigner(min, max);\n f1 = f(x1);\n }\n else {\n min = x1;\n x1 = x2;\n f1 = f2;\n x2 = maxAssigner(min, max);\n f2 = f(x2);\n }\n }\n return .5 * (x1 + x2);\n };\n return fn;\n}\nconst DEFAULT_TOLERANCE = 1e-3;\n/**\n * Weight function based on golden ratio.\n */\nconst goldenRatioSearch = (left, right, weight, tolerance = DEFAULT_TOLERANCE) => {\n const phi = 1.618;\n const minAssigner = (min, max) => max - (max - min) / phi;\n const maxAssigner = (min, max) => min + (max - min) / phi;\n const fn = searchFnFactory(minAssigner, maxAssigner);\n return fn(left, right, weight, tolerance);\n};\nfunction linearSearch(segments) {\n if (segments <= 1) {\n throw new RangeError(\"segments must be a number grater than 1.\");\n }\n return (left, right, weight, tolerance = DEFAULT_TOLERANCE) => {\n const minAssigner = (min, max) => min + (max - min) / segments;\n const maxAssigner = (min, max) => max - (max - min) / segments;\n const fn = searchFnFactory(minAssigner, maxAssigner);\n return fn(left, right, weight, tolerance);\n };\n}\nconst gaussianSearch = (left, right, weight, tolerance = DEFAULT_TOLERANCE) => {\n var sigma0 = null;\n var length0 = null;\n const computeSigma = (min, max) => {\n length0 ??= (max - min);\n sigma0 ??= length0 / Math.sqrt(12);\n return sigma0 * (max - min) / length0;\n };\n const minAssigner = (min, max) => Math.max(min, (max + min) / 2 - computeSigma(min, max));\n const maxAssigner = (min, max) => Math.min(max, (max + min) / 2 + computeSigma(min, max));\n const fn = searchFnFactory(minAssigner, maxAssigner);\n return fn(left, right, weight, tolerance);\n};\n/** Ready-made {@link SearchFunction} implementations for unimodal minimum-search over an interval. */\nexport const SearchFunctions = {\n /**\n * Creates a linear search function.\n * @param segments How many segments to split the range into.\n */\n linear: (segments = 2) => linearSearch(segments),\n /** Golden section search function. */\n goldenRatio: goldenRatioSearch,\n /** Gaussian search function. */\n gaussian: gaussianSearch,\n};\n//}\n", "import { Numbers, NullChecker } from '@pacem/pacem-foundation';\n//namespace Pacem.Mathematics.NumberTheory {\nconst ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz';\nconst OUT_OF_RANGE = `Radix out of range: possible values go between positive 1 exclusive and ${ALPHABET.length} inclusive`;\n/** Utility tools about number theory, 'diophantine' stuff... */\nexport class Utils {\n /**\n * Computes the least common multiple (LCM) of the given numbers (each rounded to the nearest integer).\n * @param args Two or more numbers.\n * @returns The least common multiple.\n * @throws If fewer than two numbers are provided.\n */\n static lcd(...args) {\n if (NullChecker.isNullOrEmpty(args) || args.length <= 1) {\n throw 'Insufficient set of numbers.';\n }\n function ex9(x, y) {\n if (!y)\n return y === 0 ? x : NaN;\n return ex9(y, x % y);\n }\n function ex10(x, y) {\n return x * y / ex9(x, y);\n }\n let result = Math.round(args[0]);\n for (let j = 1; j < args.length; j++) {\n result = ex10(result, Math.round(args[j]));\n }\n return result;\n }\n /**\n * Computes the greatest common divisor (GCD) of two numbers (each rounded to the nearest integer)\n * using the Euclidean algorithm.\n * @param a\n * @param b\n */\n static gcd(a, b) {\n // force integers\n a = Math.round(a),\n b = Math.round(b);\n if (a === 0) {\n return b;\n }\n return Utils.gcd(b % a, a);\n }\n /**\n * Converts an integer value from one numeric base (radix) to another.\n * @param v Value to convert, in the source radix.\n * @param from Source radix.\n * @param to Target radix.\n * @returns The value re-expressed in the target radix, as a string.\n */\n static rebaseInt(v, from, to) {\n return Numbers.rebase(v, from, to);\n }\n /**\n * Converts a (possibly fractional) numeric value from one radix to another, dispatching to the\n * appropriate specialized conversion routine depending on whether base-10 is the source, the\n * target, or neither.\n * @param v Value to convert, in the source radix.\n * @param fromRadix Source radix.\n * @param toRadix Target radix.\n * @param precision Maximum number of digits to compute for the fractional part (default 12).\n * @returns The converted value: a number when converting to base 10, otherwise a string.\n */\n static rebaseFloat(v, fromRadix, toRadix, precision = 12) {\n const from10 = Utils.rebaseFloat10ToN, to10 = Utils.rebaseFloatNTo10;\n if (fromRadix === 10) {\n const vFloat = parseFloat(v.toString());\n if (toRadix % 1 === 0) {\n return Utils.rebaseFloat10ToNIntBase(vFloat, toRadix, precision);\n }\n return from10(vFloat, toRadix, precision);\n }\n if (toRadix === 10) {\n return to10(v.toString(), fromRadix, precision);\n }\n const _10 = to10(v.toString(), fromRadix, precision + 1);\n return from10(_10, toRadix, precision);\n }\n /**\n * Converts a numeric string expressed in the given radix into its base-10 (decimal) value.\n * @param v Value to convert, expressed in the source radix (digits from `0-9a-z`).\n * @param radix Source radix (must be greater than 1 and no larger than the size of the digit alphabet).\n * @param precision Unused for the integer part; reserved for symmetry with the sibling conversion methods.\n * @returns The base-10 numeric value, or `NaN` if the input contains invalid digits.\n * @throws If radix is out of range.\n */\n static rebaseFloatNTo10(v, radix, precision = 12) {\n const alphabet = ALPHABET;\n if (radix <= 1 || radix > alphabet.length) {\n throw new Error(OUT_OF_RANGE);\n }\n const vs = (v ?? '0').toString().toLowerCase(), nan = Number.NaN;\n if (vs === '0') {\n return 0;\n }\n const arr = /^([-+]?) *([\\da-z]+)?(.[\\da-z]+)?$/.exec(vs);\n if (arr.length < 2) {\n return nan;\n }\n const sign = arr[1] === '-' ? -1 : 1, int = arr[2] || '0', frac = arr[3] || '.0';\n let retval = 0, cursor = 0;\n for (let digit of (int + frac.substr(1))) {\n const num = alphabet.indexOf(digit);\n if (num === -1 || num >= radix) {\n return nan;\n }\n retval += num * Math.pow(radix, int.length - cursor - 1);\n cursor++;\n }\n return sign * retval;\n }\n /**\n * Converts a base-10 number into its representation in another **integer** radix.\n * @param v Base-10 value to convert.\n * @param radix Target integer radix (must be greater than 1 and no larger than the size of the digit alphabet).\n * @param precision Maximum number of digits to compute for the fractional part (default 12).\n * @returns The value re-expressed in the target radix, as a string.\n * @throws If radix is out of range.\n */\n static rebaseFloat10ToNIntBase(v, radix, precision = 12) {\n const alphabet = ALPHABET;\n if (radix <= 1 || radix > alphabet.length) {\n throw new Error(OUT_OF_RANGE);\n }\n const to = radix;\n let value = Math.abs(v ?? 0);\n if (value === 0 || Number.isNaN(value)) {\n return v.toString();\n }\n let decimals = (value % 1).roundoff();\n let output = '';\n // loop\n do {\n // std\n let div = value / to /* do not roundoff: e.g. 35.99999999999986 / 36 rounds off to 1 */;\n let divFloor = Math.floor(div);\n let mod = (value - divFloor * to).roundoff();\n let intPart = Math.floor(mod);\n if (intPart >= alphabet.length) {\n output = `[${intPart}]` + output;\n }\n else {\n output = alphabet[intPart] + output;\n }\n if (divFloor <= 0) {\n break;\n }\n value = divFloor;\n } while (true);\n output = output.replace(/^0+/, '');\n output ||= '0';\n if (decimals === 0) {\n return output;\n }\n let rebasedFrac = '';\n // loop (same)\n // TODO: tidy up code.\n do {\n value = (decimals * to).roundoff();\n const intPart = Math.floor(value), remainder = (value - intPart).roundoff();\n if (intPart >= alphabet.length) {\n rebasedFrac = `[${intPart}]`;\n }\n else {\n rebasedFrac += alphabet[intPart];\n }\n decimals = remainder;\n } while (!decimals.isCloseTo(0) && rebasedFrac.length < precision);\n if (/^0*$/.test(rebasedFrac)) {\n return output;\n }\n return (Math.sign(v) < 0 ? '-' : '') + output + '.' + rebasedFrac.replace(/0+$/, '');\n }\n /**\n * Converts a base-10 number into its representation in another (possibly non-integer) radix.\n * @param v Base-10 value to convert.\n * @param radix Target radix, possibly fractional (must be greater than 1 and no larger than the size of the digit alphabet).\n * @param precision Maximum number of digits to compute for the fractional part (default 12).\n * @returns The value re-expressed in the target radix, as a string.\n * @throws If radix is out of range.\n */\n static rebaseFloat10ToN(v, radix, precision = 12) {\n const alphabet = ALPHABET;\n if (radix <= 1 || radix > alphabet.length) {\n throw new Error(OUT_OF_RANGE);\n }\n const to = radix;\n let value = Math.abs(v ?? 0);\n if (value === 0 || Number.isNaN(value)) {\n return v.toString();\n }\n let sign = Math.sign(v) < 0 ? '-' : '';\n let int = [];\n let dec = [];\n for (let j = 0; j < 20; j++) {\n int.push('0');\n dec.push('0');\n }\n const maxIndex = to % 1 === 0 ? to : Math.ceil(to);\n function add(integers, j /* cellIndex */, digitIndex) {\n const output = integers ? int : dec;\n const current = output[j] = output[j] || '0';\n const index = alphabet.indexOf(current) + digitIndex, tgetIndex = index % maxIndex, carryIndex = Math.floor(index / maxIndex);\n output[j] = alphabet[tgetIndex];\n if (carryIndex > 0) {\n if (integers) {\n // integers\n add(integers, j + 1, carryIndex);\n }\n else {\n // fractionals\n if (j === 0) {\n // carry on integers\n add(true, 0, carryIndex);\n }\n else {\n add(false, j - 1, carryIndex);\n }\n }\n }\n return carryIndex;\n }\n let step = 0;\n do {\n const magnitude = Math.floor(Numbers.log(value, to));\n const isInteger = magnitude >= 0;\n const absMagnitude = isInteger ? magnitude : Math.abs(1 + magnitude);\n add(isInteger, absMagnitude, 1);\n value = (value - Math.pow(to, magnitude).roundoff()).roundoff();\n if (!isInteger) {\n step++;\n }\n if (value === 0 || step >= 100) {\n const integer = sign + (int.reverse().map(i => i || '0').join('').replace(/^0+/, '') || '0'), fractional = dec.map(i => i || '0').join('').substr(0, precision).replace(/0+$/, '');\n if (/^0*$/.test(fractional)) {\n return integer;\n }\n return integer + '.' + fractional;\n }\n } while (true);\n }\n}\n//}\n"],
4
+ "sourcesContent": ["export * from './geom/geom';\nexport * from './geom/polygon';\nexport * from './geom/util3d';\nimport * as LinearAlgebra from './index-geometry-linearalgebra';\nexport { LinearAlgebra };\n", "import { Point, Rect, NullChecker } from '@pacem/pacem-foundation';\nimport { Vector } from './linear-algebra';\nimport { Delaunay } from './algorithms/delaunay';\nconst RAD2DEG = 180.0 / Math.PI;\nconst RAD_ROUND = 2 * Math.PI;\nconst PRECISION = 12; // default epsilon 1e-12 checking proximity (not used for roundoffs)\n;\nfunction isPoint(p) {\n return Point.isPoint(p);\n}\nfunction isSegment(s) {\n return s != null && Array.isArray(s) && s.length === 2\n && isPoint(s[0]) && isPoint(s[1]);\n}\n/** Utility tools for 2D geometry: points, segments, polygons and their interactions. */\nexport class Utils {\n /**\n * Computes the slope (in radians) of the segment joining two points.\n * @param p1 Point 1\n * @param p2 Point 2\n */\n static slopeRad(p1, p2) {\n return Math.atan2(p2.y - p1.y, p2.x - p1.x);\n }\n /**\n * Computes the slope (in radians) of the segment joining two points and returns a strictly positive value (0 to 2*pi).\n * @param p1 Point 1\n * @param p2 Point 2\n */\n static slopeRad2(p1, p2) {\n return (RAD_ROUND + Utils.slopeRad(p1, p2)) % RAD_ROUND;\n }\n /**\n * Computes the slope (in degrees) of the segment joining two points.\n * @param p1 Point 1\n * @param p2 Point 2\n */\n static slopeDeg(p1, p2) {\n return Utils.slopeRad(p1, p2) * RAD2DEG;\n }\n /**\n * Computes the slope (in degrees) of the segment joining two points and returns a strictly positive value (0 to 360).\n * @param p1 Point 1\n * @param p2 Point 2\n */\n static slopeDeg2(p1, p2) {\n return (360 + Utils.slopeDeg(p1, p2)) % 360;\n }\n static intersect(arg1, arg2, ...args) {\n if (Array.isArray(arg1) && Array.isArray(arg2)) {\n return Utils._intersectSegments(arg1, arg2, true);\n }\n else if (Rect.isRect(arg1)) {\n return Utils._intersectRects(...arguments);\n }\n else if ('vertices' in arg1) {\n return Utils._mergePolygons(arg1, arg2, 'intersect')?.polygons ?? null;\n }\n else {\n return null;\n }\n }\n /**\n * Computes the axis-aligned bounding box of a set of points.\n * @param vertices Points to enclose.\n * @returns The smallest rect containing all provided points.\n */\n static boundingBox(vertices) {\n let xmin = Number.MAX_VALUE, ymin = Number.MAX_VALUE, xmax = -Number.MAX_VALUE, ymax = -Number.MAX_VALUE;\n const l = vertices.length;\n for (let v of vertices) {\n xmin = Math.min(xmin, v.x);\n ymin = Math.min(ymin, v.y);\n xmax = Math.max(xmax, v.x);\n ymax = Math.max(ymax, v.y);\n }\n return { x: xmin, y: ymin, width: xmax - xmin, height: ymax - ymin };\n }\n /**\n * Combines two polygons using a boolean set operator (union, intersection or difference).\n * Internally triangulates the merged vertex set (via {@link mesh}) and filters the resulting\n * triangles by whether their barycenter falls inside either source polygon.\n * @param polygon1 First polygon.\n * @param polygon2 Second polygon.\n * @param operator Boolean operator to apply.\n * @returns The resulting polygon(s), plus the underlying triangulation mesh and triangles used to compute them; or `null` if the operation yields no polygon.\n */\n static combinePolygons(polygon1, polygon2, operator) {\n return Utils._mergePolygons(polygon1, polygon2, operator);\n }\n static _mergePolygons(polygon1, polygon2, operator) {\n if (NullChecker.isNullOrEmpty(polygon1?.vertices) || NullChecker.isNullOrEmpty(polygon2?.vertices)) {\n return null;\n }\n // look for sudden exit\n // 2 contains 1\n const contained1 = polygon1.vertices.filter(v => Utils.inPolygon(v, polygon2.vertices));\n if (polygon1.vertices.length == contained1.length) {\n return {\n polygons: operator === 'intersect' ? [polygon1] : /* hole in difference */ [polygon2]\n };\n }\n // 1 contains 2\n const contained2 = polygon2.vertices.filter(v => Utils.inPolygon(v, polygon1.vertices));\n if (polygon2.vertices.length === contained2.length) {\n return {\n polygons: operator === 'intersect' ? [polygon2] : /* hole in difference */ [polygon1]\n };\n }\n // bboxes do not intersect\n const bbox1 = Utils.boundingBox(polygon1.vertices), bbox2 = Utils.boundingBox(polygon2.vertices);\n const rect = Utils.intersect(bbox1, bbox2);\n if (operator !== 'union' && (!Rect.isRect(rect) || !(rect.width > 0) || !(rect.height > 0))) {\n return null; // { polygons: [] };\n }\n const { vertices: vertices1 } = polygon1, { vertices: vertices2 } = polygon2;\n if (vertices1.length < 3 || vertices2.length < 3) {\n return null;\n }\n // steps:\n // 1. compute the intersection points between the two polygon's edges,\n // 2. triangulate all the vertices (original + intersection points)\n // 3. filter the triangles whose barycenter is not within both the original polygons\n // 4. return the vertices of the remaining triangles as the intersection polygon vertices\n const sideBuilderCallback = (v, j, arr) => [v, arr[(j + 1) % arr.length]];\n const verticesSortCallback = (a, b) => a.x === b.x ? a.y - b.y : a.x - b.x;\n const edges1 = vertices1.map(sideBuilderCallback), edges2 = vertices2.map(sideBuilderCallback);\n const outputVertices = vertices1.concat(vertices2);\n const memoizer = new Map();\n const ensureMemoizer = e => {\n if (!memoizer.has(e)) {\n const retval = [];\n memoizer.set(e, retval);\n }\n return memoizer.get(e);\n };\n // loop to find edge intersections\n let thereAreIntersections = false;\n for (let edge1 of edges1) {\n const additionalVertices1 = ensureMemoizer(edge1);\n for (let edge2 of edges2) {\n const additionalVertices2 = ensureMemoizer(edge2);\n const intersection = Utils.intersect(edge1, edge2);\n if (!NullChecker.isNull(intersection)) {\n // found intersection\n thereAreIntersections = true;\n outputVertices.push(intersection);\n additionalVertices1.push(intersection);\n additionalVertices2.push(intersection);\n }\n }\n }\n // if no point is contained in each other's polygon AND additionalVertices is empty AND 'intersect' => exit\n if (contained1.length === 0 && contained2.length === 0 && !thereAreIntersections) {\n switch (operator) {\n case 'union':\n return { polygons: [polygon1, polygon2] };\n default:\n return null; // { polygons: [] };\n }\n }\n const constraints = [];\n for (let edge of edges1.concat(edges2)) {\n const additionalVertices = ensureMemoizer(edge);\n if (NullChecker.isNullOrEmpty(additionalVertices)) {\n constraints.push(edge);\n }\n else {\n // split the edge into segments by the additional vertices\n const totalVertices = edge.concat(additionalVertices).sort(verticesSortCallback);\n for (let j = 0; j < totalVertices.length - 1; j++) {\n constraints.push([totalVertices[j], totalVertices[j + 1]]);\n }\n }\n }\n // simplify by removing coinciding vertices\n var dirty = false;\n var mesh;\n do {\n outputVertices.sort(verticesSortCallback);\n outputVertices.filter((v, i, arr) => { return i === 0 || !Utils.areClose(v, arr[i - 1]); });\n // triangulate\n mesh = Utils.mesh(outputVertices);\n const { vertices, triangleIndices } = mesh;\n dirty = false;\n // enforce constraints\n for (let j = 0; j < triangleIndices.length; j += 3) {\n const indexA = triangleIndices[j], indexB = triangleIndices[j + 1], indexC = triangleIndices[j + 2];\n const A = vertices[indexA], B = vertices[indexB], C = vertices[indexC];\n const sides = [[A, B], [B, C], [C, A]];\n for (let constraint of constraints) {\n for (let side of sides) {\n const consecutive = Utils.areClose(side[0], constraint[0])\n || Utils.areClose(side[1], constraint[1])\n || Utils.areClose(side[0], constraint[1])\n || Utils.areClose(side[1], constraint[0]);\n const intersection = consecutive ? null : Utils.intersect(side, constraint);\n if (!NullChecker.isNull(intersection) && outputVertices.findIndex(p => Utils.areClose(p, intersection, 4)) === -1) {\n // pick triangle adjacent to the intesected side\n dirty = true;\n outputVertices.push(intersection);\n //break;\n }\n }\n }\n }\n } while (dirty);\n const { vertices, triangleIndices } = mesh;\n // loop through triangles and filter by barycenter\n const triangles = [];\n for (let j = 0; j < triangleIndices.length; j += 3) {\n const jA = j, jB = j + 1, jC = j + 2;\n const A = vertices[triangleIndices[jA]], B = vertices[triangleIndices[jB]], C = vertices[triangleIndices[jC]];\n const O = { x: (A.x + B.x + C.x) / 3, y: (A.y + B.y + C.y) / 3 };\n const in1 = Utils.inPolygon(O, vertices1), in2 = Utils.inPolygon(O, vertices2);\n if (in1 && in2 && operator === 'intersect'\n || (in1 || in2) && operator === 'union'\n || (in1 && !in2 || !in1 && in2) && operator === 'difference') {\n triangles.push([A, B, C]);\n }\n }\n // return the unique vertices of the remaining triangles as the intersection polygon vertices\n // 1. list all edges\n const edges = triangles.flatMap(([A, B, C]) => [[A, B], [B, C], [C, A]]);\n // 2. filter by uniqueness\n const uniqueEdges = [];\n for (let j = 0; j < edges.length; j++) {\n const edge = edges[j];\n if (j == 0) {\n uniqueEdges.push(edge);\n continue;\n }\n const alreadyIn = uniqueEdges.findIndex(e => Utils.areClose(e[0], edge[0]) && Utils.areClose(e[1], edge[1]) || Utils.areClose(e[0], edge[1]) && Utils.areClose(e[1], edge[0]));\n if (alreadyIn === -1) {\n uniqueEdges.push(edge);\n }\n else {\n uniqueEdges.splice(alreadyIn, 1);\n }\n }\n if (uniqueEdges.length < 3) {\n return null;\n }\n const polygons = [];\n const cleanupPolygon = (vertices) => {\n // check that the starting vertex is not repeated\n const { length } = vertices;\n const repeated = Utils.areClose(vertices[0], vertices[length - 1]);\n const retval = vertices.slice(0, repeated ? (length - 1) : length);\n // check sneaky starting in-segment vertex\n if (retval.length > 3 && Utils.inSegment(retval[0], [retval[1], retval[retval.length - 1]])) {\n retval.shift();\n }\n return retval;\n };\n // 3. order the boundary vertices by following the edges\n const [P0, P1] = uniqueEdges.shift();\n const boundaryVertices = [P0, P1];\n while (uniqueEdges.length > 1) {\n const lastVertex = boundaryVertices[boundaryVertices.length - 1];\n const nextEdgeIndex = uniqueEdges.findIndex(e => Utils.areClose(e[0], lastVertex) || Utils.areClose(e[1], lastVertex));\n // manage to return multiple polygons in case of multiple disconnected intersections\n // nextVertex could be null but uniqueEdges not empty, then move to another polygon to yield.\n if (nextEdgeIndex === -1) {\n // check that the starting vertex is not repeated\n polygons.push({ vertices: cleanupPolygon(boundaryVertices.splice(0)) });\n // start next polygon\n const [P2, P3] = uniqueEdges.shift();\n boundaryVertices.push(P2, P3);\n }\n else {\n const [nextEdge] = uniqueEdges.splice(nextEdgeIndex, 1);\n const nextVertex = Utils.areClose(nextEdge[0], lastVertex) ? nextEdge[1] : (Utils.areClose(nextEdge[1], lastVertex) ? nextEdge[0] : null);\n // cleanup past in-segment vertices\n if (boundaryVertices.length > 1 && Utils.inSegment(boundaryVertices[boundaryVertices.length - 1], [boundaryVertices[boundaryVertices.length - 2], nextVertex])) {\n boundaryVertices.splice(boundaryVertices.length - 1, 1, nextVertex);\n }\n else {\n boundaryVertices.push(nextVertex);\n }\n }\n }\n polygons.push({ vertices: cleanupPolygon(boundaryVertices) });\n return {\n polygons, mesh, triangles: triangles.map(vertices => { return { vertices }; })\n };\n }\n static mesh(point, ...points) {\n const vertices = [].concat(point).concat(points), triangleIndices = Delaunay.triangulate(vertices);\n return { vertices, triangleIndices };\n }\n static intersectLines(segment1, segment2, m2, q2) {\n let s1, s2;\n // overload 2 => m+q in pairs, reset as overload 1\n if (Array.isArray(segment1) && Array.isArray(segment2)\n && segment1.length === 2 && segment2.length === 2\n && typeof segment1[0] === 'number' && typeof segment2[0] === 'number' && typeof segment1[1] === 'number' && typeof segment2[1] === 'number') {\n // var type switch, instructions' order matter!\n m2 = segment2[0];\n q2 = segment2[1];\n segment2 = segment1[1];\n segment1 = segment1[0];\n }\n // overload 1?\n if (typeof segment1 === 'number' && typeof segment2 === 'number') {\n const m1 = segment1, q1 = segment2;\n // dummy segments\n s1 = [\n { x: 0, y: q1 },\n { x: 1, y: m1 + q1 }\n ];\n s2 = [\n { x: 0, y: q2 },\n { x: 1, y: m2 + q2 }\n ];\n }\n // overload 0\n else {\n s1 = segment1;\n s2 = segment2;\n }\n return Utils._intersectSegments(s1, s2, false);\n }\n static cramer(l1, l2) {\n if (Array.isArray(l1)) {\n l1 = { a: l1[0], b: l1[1], c: l1[2] };\n }\n if (Array.isArray(l2)) {\n l2 = { a: l2[0], b: l2[1], c: l2[2] };\n }\n let xP = (l1.b * l2.c - l1.c * l2.b) / (l1.b * l2.a - l1.a * l2.b), yP = (l1.c * l2.a - l1.a * l2.c) / (l1.b * l2.a - l1.a * l2.b);\n return { x: -xP.roundoff(), y: -yP.roundoff() };\n }\n static mq(arg0, p2) {\n let p1;\n if (isPoint(arg0)) {\n p1 = arg0;\n }\n else {\n p1 = arg0[0];\n p2 = arg0[1];\n }\n if (p1.x === p2.x) {\n return [Number.NaN, Number.NaN];\n }\n const m = (p2.y - p1.y) / (p2.x - p1.x);\n const q = p1.y - m * p1.x;\n return [m, q];\n }\n static _intersectSegments(segment1, segment2, excludeProjection) {\n // do bounding boxes intersect?\n const A = segment1[0], B = segment1[1], C = segment2[0], D = segment2[1], xAB = Math.min(A.x, B.x), yAB = Math.min(A.y, B.y), XAB = Math.max(A.x, B.x), wAB = XAB - xAB, YAB = Math.max(A.y, B.y), hAB = YAB - yAB, xCD = Math.min(C.x, D.x), yCD = Math.min(C.y, D.y), XCD = Math.max(C.x, D.x), wCD = XCD - xCD, YCD = Math.max(C.y, D.y), hCD = YCD - yCD;\n if (wAB === 0 && wCD === 0) {\n // both vertical segments (null or infinite intersections) return null\n return null;\n }\n if (hAB === 0 && hCD === 0) {\n // both horizontal segments (null or infinite intersections) return null\n return null;\n }\n // dry\n const outOfXBounds = (p) => {\n return p.x < xCD || p.x > XCD || p.x < xAB || p.x > XAB;\n };\n const outOfYBounds = (p) => {\n return p.y < yCD || p.y > YCD || p.y < yAB || p.y > YAB;\n };\n var retval = null;\n if (wAB === 0) {\n if (excludeProjection && (xCD > xAB || XCD < XAB)) {\n return null;\n }\n const mqCD = Utils.mq(C, D);\n retval = Utils.cramer([1, 0, -xAB], [mqCD[0], -1, mqCD[1]]);\n if (excludeProjection && outOfYBounds(retval)) {\n retval = null;\n }\n }\n else if (wCD === 0) {\n if (excludeProjection && (xAB > xCD || XAB < XCD)) {\n return null;\n }\n const mqAB = Utils.mq(A, B);\n retval = Utils.cramer([mqAB[0], -1, mqAB[1]], [1, 0, -xCD]);\n if (excludeProjection && outOfYBounds(retval)) {\n retval = null;\n }\n }\n else if (hAB === 0) {\n if (excludeProjection && (yCD > yAB || YCD < YAB)) {\n return null;\n }\n const mqCD = Utils.mq(C, D);\n retval = Utils.cramer([0, 1, -yAB], [mqCD[0], -1, mqCD[1]]);\n if (excludeProjection && outOfXBounds(retval)) {\n retval = null;\n }\n }\n else if (hCD === 0) {\n if (excludeProjection && (yAB > yCD || YAB < YCD)) {\n return null;\n }\n const mqAB = Utils.mq(A, B);\n retval = Utils.cramer([mqAB[0], -1, mqAB[1]], [0, 1, -yCD]);\n if (excludeProjection && outOfXBounds(retval)) {\n retval = null;\n }\n }\n else {\n let intersection;\n if (!excludeProjection ||\n ((intersection = Utils._intersectRects({ x: xAB, y: yAB, width: wAB, height: hAB }, { x: xCD, y: yCD, width: wCD, height: hCD }))\n && intersection.width > 0\n && intersection.height > 0)) {\n // cramer's rule\n const mqAB = Utils.mq(A, B), mqCD = Utils.mq(C, D);\n const mAB = mqAB[0], mCD = mqCD[0], qAB = mqAB[1], qCD = mqCD[1];\n // parallel os superposed segments yield null\n if (mAB !== mCD) {\n retval = Utils.cramer([mAB, -1, qAB], [mCD, -1, qCD]);\n let xR = retval.x, yR = retval.y;\n if (excludeProjection\n && (xR < intersection.x || xR > (intersection.x + intersection.width)\n || yR < intersection.y || yR > (intersection.y + intersection.height))) {\n retval = null;\n }\n }\n }\n }\n if (retval === null) {\n return null;\n }\n return { x: retval.x, y: retval.y };\n }\n static _intersectRects(...args) {\n return Rect.intersect(...args);\n }\n static _areClose(p1, p2, precision = PRECISION) {\n return Math.abs(p1.x - p2.x).isCloseTo(0, precision) && Math.abs(p1.y - p2.y).isCloseTo(0, precision);\n }\n static areClose(p1, p2, precision = PRECISION) {\n return Utils._areClose(p1, p2, precision);\n }\n /**\n * Returns the dot product between two vectors/points.\n * @param v1\n * @param v2\n */\n static dot(v1, v2) {\n return Vector.dot(v1, v2);\n }\n /**\n * Returns the cross product between two vectors/points (magnitude along the z axis).\n * @param v1\n * @param v2\n */\n static cross(v1, v2) {\n return Vector.cross(v1, v2);\n }\n static distance(p1, arg2) {\n if (isSegment(p1)) {\n return Point.distance(p1[0], p1[1]);\n }\n else if (isPoint(arg2)) {\n return Point.distance(p1, arg2);\n }\n else {\n const m = arg2[0], q = arg2[1];\n return Math.abs(m * p1.x - p1.y + q) / Math.sqrt(Math.pow(m, 2) + 1);\n }\n }\n static _pointSegmentDistance(p, segment) {\n const v1 = Vector.from(segment[0], segment[1]), v2 = Vector.from(segment[0], p);\n return Utils.cross(v1, v2);\n }\n static isWithin(p, segment, clockwise, precision = PRECISION) {\n const cross = Utils._pointSegmentDistance(p, segment);\n if (cross.isCloseTo(0, precision)) {\n return false;\n }\n return clockwise ? cross < 0 : cross > 0;\n }\n static isBeyond(p, segment, clockwise, precision = PRECISION) {\n return Utils.isWithin(p, segment, !clockwise, precision);\n }\n static inLine(p, segment, precision = PRECISION) {\n const cross = Utils._pointSegmentDistance(p, segment);\n return cross.isCloseTo(0, precision);\n }\n static inSegment(p, segment, precision = PRECISION) {\n 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);\n return p.x >= minx && p.x <= maxx && p.y >= miny && p.y <= maxy && Utils.inLine(p, segment, precision);\n }\n /**\n * Checks whether a point lies inside (or on the boundary of) a triangle, by verifying that it\n * is on the same rotational side of all three edges.\n * @param p Point to test.\n * @param triangle Triangle vertices.\n */\n static inTriangle(p, triangle) {\n let last;\n for (let j = 0; j < 3; j++) {\n const p1 = triangle[j], p2 = triangle[(j + 1) % 3], v1 /* vector */ = Point.subtract(p2, p), v2 = Point.subtract(p1, p), current = Utils.cross(v1, v2);\n if (j > 0 && (current * last) <= 0) {\n // in the current 'triangle' we face a different direction,\n // then exit (:=not in polygon)\n return false;\n }\n last = current;\n }\n return true;\n }\n static inPolygon(p, vertices, precision = PRECISION) {\n if (!(vertices?.length >= 3)) {\n throw `Not enough vertices`;\n }\n const length = vertices.length;\n if (length === 3) {\n return Utils.inTriangle(p, [vertices[0], vertices[1], vertices[2]]);\n }\n if (precision > 0) {\n vertices = vertices.map(v => { return { x: v.x.roundoff(precision), y: v.y.roundoff(precision) }; });\n p = { x: p.x.roundoff(precision), y: p.y.roundoff(precision) };\n }\n // true polygon (might be concave, hulled, ...)\n // 1. preliminary bbox check\n let minx = Number.MAX_VALUE, miny = Number.MAX_VALUE, maxx = Number.MIN_VALUE, maxy = Number.MIN_VALUE;\n for (let j = 0; j < length; j++) {\n const v = vertices[j];\n minx = Math.min(minx, v.x);\n miny = Math.min(miny, v.y);\n maxx = Math.max(maxx, v.x);\n maxy = Math.max(maxy, v.y);\n }\n if (p.x < minx || p.x > maxx || p.y < miny || p.y > maxy) {\n return false;\n }\n // 2. intersections\n const /* dummy point 'left' to the left-most point of the shape and haivng the same 'y' of the target point */ outerPoint = { x: minx - 1, y: p.y }, \n /* horizontal segment that binds the provided point with the outside one */ test = [outerPoint, p];\n let intersections = 0;\n for (let j = 0; j < length; j++) {\n const p1 = vertices[j], p2 = vertices[(j + 1) % length], side = [p1, p2];\n // edge case\n if (p1.y === p.y) {\n const p0 = vertices[(j - 1 + length) % length];\n // not on the same side (above or below)? then counts as an intersection\n if (p.x > p1.x && (p0.y - p.y) * (p2.y - p.y) < 0) {\n intersections++;\n }\n }\n else if (p2.y === p.y) {\n // already handled at previous statement one loop ago, skip\n continue;\n }\n else {\n // straddle testing\n if (Utils.intersect(side, test) != null) {\n intersections++;\n }\n }\n }\n return intersections % 2 === 1;\n }\n static area(point, ...points) {\n const pts = [].concat(point).concat(points);\n // shoelace algorithm\n let retval = 0;\n const length = pts.length;\n if (length >= 3) {\n for (let j = 0; j < pts.length; j++) {\n const { x: xj, y: yj } = pts[j], next = j === (length - 1) ? 0 : j + 1, { x: xnext, y: ynext } = pts[next];\n retval += (xj * ynext - yj * xnext);\n }\n retval *= .5;\n }\n return Math.abs(retval.roundoff());\n }\n static convexHull(point, ...points) {\n const pts = [].concat(point).concat(points);\n if (!(pts?.length > 1)) {\n return pts?.slice() ?? [];\n }\n const sorted = pts\n .map(p => ({ x: p.x, y: p.y }))\n .sort((a, b) => a.x === b.x ? a.y - b.y : a.x - b.x);\n const unique = [];\n for (const p of sorted) {\n const last = unique[unique.length - 1];\n if (!last || last.x !== p.x || last.y !== p.y) {\n unique.push(p);\n }\n }\n if (unique.length <= 2) {\n return unique;\n }\n const cross = (o, a, b) => {\n return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);\n };\n const lower = [];\n for (const p of unique) {\n while (lower.length >= 2\n && cross(lower[lower.length - 2], lower[lower.length - 1], p) <= 0) {\n lower.pop();\n }\n lower.push(p);\n }\n const upper = [];\n for (let j = unique.length - 1; j >= 0; j--) {\n const p = unique[j];\n while (upper.length >= 2\n && cross(upper[upper.length - 2], upper[upper.length - 1], p) <= 0) {\n upper.pop();\n }\n upper.push(p);\n }\n lower.pop();\n upper.pop();\n return lower.concat(upper);\n }\n}\n// }\n", "import { Point } from '@pacem/pacem-foundation';\n/** 2D vector utils. */\nexport class Vector {\n /**\n * Returns the unit (normalized) vector having the same direction and sense of the provided one.\n * @param v\n */\n static unit(v) {\n const clone = { x: v.x, y: v.y };\n this.normalize(clone);\n return clone;\n }\n /**\n * Returns the squared magnitude (length) of the vector. Cheaper than {@link mag} since it avoids the square root.\n * @param v\n */\n static magSqr(v) {\n return v.x * v.x + v.y * v.y;\n }\n /**\n * Returns the magnitude (length) of the vector.\n * @param v\n */\n static mag(v) {\n return Math.sqrt(Vector.magSqr(v));\n }\n /**\n * Normalizes the provided vector in place.\n * @param v\n */\n static normalize(v) {\n const l = Vector.mag(v);\n if (l <= 0) {\n throw 'Cannot normalize a vector of length 0.';\n }\n const inv = 1 / l;\n v.x *= inv;\n v.y *= inv;\n }\n /**\n * Returns the vector joining two points.\n * @param p1 Start point\n * @param p2 End point\n */\n static from(p1, p2) {\n return Point.subtract(p1, p2);\n }\n /**\n * Returns the dot product between two vectors/points.\n * @param v1\n * @param v2\n */\n static dot(v1, v2) {\n return v1.x * v2.x + v1.y * v2.y;\n }\n /**\n * Returns the cross product between two vectors/points (magnitude along the z axis).\n * @param v1\n * @param v2\n */\n static cross(v1, v2) {\n return v1.x * v2.y - v1.y * v2.x;\n }\n /**\n * Checks if the two points are effectively the same location.\n * @param v1 The first point.\n * @param v2 The second point.\n * @returns True if the points are considered coincident within tolerance; otherwise, false.\n */\n static areClose(v1, v2) {\n return (v2.x - v1.x).isCloseTo(0)\n && (v2.y - v1.y).isCloseTo(0);\n }\n}\n", "class Vertex {\n constructor(x, y, index = -1 // original index in the input array\n ) {\n this.x = x;\n this.y = y;\n this.index = index;\n }\n equals(other) {\n return this.x === other.x && this.y === other.y;\n }\n}\n// Compute circumcircle of a triangle (center + radius)\nfunction calcCircumCirc(v0, v1, v2) {\n const ax = v0.x, ay = v0.y;\n const bx = v1.x, by = v1.y;\n const cx = v2.x, cy = v2.y;\n const d = 2 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by));\n if (Math.abs(d) < 1e-12) {\n // Degenerate (collinear) triangle\n return { c: { x: 0, y: 0 }, r: Infinity };\n }\n const ux = ((ax * ax + ay * ay) * (by - cy) +\n (bx * bx + by * by) * (cy - ay) +\n (cx * cx + cy * cy) * (ay - by)) /\n d;\n const uy = ((ax * ax + ay * ay) * (cx - bx) +\n (bx * bx + by * by) * (ax - cx) +\n (cx * cx + cy * cy) * (bx - ax)) /\n d;\n const r = Math.hypot(ux - ax, uy - ay);\n return { c: { x: ux, y: uy }, r };\n}\nclass Triangle {\n constructor(v0, v1, v2) {\n this.v0 = v0;\n this.v1 = v1;\n this.v2 = v2;\n this.circumCirc = calcCircumCirc(v0, v1, v2);\n }\n inCircumcircle(v) {\n const dx = this.circumCirc.c.x - v.x;\n const dy = this.circumCirc.c.y - v.y;\n return Math.hypot(dx, dy) <= this.circumCirc.r + 1e-9;\n }\n}\n// Create a large \"super triangle\" that encloses all points\nfunction superTriangle(vertices) {\n let minX = Infinity, minY = Infinity;\n let maxX = -Infinity, maxY = -Infinity;\n for (const v of vertices) {\n minX = Math.min(minX, v.x);\n minY = Math.min(minY, v.y);\n maxX = Math.max(maxX, v.x);\n maxY = Math.max(maxY, v.y);\n }\n const dx = (maxX - minX) * 10;\n const dy = (maxY - minY) * 10;\n const v0 = new Vertex(minX - dx, minY - dy * 3);\n const v1 = new Vertex(minX - dx, maxY + dy);\n const v2 = new Vertex(maxX + dx * 3, maxY + dy);\n return new Triangle(v0, v1, v2);\n}\n// Collect unique edges from a list of triangles (used during point insertion)\nfunction uniqueEdges(edges) {\n const unique = [];\n for (let i = 0; i < edges.length; ++i) {\n let isUnique = true;\n for (let j = 0; j < edges.length; ++j) {\n if (i !== j) {\n const e1 = edges[i];\n const e2 = edges[j];\n if ((e1.v0.equals(e2.v0) && e1.v1.equals(e2.v1)) ||\n (e1.v0.equals(e2.v1) && e1.v1.equals(e2.v0))) {\n isUnique = false;\n break;\n }\n }\n }\n if (isUnique)\n unique.push(edges[i]);\n }\n return unique;\n}\n// Insert a new vertex into the current triangulation\nfunction addVertex(vertex, triangles) {\n const edges = [];\n // 1. Remove all triangles whose circumcircle contains the new vertex\n triangles = triangles.filter((triangle) => {\n if (triangle.inCircumcircle(vertex)) {\n edges.push({ v0: triangle.v0, v1: triangle.v1 });\n edges.push({ v0: triangle.v1, v1: triangle.v2 });\n edges.push({ v0: triangle.v2, v1: triangle.v0 });\n return false;\n }\n return true;\n });\n // 2. Create new triangles from the unique polygon edges + new vertex\n const unique = uniqueEdges(edges);\n for (const edge of unique) {\n triangles.push(new Triangle(edge.v0, edge.v1, vertex));\n }\n return triangles;\n}\n// Main Delaunay triangulation (Bowyer-Watson)\nfunction triangulate(vertices) {\n if (vertices.length < 3)\n return [];\n // 1. Create super triangle\n const st = superTriangle(vertices);\n // 2. Start with the super triangle\n let triangles = [st];\n // 3. Insert each point one by one\n for (const vertex of vertices) {\n triangles = addVertex(vertex, triangles);\n }\n // 4. Remove any triangle that touches the super triangle\n triangles = triangles.filter((t) => !(t.v0 === st.v0 ||\n t.v0 === st.v1 ||\n t.v0 === st.v2 ||\n t.v1 === st.v0 ||\n t.v1 === st.v1 ||\n t.v1 === st.v2 ||\n t.v2 === st.v0 ||\n t.v2 === st.v1 ||\n t.v2 === st.v2));\n return triangles;\n}\n// Public API: Delaunay triangulation given vertices \u2192 triangle indices\nfunction delaunayTriangulation(vertices) {\n if (vertices.length < 3)\n return [];\n // Create internal vertices that remember their original index\n const vertList = vertices.map((p, idx) => new Vertex(p.x, p.y, idx));\n const triangles = triangulate(vertList);\n // Convert to flat index array: [i0, j0, k0, i1, j1, k1, ...]\n const indices = [];\n for (const t of triangles) {\n // All vertices in the final triangulation come from the original input\n indices.push(t.v0.index, t.v1.index, t.v2.index);\n }\n return indices;\n}\n// Example usage:\n/*\nconst vertices: Point[] = [\n { x: 0, y: 0 },\n { x: 10, y: 0 },\n { x: 5, y: 10 },\n { x: 15, y: 5 },\n { x: 2, y: 8 },\n // ... any number of points\n];\n\nconst triangleIndices = delaunayTriangulation(vertices);\n\n// triangleIndices is a flat array of indices, e.g. [0,1,2, 0,2,4, 1,3,2, ...]\n// Use it like this:\nfor (let i = 0; i < triangleIndices.length; i += 3) {\n const a = vertices[triangleIndices[i]];\n const b = vertices[triangleIndices[i + 1]];\n const c = vertices[triangleIndices[i + 2]];\n console.log(`Triangle: ${a.x},${a.y} \u2192 ${b.x},${b.y} \u2192 ${c.x},${c.y}`);\n}\n*/\n// This implementation is self-contained, numerically robust (small epsilon), and works with floating-point coordinates.\n// It assumes general position (no four points exactly cocircular). For production use with degenerate cases,\n// you may want to add a tiny random jitter to the points if needed.\n/**\n * Computes the (unconstrained) 2D Delaunay triangulation of a set of points, using the\n * incremental Bowyer-Watson algorithm.\n *\n * A Delaunay triangulation connects a set of points into triangles such that no point lies\n * strictly inside the circumcircle of any triangle. Among all the ways a point set can be\n * triangulated, this property makes it the one that maximizes the minimum angle of all the\n * triangles, avoiding thin \"sliver\" triangles \u2014 which is why it's the standard choice for\n * meshes, terrain modeling, and (via its dual) Voronoi diagrams.\n *\n * The Bowyer-Watson algorithm builds the triangulation incrementally: starting from a single\n * \"super triangle\" that encloses every input point, each point is inserted one at a time by\n * removing every existing triangle whose circumcircle contains it (which necessarily leaves a\n * star-shaped polygonal hole around the new point) and re-triangulating that hole by connecting\n * the new point to the hole's boundary edges. Once every point has been inserted, any triangle\n * still touching a vertex of the initial super triangle is discarded, leaving the final\n * triangulation of the original points.\n */\nexport class Delaunay {\n /**\n * Computes the Delaunay triangulation of the given points.\n * @param vertices Points to triangulate.\n * @returns A flat array of triangle indices into {@link vertices} (each consecutive group of 3\n * entries identifies one triangle), in the same \"vertices + triangle indices\" format used by\n * most graphics/meshing libraries. Returns an empty array if fewer than 3 points are provided.\n */\n static triangulate(vertices) {\n return delaunayTriangulation(vertices);\n }\n}\n//}\n", "import { Point, Matrix2D, Angle, NullChecker } from '@pacem/pacem-foundation';\n// namespace Pacem.Geometry {\nimport { Utils } from './geom';\nimport * as LinearAlgebra from './linear-algebra';\nfunction isPolygon(obj) {\n let vertices;\n return 'vertices' in obj && Array.isArray(obj.vertices)\n && (vertices = obj.vertices).length >= 3\n && vertices.every(i => Point.isPoint(i));\n}\n/** Utility tools to build and inspect {@link Polygon}s. */\nexport class Polygon {\n static { this._eps = 1e-12; }\n /**\n * Type guard checking whether the provided value is a valid {@link Polygon} (has at least 3 point vertices).\n * @param obj\n */\n static isPolygon(obj) {\n return isPolygon(obj);\n }\n /**\n * Builds a polygon from the provided vertices, in order.\n * @param points Vertices of the polygon.\n */\n static from(...points) {\n return { vertices: Array.from(points) };\n }\n /**\n * Checks whether a point lies inside the polygon.\n * @param polygon\n * @param p Point to test.\n */\n static contains(polygon, p) {\n return Utils.inPolygon(p, polygon.vertices, 12);\n }\n /**\n * Returns the center of the polygon's bounding box.\n * Note: this is not the geometric centroid (center of mass) for non-symmetric polygons.\n * @param polygon\n */\n static centroid(polygon) {\n const bbox = Polygon.boundingBox(polygon);\n return { x: bbox.x + bbox.width / 2, y: bbox.y + bbox.height / 2 };\n }\n /**\n * Computes the axis-aligned bounding box of the polygon.\n * @param polygon\n */\n static boundingBox(polygon) {\n return Utils.boundingBox(polygon.vertices);\n }\n /**\n * Returns the polygon's edges as an ordered list of segments, each joining a vertex to the next\n * (the last one wrapping back to the first).\n * @param polygon\n */\n static sides(polygon) {\n const { vertices } = polygon;\n const retval = [];\n for (let j = 1; j <= vertices.length; j++) {\n const v = vertices[j % vertices.length], v0 = vertices[j - 1];\n retval.push([v0, v]);\n }\n return retval;\n }\n /**\n * Checks whether the polygon is convex, i.e. all its interior angles turn in the same rotational direction.\n * @param polygon\n */\n static isConvex(polygon) {\n const { vertices } = polygon, l = vertices.length;\n if (l <= 3) {\n return true;\n }\n let sign = 0;\n for (let j = 0; j < vertices.length; j++) {\n const p0 = vertices[(j - 1 + l) % l], p = vertices[j], p1 = vertices[(j + 1) % l];\n const theta = Angle.angleBetween(p, p0, p1);\n //if (Math.abs(theta) > Math.PI) {\n // return false;\n //}\n if (sign === 0) {\n sign = Math.sign(theta);\n continue;\n }\n if (sign != Math.sign(theta)) {\n return false;\n }\n }\n return true;\n }\n /**\n * Check whether a polygon is a self-intersecting one.\n * @param polygon\n * @returns\n */\n static isSelfIntersecting(polygon) {\n const { vertices } = polygon;\n if (vertices.length <= 3) {\n return false;\n }\n const sides = Polygon.sides(polygon);\n for (let side of sides) {\n for (let check of sides) {\n if ( /* same */check === side || /* contiguous */ check[0] === side[1] || side[0] === check[1]) {\n continue;\n }\n const intersection = Utils.intersect(check, side);\n if (!NullChecker.isNull(intersection)) {\n return true;\n }\n }\n }\n return false;\n }\n /**\n * Returns whether the vertices of the spcified polygon have been provided in counter-clockwise order.\n * Meaningless in case of self-intersecting polygons.\n * @param polygon\n * @returns\n */\n static isCounterClockwise(polygon) {\n const { vertices: [p0, p1, p2] } = polygon;\n return Angle.angleBetween(p1, p0, p2) > 0; /* ccw angle <=> cw polygon and viceversa */\n }\n /**\n * Expands (or contracts) a polygon by a provided offset.\n * @param polygon\n * @param offset\n *\n */\n static expand(polygon, offset) {\n // TODO: https://en.wikipedia.org/wiki/Straight_skeleton\n const { vertices } = polygon, l = vertices.length, retval = [];\n for (let j = 0; j < vertices.length; j++) {\n const p0 = vertices[(j - 1 + l) % l], p = vertices[j], p1 = vertices[(j + 1) % l];\n const theta = Angle.angleBetween(p, p0, p1), scale = -offset / Math.sin(Math.abs(theta) / 2);\n const matrix = Matrix2D.scale(Matrix2D.identity, scale);\n const v0 = Point.subtract(p, p0);\n LinearAlgebra.Vector.normalize(v0);\n const v1 = Point.subtract(p, p1);\n LinearAlgebra.Vector.normalize(v1);\n const vector = Point.add(v0, v1);\n LinearAlgebra.Vector.normalize(vector);\n const pOffset = Matrix2D.multiply(vector, matrix);\n retval.push(Point.add(p, { x: pOffset.x.roundoff(), y: pOffset.y.roundoff() }));\n }\n return { vertices: retval };\n }\n /**\n * Returns the area of a polygon using the shoelace algorithm. It's meaningless in case of self-intersecting polygons.\n * @param polygon\n * @returns\n */\n static area(polygon) {\n return Utils.area(polygon.vertices);\n }\n /**\n * Computes the intersection area(s) between two polygons.\n * @param polygon1\n * @param polygon2\n * @returns The overlapping area(s) as one or more polygons.\n */\n static intersect(polygon1, polygon2) {\n return Utils.intersect(polygon1, polygon2);\n }\n /**\n * Returns the convex hull of a polygon.\n * @param polygon\n * @returns\n */\n static convexHull(polygon) {\n const vertices = Utils.convexHull(polygon.vertices);\n return { vertices };\n }\n}\n//}\n", "import { parseAsNumericalArray } from '@pacem/pacem-foundation';\n// namespace Pacem.Geometry.LinearAlgebra {\nconst RAD2DEG = 180.0 / Math.PI;\nconst DEG2RAD = 1.0 / RAD2DEG;\n/** 3D vector utils. */\nexport class Vector3D {\n /**\n * Builds a {@link Vector3D} from its x, y, z components, in that order.\n * @param args Exactly 3 numbers: x, y, z.\n * @throws If the number of arguments is not exactly 3.\n */\n static from(...args) {\n const l = 3;\n if (args.length !== l) {\n throw new RangeError(`Must provide exactly ${l} numbers`);\n }\n return { x: args[0], y: args[1], z: args[2] };\n }\n /**\n * Parses a string representation (e.g. `\"1 2 3\"` or `\"1,2,3\"`) into a {@link Vector3D}.\n * @param input String to parse.\n * @throws If the input cannot be parsed as exactly 3 numbers.\n */\n static parse(input) {\n const arr = parseAsNumericalArray(input);\n if (arr && arr.length === 3) {\n return Vector3D.from.apply(null, arr);\n }\n throw new Error(`Cannot parse \"${input}\" as a valid Vector3D.`);\n }\n // notable vectors\n /** Returns the unit vector along the x axis: `(1, 0, 0)`. */\n static i() {\n return { x: 1, y: 0, z: 0 };\n }\n /** Returns the unit vector along the y axis: `(0, 1, 0)`. */\n static j() {\n return { x: 0, y: 1, z: 0 };\n }\n /** Returns the unit vector along the z axis: `(0, 0, 1)`. */\n static k() {\n return { x: 0, y: 0, z: 1 };\n }\n /** Returns the zero vector: `(0, 0, 0)`. */\n static zero() {\n return { x: 0, y: 0, z: 0 };\n }\n /**\n * Subtracts a point p from another and returns the resulting vector.\n * @param p Point to subtract\n * @param from Point to be subtracted from\n */\n static subtract(p, from) {\n return { x: from.x - p.x, y: from.y - p.y, z: from.z - p.z };\n }\n /**\n * Adds a set of points together and returns the resulting vector.\n * @param points Points to add\n */\n static add(...points) {\n var point = { x: 0, y: 0, z: 0 };\n for (var p of points) {\n point.x += p.x;\n point.y += p.y;\n point.z += p.z;\n }\n return point;\n }\n /**\n * Returns the dot product between two vectors/points.\n * @param v1\n * @param v2\n */\n static dot(v1, v2) {\n return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;\n }\n /**\n * Returns the cross product between two vectors/points (as a vector itself).\n * @param v1\n * @param v2\n */\n static cross(v1, v2) {\n return {\n x: (v1.y * v2.z) - (v1.z * v2.y),\n y: (v1.z * v2.x) - (v1.x * v2.z),\n z: (v1.x * v2.y) - (v1.y * v2.x)\n };\n }\n static scale(v, fx, fy = fx, fz = fx) {\n return { x: v.x * fx, y: v.y * fy, z: v.z * fz };\n }\n /**\n * Returns the squared magnitude (length) of the vector. Cheaper than {@link mag} since it avoids the square root.\n * @param v\n */\n static magSqr(v) {\n return v.x * v.x + v.y * v.y + v.z * v.z;\n }\n /**\n * Checks if the two points are effectively the same location.\n * @param v1 The first point.\n * @param v2 The second point.\n * @returns True if the points are considered coincident within tolerance; otherwise, false.\n */\n static areClose(v1, v2) {\n return (v2.x - v1.x).isCloseTo(0)\n && (v2.y - v1.y).isCloseTo(0)\n && (v2.z - v1.z).isCloseTo(0);\n }\n /**\n * Returns the magnitude (length) of the vector.\n * @param v\n */\n static mag(v) {\n return Math.sqrt(Vector3D.magSqr(v));\n }\n /**\n * Returns the opposite vector (each component negated).\n * @param v\n */\n static negate(v) {\n return { x: -v.x, y: -v.y, z: -v.z };\n }\n /**\n * Returns the unit (normalized) vector having the same direction and sense of the provided one.\n * @param v\n */\n static unit(v) {\n const clone = { x: v.x, y: v.y, z: v.z };\n this.normalize(clone);\n return clone;\n }\n /**\n * Normalizes the provided vector in place.\n * @param v\n */\n static normalize(v) {\n const l = Vector3D.mag(v);\n if (l <= 0) {\n throw 'Cannot normalize a vector of length 0.';\n }\n const inv = 1 / l;\n v.x *= inv;\n v.y *= inv;\n v.z *= inv;\n }\n /**\n * Returns the angle (in degrees) between two vectors.\n * @param vector1\n * @param vector2\n */\n static angleBetween(vector1, vector2) {\n let num;\n const v1 = Vector3D.unit(vector1);\n const v2 = Vector3D.unit(vector2);\n const dot = Vector3D.dot(v1, v2);\n if (dot < 0.0) {\n const vectord = { x: -v1.x - v2.x, y: -v1.y - v2.y, z: -v1.z - v2.z };\n const length = Vector3D.mag(vectord);\n num = Math.PI - (2.0 * Math.asin(length / 2.0));\n }\n else {\n const vectord = { x: v1.x - v2.x, y: v1.y - v2.y, z: v1.z - v2.z };\n const length = Vector3D.mag(vectord);\n num = 2.0 * Math.asin(length / 2.0);\n }\n return RAD2DEG * num;\n }\n}\n/**\n * Utilities to convert between spherical coordinates (radial distance `rho`, azimuth `theta` and\n * polar angle `phi`) and their cartesian ({@link Vector3D}) or rotation-matrix ({@link Matrix3D}) equivalents.\n */\nexport class Spherical {\n /**\n * Creates a new {@link Spherical} object.\n * @param rho radius.\n * @param theta Azimuth angle in degrees.\n * @param phi Polar angle in degrees.\n * @returns\n */\n static from(rho, theta, phi) {\n return { rho: rho.clamp(0, Infinity), theta: theta.clamp(-180, 180), phi: phi.clamp(0, 360) };\n }\n static fromVector(v, y, z) {\n if (typeof v === 'number') {\n v = Vector3D.from(v, y, z);\n }\n const rho = Vector3D.mag(v);\n if (rho.isCloseTo(0)) {\n return Spherical.from(0, 0, 0);\n }\n const theta = Math.atan2(v.x, v.z), phi = Math.acos((v.y / rho).clamp(-1, 1));\n return Spherical.from(rho, theta * RAD2DEG, phi * RAD2DEG);\n }\n /**\n * Converts {@link Spherical} coordinates back into cartesian {@link Vector3D} coordinates.\n * @param coords\n */\n static toVector(coords) {\n const { rho, theta: thetaDeg, phi: phiDeg } = coords;\n const phi = phiDeg * DEG2RAD;\n const theta = thetaDeg * DEG2RAD;\n const sinPhiRho = Math.sin(phi) * rho;\n return {\n x: sinPhiRho * Math.sin(theta),\n y: Math.cos(phi) * rho,\n z: sinPhiRho * Math.cos(theta)\n };\n //const t = DEG2RAD * theta,\n // sinTheta = Math.sin(t),\n // cosTheta = Math.cos(t),\n // p = DEG2RAD * phi,\n // sinPhi = Math.sin(p),\n // cosPhi = Math.cos(p);\n //const m = Matrix3D.from(\n // sinTheta * cosPhi, cosTheta * cosPhi, -sinPhi, 0,\n // sinTheta * sinPhi, cosTheta * sinPhi, cosPhi, 0,\n // cosTheta, -sinTheta, 0, 0,\n // 0, 0, 0, 1\n //);\n //return Matrix3D.transform({ x: rho, y: t, z: p }, m);\n }\n static toRotationMatrix(coords) {\n const { theta, phi } = coords;\n const t = DEG2RAD * theta, sinTheta = Math.sin(t), cosTheta = Math.cos(t), p = DEG2RAD * phi, sinPhi = Math.sin(p), cosPhi = Math.cos(p);\n return Matrix3D.from(sinTheta * cosPhi, sinTheta * sinPhi, cosTheta, 0, cosTheta * cosPhi, cosTheta * sinPhi, -sinTheta, 0, -sinPhi, cosPhi, 0, 0, 0, 0, 0, 1);\n }\n}\nclass Matrix3DUtils {\n /**\n * Modifies the content of a provided matrix and returns it as a new matrix instance.\n * @param m Input matrix\n * @param action Content change callback\n * @returns New matrix instance.\n */\n static modify(m, action) {\n const { m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, offsetX, offsetY, offsetZ, m44 } = m;\n const retval = {\n m11, m12, m13, m14,\n m21, m22, m23, m24,\n m31, m32, m33, m34,\n offsetX, offsetY, offsetZ, m44\n };\n action(retval);\n return retval;\n }\n static clone(m) {\n return Matrix3DUtils.modify(m, _ => { });\n }\n static multiply(m1, m2) {\n if (Matrix3D.isIdentity(m1))\n return m2;\n if (Matrix3D.isIdentity(m2))\n return m1;\n return Matrix3D.from((((m1.m11 * m2.m11) + (m1.m12 * m2.m21)) + (m1.m13 * m2.m31)) + (m1.m14 * m2.offsetX), (((m1.m11 * m2.m12) + (m1.m12 * m2.m22)) + (m1.m13 * m2.m32)) + (m1.m14 * m2.offsetY), (((m1.m11 * m2.m13) + (m1.m12 * m2.m23)) + (m1.m13 * m2.m33)) + (m1.m14 * m2.offsetZ), (((m1.m11 * m2.m14) + (m1.m12 * m2.m24)) + (m1.m13 * m2.m34)) + (m1.m14 * m2.m44), (((m1.m21 * m2.m11) + (m1.m22 * m2.m21)) + (m1.m23 * m2.m31)) + (m1.m24 * m2.offsetX), (((m1.m21 * m2.m12) + (m1.m22 * m2.m22)) + (m1.m23 * m2.m32)) + (m1.m24 * m2.offsetY), (((m1.m21 * m2.m13) + (m1.m22 * m2.m23)) + (m1.m23 * m2.m33)) + (m1.m24 * m2.offsetZ), (((m1.m21 * m2.m14) + (m1.m22 * m2.m24)) + (m1.m23 * m2.m34)) + (m1.m24 * m2.m44), (((m1.m31 * m2.m11) + (m1.m32 * m2.m21)) + (m1.m33 * m2.m31)) + (m1.m34 * m2.offsetX), (((m1.m31 * m2.m12) + (m1.m32 * m2.m22)) + (m1.m33 * m2.m32)) + (m1.m34 * m2.offsetY), (((m1.m31 * m2.m13) + (m1.m32 * m2.m23)) + (m1.m33 * m2.m33)) + (m1.m34 * m2.offsetZ), (((m1.m31 * m2.m14) + (m1.m32 * m2.m24)) + (m1.m33 * m2.m34)) + (m1.m34 * m2.m44), (((m1.offsetX * m2.m11) + (m1.offsetY * m2.m21)) + (m1.offsetZ * m2.m31)) + (m1.m44 * m2.offsetX), (((m1.offsetX * m2.m12) + (m1.offsetY * m2.m22)) + (m1.offsetZ * m2.m32)) + (m1.m44 * m2.offsetY), (((m1.offsetX * m2.m13) + (m1.offsetY * m2.m23)) + (m1.offsetZ * m2.m33)) + (m1.m44 * m2.offsetZ), (((m1.offsetX * m2.m14) + (m1.offsetY * m2.m24)) + (m1.offsetZ * m2.m34)) + (m1.m44 * m2.m44));\n }\n}\n/** Utilities to build, combine and invert 4x4 transformation matrices ({@link Matrix3D}) in 3D space. */\nexport class Matrix3D {\n //#region notable matrices\n /**\n * Identity 4x4 matrix.\n * @returns\n */\n static identity() {\n return {\n m11: 1, m12: 0, m13: 0, m14: 0,\n m21: 0, m22: 1, m23: 0, m24: 0,\n m31: 0, m32: 0, m33: 1, m34: 0,\n offsetX: 0, offsetY: 0, offsetZ: 0, m44: 1\n };\n }\n //#endregion\n /**\n * Builds a {@link Matrix3D} from its 16 components, in row-major order.\n * @param args Exactly 16 numbers.\n * @throws If the number of arguments is not exactly 16.\n */\n static from(...args) {\n const l = 16;\n if (args.length !== l) {\n throw new RangeError(`Must provide exactly ${l} numbers`);\n }\n return {\n m11: args[0],\n m12: args[1],\n m13: args[2],\n m14: args[3],\n m21: args[4],\n m22: args[5],\n m23: args[6],\n m24: args[7],\n m31: args[8],\n m32: args[9],\n m33: args[10],\n m34: args[11],\n offsetX: args[12],\n offsetY: args[13],\n offsetZ: args[14],\n m44: args[15]\n };\n }\n /**\n * Returns the transpose of the given matrix (rows and columns swapped).\n * @param m\n */\n static transpose(m) {\n 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);\n }\n /**\n * Flattens the matrix into a 16-number array, in row-major order (the same order accepted by {@link from}).\n * @param m\n */\n static toArray(m) {\n return [m.m11, m.m12, m.m13, m.m14,\n m.m21, m.m22, m.m23, m.m24,\n m.m31, m.m32, m.m33, m.m34,\n m.offsetX, m.offsetY, m.offsetZ, m.m44];\n }\n static clone(m, modifier) {\n return typeof modifier === 'function' ? Matrix3DUtils.modify(m, modifier) : Matrix3DUtils.clone(m);\n }\n static scale(m, x, y, z) {\n if (typeof x === 'number') {\n y ??= x;\n z ??= x;\n }\n else {\n z = x.z;\n y = x.y;\n x = x.x;\n }\n return Matrix3DUtils.modify(m, s => {\n s.m11 *= x;\n s.m22 *= y;\n s.m33 *= z;\n });\n }\n /**\n * Returns a copy of the matrix translated (offset) by the given vector.\n * @param m\n * @param offset\n */\n static translate(m, offset) {\n return Matrix3DUtils.modify(m, s => {\n s.offsetX += offset.x;\n s.offsetY += offset.y;\n s.offsetZ += offset.z;\n });\n }\n /**\n * Parses a string representation of a matrix (16 numbers) into a {@link Matrix3D}.\n * @param input String to parse.\n * @throws If the input cannot be parsed as exactly 16 numbers.\n */\n static parse(input) {\n const arr = parseAsNumericalArray(input);\n if (arr && arr.length === 16) {\n return Matrix3D.from.apply(null, arr);\n }\n throw new Error(`Cannot parse \"${input}\" as a valid Matrix3D.`);\n }\n /**\n * Checks whether the matrix is the identity matrix.\n * @param m\n */\n static isIdentity(m) {\n return m.m11 == 1.0 && m.m12 == .0 && m.m13 == .0 && m.m14 == .0\n && m.m21 == .0 && m.m22 == 1.0 && m.m23 == .0 && m.m24 == .0\n && m.m31 == .0 && m.m32 == .0 && m.m33 == 1.0 && m.m34 == .0\n && m.offsetX == .0 && m.offsetY == .0 && m.offsetZ == .0 && m.m44 == 1.0;\n }\n /**\n * Checks whether the matrix represents a pure affine transform, i.e. it has no perspective\n * component (its 4th column is `(0, 0, 0, 1)`).\n * @param m\n */\n static isAffine(m) {\n return m.m14 == .0 && m.m24 == .0 && m.m34 == .0 && m.m44 == 1.0;\n }\n /**\n * Computes the determinant of the matrix.\n * @param m\n */\n static determinant(m) {\n if (Matrix3D.isIdentity(m)) {\n return 1.0;\n }\n else if (Matrix3D.isAffine(m)) {\n return m.m11 * (m.m22 * m.m33 - m.m32 * m.m23)\n - m.m12 * (m.m21 * m.m33 - m.m31 * m.m23)\n + m.m13 * (m.m21 * m.m32 - m.m31 * m.m22);\n }\n else {\n const num6 = (m.m13 * m.m24) - (m.m23 * m.m14);\n const num5 = (m.m13 * m.m34) - (m.m33 * m.m14);\n const num4 = (m.m13 * m.m44) - (m.offsetZ * m.m14);\n const num3 = (m.m23 * m.m34) - (m.m33 * m.m24);\n const num2 = (m.m23 * m.m44) - (m.offsetZ * m.m24);\n const num = (m.m33 * m.m44) - (m.offsetZ * m.m34);\n const num10 = ((m.m22 * num5) - (m.m32 * num6)) - (m.m12 * num3);\n const num9 = ((m.m12 * num2) - (m.m22 * num4)) + (m.offsetY * num6);\n const num8 = ((m.m32 * num4) - (m.offsetY * num5)) - (m.m12 * num);\n const num7 = ((m.m22 * num) - (m.m32 * num2)) + (m.offsetY * num3);\n const det = ((((m.offsetX * num10) + (m.m31 * num9)) + (m.m21 * num8)) + (m.m11 * num7));\n return det;\n }\n }\n /**\n * Multiplies two matrices in the provided order (i.e.: applies {@link m2} to {@link m1}).\n * @param matrices Matrices to apply one to the other, sequentially.\n * @returns Combination matrix.\n */\n static multiply(...matrices) {\n if (matrices.length === 0) {\n throw new ReferenceError('Matrix not provided.');\n }\n const arr = Array.from(matrices);\n let m = arr[0];\n for (let i = 1; i < arr.length; i++) {\n m = Matrix3DUtils.multiply(m, arr[i]);\n }\n return m;\n }\n /**\n * Computes the inverse of the matrix, using the cofactor/adjugate method (with a specialized,\n * cheaper path for affine matrices).\n * @param m\n * @returns The inverse matrix, or `null` if the matrix is singular (determinant is 0).\n */\n static invert(m) {\n if (Matrix3D.isAffine(m)) {\n // normalize affine invert\n const determinant = Matrix3D.determinant(m);\n if (determinant == 0.0) {\n return null;\n }\n const cofactor31 = (m.m12 * m.m23) - (m.m22 * m.m13);\n const cofactor21 = (m.m32 * m.m13) - (m.m12 * m.m33);\n const cofactor11 = (m.m22 * m.m33) - (m.m32 * m.m23);\n //\n const num20 = (m.m21 * m.m13) - (m.m11 * m.m23);\n const num19 = (m.m11 * m.m33) - (m.m31 * m.m13);\n const num18 = (m.m31 * m.m23) - (m.m21 * m.m33);\n const num7 = (m.m11 * m.m22) - (m.m21 * m.m12);\n const num6 = (m.m11 * m.m32) - (m.m31 * m.m12);\n const num5 = (m.m11 * m.offsetY) - (m.offsetX * m.m12);\n const num4 = (m.m21 * m.m32) - (m.m31 * m.m22);\n const num3 = (m.m21 * m.offsetY) - (m.offsetX * m.m22);\n const num2 = (m.m31 * m.offsetY) - (m.offsetX * m.m32);\n const num17 = ((m.m23 * num5) - (m.offsetZ * num7)) - (m.m13 * num3);\n const num16 = ((m.m13 * num2) - (m.m33 * num5)) + (m.offsetZ * num6);\n const num15 = ((m.m33 * num3) - (m.offsetZ * num4)) - (m.m23 * num2);\n const num14 = num7;\n const num13 = -num6;\n const num12 = num4;\n const invdet = 1.0 / determinant;\n return Matrix3D.from(cofactor11 * invdet, cofactor21 * invdet, cofactor31 * invdet, .0, num18 * invdet, num19 * invdet, num20 * invdet, .0, num12 * invdet, num13 * invdet, num14 * invdet, .0, num15 * invdet, num16 * invdet, num17 * invdet, 1.0);\n }\n else {\n const determinant = Matrix3D.determinant(m);\n if (determinant == 0.0) {\n return null;\n }\n const num1 = m.m33 * m.m44 - m.m34 * m.offsetZ;\n const num2 = m.m32 * m.m44 - m.m34 * m.offsetY;\n const num3 = m.m31 * m.m44 - m.m34 * m.offsetX;\n const num4 = m.m32 * m.offsetZ - m.m33 * m.offsetY;\n const num5 = m.m31 * m.offsetZ - m.m33 * m.offsetX;\n const num6 = m.m31 * m.offsetY - m.m32 * m.offsetX;\n const num7 = m.m33 * m.m44 - m.m34 * m.offsetZ;\n const num8 = m.m32 * m.m44 - m.m34 * m.offsetY;\n const num9 = m.m31 * m.m44 - m.m34 * m.offsetX;\n const num10 = m.m32 * m.offsetZ - m.m33 * m.offsetY;\n const num11 = m.m31 * m.offsetZ - m.m33 * m.offsetX;\n const num12 = m.m31 * m.offsetY - m.m32 * m.offsetX;\n const num13 = m.m23 * m.m44 - m.m24 * m.offsetZ;\n const num14 = m.m22 * m.m44 - m.m24 * m.offsetY;\n const num15 = m.m21 * m.m44 - m.m24 * m.offsetX;\n const num16 = m.m22 * m.offsetZ - m.m23 * m.offsetY;\n const num17 = m.m21 * m.offsetZ - m.m23 * m.offsetX;\n const num18 = m.m21 * m.offsetY - m.m22 * m.offsetX;\n const num19 = m.m23 * m.m34 - m.m24 * m.m33;\n const num20 = m.m22 * m.m34 - m.m24 * m.m32;\n const num21 = m.m21 * m.m34 - m.m24 * m.m31;\n const num22 = m.m22 * m.m33 - m.m23 * m.m32;\n const num23 = m.m21 * m.m33 - m.m23 * m.m31;\n const num24 = m.m21 * m.m32 - m.m22 * m.m31;\n const cofactor11 = (m.m22 * num1 - m.m23 * num2 + m.m24 * num4);\n const cofactor12 = -(m.m21 * num1 - m.m23 * num3 + m.m24 * num5);\n const cofactor13 = (m.m21 * num2 - m.m22 * num3 + m.m24 * num6);\n const cofactor14 = -(m.m21 * num4 - m.m22 * num5 + m.m23 * num6);\n const cofactor21 = -(m.m12 * num7 - m.m13 * num8 + m.m14 * num10);\n const cofactor22 = (m.m11 * num7 - m.m13 * num9 + m.m14 * num11);\n const cofactor23 = -(m.m11 * num8 - m.m12 * num9 + m.m14 * num12);\n const cofactor24 = (m.m11 * num10 - m.m12 * num11 + m.m13 * num12);\n const cofactor31 = (m.m12 * num13 - m.m13 * num14 + m.m14 * num16);\n const cofactor32 = -(m.m11 * num13 - m.m13 * num15 + m.m14 * num17);\n const cofactor33 = (m.m11 * num14 - m.m12 * num15 + m.m14 * num18);\n const cofactor34 = -(m.m11 * num16 - m.m12 * num17 + m.m13 * num18);\n const cofactor41 = -(m.m12 * num19 - m.m13 * num20 + m.m14 * num22);\n const cofactor42 = (m.m11 * num19 - m.m13 * num21 + m.m14 * num23);\n const cofactor43 = -(m.m11 * num20 - m.m12 * num21 + m.m14 * num24);\n const cofactor44 = (m.m11 * num22 - m.m12 * num23 + m.m13 * num24);\n const inverseDet = 1.0 / determinant;\n return Matrix3D.from(cofactor11 * inverseDet, cofactor21 * inverseDet, cofactor31 * inverseDet, cofactor41 * inverseDet, cofactor12 * inverseDet, cofactor22 * inverseDet, cofactor32 * inverseDet, cofactor42 * inverseDet, cofactor13 * inverseDet, cofactor23 * inverseDet, cofactor33 * inverseDet, cofactor43 * inverseDet, cofactor14 * inverseDet, cofactor24 * inverseDet, cofactor34 * inverseDet, cofactor44 * inverseDet);\n }\n }\n /**\n * Moves a given point in 3D space given the transformation matrix.\n * @param point\n * @param matrix\n */\n static transform(point, matrix) {\n var pt = { x: point.x, y: point.y, z: point.z };\n if (!Matrix3D.isIdentity(matrix)) {\n var x = pt.x;\n var y = pt.y;\n var z = pt.z;\n pt.x = (((x * matrix.m11) + (y * matrix.m21)) + (z * matrix.m31)) + matrix.offsetX;\n pt.y = (((x * matrix.m12) + (y * matrix.m22)) + (z * matrix.m32)) + matrix.offsetY;\n pt.z = (((x * matrix.m13) + (y * matrix.m23)) + (z * matrix.m33)) + matrix.offsetZ;\n if (!Matrix3D.isAffine(matrix)) {\n var num4 = (((x * matrix.m14) + (y * matrix.m24)) + (z * matrix.m34)) + matrix.m44;\n if (num4 != .0) {\n pt.x /= num4;\n pt.y /= num4;\n pt.z /= num4;\n }\n }\n }\n return pt;\n }\n}\n/** Utilities to build, combine and convert {@link Quaternion} rotations. */\nexport class Quaternion {\n /** Returns the identity quaternion (no rotation). */\n static identity() {\n return Quaternion.from(0, 0, 0, 1);\n }\n /**\n * Builds a {@link Quaternion} from its x, y, z, w components, in that order.\n * @param args Exactly 4 numbers: x, y, z, w.\n * @throws If the number of arguments is not exactly 4.\n */\n static from(...args) {\n const l = 4;\n if (args.length !== l) {\n throw new RangeError(`Must provide exactly ${l} numbers`);\n }\n return {\n x: args[0],\n y: args[1],\n z: args[2],\n w: args[3],\n };\n }\n /**\n * Parses a string representation of a quaternion (4 numbers) into a {@link Quaternion}.\n * @param input String to parse.\n * @throws If the input cannot be parsed as exactly 4 numbers.\n */\n static parse(input) {\n const arr = parseAsNumericalArray(input);\n if (arr && arr.length === 4) {\n return Quaternion.from.apply(null, arr);\n }\n throw new Error(`Cannot parse \"${input}\" as a valid Quaternion.`);\n }\n /**\n * Builds the (shortest-arc) quaternion representing the rotation that takes one unit vector onto another.\n * Normalizes both input vectors in place as a side effect.\n * @param from Source direction.\n * @param to Target direction.\n */\n static fromVectors(from, to) {\n // setup\n Vector3D.normalize(from);\n Vector3D.normalize(to);\n const yieldQ = (x, y, z, w) => {\n const retval = Quaternion.from(x, y, z, w);\n Quaternion.normalize(retval);\n return retval;\n };\n // process\n let r = Vector3D.dot(from, to) + 1;\n if (r.isCloseTo(0)) {\n if (Math.abs(from.x) > Math.abs(from.z)) {\n return yieldQ(-from.y, from.x, 0, /* r */ 0);\n }\n return yieldQ(0, -from.z, from.y, /* r */ 0);\n }\n else {\n return yieldQ(from.y * to.z - from.z * to.y, from.z * to.x - from.x * to.z, from.x * to.y - from.y * to.x, r);\n }\n }\n /**\n * In-place normalizarion of the provided quaternion\n * @param q {Quaternion}\n */\n static normalize(q) {\n const l = Quaternion.mag(q);\n if (l.isCloseTo(0)) {\n q.x = q.y = q.z = 0;\n q.w = 1;\n }\n else {\n const f = 1 / l;\n q.x *= f;\n q.y *= f;\n q.z *= f;\n q.w *= f;\n }\n }\n /**\n * Returns a normalized copy of the source quaternion.\n * @param q {Quaternion}\n */\n static unit(q) {\n const clone = Quaternion.from(q.x, q.y, q.z, q.w);\n Quaternion.normalize(clone);\n return clone;\n }\n /**\n * Creates a quaternion instance given the rotation axis and an angle (in degrees).\n * @param axis\n * @param angleDeg\n */\n static fromAxisAngle(axis, angleDeg) {\n angleDeg %= 360.0;\n var angleInRadians = DEG2RAD * angleDeg;\n var length = Vector3D.mag(axis);\n if (length == 0.0) {\n throw new RangeError('Invalid argument');\n }\n var factor = Math.sin(0.5 * angleInRadians) / length;\n var x = axis.x * factor;\n var y = axis.y * factor;\n var z = axis.z * factor;\n return Quaternion.from(x, y, z, Math.cos(.5 * angleInRadians));\n }\n /**\n * Creates a quaternion instance given the rotation matrix.\n * @param rotationMatrix\n */\n static fromRotationMatrix(rotationMatrix) {\n const trace = rotationMatrix.m11 + rotationMatrix.m22 + rotationMatrix.m33 + rotationMatrix.m44;\n if (trace > 0) {\n const sq = 0.5 / Math.sqrt(trace);\n const w = 0.25 / sq;\n const x = (rotationMatrix.m23 - rotationMatrix.m32) * sq;\n const y = (rotationMatrix.m31 - rotationMatrix.m13) * sq;\n const z = (rotationMatrix.m12 - rotationMatrix.m21) * sq;\n return Quaternion.from(x, y, z, w);\n }\n else {\n if (rotationMatrix.m11 > rotationMatrix.m22 && rotationMatrix.m11 > rotationMatrix.m22) {\n const sq = 0.5 / Math.sqrt(rotationMatrix.m44 + rotationMatrix.m11 - rotationMatrix.m22 - rotationMatrix.m33);\n const w = (rotationMatrix.m23 - rotationMatrix.m32) * sq;\n const x = 0.25 / sq;\n const y = (rotationMatrix.m12 + rotationMatrix.m21) * sq;\n const z = (rotationMatrix.m31 + rotationMatrix.m13) * sq;\n return Quaternion.from(x, y, z, w);\n }\n else if (rotationMatrix.m22 > rotationMatrix.m33) {\n const sq = .5 / Math.sqrt(rotationMatrix.m44 + rotationMatrix.m22 - rotationMatrix.m11 - rotationMatrix.m33);\n const z = (rotationMatrix.m23 + rotationMatrix.m32) * sq;\n const y = 0.25 / sq;\n const x = (rotationMatrix.m12 + rotationMatrix.m21) * sq;\n const w = (rotationMatrix.m31 - rotationMatrix.m13) * sq;\n return Quaternion.from(x, y, z, w);\n }\n else {\n const sq = .5 / Math.sqrt(rotationMatrix.m44 + rotationMatrix.m33 - rotationMatrix.m11 - rotationMatrix.m22);\n const y = (rotationMatrix.m23 + rotationMatrix.m32) * sq;\n const z = 0.25 / sq;\n const w = (rotationMatrix.m12 - rotationMatrix.m21) * sq;\n const x = (rotationMatrix.m31 - rotationMatrix.m13) * sq;\n return Quaternion.from(x, y, z, w);\n }\n }\n }\n /**\n * Returns the conjugate of the quaternion (vector part negated). For a unit quaternion, this\n * represents the inverse rotation.\n * @param q\n */\n static conjugate(q) {\n return Quaternion.from(-q.x, -q.y, -q.z, q.w);\n }\n /**\n * Returns the magnitude/length of the provided quaternion.\n * @param q {Quaternion}\n */\n static mag(q) {\n return Math.sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w);\n }\n /**\n * Returns the squared magnitude of the vector (imaginary) part of the quaternion.\n * @param q\n */\n static norm(q) {\n return (q.x * q.x + q.y * q.y + q.z * q.z);\n }\n /**\n * Returns the (unit) rotation axis represented by the quaternion, defaulting to the y axis\n * when the quaternion has no vector part (i.e. represents no rotation).\n * @param q\n */\n static axis(q) {\n if (q.x == .0 && q.y == .0 && q.z == .0) {\n return Vector3D.j();\n }\n return Vector3D.unit(q);\n }\n /**\n * Rotates a vector by the given quaternion (normalizes the quaternion in place as a side effect).\n * @param v Vector to rotate.\n * @param q Rotation quaternion.\n */\n static transform(v, q) {\n Quaternion.normalize(q);\n const cross = Vector3D.cross(q, v);\n const t = Vector3D.scale(cross, 2);\n const tCross = Vector3D.cross(q, t);\n return {\n x: v.x + q.w * t.x + tCross.x,\n y: v.y + q.w * t.y + tCross.y,\n z: v.z + q.w * t.z + tCross.z,\n };\n }\n /**\n * Returns the rotation angle (in degrees) of the provided quaternion.\n * @param q\n */\n static angle(q) {\n let y = Math.sqrt(q.x * q.x + q.y * q.y + q.z * q.z);\n let x = q.w;\n if (y > Number.MAX_VALUE) {\n const num = Math.max(Math.abs(q.x), Math.max(Math.abs(q.y), Math.abs(q.z)));\n const num5 = q.x / num;\n const num4 = q.y / num;\n const num3 = q.z / num;\n y = Math.sqrt(((num5 * num5) + (num4 * num4)) + (num3 * num3));\n x /= num;\n }\n return (Math.atan2(y, x) * 114.59155902616465);\n }\n /**\n * Builds the rotation matrix equivalent to the given quaternion.\n * @param q\n */\n static toRotationMatrix(q) {\n var m = Matrix3D.identity();\n var X = q.x;\n var Y = q.y;\n var Z = q.z;\n var W = q.w;\n m.m11 = 1.0 - 2.0 * Y * Y - 2.0 * Z * Z;\n m.m12 = 2.0 * X * Y + 2.0 * W * Z;\n m.m13 = 2.0 * X * Z - 2.0 * W * Y;\n m.m21 = 2.0 * X * Y - 2.0 * W * Z;\n m.m22 = 1.0 - 2.0 * X * X - 2.0 * Z * Z;\n m.m23 = 2.0 * Y * Z + 2.0 * W * X;\n m.m31 = 2.0 * W * Y + 2.0 * X * Z;\n m.m32 = 2.0 * Y * Z - 2.0 * W * X;\n m.m33 = 1.0 - 2.0 * X * X - 2.0 * Y * Y;\n return m;\n }\n /**\n * Returns the inverse rotation of the given quaternion (the conjugate of its normalized form).\n * @param q\n */\n static invert(q) {\n const n = Quaternion.unit(q);\n return Quaternion.conjugate(n);\n }\n /**\n * Combines two quaternions.\n * @param q1\n * @param q2\n */\n static multiply(q1, q2) {\n return Quaternion.from(q1.w * q2.x + q1.x + q2.w + q1.y * q2.z - q1.z * q2.y, q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x, q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w, q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z);\n }\n /**\n * Returns the dot product of two quaternions.\n * @param q1\n * @param q2\n */\n static dot(q1, q2) {\n var q = Quaternion.multiply(q1, Quaternion.conjugate(q2));\n return q.w;\n }\n}\n// #endregion\n//}\n", "//namespace Pacem.Geometry {\nimport { Vector3D } from './geom3d';\n//#region Utils\n/** Utility tools for 3D geometry: rays, triangles and their interactions. */\nexport class Utils3D {\n /**\n * Computes the intersection between a ray and a triangle in the 3D space - if any - using the M\u00F6ller\u2013Trumbore algorithm.\n * @param ray Array of two points identifying a ray.\n * @param triangle Array of three points identifying a triangle.\n * @returns Intersection point if any, otherwise null.\n */\n static intersect(ray, triangle) {\n // M\u00F6ller\u2013Trumbore algorithm\n const [start, end] = ray;\n const vector = Vector3D.subtract(start, end);\n const [a, b, c] = triangle;\n const ab = Vector3D.subtract(a, b);\n const ac = Vector3D.subtract(a, c);\n const cross = Vector3D.cross(vector, ac);\n const det = Vector3D.dot(ab, cross);\n if (det.isCloseTo(0)) {\n return null;\n }\n const invDet = 1 / det;\n const s = Vector3D.subtract(start, a);\n const u = invDet * Vector3D.dot(s, cross);\n if (u < 0 || u > 1) {\n return null;\n }\n const scross = Vector3D.cross(s, ab);\n const v = invDet * Vector3D.dot(vector, scross);\n if (v < 0 || (u + v) > 1) {\n return null;\n }\n const t = invDet * Vector3D.dot(ac, scross);\n if (t < 0 || t.isCloseTo(0)) {\n return null;\n }\n return Vector3D.add(start, Vector3D.scale(vector, t));\n }\n}\n//#endregion\n//}\n", "export * from './geom/linear-algebra';\nexport * from './geom/geom3d';\n", "export * from './math/complex';\nimport * as DataAnalysis from './index-mathematics-dataanalysis.js';\nexport { DataAnalysis };\nimport * as NumberTheory from './math/math';\nexport { NumberTheory };\n", "// namespace Pacem.Mathematics {\nfunction complex(c) {\n if (typeof c === 'number') {\n c = { real: c, img: 0 };\n }\n return c;\n}\nvar NOT_A_COMPLEX;\nfunction buildComplex(real, img) {\n const c = {};\n Object.defineProperty(c, 'real', { value: real, writable: false });\n Object.defineProperty(c, 'img', { value: img, writable: false });\n return c;\n}\nfunction nac() {\n return NOT_A_COMPLEX || (NOT_A_COMPLEX = buildComplex(Number.NaN, Number.NaN));\n}\n/** Utility tools to build and operate on {@link Complex} numbers. */\nexport class Complex {\n static build(real, img) {\n if (this.isComplex(real)) {\n return real;\n }\n img ??= 0;\n if (typeof real != 'number' || typeof img != 'number') {\n return nac();\n }\n return buildComplex(real, img || 0);\n }\n /**\n * Adds two complex numbers (real numbers are treated as having a zero imaginary part).\n * @param a First addend.\n * @param b Second addend.\n */\n static add(a, b) {\n const ac = complex(a), bc = complex(b);\n return buildComplex(ac.real + bc.real, ac.img + bc.img);\n }\n /**\n * Subtracts one complex number from another.\n * @param from Minuend.\n * @param what Subtrahend.\n */\n static subtract(from, what) {\n const ac = complex(from), bc = complex(what);\n return buildComplex(ac.real - bc.real, ac.img - bc.img);\n }\n /**\n * Multiplies two complex numbers.\n * @param a First factor.\n * @param b Second factor.\n */\n static multiply(a, b) {\n const ac = complex(a), bc = complex(b);\n return buildComplex(\n /* real*/ ac.real * bc.real - ac.img * bc.img, \n /* img */ ac.real * bc.img + ac.img * bc.real);\n }\n /**\n * Divides one complex number by another.\n * @param a Dividend.\n * @param b Divisor.\n * @returns The quotient, or {@link Complex.NaC} if the divisor is (close to) zero.\n */\n static divide(a, b) {\n const ac = complex(a), bc = complex(b);\n const div = this.absSquare(bc).roundoff();\n if (div === 0) {\n return nac();\n }\n const inv_div = 1 / div;\n return buildComplex(\n /* real*/ inv_div * (ac.real * bc.real + ac.img * bc.img), \n /* img */ inv_div * (ac.img * bc.real - ac.real * bc.img));\n }\n /**\n * Returns the squared modulus (|z|\u00B2) of the complex number, i.e. real\u00B2 + img\u00B2.\n * Cheaper than {@link modulus} since it avoids the square root.\n * @param c\n */\n static absSquare(c) {\n const ac = complex(c);\n return Math.pow(ac.real, 2) + Math.pow(ac.img, 2);\n }\n /**\n * Returns the modulus (magnitude) of the complex number.\n * @param c\n */\n static modulus(c) {\n return Math.sqrt(this.absSquare(c));\n }\n /**\n * Type guard checking whether the provided value is a {@link Complex} number.\n * @param c\n */\n static isComplex(c) {\n return c != null && typeof c === 'object' && 'real' in c && 'img' in c && typeof c.real === 'number' && typeof c.img === 'number';\n }\n /**\n * Returns the complex conjugate: same real part, negated imaginary part.\n * @param a\n */\n static conjugate(a) {\n a = complex(a);\n return buildComplex(a.real, Math.abs(a.img) == 0 ? 0 : -a.img);\n }\n /**\n * Checks whether two complex numbers have the same real and imaginary parts.\n * @param c1\n * @param c2\n */\n static equals(c1, c2) {\n const c_1 = this.build(c1), c_2 = this.build(c2);\n if (!this.isComplex(c1) || !this.isComplex(c2)) {\n return false;\n }\n return c_1.real === c_2.real && c_1.img === c_2.img;\n }\n //static isNaN(c: Complex | number): boolean {\n // switch (c) {\n // case undefined:\n // // doh!\n // return true;\n // case null:\n // // doh!\n // return false;\n // default:\n // if (!this.isComplex( c)\n // }\n //}\n /** The \"Not a Complex\" sentinel value (`NaN + NaNi`), returned by operations on invalid input. */\n static get NaC() { return nac(); }\n}\n//}\n", "export * from './math/fourier';\nexport * from './math/gaussian';\n;\nexport * from './math/interpolation';\nexport * from './math/statistics';\n", "//namespace Pacem.Mathematics.DataAnalysis {\nimport { Complex } from './complex';\n// #region DFT utils\n/**\n * Unit circle Euler's formula\n * @param k partial 'slices'\n * @param N total 'slices'\n */\nfunction euler(k, N) {\n const x = 2 * Math.PI * k / N;\n return Complex.build(Math.cos(x), Math.sin(x));\n}\n/** Unit circle memoizer */\nconst unitCircle = {};\nfunction exp(k, N) {\n const memN = unitCircle[N] = unitCircle[N] || {};\n return memN[k] = memN[k] || euler(k, N);\n}\n// #endregion\nfunction isPowerOfTwo(length) {\n return length > 0 && (length & (length - 1)) === 0;\n}\n/** Cooley-Tukey */\nfunction fftRec(data) {\n const retval = [], N = data.length;\n if (N === 1) {\n return [Complex.build(data[0])];\n }\n // even/odds recursion\n const retval_2n = fftRec(data.filter((_, i) => i % 2 === 0)), retval_2n1 = fftRec(data.filter((_, i) => i % 2 === 1));\n for (var k = 0; k < N / 2; k++) {\n const t = retval_2n[k], e = Complex.multiply(exp(k, N), retval_2n1[k]);\n retval[k] = Complex.add(t, e);\n retval[k + (N / 2)] = Complex.subtract(t, e);\n }\n return retval;\n}\n/** Discrete Fourier Transform (DFT) utilities, including a Cooley-Tukey FFT fast path for power-of-two inputs. */\nexport class Fourier {\n /**\n * Checks the input vector and outputs a frequency vector using the best performing algo.\n * @param data Input vector of any size\n * @param normalize Whether to normalize the signal or not (default true)\n */\n static transform(data, normalize = true) {\n data = data || [];\n if (isPowerOfTwo(data.length)) {\n return this.fft(data, normalize);\n }\n return this.dft(data, normalize);\n }\n /**\n * Checks the input vector and applies inverted fourier transform's best performing algo.\n * @param data Input frequency vector\n */\n static invert(data, normalize = true) {\n return this.idft(data || [], normalize);\n }\n /**\n * Naive Discrete Fourier Transform implementation (O(n^2) algo).\n * @param data Input vector of any size\n * @param normalize Whether to normalize the signal or not (default true)\n */\n static dft(data, normalize = true) {\n const N = (data || [])?.length, DEN = normalize ? 1 / Math.sqrt(N) : 1, retval = [];\n for (let k = 0; k < N; k++) {\n retval.push({ real: 0, img: 0 });\n for (let j = 0; j < N; j++) {\n const e = exp(k * j, N), item = Complex.multiply(data[j], e), itemN = Complex.multiply(item, DEN);\n retval[k] = Complex.add(retval[k], itemN);\n }\n }\n return retval;\n }\n /**\n * Inverse Discrete Fourier Transform.\n * @param data Input vector data of any size\n */\n static idft(data, normalize = true) {\n const reversed = data.map(i => Complex.build(i.img, i.real)), temp = this.transform(reversed, normalize);\n return temp.map(c => Complex.build(c.img, c.real));\n }\n /**\n * FFT processing using Cooley-Tukey.\n * @param data Input vector (size MUST be power of 2)\n */\n static fft(data, normalize = true) {\n const retval = fftRec(data);\n if (!normalize) {\n return retval;\n }\n const DEN = 1 / Math.sqrt(data.length);\n return retval.map(i => Complex.multiply(i, DEN));\n }\n}\n//}\n", "//namespace Pacem.Mathematics.DataAnalysis {\nconst SQRT_PI = Math.sqrt(Math.PI);\n/**\n * Complementary Error Function as seen on Numerical Recipes in C (p.221).\n * @param x Input\n */\nfunction erfc(x) {\n const z = Math.abs(x);\n const t = 1.0 / (1.0 + 0.5 * z);\n const ans = t * Math.exp(-z * z - 1.26551223 + t * (1.00002368 + t * (0.37409196 + t * (0.09678418 +\n t * (-0.18628806 + t * (0.27886807 + t * (-1.13520398 + t * (1.48851587 +\n t * (-0.82215223 + t * 0.17087277)))))))));\n return x >= 0.0 ? ans : 2.0 - ans;\n}\n/**\n * Error Function.\n * @param x\n */\nfunction erf(x) {\n return 1 - erfc(x);\n}\n/** Represents a Gaussian (normal) distribution and exposes its density and cumulative probability functions. */\nexport class Gaussian {\n /**\n * Creates a new {@link Gaussian} distribution with the given mean and standard deviation.\n * @param mean Mean (\u03BC) of the distribution.\n * @param stdev Standard deviation (\u03C3) of the distribution (its absolute value is used).\n */\n constructor(mean, stdev) {\n this.mean = mean;\n this.stdev = Math.abs(stdev);\n this.variance = Math.pow(stdev, 2);\n }\n /** The standard normal distribution (mean 0, standard deviation 1). */\n static get normal() {\n return _normal;\n }\n /**\n * Un-normalized probability density function.\n * Can be useful as a weight function without requiring the integral w(x)dx to be 1.\n * @param x Input value\n */\n weight(x) {\n // e^(.5 *(-Z^2))\n return Math.exp(-0.5 * Math.pow(this._z(x), 2));\n }\n /**\n * Probability density function (PDF).\n * @param x Input value\n */\n probabilityDensity(x) {\n // 1/(\u03C3 \u221A2\u03C0) * e^(.5 *(-Z^2))\n const inv_coeff = this.stdev * Math.SQRT2 * SQRT_PI, exp_part = this.weight(x);\n return exp_part / inv_coeff;\n }\n _z(x) {\n // Z = (x - \u03BC)/\u03C3\n return (x - this.mean) / this.stdev;\n }\n /**\n * Returns the area under the PDF from -\u221E to x\n * @param x Input value\n */\n probability(x) {\n return 0.5 * erfc(-this._z(x) / Math.SQRT2);\n }\n}\nconst _normal = new Gaussian(0, 1);\n//}\n", "/**\n * Lagrange polynomial interpolation, evaluated using the numerically stable barycentric form.\n * Given a set of `(x, y)` points, builds the unique polynomial of minimal degree passing through\n * all of them and evaluates it at arbitrary x values.\n */\nexport class Lagrange {\n /** Use {@link Lagrange.create} to build an instance. */\n constructor(points) {\n this.#set = points;\n }\n #set;\n #weights = null;\n _prepareBarycentric() {\n if (this.#weights) {\n return;\n }\n const points = this.#set || [];\n const n = points.length;\n if (n === 0) {\n this.#weights = [];\n return;\n }\n // Compute barycentric weights in a numerically stable way.\n // Direct product of differences can overflow/underflow for large n.\n // We compute log-weights and normalize by subtracting the max log to\n // keep values in a reasonable range (scaling cancels out in evaluation).\n const logs = new Array(n);\n const signs = new Array(n);\n for (let j = 0; j < n; j++) {\n let sumLog = 0;\n let sign = 1;\n const xj = points[j].x;\n for (let m = 0; m < n; m++) {\n if (m === j)\n continue;\n const diff = xj - points[m].x;\n if (diff === 0) {\n throw new Error('Invalid function provided.');\n }\n if (diff < 0)\n sign = -sign;\n sumLog += Math.log(Math.abs(diff));\n }\n // log of weight is -sumLog\n logs[j] = -sumLog;\n signs[j] = sign;\n }\n // normalize logs to avoid underflow/overflow when exponentiating\n let maxLog = logs[0];\n for (let j = 1; j < n; j++) {\n if (logs[j] > maxLog)\n maxLog = logs[j];\n }\n const w = new Array(n);\n for (let j = 0; j < n; j++) {\n // scaled weight: sign * exp(log - maxLog)\n const scaled = Math.exp(logs[j] - maxLog);\n w[j] = signs[j] * scaled;\n }\n this.#weights = w;\n }\n _computeBarycentric(x) {\n const points = this.#set || [];\n if (!this.#weights) {\n this._prepareBarycentric();\n }\n const w = this.#weights || [];\n let numerator = 0;\n let denominator = 0;\n for (let j = 0; j < points.length; j++) {\n const xj = points[j].x;\n if (x === xj) {\n return points[j].y;\n }\n const temp = w[j] / (x - xj);\n numerator += temp * points[j].y;\n denominator += temp;\n }\n return numerator / denominator;\n }\n // Iterative/global Lagrange computation removed \u2014 barycentric is used\n // exclusively for interpolation.\n /**\n * Evaluates the Lagrange interpolating polynomial at the given x, using barycentric weights.\n * @param x Input value.\n * @returns The interpolated y value (the exact node y if x coincides with a node).\n */\n interpolate(x) {\n return this._computeBarycentric(x);\n }\n static create(...values) {\n var array = [];\n if (arguments.length > 0 && Array.isArray(arguments[0])) {\n array = arguments[0];\n }\n else {\n array = Array.from(values);\n }\n const points = array.map((y, x) => { return typeof y === 'number' ? { x, y } : y; });\n return new Lagrange(points);\n }\n}\n/**\n * @deprecated Use Lagrange instead. This alias is kept for backward compatibility.\n */\nexport const Lagrangian = {\n create: Lagrange.create\n};\n/**\n * Piecewise Cubic Hermite Interpolating Polynomial (PCHIP).\n * Builds a shape-preserving (monotonicity-respecting) piecewise-cubic curve through a set of\n * `(x, y)` points: unlike {@link Lagrange}, it does not overshoot between nodes, at the cost of\n * only being C\u00B9 (continuous first derivative, not second).\n */\nexport class Pchip {\n /** Use {@link Pchip.create} to build an instance. */\n constructor(points) {\n if (!points || points.length < 2)\n throw new Error('Need at least 2 points');\n const pts = points.slice().sort((a, b) => a.x - b.x);\n this.xs = pts.map(p => p.x);\n this.ys = pts.map(p => p.y);\n this.ms = this.computeDerivatives();\n }\n computeDerivatives() {\n const n = this.xs.length;\n const h = new Array(n - 1);\n const delta = new Array(n - 1);\n for (let i = 0; i < n - 1; i++) {\n h[i] = this.xs[i + 1] - this.xs[i];\n delta[i] = (this.ys[i + 1] - this.ys[i]) / h[i];\n }\n const m = new Array(n).fill(0);\n // endpoints: use one-sided slope\n m[0] = delta[0];\n m[n - 1] = delta[n - 2];\n // interior: weighted harmonic mean (PCHIP)\n for (let i = 1; i < n - 1; i++) {\n const d1 = delta[i - 1], d2 = delta[i];\n if (d1 === 0 || d2 === 0 || d1 * d2 <= 0) {\n m[i] = 0;\n }\n else {\n const w1 = 2 * h[i] + h[i - 1];\n const w2 = h[i] + 2 * h[i - 1];\n m[i] = (w1 + w2) / ((w1 / d1) + (w2 / d2));\n }\n }\n // (Optional) limit derivative to avoid overshoot: monotonicity constraints\n for (let i = 0; i < n - 1; i++) {\n if (delta[i] === 0) {\n m[i] = 0;\n m[i + 1] = 0;\n }\n else {\n const a = m[i] / delta[i];\n const b = m[i + 1] / delta[i];\n const s = a * a + b * b;\n if (s > 9) { // limit size, algorithm from Fritsch-Carlson/PCHIP\n const tau = 3 / Math.sqrt(s);\n m[i] = tau * a * delta[i];\n m[i + 1] = tau * b * delta[i];\n }\n }\n }\n return m;\n }\n /**\n * Evaluates the PCHIP curve at the given x, using cubic Hermite interpolation on the enclosing segment.\n * Values outside the node range are linearly extrapolated using the boundary derivative.\n * @param x Input value.\n * @returns The interpolated y value.\n */\n interpolate(x) {\n const xs = this.xs, ys = this.ys, ms = this.ms;\n const n = xs.length;\n // quick bounds\n if (x <= xs[0]) {\n // avoid dangerous extrapolation: use linear extension or return ys[0]\n const slope = ms[0];\n return ys[0] + slope * (x - xs[0]);\n }\n if (x >= xs[n - 1]) {\n const slope = ms[n - 1];\n return ys[n - 1] + slope * (x - xs[n - 1]);\n }\n // locate interval\n let i = 0, j = n - 1;\n while (j - i > 1) {\n const mid = (i + j) >> 1;\n if (xs[mid] <= x)\n i = mid;\n else\n j = mid;\n }\n const h = xs[i + 1] - xs[i];\n const t = (x - xs[i]) / h;\n const t2 = t * t, t3 = t2 * t;\n // Hermite basis\n const h00 = 2 * t3 - 3 * t2 + 1;\n const h10 = t3 - 2 * t2 + t;\n const h01 = -2 * t3 + 3 * t2;\n const h11 = t3 - t2;\n return h00 * ys[i] + h10 * (ms[i] * h) + h01 * ys[i + 1] + h11 * (ms[i + 1] * h);\n }\n static create(...values) {\n var array = [];\n if (arguments.length > 0 && Array.isArray(arguments[0])) {\n array = arguments[0];\n }\n else {\n array = Array.from(values);\n }\n const points = array.map((y, x) => { return typeof y === 'number' ? { x, y } : y; });\n return new Pchip(points);\n }\n}\n/**\n * Newton's divided-difference polynomial interpolation.\n * Builds the same interpolating polynomial as {@link Lagrange} but represents it in Newton form\n * (a nested/Horner-like product of divided differences), which is efficient to evaluate and to\n * extend incrementally as new points are added.\n */\nexport class Newton {\n /** Use {@link Newton.create} to build an instance. */\n constructor(points) {\n if (!points || points.length === 0)\n throw new Error('Need at least 1 point');\n const pts = points.slice().sort((a, b) => a.x - b.x);\n this.xs = pts.map(p => p.x);\n const n = pts.length;\n // copy y values into coefficients array and convert in-place to divided differences\n const a = pts.map(p => p.y);\n for (let j = 1; j < n; j++) {\n for (let i = n - 1; i >= j; i--) {\n const denom = this.xs[i] - this.xs[i - j];\n if (denom === 0)\n throw new Error('Invalid function provided.');\n a[i] = (a[i] - a[i - 1]) / denom;\n }\n }\n this.coeffs = a;\n }\n /**\n * Evaluates the Newton form of the interpolating polynomial at the given x, via nested multiplication.\n * @param x Input value.\n * @returns The interpolated y value (`NaN` if the interpolator has no points).\n */\n interpolate(x) {\n const xs = this.xs, a = this.coeffs;\n const n = a.length;\n if (n === 0)\n return NaN;\n // evaluate Newton form with nested multiplication (Horner-like)\n let result = a[n - 1];\n for (let i = n - 2; i >= 0; i--) {\n result = result * (x - xs[i]) + a[i];\n }\n return result;\n }\n static create(...values) {\n var array = [];\n if (arguments.length > 0 && Array.isArray(arguments[0])) {\n array = arguments[0];\n }\n else {\n array = Array.from(values);\n }\n const points = array.map((y, x) => { return typeof y === 'number' ? { x, y } : y; });\n return new Newton(points);\n }\n}\n//}\n", "import { Gaussian } from './gaussian';\nconst selfSelector = (i, _) => i;\nfunction mode(set, selector = selfSelector) {\n const groups = Object.groupBy(set, selector);\n let key, max = 0;\n for (let group in groups) {\n const l = groups[group].length;\n if (l > max) {\n key = parseInt(group);\n max = l;\n }\n }\n return key;\n}\nfunction median(set, selector = selfSelector) {\n const setCopy = set.slice(0), length = setCopy.length;\n setCopy.sort((a, b) => {\n const i = selector(a), j = selector(b);\n return i - j;\n });\n const index = Math.ceil(setCopy.length / 2) - 1;\n if (length % 2 == 1) {\n return setCopy[index];\n }\n return .5 * (setCopy[index + 1] + setCopy[index]);\n}\nfunction sum(set, selector = selfSelector) {\n return set.reduce((p, c, i) => p + selector(c, i), 0);\n}\nfunction mean(set, selector = selfSelector) {\n return sum(set, selector) / set.length;\n}\nfunction variance(set, selector = selfSelector, bessel = false) {\n const avg = mean(set, selector);\n return set.reduce((p, c) => Math.pow(c - avg, 2) + p, 0) / (set.length - (bessel ? 1 : 0));\n}\nfunction stdev(set, selector = selfSelector, bessel = false) {\n const v = variance(set, selector, bessel);\n return Math.sqrt(v);\n}\nfunction correlation(set, arg2, selector1 = selfSelector, selector2 = selfSelector) {\n const twoArrays = Array.isArray(arg2);\n if (twoArrays && arg2.length !== set.length) {\n throw new Error('Sets must be of the same length.');\n }\n const length = set.length;\n const setX = set, setY = twoArrays ? arg2 : set;\n const selectorX = twoArrays ? selector1 : arg2;\n const selectorY = twoArrays ? selector2 : selector1;\n const meanX = mean(setX, selectorX);\n const meanY = mean(setY, selectorY);\n let accNum = 0;\n let accDenXSq = 0;\n let accDenYSq = 0;\n for (let i = 0; i < length; i++) {\n const itemX = setX[i], itemY = setY[i];\n const a = selectorX(itemX, i) - meanX;\n const b = selectorY(itemY, i) - meanY;\n accNum += (a * b);\n accDenXSq += (a * a);\n accDenYSq += (b * b);\n }\n return accNum / Math.sqrt(accDenXSq * accDenYSq);\n}\nfunction linearRegression(set, arg2, selector1 = selfSelector, selector2 = selfSelector) {\n const twoArrays = Array.isArray(arg2);\n if (twoArrays && arg2.length !== set.length) {\n throw new Error('Sets must be of the same length.');\n }\n const setX = set, setY = twoArrays ? arg2 : set;\n const selectorX0 = twoArrays ? selector1 : arg2;\n const selectorY0 = twoArrays ? selector2 : selectorX0;\n const selectorX = selectorX0 ?? (p => p.x);\n const selectorY = selectorY0 ?? (p => p.y);\n const length = set.length;\n let xyAcc = 0, xAcc = 0, yAcc = 0, x2Acc = 0, y2Acc = 0;\n for (let i = 0; i < length; i++) {\n const itemX = setX[i], itemY = setY[i];\n const x = selectorX(itemX, i);\n const y = selectorY(itemY, i);\n xyAcc += x * y;\n xAcc += x;\n yAcc += y;\n x2Acc += x * x;\n y2Acc += y * y;\n }\n const m = (length * xyAcc - xAcc * yAcc) / (length * x2Acc - Math.pow(xAcc, 2));\n const q = (yAcc - m * xAcc) / length;\n return [m, q];\n}\n/** Utility tools about statistics, probability, data analysis... */\nexport class Utils {\n static sum(set, selector) {\n return sum(set, selector);\n }\n static mean(set, selector) {\n return mean(set, selector);\n }\n static median(set, selector) {\n return median(set, selector);\n }\n static mode(set, selector) {\n return mode(set, selector);\n }\n static var(set, selector) {\n return variance(set, selector, true);\n }\n static varp(set, selector) {\n return variance(set, selector, false);\n }\n static stdevp(set, selector) {\n return stdev(set, selector, false);\n }\n static stdev(set, selector) {\n return stdev(set, selector, true);\n }\n static correlation(set, arg2, selector1, selector2) {\n return correlation(set, arg2, selector1, selector2);\n }\n static linearRegression(set, arg2, selector1, selector2) {\n return linearRegression(set, arg2, selector1, selector2);\n }\n // restart from here: https://en.wikipedia.org/wiki/Multivariate_statistics#Multivariate_analysis\n /**\n * Returns a set of utilities for gaussian distribution computations.\n * @param mean\n * @param stdev\n */\n static gaussian(mean, stdev) {\n return new Gaussian(mean, stdev);\n }\n}\nfunction searchFnFactory(minAssigner, maxAssigner) {\n const fn = (left, right, f, tolerance) => {\n let min = left;\n let max = right;\n let x1 = minAssigner(min, max);\n let x2 = maxAssigner(min, max);\n let f1 = f(x1);\n let f2 = f(x2);\n while ((max - min) > tolerance) {\n if (f1 < f2) {\n max = x2;\n x2 = x1;\n f2 = f1;\n x1 = minAssigner(min, max);\n f1 = f(x1);\n }\n else {\n min = x1;\n x1 = x2;\n f1 = f2;\n x2 = maxAssigner(min, max);\n f2 = f(x2);\n }\n }\n return .5 * (x1 + x2);\n };\n return fn;\n}\nconst DEFAULT_TOLERANCE = 1e-3;\n/**\n * Weight function based on golden ratio.\n */\nconst goldenRatioSearch = (left, right, weight, tolerance = DEFAULT_TOLERANCE) => {\n const phi = 1.618;\n const minAssigner = (min, max) => max - (max - min) / phi;\n const maxAssigner = (min, max) => min + (max - min) / phi;\n const fn = searchFnFactory(minAssigner, maxAssigner);\n return fn(left, right, weight, tolerance);\n};\nfunction linearSearch(segments) {\n if (segments <= 1) {\n throw new RangeError(\"segments must be a number grater than 1.\");\n }\n return (left, right, weight, tolerance = DEFAULT_TOLERANCE) => {\n const minAssigner = (min, max) => min + (max - min) / segments;\n const maxAssigner = (min, max) => max - (max - min) / segments;\n const fn = searchFnFactory(minAssigner, maxAssigner);\n return fn(left, right, weight, tolerance);\n };\n}\nconst gaussianSearch = (left, right, weight, tolerance = DEFAULT_TOLERANCE) => {\n var sigma0 = null;\n var length0 = null;\n const computeSigma = (min, max) => {\n length0 ??= (max - min);\n sigma0 ??= length0 / Math.sqrt(12);\n return sigma0 * (max - min) / length0;\n };\n const minAssigner = (min, max) => Math.max(min, (max + min) / 2 - computeSigma(min, max));\n const maxAssigner = (min, max) => Math.min(max, (max + min) / 2 + computeSigma(min, max));\n const fn = searchFnFactory(minAssigner, maxAssigner);\n return fn(left, right, weight, tolerance);\n};\n/** Ready-made {@link SearchFunction} implementations for unimodal minimum-search over an interval. */\nexport const SearchFunctions = {\n /**\n * Creates a linear search function.\n * @param segments How many segments to split the range into.\n */\n linear: (segments = 2) => linearSearch(segments),\n /** Golden section search function. */\n goldenRatio: goldenRatioSearch,\n /** Gaussian search function. */\n gaussian: gaussianSearch,\n};\n//}\n", "import { Numbers, NullChecker } from '@pacem/pacem-foundation';\n//namespace Pacem.Mathematics.NumberTheory {\nconst ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz';\nconst OUT_OF_RANGE = `Radix out of range: possible values go between positive 1 exclusive and ${ALPHABET.length} inclusive`;\n/** Utility tools about number theory, 'diophantine' stuff... */\nexport class Utils {\n /**\n * Computes the least common multiple (LCM) of the given numbers (each rounded to the nearest integer).\n * @param args Two or more numbers.\n * @returns The least common multiple.\n * @throws If fewer than two numbers are provided.\n */\n static lcd(...args) {\n if (NullChecker.isNullOrEmpty(args) || args.length <= 1) {\n throw 'Insufficient set of numbers.';\n }\n function ex9(x, y) {\n if (!y)\n return y === 0 ? x : NaN;\n return ex9(y, x % y);\n }\n function ex10(x, y) {\n return x * y / ex9(x, y);\n }\n let result = Math.round(args[0]);\n for (let j = 1; j < args.length; j++) {\n result = ex10(result, Math.round(args[j]));\n }\n return result;\n }\n /**\n * Computes the greatest common divisor (GCD) of two numbers (each rounded to the nearest integer)\n * using the Euclidean algorithm.\n * @param a\n * @param b\n */\n static gcd(a, b) {\n // force integers\n a = Math.round(a),\n b = Math.round(b);\n if (a === 0) {\n return b;\n }\n return Utils.gcd(b % a, a);\n }\n /**\n * Converts an integer value from one numeric base (radix) to another.\n * @param v Value to convert, in the source radix.\n * @param from Source radix.\n * @param to Target radix.\n * @returns The value re-expressed in the target radix, as a string.\n */\n static rebaseInt(v, from, to) {\n return Numbers.rebase(v, from, to);\n }\n /**\n * Converts a (possibly fractional) numeric value from one radix to another, dispatching to the\n * appropriate specialized conversion routine depending on whether base-10 is the source, the\n * target, or neither.\n * @param v Value to convert, in the source radix.\n * @param fromRadix Source radix.\n * @param toRadix Target radix.\n * @param precision Maximum number of digits to compute for the fractional part (default 12).\n * @returns The converted value: a number when converting to base 10, otherwise a string.\n */\n static rebaseFloat(v, fromRadix, toRadix, precision = 12) {\n const from10 = Utils.rebaseFloat10ToN, to10 = Utils.rebaseFloatNTo10;\n if (fromRadix === 10) {\n const vFloat = parseFloat(v.toString());\n if (toRadix % 1 === 0) {\n return Utils.rebaseFloat10ToNIntBase(vFloat, toRadix, precision);\n }\n return from10(vFloat, toRadix, precision);\n }\n if (toRadix === 10) {\n return to10(v.toString(), fromRadix, precision);\n }\n const _10 = to10(v.toString(), fromRadix, precision + 1);\n return from10(_10, toRadix, precision);\n }\n /**\n * Converts a numeric string expressed in the given radix into its base-10 (decimal) value.\n * @param v Value to convert, expressed in the source radix (digits from `0-9a-z`).\n * @param radix Source radix (must be greater than 1 and no larger than the size of the digit alphabet).\n * @param precision Unused for the integer part; reserved for symmetry with the sibling conversion methods.\n * @returns The base-10 numeric value, or `NaN` if the input contains invalid digits.\n * @throws If radix is out of range.\n */\n static rebaseFloatNTo10(v, radix, precision = 12) {\n const alphabet = ALPHABET;\n if (radix <= 1 || radix > alphabet.length) {\n throw new Error(OUT_OF_RANGE);\n }\n const vs = (v ?? '0').toString().toLowerCase(), nan = Number.NaN;\n if (vs === '0') {\n return 0;\n }\n const arr = /^([-+]?) *([\\da-z]+)?(.[\\da-z]+)?$/.exec(vs);\n if (arr.length < 2) {\n return nan;\n }\n const sign = arr[1] === '-' ? -1 : 1, int = arr[2] || '0', frac = arr[3] || '.0';\n let retval = 0, cursor = 0;\n for (let digit of (int + frac.substr(1))) {\n const num = alphabet.indexOf(digit);\n if (num === -1 || num >= radix) {\n return nan;\n }\n retval += num * Math.pow(radix, int.length - cursor - 1);\n cursor++;\n }\n return sign * retval;\n }\n /**\n * Converts a base-10 number into its representation in another **integer** radix.\n * @param v Base-10 value to convert.\n * @param radix Target integer radix (must be greater than 1 and no larger than the size of the digit alphabet).\n * @param precision Maximum number of digits to compute for the fractional part (default 12).\n * @returns The value re-expressed in the target radix, as a string.\n * @throws If radix is out of range.\n */\n static rebaseFloat10ToNIntBase(v, radix, precision = 12) {\n const alphabet = ALPHABET;\n if (radix <= 1 || radix > alphabet.length) {\n throw new Error(OUT_OF_RANGE);\n }\n const to = radix;\n let value = Math.abs(v ?? 0);\n if (value === 0 || Number.isNaN(value)) {\n return v.toString();\n }\n let decimals = (value % 1).roundoff();\n let output = '';\n // loop\n do {\n // std\n let div = value / to /* do not roundoff: e.g. 35.99999999999986 / 36 rounds off to 1 */;\n let divFloor = Math.floor(div);\n let mod = (value - divFloor * to).roundoff();\n let intPart = Math.floor(mod);\n if (intPart >= alphabet.length) {\n output = `[${intPart}]` + output;\n }\n else {\n output = alphabet[intPart] + output;\n }\n if (divFloor <= 0) {\n break;\n }\n value = divFloor;\n } while (true);\n output = output.replace(/^0+/, '');\n output ||= '0';\n if (decimals === 0) {\n return output;\n }\n let rebasedFrac = '';\n // loop (same)\n // TODO: tidy up code.\n do {\n value = (decimals * to).roundoff();\n const intPart = Math.floor(value), remainder = (value - intPart).roundoff();\n if (intPart >= alphabet.length) {\n rebasedFrac = `[${intPart}]`;\n }\n else {\n rebasedFrac += alphabet[intPart];\n }\n decimals = remainder;\n } while (!decimals.isCloseTo(0) && rebasedFrac.length < precision);\n if (/^0*$/.test(rebasedFrac)) {\n return output;\n }\n return (Math.sign(v) < 0 ? '-' : '') + output + '.' + rebasedFrac.replace(/0+$/, '');\n }\n /**\n * Converts a base-10 number into its representation in another (possibly non-integer) radix.\n * @param v Base-10 value to convert.\n * @param radix Target radix, possibly fractional (must be greater than 1 and no larger than the size of the digit alphabet).\n * @param precision Maximum number of digits to compute for the fractional part (default 12).\n * @returns The value re-expressed in the target radix, as a string.\n * @throws If radix is out of range.\n */\n static rebaseFloat10ToN(v, radix, precision = 12) {\n const alphabet = ALPHABET;\n if (radix <= 1 || radix > alphabet.length) {\n throw new Error(OUT_OF_RANGE);\n }\n const to = radix;\n let value = Math.abs(v ?? 0);\n if (value === 0 || Number.isNaN(value)) {\n return v.toString();\n }\n let sign = Math.sign(v) < 0 ? '-' : '';\n let int = [];\n let dec = [];\n for (let j = 0; j < 20; j++) {\n int.push('0');\n dec.push('0');\n }\n const maxIndex = to % 1 === 0 ? to : Math.ceil(to);\n function add(integers, j /* cellIndex */, digitIndex) {\n const output = integers ? int : dec;\n const current = output[j] = output[j] || '0';\n const index = alphabet.indexOf(current) + digitIndex, tgetIndex = index % maxIndex, carryIndex = Math.floor(index / maxIndex);\n output[j] = alphabet[tgetIndex];\n if (carryIndex > 0) {\n if (integers) {\n // integers\n add(integers, j + 1, carryIndex);\n }\n else {\n // fractionals\n if (j === 0) {\n // carry on integers\n add(true, 0, carryIndex);\n }\n else {\n add(false, j - 1, carryIndex);\n }\n }\n }\n return carryIndex;\n }\n let step = 0;\n do {\n const magnitude = Math.floor(Numbers.log(value, to));\n const isInteger = magnitude >= 0;\n const absMagnitude = isInteger ? magnitude : Math.abs(1 + magnitude);\n add(isInteger, absMagnitude, 1);\n value = (value - Math.pow(to, magnitude).roundoff()).roundoff();\n if (!isInteger) {\n step++;\n }\n if (value === 0 || step >= 100) {\n const integer = sign + (int.reverse().map(i => i || '0').join('').replace(/^0+/, '') || '0'), fractional = dec.map(i => i || '0').join('').substr(0, precision).replace(/0+$/, '');\n if (/^0*$/.test(fractional)) {\n return integer;\n }\n return integer + '.' + fractional;\n }\n } while (true);\n }\n}\n//}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["Point", "Point", "vertices", "triangleIndices", "uniqueEdges", "Point", "NullChecker", "Point", "NullChecker", "RAD2DEG", "Utils", "mean", "stdev", "a", "Utils", "mean", "stdev", "Utils", "NullChecker"]
7
7
  }
@@ -193,7 +193,7 @@
193
193
  "canonicalReference": "@pacem/pacem-numerical!Geometry:namespace",
194
194
  "docComment": "",
195
195
  "excerptTokens": [],
196
- "fileUrlPath": "dist/types/index.d.ts",
196
+ "fileUrlPath": "dist/types/index-root.d.ts",
197
197
  "releaseTag": "None",
198
198
  "name": "Geometry",
199
199
  "preserveMemberOrder": false,
@@ -8716,7 +8716,7 @@
8716
8716
  "canonicalReference": "@pacem/pacem-numerical!Mathematics:namespace",
8717
8717
  "docComment": "",
8718
8718
  "excerptTokens": [],
8719
- "fileUrlPath": "dist/types/index.d.ts",
8719
+ "fileUrlPath": "dist/types/index-root.d.ts",
8720
8720
  "releaseTag": "None",
8721
8721
  "name": "Mathematics",
8722
8722
  "preserveMemberOrder": false,
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @pacem/pacem-numerical v1.0.3 (https://js.pacem.it)
2
+ * @pacem/pacem-numerical v1.0.5-archimedes (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
@@ -1,9 +1,10 @@
1
1
  /*!
2
- * @pacem/pacem-numerical v1.0.3 (https://js.pacem.it)
2
+ * @pacem/pacem-numerical v1.0.5-archimedes (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
6
6
  export * from './geom/geom';
7
7
  export * from './geom/polygon';
8
8
  export * from './geom/util3d';
9
- export * as LinearAlgebra from './index-geometry-linearalgebra';
9
+ import * as LinearAlgebra from './index-geometry-linearalgebra';
10
+ export { LinearAlgebra };
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @pacem/pacem-numerical v1.0.3 (https://js.pacem.it)
2
+ * @pacem/pacem-numerical v1.0.5-archimedes (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @pacem/pacem-numerical v1.0.3 (https://js.pacem.it)
2
+ * @pacem/pacem-numerical v1.0.5-archimedes (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
@@ -1,8 +1,10 @@
1
1
  /*!
2
- * @pacem/pacem-numerical v1.0.3 (https://js.pacem.it)
2
+ * @pacem/pacem-numerical v1.0.5-archimedes (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
6
6
  export * from './math/complex';
7
- export * as DataAnalysis from './index-mathematics-dataanalysis.js';
8
- export * as NumberTheory from './math/math';
7
+ import * as DataAnalysis from './index-mathematics-dataanalysis.js';
8
+ export { DataAnalysis };
9
+ import * as NumberTheory from './math/math';
10
+ export { NumberTheory };
@@ -0,0 +1,9 @@
1
+ /*!
2
+ * @pacem/pacem-numerical v1.0.5-archimedes (https://js.pacem.it)
3
+ * Pacem (https://pacem.it)
4
+ * Licensed under Apache-2.0
5
+ */
6
+ import * as Geometry from './index-geometry';
7
+ export { Geometry };
8
+ import * as Mathematics from './index-mathematics';
9
+ export { Mathematics };
package/dist/esm/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  /*!
2
- * @pacem/pacem-numerical v1.0.3 (https://js.pacem.it)
2
+ * @pacem/pacem-numerical v1.0.5-archimedes (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
6
- export * as Geometry from './index-geometry';
7
- export * as Mathematics from './index-mathematics';
6
+ export * from './index-root';
package/package.json CHANGED
@@ -28,7 +28,7 @@
28
28
  "types": "./typings/index.d.ts"
29
29
  }
30
30
  },
31
- "version": "1.0.3",
31
+ "version": "1.0.5-archimedes",
32
32
  "author": {
33
33
  "name": "Pacem",
34
34
  "url": "https://pacem.it"
@@ -78,7 +78,7 @@ declare class Complex {
78
78
  static get NaC(): Complex;
79
79
  }
80
80
 
81
- export declare namespace DataAnalysis {
81
+ declare namespace DataAnalysis {
82
82
  export {
83
83
  Fourier,
84
84
  Gaussian,
@@ -159,7 +159,7 @@ declare class Gaussian {
159
159
  probability(x: number): number;
160
160
  }
161
161
 
162
- export declare namespace Geometry {
162
+ declare namespace Geometry {
163
163
  export {
164
164
  LinearAlgebra,
165
165
  Segment,
@@ -169,6 +169,7 @@ export declare namespace Geometry {
169
169
  Utils3D
170
170
  }
171
171
  }
172
+ export { Geometry }
172
173
 
173
174
  /** Common contract for the interpolation strategies of this module: given an x, returns the estimated y. */
174
175
  declare interface Interpolator {
@@ -226,7 +227,7 @@ declare const Lagrangian: {
226
227
  create: typeof Lagrange.create;
227
228
  };
228
229
 
229
- export declare namespace LinearAlgebra {
230
+ declare namespace LinearAlgebra {
230
231
  export {
231
232
  Vector,
232
233
  Point3D,
@@ -237,13 +238,14 @@ export declare namespace LinearAlgebra {
237
238
  }
238
239
  }
239
240
 
240
- export declare namespace Mathematics {
241
+ declare namespace Mathematics {
241
242
  export {
242
243
  DataAnalysis,
243
244
  NumberTheory,
244
245
  Complex
245
246
  }
246
247
  }
248
+ export { Mathematics }
247
249
 
248
250
  /**
249
251
  * Represents a 4x4 transformation matrix in 3D space, in row-major layout (`m{row}{col}`, with the
@@ -414,7 +416,7 @@ declare class Newton implements Interpolator {
414
416
  static create(values: number[]): Newton;
415
417
  }
416
418
 
417
- export declare namespace NumberTheory {
419
+ declare namespace NumberTheory {
418
420
  export {
419
421
  Utils_3 as Utils
420
422
  }
@@ -1294,11 +1296,8 @@ declare class Vector3D {
1294
1296
  declare global {
1295
1297
  namespace Pacem {
1296
1298
  export {
1297
- DataAnalysis,
1298
1299
  Geometry,
1299
- LinearAlgebra,
1300
- Mathematics,
1301
- NumberTheory
1300
+ Mathematics
1302
1301
  };
1303
1302
  }
1304
1303
  }