@woosh/meep-engine 2.134.5 → 2.135.0

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.
Files changed (155) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/editor/tools/v2/TransformControlsGizmo.js +1 -1
  4. package/editor/view/node-graph/NodeGraphEditorView.js +2 -2
  5. package/package.json +1 -1
  6. package/src/core/assert.d.ts +0 -2
  7. package/src/core/assert.d.ts.map +1 -1
  8. package/src/core/assert.js +0 -6
  9. package/src/core/color/Color.d.ts +0 -5
  10. package/src/core/color/Color.d.ts.map +1 -1
  11. package/src/core/color/Color.js +1 -7
  12. package/src/core/geom/2d/hash-grid/SpatialHashGrid.js +386 -386
  13. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_2d.js +1 -1
  14. package/src/core/geom/2d/quad-tree-binary/QuadTree.js +714 -714
  15. package/src/core/geom/3d/triangle/computeTriangleRayIntersection.js +160 -160
  16. package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js +96 -96
  17. package/src/core/geom/packing/max-rect/MaxRectanglesPacker.js +1 -1
  18. package/src/core/geom/packing/max-rect/findBestContainer.js +4 -4
  19. package/src/core/geom/packing/max-rect/packOneBox.js +2 -2
  20. package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.js +1 -1
  21. package/src/core/graph/layout/box/BoxLayouter.js +7 -7
  22. package/src/core/graph/layout/box/position_box_next_to_box.js +6 -6
  23. package/src/core/math/computeWholeDivisorLow.js +33 -33
  24. package/src/core/math/linalg/eigen/eigen_values_find_spectral_gap.d.ts.map +1 -0
  25. package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts +10 -0
  26. package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts.map +1 -0
  27. package/src/core/{graph → math/linalg}/eigen/matrix_eigenvalues_in_place.js +8 -7
  28. package/src/core/math/linalg/eigen/matrix_householder_in_place.d.ts.map +1 -0
  29. package/src/core/{graph → math/linalg}/eigen/matrix_householder_in_place.js +11 -5
  30. package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts +15 -0
  31. package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts.map +1 -0
  32. package/src/core/{graph → math/linalg}/eigen/matrix_qr_in_place.js +8 -2
  33. package/src/core/{graph → math/linalg}/eigen/matrix_top_eigenvector_power_iteration.d.ts +0 -3
  34. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +1 -0
  35. package/src/core/{graph → math/linalg}/eigen/matrix_top_eigenvector_power_iteration.js +0 -3
  36. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts +19 -0
  37. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts.map +1 -0
  38. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.js +161 -0
  39. package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts +15 -0
  40. package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts.map +1 -0
  41. package/src/core/math/linalg/polynomial_real_roots_in_interval.js +200 -0
  42. package/src/core/math/solveCubic.d.ts +15 -0
  43. package/src/core/math/solveCubic.d.ts.map +1 -0
  44. package/src/core/math/solveCubic.js +82 -0
  45. package/src/core/math/spline/spline3_hermite_bounds_t.d.ts +23 -0
  46. package/src/core/math/spline/spline3_hermite_bounds_t.d.ts.map +1 -0
  47. package/src/core/math/spline/spline3_hermite_bounds_t.js +109 -0
  48. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts +25 -0
  49. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts.map +1 -0
  50. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.js +44 -0
  51. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts +16 -0
  52. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts.map +1 -0
  53. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.js +120 -0
  54. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts +11 -0
  55. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts.map +1 -0
  56. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.js +451 -0
  57. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts +12 -0
  58. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -0
  59. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +339 -0
  60. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts +15 -0
  61. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts.map +1 -0
  62. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.js +21 -0
  63. package/src/core/math/spline/spline3_hermite_to_monomial.d.ts +24 -0
  64. package/src/core/math/spline/spline3_hermite_to_monomial.d.ts.map +1 -0
  65. package/src/core/math/spline/spline3_hermite_to_monomial.js +37 -0
  66. package/src/core/math/spline/v3_computeCatmullRomSplineUniformDistance.js +1 -1
  67. package/src/core/model/node-graph/visual/NodeGraphVisualData.js +1 -1
  68. package/src/core/model/reactive/model/util/createRandomReactiveExpression.js +185 -185
  69. package/src/core/process/delay.js +16 -16
  70. package/src/engine/animation/async/TimeSeries.js +300 -300
  71. package/src/engine/animation/curve/AnimationCurve.d.ts +0 -4
  72. package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
  73. package/src/engine/animation/curve/AnimationCurve.js +1 -6
  74. package/src/engine/animation/curve/draw/position_canvas_to_curve.js +2 -2
  75. package/src/engine/animation/curve/draw/position_curve_to_canvas.js +2 -2
  76. package/src/engine/ecs/fow/shader/FogOfWarRenderer.js +145 -145
  77. package/src/engine/ecs/gui/position/ViewportPositionSystem.js +2 -2
  78. package/src/engine/ecs/parent/entity_node_compute_bounding_box.js +1 -1
  79. package/src/engine/ecs/transform/Transform.d.ts +0 -10
  80. package/src/engine/ecs/transform/Transform.d.ts.map +1 -1
  81. package/src/engine/ecs/transform/Transform.js +0 -12
  82. package/src/engine/graphics/composit/CompositLayer.js +254 -254
  83. package/src/engine/graphics/ecs/mesh-v2/sg_hierarchy_compute_bounding_box_via_parent_entity.js +1 -1
  84. package/src/engine/graphics/ecs/path/tube/build/build_geometry_linear.js +2 -2
  85. package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +3 -3
  86. package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +201 -201
  87. package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -1
  88. package/src/engine/graphics/render/buffer/slot/parameter/ProgramValueSlotParameterSet.js +2 -2
  89. package/src/engine/graphics/render/forward_plus/LightManager.js +1226 -1226
  90. package/src/engine/graphics/render/forward_plus/model/PointLight.js +1 -1
  91. package/src/engine/graphics/sh3/lpv/lpv_obtain_storage_cached_volume.js +1 -1
  92. package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +2 -2
  93. package/src/engine/graphics/texture/atlas/TextureAtlasDebugger.js +1 -1
  94. package/src/engine/graphics/texture/sampler/HarmonicDiffusionGrid.js +145 -145
  95. package/src/engine/graphics/texture/sampler/serialization/TextureBinaryBufferSerializer.js +2 -2
  96. package/src/engine/intelligence/behavior/ecs/BehaviorComponent.d.ts +2 -6
  97. package/src/engine/intelligence/behavior/ecs/BehaviorComponent.d.ts.map +1 -1
  98. package/src/engine/intelligence/behavior/ecs/BehaviorComponent.js +0 -10
  99. package/src/engine/intelligence/mcts/MonteCarlo.js +275 -275
  100. package/src/engine/navigation/ecs/path_following/PathFollower.js +222 -222
  101. package/src/generation/grid/GridData.js +220 -220
  102. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +385 -385
  103. package/src/view/elements/image/SvgImageView.js +1 -1
  104. package/src/view/elements/windrose/WindRoseDiagram.js +369 -369
  105. package/src/view/minimap/gl/MinimapFogOfWar.js +3 -3
  106. package/src/view/util/DomSizeObserver.js +1 -1
  107. package/src/core/binary/clz32.d.ts +0 -6
  108. package/src/core/binary/clz32.d.ts.map +0 -1
  109. package/src/core/binary/clz32.js +0 -5
  110. package/src/core/binary/type/dataTypeFromTypedArray.d.ts +0 -8
  111. package/src/core/binary/type/dataTypeFromTypedArray.d.ts.map +0 -1
  112. package/src/core/binary/type/dataTypeFromTypedArray.js +0 -11
  113. package/src/core/collection/array/computeHashIntegerArray.d.ts +0 -1
  114. package/src/core/collection/array/computeHashIntegerArray.d.ts.map +0 -1
  115. package/src/core/collection/array/computeHashIntegerArray.js +0 -7
  116. package/src/core/collection/array/typed/typedArrayToDataType.d.ts +0 -6
  117. package/src/core/collection/array/typed/typedArrayToDataType.d.ts.map +0 -1
  118. package/src/core/collection/array/typed/typedArrayToDataType.js +0 -6
  119. package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.d.ts +0 -6
  120. package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.d.ts.map +0 -1
  121. package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.js +0 -7
  122. package/src/core/graph/eigen/eigen_values_find_spectral_gap.d.ts.map +0 -1
  123. package/src/core/graph/eigen/matrix_eigenvalues_in_place.d.ts +0 -8
  124. package/src/core/graph/eigen/matrix_eigenvalues_in_place.d.ts.map +0 -1
  125. package/src/core/graph/eigen/matrix_householder_in_place.d.ts.map +0 -1
  126. package/src/core/graph/eigen/matrix_qr_in_place.d.ts +0 -9
  127. package/src/core/graph/eigen/matrix_qr_in_place.d.ts.map +0 -1
  128. package/src/core/graph/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +0 -1
  129. package/src/core/math/spline/cubicCurve.d.ts +0 -6
  130. package/src/core/math/spline/cubicCurve.d.ts.map +0 -1
  131. package/src/core/math/spline/cubicCurve.js +0 -6
  132. package/src/core/math/spline/spline_bezier2.d.ts +0 -6
  133. package/src/core/math/spline/spline_bezier2.d.ts.map +0 -1
  134. package/src/core/math/spline/spline_bezier2.js +0 -6
  135. package/src/core/math/spline/spline_bezier3.d.ts +0 -6
  136. package/src/core/math/spline/spline_bezier3.d.ts.map +0 -1
  137. package/src/core/math/spline/spline_bezier3.js +0 -6
  138. package/src/core/math/spline/spline_bezier3_bounds.d.ts +0 -6
  139. package/src/core/math/spline/spline_bezier3_bounds.d.ts.map +0 -1
  140. package/src/core/math/spline/spline_bezier3_bounds.js +0 -6
  141. package/src/core/math/spline/spline_hermite3.d.ts +0 -6
  142. package/src/core/math/spline/spline_hermite3.d.ts.map +0 -1
  143. package/src/core/math/spline/spline_hermite3.js +0 -6
  144. package/src/core/math/spline/spline_hermite3_bounds.d.ts +0 -6
  145. package/src/core/math/spline/spline_hermite3_bounds.d.ts.map +0 -1
  146. package/src/core/math/spline/spline_hermite3_bounds.js +0 -6
  147. package/src/core/math/spline/spline_hermite3_to_bezier.d.ts +0 -2
  148. package/src/core/math/spline/spline_hermite3_to_bezier.d.ts.map +0 -1
  149. package/src/core/math/spline/spline_hermite3_to_bezier.js +0 -6
  150. package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.d.ts +0 -37
  151. package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.d.ts.map +0 -1
  152. package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.js +0 -70
  153. /package/src/core/{graph → math/linalg}/eigen/eigen_values_find_spectral_gap.d.ts +0 -0
  154. /package/src/core/{graph → math/linalg}/eigen/eigen_values_find_spectral_gap.js +0 -0
  155. /package/src/core/{graph → math/linalg}/eigen/matrix_householder_in_place.d.ts +0 -0
@@ -0,0 +1,82 @@
1
+ import { assert } from "../assert.js";
2
+ import { EPSILON } from "./EPSILON.js";
3
+ import { solveQuadratic } from "./solveQuadratic.js";
4
+
5
+ const ONE_THIRD = 1.0 / 3.0;
6
+ const TWO_THIRDS_PI = 2.0 * Math.PI / 3.0;
7
+
8
+ /**
9
+ * Return real solutions for a cubic polynomial: ax³ + bx² + cx + d
10
+ * Repeated roots are written once each — multiplicity is not duplicated in the output.
11
+ * Imaginary roots are not provided.
12
+ *
13
+ * @param {number[]|Float32Array|Float64Array} result solutions are written here
14
+ * @param {number} result_offset offset into result array where solutions are written to
15
+ * @param {number} a
16
+ * @param {number} b
17
+ * @param {number} c
18
+ * @param {number} d
19
+ * @returns {number} number of real roots found (0, 1, 2, or 3)
20
+ */
21
+ export function solveCubic(result, result_offset, a, b, c, d) {
22
+ assert.isNumber(a, 'a');
23
+ assert.isNumber(b, 'b');
24
+ assert.isNumber(c, 'c');
25
+ assert.isNumber(d, 'd');
26
+
27
+ if (Math.abs(a) < EPSILON) {
28
+ // degrade to quadratic
29
+ return solveQuadratic(result, result_offset, b, c, d);
30
+ }
31
+
32
+ // normalize: x³ + B·x² + C·x + D = 0
33
+ const inv_a = 1 / a;
34
+ const B = b * inv_a;
35
+ const C = c * inv_a;
36
+ const D = d * inv_a;
37
+
38
+ // depress via x = y - B/3 → y³ + p·y + q = 0
39
+ const B_third = B * ONE_THIRD;
40
+ const p = C - B * B_third;
41
+ const q = 2 * B_third * B_third * B_third - C * B_third + D;
42
+
43
+ if (Math.abs(p) < EPSILON && Math.abs(q) < EPSILON) {
44
+ // triple root at y = 0
45
+ result[result_offset] = -B_third;
46
+ return 1;
47
+ }
48
+
49
+ // Cardano's discriminant criterion. ratio = (q/2)² + (p/3)³.
50
+ // ratio > 0 → one real root, two complex
51
+ // ratio = 0 → repeated real roots (single + double, or triple covered above)
52
+ // ratio < 0 → three distinct real roots
53
+ const half_q = q * 0.5;
54
+ const third_p = p * ONE_THIRD;
55
+ const ratio = half_q * half_q + third_p * third_p * third_p;
56
+
57
+ if (ratio > EPSILON) {
58
+ const sqrt_ratio = Math.sqrt(ratio);
59
+ const u = Math.cbrt(-half_q + sqrt_ratio);
60
+ const v = Math.cbrt(-half_q - sqrt_ratio);
61
+
62
+ result[result_offset] = u + v - B_third;
63
+ return 1;
64
+ }
65
+
66
+ if (ratio < -EPSILON) {
67
+ // p must be negative for ratio < 0; sqrt(-p/3) is real
68
+ const m = 2 * Math.sqrt(-third_p);
69
+ const theta_third = ONE_THIRD * Math.acos(3 * q / (p * m));
70
+
71
+ result[result_offset] = m * Math.cos(theta_third) - B_third;
72
+ result[result_offset + 1] = m * Math.cos(theta_third - TWO_THIRDS_PI) - B_third;
73
+ result[result_offset + 2] = m * Math.cos(theta_third - 2 * TWO_THIRDS_PI) - B_third;
74
+ return 3;
75
+ }
76
+
77
+ // ratio ≈ 0: simple + double root
78
+ const u = Math.cbrt(-half_q);
79
+ result[result_offset] = 2 * u - B_third;
80
+ result[result_offset + 1] = -u - B_third;
81
+ return 2;
82
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Compute the parameter values `t` at which a cubic Hermite spline reaches its
3
+ * minimum and maximum on `[0, 1]`. `t_at_min` is written to
4
+ * `result[result_offset]`, `t_at_max` to `result[result_offset + result_stride]`.
5
+ * Both values lie in `[0, 1]`.
6
+ *
7
+ * Companion to {@link spline3_hermite_bounds}, which writes the values; this
8
+ * one writes the parameters at which those values are reached. Either function
9
+ * does its own critical-point search — call whichever you actually need.
10
+ *
11
+ * @param {number[]|Float32Array|Float64Array} result
12
+ * @param {number} result_offset
13
+ * @param {number} result_stride
14
+ * @param {number} p0
15
+ * @param {number} p1
16
+ * @param {number} m0
17
+ * @param {number} m1
18
+ *
19
+ * @author Alex Goldring
20
+ * @copyright Company Named Limited (c) 2025
21
+ */
22
+ export function spline3_hermite_bounds_t(result: number[] | Float32Array | Float64Array, result_offset: number, result_stride: number, p0: number, p1: number, m0: number, m1: number): void;
23
+ //# sourceMappingURL=spline3_hermite_bounds_t.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spline3_hermite_bounds_t.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/spline/spline3_hermite_bounds_t.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,iDAXW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,iBAClC,MAAM,iBACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAyFhB"}
@@ -0,0 +1,109 @@
1
+ import { assert } from "../../assert.js";
2
+ import { spline3_hermite } from "./spline3_hermite.js";
3
+
4
+ /**
5
+ * Compute the parameter values `t` at which a cubic Hermite spline reaches its
6
+ * minimum and maximum on `[0, 1]`. `t_at_min` is written to
7
+ * `result[result_offset]`, `t_at_max` to `result[result_offset + result_stride]`.
8
+ * Both values lie in `[0, 1]`.
9
+ *
10
+ * Companion to {@link spline3_hermite_bounds}, which writes the values; this
11
+ * one writes the parameters at which those values are reached. Either function
12
+ * does its own critical-point search — call whichever you actually need.
13
+ *
14
+ * @param {number[]|Float32Array|Float64Array} result
15
+ * @param {number} result_offset
16
+ * @param {number} result_stride
17
+ * @param {number} p0
18
+ * @param {number} p1
19
+ * @param {number} m0
20
+ * @param {number} m1
21
+ *
22
+ * @author Alex Goldring
23
+ * @copyright Company Named Limited (c) 2025
24
+ */
25
+ export function spline3_hermite_bounds_t(
26
+ result,
27
+ result_offset,
28
+ result_stride,
29
+ p0, p1, m0, m1
30
+ ) {
31
+ assert.greaterThan(result_stride, 0, 'result_stride must be greater than 0');
32
+ assert.isInteger(result_stride, 'result_stride');
33
+
34
+ // Derivative of the Hermite polynomial:
35
+ // 3 t² (m0 + m1 + 2 p0 - 2 p1) - 2 t (2 m0 + m1 + 3 p0 - 3 p1) + m0
36
+ const a = 3 * (m0 + m1 + 2 * p0 - 2 * p1);
37
+ const b = -2 * (2 * m0 + m1 + 3 * p0 - 3 * p1);
38
+ const c = m0;
39
+
40
+ let min, max, t_at_min, t_at_max;
41
+ if (p0 <= p1) {
42
+ min = p0; t_at_min = 0;
43
+ max = p1; t_at_max = 1;
44
+ } else {
45
+ min = p1; t_at_min = 1;
46
+ max = p0; t_at_max = 0;
47
+ }
48
+
49
+ if (Math.abs(a) < 1e-12) {
50
+
51
+ if (Math.abs(b) >= 1e-12) {
52
+ const t = -c / b;
53
+
54
+ if (0 < t && t < 1) {
55
+ const value = spline3_hermite(t, p0, p1, m0, m1);
56
+
57
+ if (value < min) {
58
+ min = value;
59
+ t_at_min = t;
60
+ }
61
+ if (value > max) {
62
+ max = value;
63
+ t_at_max = t;
64
+ }
65
+ }
66
+ }
67
+
68
+ } else {
69
+
70
+ const b2ac = b * b - 4 * c * a;
71
+
72
+ if (b2ac >= 0) {
73
+ const sqrtb2ac = Math.sqrt(b2ac);
74
+
75
+ const t1 = (-b + sqrtb2ac) / (2 * a);
76
+
77
+ if (0 < t1 && t1 < 1) {
78
+ const value = spline3_hermite(t1, p0, p1, m0, m1);
79
+
80
+ if (value < min) {
81
+ min = value;
82
+ t_at_min = t1;
83
+ }
84
+ if (value > max) {
85
+ max = value;
86
+ t_at_max = t1;
87
+ }
88
+ }
89
+
90
+ const t2 = (-b - sqrtb2ac) / (2 * a);
91
+
92
+ if (0 < t2 && t2 < 1) {
93
+ const value = spline3_hermite(t2, p0, p1, m0, m1);
94
+
95
+ if (value < min) {
96
+ min = value;
97
+ t_at_min = t2;
98
+ }
99
+ if (value > max) {
100
+ max = value;
101
+ t_at_max = t2;
102
+ }
103
+ }
104
+ }
105
+ }
106
+
107
+ result[result_offset] = t_at_min;
108
+ result[result_offset + result_stride] = t_at_max;
109
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Closest approach between two cubic Hermite curves over the full [0,1]²
3
+ * parameter square. Writes `[s, t]` of the closest pair to
4
+ * `result[result_offset], result[result_offset + 1]` and returns the squared
5
+ * distance at that pair.
6
+ *
7
+ * Coefficient layout for `a` and `b`: per-dimension grouped quads,
8
+ * `[p0_0, p1_0, m0_0, m1_0, p0_1, p1_1, m0_1, m1_1, ..., m1_{dim-1}]`,
9
+ * length `4 * dim`. dim ≥ 1.
10
+ *
11
+ * Internally dispatched by dimension because the algebra of the closest-
12
+ * approach problem is genuinely different per dim:
13
+ * - 1D: range overlap (a single equation in two unknowns).
14
+ * - 2D: direct (3,3)/(3,3) Bezout resultant of degree ≤ 9.
15
+ * - ND (≥ 3): gradient resultant of distance², degree ≤ 34.
16
+ *
17
+ * @param {Float64Array|number[]} a length 4*dim
18
+ * @param {Float64Array|number[]} b length 4*dim
19
+ * @param {number} dim
20
+ * @param {Float64Array|number[]} result
21
+ * @param {number} result_offset
22
+ * @returns {number} squared distance at closest approach
23
+ */
24
+ export function spline3_hermite_intersection_spline3_hermite(a: Float64Array | number[], b: Float64Array | number[], dim: number, result: Float64Array | number[], result_offset: number): number;
25
+ //# sourceMappingURL=spline3_hermite_intersection_spline3_hermite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spline3_hermite_intersection_spline3_hermite.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/spline/spline3_hermite_intersection_spline3_hermite.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,gEAPW,YAAY,GAAC,MAAM,EAAE,KACrB,YAAY,GAAC,MAAM,EAAE,OACrB,MAAM,UACN,YAAY,GAAC,MAAM,EAAE,iBACrB,MAAM,GACJ,MAAM,CAiBlB"}
@@ -0,0 +1,44 @@
1
+ import { assert } from "../../assert.js";
2
+ import { spline3_hermite_intersection_spline3_hermite_1d } from "./spline3_hermite_intersection_spline3_hermite_1d.js";
3
+ import { spline3_hermite_intersection_spline3_hermite_2d } from "./spline3_hermite_intersection_spline3_hermite_2d.js";
4
+ import { spline3_hermite_intersection_spline3_hermite_nd } from "./spline3_hermite_intersection_spline3_hermite_nd.js";
5
+
6
+ /**
7
+ * Closest approach between two cubic Hermite curves over the full [0,1]²
8
+ * parameter square. Writes `[s, t]` of the closest pair to
9
+ * `result[result_offset], result[result_offset + 1]` and returns the squared
10
+ * distance at that pair.
11
+ *
12
+ * Coefficient layout for `a` and `b`: per-dimension grouped quads,
13
+ * `[p0_0, p1_0, m0_0, m1_0, p0_1, p1_1, m0_1, m1_1, ..., m1_{dim-1}]`,
14
+ * length `4 * dim`. dim ≥ 1.
15
+ *
16
+ * Internally dispatched by dimension because the algebra of the closest-
17
+ * approach problem is genuinely different per dim:
18
+ * - 1D: range overlap (a single equation in two unknowns).
19
+ * - 2D: direct (3,3)/(3,3) Bezout resultant of degree ≤ 9.
20
+ * - ND (≥ 3): gradient resultant of distance², degree ≤ 34.
21
+ *
22
+ * @param {Float64Array|number[]} a length 4*dim
23
+ * @param {Float64Array|number[]} b length 4*dim
24
+ * @param {number} dim
25
+ * @param {Float64Array|number[]} result
26
+ * @param {number} result_offset
27
+ * @returns {number} squared distance at closest approach
28
+ */
29
+ export function spline3_hermite_intersection_spline3_hermite(
30
+ a, b, dim,
31
+ result, result_offset
32
+ ) {
33
+ assert.greaterThanOrEqual(dim, 1, 'dim');
34
+
35
+ if (dim === 1) {
36
+ return spline3_hermite_intersection_spline3_hermite_1d(a, b, result, result_offset);
37
+ }
38
+
39
+ if (dim === 2) {
40
+ return spline3_hermite_intersection_spline3_hermite_2d(a, b, result, result_offset);
41
+ }
42
+
43
+ return spline3_hermite_intersection_spline3_hermite_nd(a, b, dim, result, result_offset);
44
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Closest approach of two 1D cubic Hermite curves. Inputs are flat 4-element
3
+ * arrays `[p0, p1, m0, m1]` for each curve (the dim=1 slice of the full
4
+ * intersection API).
5
+ *
6
+ * Writes `[s, t]` to `result[result_offset], result[result_offset + 1]` and
7
+ * returns the squared distance at the closest approach.
8
+ *
9
+ * @param {Float64Array|number[]} a length 4
10
+ * @param {Float64Array|number[]} b length 4
11
+ * @param {Float64Array|number[]} result length >= result_offset + 2
12
+ * @param {number} result_offset
13
+ * @returns {number}
14
+ */
15
+ export function spline3_hermite_intersection_spline3_hermite_1d(a: Float64Array | number[], b: Float64Array | number[], result: Float64Array | number[], result_offset: number): number;
16
+ //# sourceMappingURL=spline3_hermite_intersection_spline3_hermite_1d.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spline3_hermite_intersection_spline3_hermite_1d.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.js"],"names":[],"mappings":"AA2CA;;;;;;;;;;;;;GAaG;AACH,mEANW,YAAY,GAAC,MAAM,EAAE,KACrB,YAAY,GAAC,MAAM,EAAE,UACrB,YAAY,GAAC,MAAM,EAAE,iBACrB,MAAM,GACJ,MAAM,CAgElB"}
@@ -0,0 +1,120 @@
1
+ import { solveCubic } from "../solveCubic.js";
2
+ import { spline3_hermite_bounds } from "./spline3_hermite_bounds.js";
3
+ import { spline3_hermite_bounds_t } from "./spline3_hermite_bounds_t.js";
4
+
5
+ /*
6
+ 1D specialization: A and B are scalar functions on [0, 1]. The "intersection"
7
+ is anywhere their value ranges coincide.
8
+
9
+ Two regimes:
10
+ - Ranges overlap: any (s, t) with A(s) = v = B(t) for some v in the overlap
11
+ is a true intersection. We pick v = midpoint of the overlap, then solve
12
+ each cubic A(s) = v and B(t) = v for the first root in [0, 1].
13
+ - Ranges disjoint: the closest pair sits at the inner extrema — A's max if A
14
+ is below B (or A's min if A is above B), paired with the corresponding
15
+ extremum of B. The parameter at each extremum comes from
16
+ `spline3_hermite_bounds_t`.
17
+ */
18
+
19
+ const _bounds_value = new Float64Array(4); // [a_lo, a_hi, b_lo, b_hi]
20
+ const _bounds_t = new Float64Array(4); // [a_t_min, a_t_max, b_t_min, b_t_max]
21
+ const _cubic_roots = new Float64Array(3);
22
+
23
+ function first_cubic_root_in_unit(p0, p1, m0, m1, target) {
24
+ // A(s) - target = (2 p0 - 2 p1 + m0 + m1) s³
25
+ // + (-3 p0 + 3 p1 - 2 m0 - m1) s²
26
+ // + m0 s
27
+ // + (p0 - target)
28
+ const a3 = 2 * p0 - 2 * p1 + m0 + m1;
29
+ const a2 = -3 * p0 + 3 * p1 - 2 * m0 - m1;
30
+ const a1 = m0;
31
+ const a0 = p0 - target;
32
+
33
+ const count = solveCubic(_cubic_roots, 0, a3, a2, a1, a0);
34
+ let best_s = -1;
35
+ for (let i = 0; i < count; i++) {
36
+ const r = _cubic_roots[i];
37
+ if (r >= 0 && r <= 1) {
38
+ if (best_s < 0 || r < best_s) best_s = r;
39
+ }
40
+ }
41
+ return best_s;
42
+ }
43
+
44
+ /**
45
+ * Closest approach of two 1D cubic Hermite curves. Inputs are flat 4-element
46
+ * arrays `[p0, p1, m0, m1]` for each curve (the dim=1 slice of the full
47
+ * intersection API).
48
+ *
49
+ * Writes `[s, t]` to `result[result_offset], result[result_offset + 1]` and
50
+ * returns the squared distance at the closest approach.
51
+ *
52
+ * @param {Float64Array|number[]} a length 4
53
+ * @param {Float64Array|number[]} b length 4
54
+ * @param {Float64Array|number[]} result length >= result_offset + 2
55
+ * @param {number} result_offset
56
+ * @returns {number}
57
+ */
58
+ export function spline3_hermite_intersection_spline3_hermite_1d(
59
+ a, b,
60
+ result, result_offset
61
+ ) {
62
+ const a_p0 = a[0], a_p1 = a[1], a_m0 = a[2], a_m1 = a[3];
63
+ const b_p0 = b[0], b_p1 = b[1], b_m0 = b[2], b_m1 = b[3];
64
+
65
+ spline3_hermite_bounds(_bounds_value, 0, 1, a_p0, a_p1, a_m0, a_m1);
66
+ const a_lo = _bounds_value[0];
67
+ const a_hi = _bounds_value[1];
68
+
69
+ spline3_hermite_bounds(_bounds_value, 2, 1, b_p0, b_p1, b_m0, b_m1);
70
+ const b_lo = _bounds_value[2];
71
+ const b_hi = _bounds_value[3];
72
+
73
+ const overlap_lo = a_lo > b_lo ? a_lo : b_lo;
74
+ const overlap_hi = a_hi < b_hi ? a_hi : b_hi;
75
+
76
+ if (overlap_lo <= overlap_hi) {
77
+ // Ranges overlap → exact intersection at distance 0.
78
+ const target = 0.5 * (overlap_lo + overlap_hi);
79
+
80
+ let s = first_cubic_root_in_unit(a_p0, a_p1, a_m0, a_m1, target);
81
+ let t = first_cubic_root_in_unit(b_p0, b_p1, b_m0, b_m1, target);
82
+
83
+ // The cubic root finder shouldn't miss given that target lies inside
84
+ // both ranges, but guard against pathological numerics by falling back
85
+ // to the relevant extremum parameter.
86
+ if (s < 0 || t < 0) {
87
+ spline3_hermite_bounds_t(_bounds_t, 0, 1, a_p0, a_p1, a_m0, a_m1);
88
+ spline3_hermite_bounds_t(_bounds_t, 2, 1, b_p0, b_p1, b_m0, b_m1);
89
+ if (s < 0) s = (target === a_lo) ? _bounds_t[0] : _bounds_t[1];
90
+ if (t < 0) t = (target === b_lo) ? _bounds_t[2] : _bounds_t[3];
91
+ }
92
+
93
+ result[result_offset] = s;
94
+ result[result_offset + 1] = t;
95
+ return 0;
96
+ }
97
+
98
+ // Ranges disjoint. Recover the t parameters at the inner extrema.
99
+ spline3_hermite_bounds_t(_bounds_t, 0, 1, a_p0, a_p1, a_m0, a_m1);
100
+ spline3_hermite_bounds_t(_bounds_t, 2, 1, b_p0, b_p1, b_m0, b_m1);
101
+ const a_t_min = _bounds_t[0];
102
+ const a_t_max = _bounds_t[1];
103
+ const b_t_min = _bounds_t[2];
104
+ const b_t_max = _bounds_t[3];
105
+
106
+ let s, t, gap;
107
+ if (a_hi < b_lo) {
108
+ s = a_t_max;
109
+ t = b_t_min;
110
+ gap = b_lo - a_hi;
111
+ } else {
112
+ s = a_t_min;
113
+ t = b_t_max;
114
+ gap = a_lo - b_hi;
115
+ }
116
+
117
+ result[result_offset] = s;
118
+ result[result_offset + 1] = t;
119
+ return gap * gap;
120
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 2D specialization of the closest-approach intersection finder.
3
+ *
4
+ * @param {Float64Array|number[]} a length 8: [a_p0_x, a_p1_x, a_m0_x, a_m1_x, a_p0_y, a_p1_y, a_m0_y, a_m1_y]
5
+ * @param {Float64Array|number[]} b length 8 (same layout)
6
+ * @param {Float64Array|number[]} result writes [s, t]
7
+ * @param {number} result_offset
8
+ * @returns {number} squared distance at the closest approach
9
+ */
10
+ export function spline3_hermite_intersection_spline3_hermite_2d(a: Float64Array | number[], b: Float64Array | number[], result: Float64Array | number[], result_offset: number): number;
11
+ //# sourceMappingURL=spline3_hermite_intersection_spline3_hermite_2d.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spline3_hermite_intersection_spline3_hermite_2d.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.js"],"names":[],"mappings":"AA4VA;;;;;;;;GAQG;AACH,mEANW,YAAY,GAAC,MAAM,EAAE,KACrB,YAAY,GAAC,MAAM,EAAE,UACrB,YAAY,GAAC,MAAM,EAAE,iBACrB,MAAM,GACJ,MAAM,CA+FlB"}