@woosh/meep-engine 2.134.4 → 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 (156) 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.d.ts +23 -0
  21. package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.d.ts.map +1 -0
  22. package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.js +96 -0
  23. package/src/core/graph/layout/box/BoxLayouter.js +7 -7
  24. package/src/core/graph/layout/box/position_box_next_to_box.js +6 -6
  25. package/src/core/math/computeWholeDivisorLow.js +33 -33
  26. package/src/core/math/linalg/eigen/eigen_values_find_spectral_gap.d.ts.map +1 -0
  27. package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts +10 -0
  28. package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts.map +1 -0
  29. package/src/core/{graph → math/linalg}/eigen/matrix_eigenvalues_in_place.js +8 -7
  30. package/src/core/math/linalg/eigen/matrix_householder_in_place.d.ts.map +1 -0
  31. package/src/core/{graph → math/linalg}/eigen/matrix_householder_in_place.js +11 -5
  32. package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts +15 -0
  33. package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts.map +1 -0
  34. package/src/core/{graph → math/linalg}/eigen/matrix_qr_in_place.js +8 -2
  35. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts +17 -0
  36. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +1 -0
  37. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.js +107 -0
  38. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts +19 -0
  39. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts.map +1 -0
  40. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.js +161 -0
  41. package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts +15 -0
  42. package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts.map +1 -0
  43. package/src/core/math/linalg/polynomial_real_roots_in_interval.js +200 -0
  44. package/src/core/math/solveCubic.d.ts +15 -0
  45. package/src/core/math/solveCubic.d.ts.map +1 -0
  46. package/src/core/math/solveCubic.js +82 -0
  47. package/src/core/math/spline/spline3_hermite_bounds_t.d.ts +23 -0
  48. package/src/core/math/spline/spline3_hermite_bounds_t.d.ts.map +1 -0
  49. package/src/core/math/spline/spline3_hermite_bounds_t.js +109 -0
  50. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts +25 -0
  51. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts.map +1 -0
  52. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.js +44 -0
  53. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts +16 -0
  54. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts.map +1 -0
  55. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.js +120 -0
  56. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts +11 -0
  57. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts.map +1 -0
  58. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.js +451 -0
  59. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts +12 -0
  60. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -0
  61. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +339 -0
  62. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts +15 -0
  63. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts.map +1 -0
  64. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.js +21 -0
  65. package/src/core/math/spline/spline3_hermite_to_monomial.d.ts +24 -0
  66. package/src/core/math/spline/spline3_hermite_to_monomial.d.ts.map +1 -0
  67. package/src/core/math/spline/spline3_hermite_to_monomial.js +37 -0
  68. package/src/core/math/spline/v3_computeCatmullRomSplineUniformDistance.js +1 -1
  69. package/src/core/model/node-graph/visual/NodeGraphVisualData.js +1 -1
  70. package/src/core/model/reactive/model/util/createRandomReactiveExpression.js +185 -185
  71. package/src/core/process/delay.js +16 -16
  72. package/src/engine/animation/async/TimeSeries.js +300 -300
  73. package/src/engine/animation/curve/AnimationCurve.d.ts +3 -2
  74. package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
  75. package/src/engine/animation/curve/AnimationCurve.js +3 -2
  76. package/src/engine/animation/curve/draw/position_canvas_to_curve.js +2 -2
  77. package/src/engine/animation/curve/draw/position_curve_to_canvas.js +2 -2
  78. package/src/engine/ecs/fow/shader/FogOfWarRenderer.js +145 -145
  79. package/src/engine/ecs/gui/position/ViewportPositionSystem.js +2 -2
  80. package/src/engine/ecs/parent/entity_node_compute_bounding_box.js +1 -1
  81. package/src/engine/ecs/transform/Transform.d.ts +0 -10
  82. package/src/engine/ecs/transform/Transform.d.ts.map +1 -1
  83. package/src/engine/ecs/transform/Transform.js +0 -12
  84. package/src/engine/graphics/composit/CompositLayer.js +254 -254
  85. package/src/engine/graphics/ecs/mesh-v2/sg_hierarchy_compute_bounding_box_via_parent_entity.js +1 -1
  86. package/src/engine/graphics/ecs/path/tube/build/build_geometry_linear.js +2 -2
  87. package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +3 -3
  88. package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +201 -201
  89. package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -1
  90. package/src/engine/graphics/render/buffer/slot/parameter/ProgramValueSlotParameterSet.js +2 -2
  91. package/src/engine/graphics/render/forward_plus/LightManager.js +1226 -1226
  92. package/src/engine/graphics/render/forward_plus/model/PointLight.js +1 -1
  93. package/src/engine/graphics/sh3/lpv/lpv_obtain_storage_cached_volume.js +1 -1
  94. package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +2 -2
  95. package/src/engine/graphics/texture/atlas/TextureAtlasDebugger.js +1 -1
  96. package/src/engine/graphics/texture/sampler/HarmonicDiffusionGrid.js +145 -145
  97. package/src/engine/graphics/texture/sampler/serialization/TextureBinaryBufferSerializer.js +2 -2
  98. package/src/engine/intelligence/behavior/ecs/BehaviorComponent.d.ts +2 -6
  99. package/src/engine/intelligence/behavior/ecs/BehaviorComponent.d.ts.map +1 -1
  100. package/src/engine/intelligence/behavior/ecs/BehaviorComponent.js +0 -10
  101. package/src/engine/intelligence/mcts/MonteCarlo.js +275 -275
  102. package/src/engine/navigation/ecs/path_following/PathFollower.js +222 -222
  103. package/src/generation/grid/GridData.js +220 -220
  104. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +385 -385
  105. package/src/view/elements/image/SvgImageView.js +1 -1
  106. package/src/view/elements/windrose/WindRoseDiagram.js +369 -369
  107. package/src/view/minimap/gl/MinimapFogOfWar.js +3 -3
  108. package/src/view/util/DomSizeObserver.js +1 -1
  109. package/src/core/binary/clz32.d.ts +0 -6
  110. package/src/core/binary/clz32.d.ts.map +0 -1
  111. package/src/core/binary/clz32.js +0 -5
  112. package/src/core/binary/type/dataTypeFromTypedArray.d.ts +0 -8
  113. package/src/core/binary/type/dataTypeFromTypedArray.d.ts.map +0 -1
  114. package/src/core/binary/type/dataTypeFromTypedArray.js +0 -11
  115. package/src/core/collection/array/computeHashIntegerArray.d.ts +0 -1
  116. package/src/core/collection/array/computeHashIntegerArray.d.ts.map +0 -1
  117. package/src/core/collection/array/computeHashIntegerArray.js +0 -7
  118. package/src/core/collection/array/typed/typedArrayToDataType.d.ts +0 -6
  119. package/src/core/collection/array/typed/typedArrayToDataType.d.ts.map +0 -1
  120. package/src/core/collection/array/typed/typedArrayToDataType.js +0 -6
  121. package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.d.ts +0 -6
  122. package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.d.ts.map +0 -1
  123. package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.js +0 -7
  124. package/src/core/graph/eigen/eigen_values_find_spectral_gap.d.ts.map +0 -1
  125. package/src/core/graph/eigen/matrix_eigenvalues_in_place.d.ts +0 -8
  126. package/src/core/graph/eigen/matrix_eigenvalues_in_place.d.ts.map +0 -1
  127. package/src/core/graph/eigen/matrix_householder_in_place.d.ts.map +0 -1
  128. package/src/core/graph/eigen/matrix_qr_in_place.d.ts +0 -9
  129. package/src/core/graph/eigen/matrix_qr_in_place.d.ts.map +0 -1
  130. package/src/core/math/spline/cubicCurve.d.ts +0 -6
  131. package/src/core/math/spline/cubicCurve.d.ts.map +0 -1
  132. package/src/core/math/spline/cubicCurve.js +0 -6
  133. package/src/core/math/spline/spline_bezier2.d.ts +0 -6
  134. package/src/core/math/spline/spline_bezier2.d.ts.map +0 -1
  135. package/src/core/math/spline/spline_bezier2.js +0 -6
  136. package/src/core/math/spline/spline_bezier3.d.ts +0 -6
  137. package/src/core/math/spline/spline_bezier3.d.ts.map +0 -1
  138. package/src/core/math/spline/spline_bezier3.js +0 -6
  139. package/src/core/math/spline/spline_bezier3_bounds.d.ts +0 -6
  140. package/src/core/math/spline/spline_bezier3_bounds.d.ts.map +0 -1
  141. package/src/core/math/spline/spline_bezier3_bounds.js +0 -6
  142. package/src/core/math/spline/spline_hermite3.d.ts +0 -6
  143. package/src/core/math/spline/spline_hermite3.d.ts.map +0 -1
  144. package/src/core/math/spline/spline_hermite3.js +0 -6
  145. package/src/core/math/spline/spline_hermite3_bounds.d.ts +0 -6
  146. package/src/core/math/spline/spline_hermite3_bounds.d.ts.map +0 -1
  147. package/src/core/math/spline/spline_hermite3_bounds.js +0 -6
  148. package/src/core/math/spline/spline_hermite3_to_bezier.d.ts +0 -2
  149. package/src/core/math/spline/spline_hermite3_to_bezier.d.ts.map +0 -1
  150. package/src/core/math/spline/spline_hermite3_to_bezier.js +0 -6
  151. package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.d.ts +0 -37
  152. package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.d.ts.map +0 -1
  153. package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.js +0 -70
  154. /package/src/core/{graph → math/linalg}/eigen/eigen_values_find_spectral_gap.d.ts +0 -0
  155. /package/src/core/{graph → math/linalg}/eigen/eigen_values_find_spectral_gap.js +0 -0
  156. /package/src/core/{graph → math/linalg}/eigen/matrix_householder_in_place.d.ts +0 -0
@@ -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"}
@@ -0,0 +1,451 @@
1
+ import { polynomial_real_roots_in_interval } from "../linalg/polynomial_real_roots_in_interval.js";
2
+ import { solveCubic } from "../solveCubic.js";
3
+ import { spline3_hermite } from "./spline3_hermite.js";
4
+ import { spline3_hermite_intersection_spline3_hermite_nd } from "./spline3_hermite_intersection_spline3_hermite_nd.js";
5
+ import { spline3_hermite_to_monomial } from "./spline3_hermite_to_monomial.js";
6
+
7
+ /*
8
+ 2D specialization. Two equations (one per axis), each bidegree (3,3) in (s,t):
9
+
10
+ P(s, t) = A_x(s) − B_x(t) = 0
11
+ Q(s, t) = A_y(s) − B_y(t) = 0
12
+
13
+ Eliminate t through the Bezout 3×3 resultant matrix (smaller and easier than
14
+ the 6×6 Sylvester form). The resultant det(Bezout) is a univariate polynomial
15
+ in s of degree ≤ 9. Its real roots in [0, 1] give the s-coordinates of all
16
+ true intersections; for each, the corresponding t is recovered by solving the
17
+ cubic A_x(s_i) − B_x(t) = 0 and verifying agreement on the y component.
18
+
19
+ Closest-approach handling:
20
+ - Any true interior intersection ⇒ distance² = 0; report it.
21
+ - Otherwise, the global minimum of squared distance over [0,1]² lies on the
22
+ boundary: an edge minimum (one parameter pinned at 0 or 1, the other a
23
+ quintic minimisation reduced to a quartic root-finding) or a corner.
24
+
25
+ Polynomial-coefficient buffers and the small ad-hoc polynomial arithmetic
26
+ used to assemble det(Bezout) are kept private to this module — they are
27
+ implementation glue, not a general "polynomial library".
28
+ */
29
+
30
+ // Per-curve monomial buffers (4 coeffs per axis).
31
+ const _A_x_mono = new Float64Array(4);
32
+ const _A_y_mono = new Float64Array(4);
33
+ const _B_x_mono = new Float64Array(4);
34
+ const _B_y_mono = new Float64Array(4);
35
+
36
+ // Bezout entries. The four polynomial-valued ones are degree ≤ 3 in s; the two
37
+ // scalar-valued ones are stored as plain numbers in `_bz_const`.
38
+ // _bz_poly[0] = B[0,0] (degree 3 in s)
39
+ // _bz_poly[1] = B[0,1]
40
+ // _bz_poly[2] = B[0,2]
41
+ // _bz_poly[3] = B[1,1]
42
+ const _bz_poly = [
43
+ new Float64Array(4),
44
+ new Float64Array(4),
45
+ new Float64Array(4),
46
+ new Float64Array(4),
47
+ ];
48
+ // _bz_const[0] = B[1,2], _bz_const[1] = B[2,2]
49
+ const _bz_const = new Float64Array(2);
50
+
51
+ // Resultant coefficients (degree ≤ 9 → 10 slots).
52
+ const _resultant = new Float64Array(10);
53
+
54
+ // Scratch polynomials used while computing det(Bezout).
55
+ const _tmp_poly_a = new Float64Array(10);
56
+ const _tmp_poly_b = new Float64Array(10);
57
+ const _tmp_poly_c = new Float64Array(10);
58
+ const _tmp_poly_d = new Float64Array(10);
59
+
60
+ const _root_buffer_s = new Float64Array(9);
61
+ const _root_buffer_t = new Float64Array(3);
62
+
63
+ const Y_MATCH_TOLERANCE = 1e-7;
64
+
65
+ // ── private polynomial helpers (coefficient-array form) ────────────────────
66
+
67
+ function poly_mul(out, a, a_len, b, b_len) {
68
+ const out_len = a_len + b_len - 1;
69
+ for (let i = 0; i < out_len; i++) out[i] = 0;
70
+ for (let i = 0; i < a_len; i++) {
71
+ const ai = a[i];
72
+ if (ai === 0) continue;
73
+ for (let j = 0; j < b_len; j++) {
74
+ out[i + j] += ai * b[j];
75
+ }
76
+ }
77
+ return out_len;
78
+ }
79
+
80
+ function poly_add_into(target, target_len, a, a_len) {
81
+ const n = a_len > target_len ? a_len : target_len;
82
+ for (let i = target_len; i < n; i++) target[i] = 0;
83
+ for (let i = 0; i < a_len; i++) target[i] += a[i];
84
+ return n;
85
+ }
86
+
87
+ function poly_sub_into(target, target_len, a, a_len) {
88
+ const n = a_len > target_len ? a_len : target_len;
89
+ for (let i = target_len; i < n; i++) target[i] = 0;
90
+ for (let i = 0; i < a_len; i++) target[i] -= a[i];
91
+ return n;
92
+ }
93
+
94
+ function poly_scale_into(target, target_len, scalar) {
95
+ for (let i = 0; i < target_len; i++) target[i] *= scalar;
96
+ }
97
+
98
+ // ── core algorithm helpers ────────────────────────────────────────────────
99
+
100
+ /**
101
+ * Build the 6 Bezout entries (4 polynomial, 2 constant) from the monomial
102
+ * coefficients of A and B. See module preamble for the algebraic derivation.
103
+ *
104
+ * Layout:
105
+ * a-side polys are A_*(s) in monomial basis (cubic in s). Their coefficient
106
+ * arrays here are length 4 (constant ... s³).
107
+ * b-side polys are B_*(t) — we only need the *coefficients* (constants
108
+ * wrt s) in the bivariate form P(s,t) = A_x(s) − B_x(t). So β_kx = the k-th
109
+ * monomial coefficient of B_x.
110
+ */
111
+ function build_bezout_entries(a_x, a_y, b_x, b_y) {
112
+ // Coefficients of P(s, t) viewed as polynomial in t with s-poly coeffs:
113
+ // p_0(s) = A_x(s) − β0_x (cubic in s)
114
+ // p_1 = -β1_x (constant)
115
+ // p_2 = -β2_x
116
+ // p_3 = -β3_x
117
+ // and similarly q_k for Q.
118
+
119
+ const beta_1x = -b_x[1];
120
+ const beta_2x = -b_x[2];
121
+ const beta_3x = -b_x[3];
122
+ const beta_1y = -b_y[1];
123
+ const beta_2y = -b_y[2];
124
+ const beta_3y = -b_y[3];
125
+
126
+ // p_0(s) = A_x(s) - β0_x
127
+ const p0 = _tmp_poly_a;
128
+ p0[0] = a_x[0] - b_x[0];
129
+ p0[1] = a_x[1];
130
+ p0[2] = a_x[2];
131
+ p0[3] = a_x[3];
132
+
133
+ // q_0(s) = A_y(s) - β0_y
134
+ const q0 = _tmp_poly_b;
135
+ q0[0] = a_y[0] - b_y[0];
136
+ q0[1] = a_y[1];
137
+ q0[2] = a_y[2];
138
+ q0[3] = a_y[3];
139
+
140
+ // B[0,0] = a_1 b_0 - a_0 b_1 = beta_1x * q_0(s) - p_0(s) * beta_1y
141
+ const b00 = _bz_poly[0];
142
+ for (let i = 0; i < 4; i++) b00[i] = beta_1x * q0[i] - p0[i] * beta_1y;
143
+
144
+ // B[0,1] = a_2 b_0 - a_0 b_2 = beta_2x * q_0(s) - p_0(s) * beta_2y
145
+ const b01 = _bz_poly[1];
146
+ for (let i = 0; i < 4; i++) b01[i] = beta_2x * q0[i] - p0[i] * beta_2y;
147
+
148
+ // B[0,2] = a_3 b_0 - a_0 b_3 = beta_3x * q_0(s) - p_0(s) * beta_3y
149
+ const b02 = _bz_poly[2];
150
+ for (let i = 0; i < 4; i++) b02[i] = beta_3x * q0[i] - p0[i] * beta_3y;
151
+
152
+ // B[1,1] = (a_3 b_0 - a_0 b_3) + (a_2 b_1 - a_1 b_2)
153
+ // = B[0,2] + (beta_2x * beta_1y - beta_1x * beta_2y)
154
+ const b11 = _bz_poly[3];
155
+ const inner = beta_2x * beta_1y - beta_1x * beta_2y;
156
+ for (let i = 0; i < 4; i++) b11[i] = b02[i];
157
+ b11[0] += inner;
158
+
159
+ // B[1,2] = a_3 b_1 - a_1 b_3 = beta_3x * beta_1y - beta_1x * beta_3y (constant)
160
+ _bz_const[0] = beta_3x * beta_1y - beta_1x * beta_3y;
161
+
162
+ // B[2,2] = a_3 b_2 - a_2 b_3 = beta_3x * beta_2y - beta_2x * beta_3y (constant)
163
+ _bz_const[1] = beta_3x * beta_2y - beta_2x * beta_3y;
164
+ }
165
+
166
+ /**
167
+ * Compute det(Bezout) as a polynomial in s and write its coefficients into
168
+ * `_resultant`. Returns the (effective) degree + 1 — i.e. the number of
169
+ * coefficients that are meaningful.
170
+ *
171
+ * Closed form: det(B) = B[0,2]·(B[0,1]·B[1,2] − B[0,2]·B[1,1])
172
+ * − B[1,2]·(B[0,0]·B[1,2] − B[0,2]·B[0,1])
173
+ * + B[2,2]·(B[0,0]·B[1,1] − B[0,1]²)
174
+ *
175
+ * B[0,0], B[0,1], B[0,2], B[1,1] are cubic polynomials in s (length 4).
176
+ * B[1,2], B[2,2] are constants (length 1).
177
+ */
178
+ function compute_resultant() {
179
+ const b00 = _bz_poly[0]; // length 4
180
+ const b01 = _bz_poly[1]; // length 4
181
+ const b02 = _bz_poly[2]; // length 4
182
+ const b11 = _bz_poly[3]; // length 4
183
+ const b12 = _bz_const[0];
184
+ const b22 = _bz_const[1];
185
+
186
+ for (let i = 0; i < 10; i++) _resultant[i] = 0;
187
+
188
+ // ── Term A: B[0,2] · (B[0,1] · B[1,2] − B[0,2] · B[1,1]) ──
189
+ // tmp_c = B[0,1] · B[1,2] (cubic × constant → cubic, length 4)
190
+ const tmp_c = _tmp_poly_c;
191
+ let tmp_c_len = 4;
192
+ for (let i = 0; i < 4; i++) tmp_c[i] = b01[i] * b12;
193
+
194
+ // tmp_d = B[0,2] · B[1,1] (cubic × cubic → degree 6, length 7)
195
+ const tmp_d = _tmp_poly_d;
196
+ const tmp_d_len = poly_mul(tmp_d, b02, 4, b11, 4);
197
+
198
+ // tmp_c -= tmp_d (length 7)
199
+ tmp_c_len = poly_sub_into(tmp_c, tmp_c_len, tmp_d, tmp_d_len);
200
+
201
+ // term_a = B[0,2] · tmp_c (length 4 + 7 − 1 = 10)
202
+ const tmp_a = _tmp_poly_a;
203
+ const tmp_a_len = poly_mul(tmp_a, b02, 4, tmp_c, tmp_c_len);
204
+
205
+ // resultant += term_a
206
+ poly_add_into(_resultant, 0, tmp_a, tmp_a_len);
207
+
208
+ // ── Term B: −B[1,2] · (B[0,0] · B[1,2] − B[0,2] · B[0,1]) ──
209
+ // tmp_c = B[0,0] · B[1,2] (cubic × constant)
210
+ tmp_c_len = 4;
211
+ for (let i = 0; i < 4; i++) tmp_c[i] = b00[i] * b12;
212
+
213
+ // tmp_d = B[0,2] · B[0,1] (cubic × cubic → length 7)
214
+ const tmp_d_len_2 = poly_mul(tmp_d, b02, 4, b01, 4);
215
+
216
+ tmp_c_len = poly_sub_into(tmp_c, tmp_c_len, tmp_d, tmp_d_len_2);
217
+
218
+ poly_scale_into(tmp_c, tmp_c_len, -b12);
219
+ poly_add_into(_resultant, _resultant.length, tmp_c, tmp_c_len);
220
+
221
+ // ── Term C: B[2,2] · (B[0,0] · B[1,1] − B[0,1]²) ──
222
+ const tmp_d_len_3 = poly_mul(tmp_d, b00, 4, b11, 4); // length 7
223
+ tmp_c_len = poly_mul(tmp_c, b01, 4, b01, 4); // length 7
224
+
225
+ poly_sub_into(tmp_d, tmp_d_len_3, tmp_c, tmp_c_len);
226
+
227
+ poly_scale_into(tmp_d, tmp_d_len_3, b22);
228
+ poly_add_into(_resultant, _resultant.length, tmp_d, tmp_d_len_3);
229
+ }
230
+
231
+ /**
232
+ * For a given s, find a t in [0,1] such that A_x(s) − B_x(t) = 0 AND
233
+ * A_y(s) ≈ B_y(t) (the latter within Y_MATCH_TOLERANCE). Returns the matched
234
+ * t, or -1 if none.
235
+ */
236
+ function recover_t(a, b, s) {
237
+ // A_x(s) value:
238
+ const a_x_at_s = spline3_hermite(s, a[0], a[1], a[2], a[3]);
239
+ const a_y_at_s = spline3_hermite(s, a[4], a[5], a[6], a[7]);
240
+
241
+ // Solve B_x(t) = a_x_at_s for t:
242
+ // B_x in monomial: β0_x + β1_x t + β2_x t² + β3_x t³ - a_x_at_s = 0
243
+ const t_count = solveCubic(
244
+ _root_buffer_t, 0,
245
+ _B_x_mono[3], _B_x_mono[2], _B_x_mono[1], _B_x_mono[0] - a_x_at_s
246
+ );
247
+
248
+ let best_t = -1;
249
+ let best_dy = Number.POSITIVE_INFINITY;
250
+
251
+ for (let i = 0; i < t_count; i++) {
252
+ const t = _root_buffer_t[i];
253
+ if (t < 0 || t > 1) continue;
254
+ const b_y_at_t = spline3_hermite(t, b[4], b[5], b[6], b[7]);
255
+ const dy = Math.abs(a_y_at_s - b_y_at_t);
256
+ if (dy < best_dy) {
257
+ best_dy = dy;
258
+ best_t = t;
259
+ }
260
+ }
261
+
262
+ if (best_dy > Y_MATCH_TOLERANCE) return -1;
263
+ return best_t;
264
+ }
265
+
266
+ /**
267
+ * Find the minimum of ||point − B(t)||² over t in [0,1], where `point` is a 2D
268
+ * point (px, py). Solves the quintic ∂/∂t = 0 by feeding it to
269
+ * polynomial_real_roots_in_interval and tests each root + the two endpoints.
270
+ *
271
+ * Writes `[t, dist²]` into the returned 2-element module scratch.
272
+ */
273
+ const _edge_tmp_eval = new Float64Array(6);
274
+ const _edge_tmp_quintic = new Float64Array(6);
275
+ const _edge_tmp_roots = new Float64Array(5);
276
+ const _edge_result = new Float64Array(2);
277
+
278
+ function nearest_t_on_curve(b_mono_x, b_mono_y, point_x, point_y) {
279
+ // B(t) − point is a cubic in t per axis. ‖B(t) − point‖² is degree 6.
280
+ // Its derivative wrt t is degree 5.
281
+
282
+ // Δ_x(t) = (β0_x − px) + β1_x t + β2_x t² + β3_x t³
283
+ const dx0 = b_mono_x[0] - point_x;
284
+ const dx1 = b_mono_x[1];
285
+ const dx2 = b_mono_x[2];
286
+ const dx3 = b_mono_x[3];
287
+
288
+ const dy0 = b_mono_y[0] - point_y;
289
+ const dy1 = b_mono_y[1];
290
+ const dy2 = b_mono_y[2];
291
+ const dy3 = b_mono_y[3];
292
+
293
+ // d/dt ‖Δ‖² = 2 (Δ_x · dΔ_x/dt + Δ_y · dΔ_y/dt) → drop the factor of 2.
294
+ // dΔ_x/dt = β1_x + 2 β2_x t + 3 β3_x t² (degree 2)
295
+
296
+ // Compute each pair-product as a quintic, then sum.
297
+ // (a0 + a1 t + a2 t² + a3 t³) · (b0 + b1 t + b2 t²) = up to degree 5.
298
+
299
+ const quintic = _edge_tmp_quintic;
300
+ for (let i = 0; i < 6; i++) quintic[i] = 0;
301
+
302
+ // x-axis contribution
303
+ {
304
+ const a0 = dx0, a1 = dx1, a2 = dx2, a3 = dx3;
305
+ const b0 = dx1, b1 = 2 * dx2, b2 = 3 * dx3;
306
+ quintic[0] += a0 * b0;
307
+ quintic[1] += a0 * b1 + a1 * b0;
308
+ quintic[2] += a0 * b2 + a1 * b1 + a2 * b0;
309
+ quintic[3] += a1 * b2 + a2 * b1 + a3 * b0;
310
+ quintic[4] += a2 * b2 + a3 * b1;
311
+ quintic[5] += a3 * b2;
312
+ }
313
+ // y-axis contribution
314
+ {
315
+ const a0 = dy0, a1 = dy1, a2 = dy2, a3 = dy3;
316
+ const b0 = dy1, b1 = 2 * dy2, b2 = 3 * dy3;
317
+ quintic[0] += a0 * b0;
318
+ quintic[1] += a0 * b1 + a1 * b0;
319
+ quintic[2] += a0 * b2 + a1 * b1 + a2 * b0;
320
+ quintic[3] += a1 * b2 + a2 * b1 + a3 * b0;
321
+ quintic[4] += a2 * b2 + a3 * b1;
322
+ quintic[5] += a3 * b2;
323
+ }
324
+
325
+ const root_count = polynomial_real_roots_in_interval(
326
+ quintic, 5, 0, 1, _edge_tmp_roots, 0
327
+ );
328
+
329
+ let best_t = 0;
330
+ let best_d2 = Number.POSITIVE_INFINITY;
331
+
332
+ for (let i = -2; i < root_count; i++) {
333
+ // i = -2 → t = 0; i = -1 → t = 1; otherwise interior roots
334
+ const t = i === -2 ? 0 : (i === -1 ? 1 : _edge_tmp_roots[i]);
335
+ const ex = dx0 + t * (dx1 + t * (dx2 + t * dx3));
336
+ const ey = dy0 + t * (dy1 + t * (dy2 + t * dy3));
337
+ const d2 = ex * ex + ey * ey;
338
+ if (d2 < best_d2) {
339
+ best_d2 = d2;
340
+ best_t = t;
341
+ }
342
+ }
343
+
344
+ _edge_result[0] = best_t;
345
+ _edge_result[1] = best_d2;
346
+ return _edge_result;
347
+ }
348
+
349
+ /**
350
+ * 2D specialization of the closest-approach intersection finder.
351
+ *
352
+ * @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]
353
+ * @param {Float64Array|number[]} b length 8 (same layout)
354
+ * @param {Float64Array|number[]} result writes [s, t]
355
+ * @param {number} result_offset
356
+ * @returns {number} squared distance at the closest approach
357
+ */
358
+ export function spline3_hermite_intersection_spline3_hermite_2d(
359
+ a, b,
360
+ result, result_offset
361
+ ) {
362
+ spline3_hermite_to_monomial(_A_x_mono, 0, 1, a[0], a[1], a[2], a[3]);
363
+ spline3_hermite_to_monomial(_A_y_mono, 0, 1, a[4], a[5], a[6], a[7]);
364
+ spline3_hermite_to_monomial(_B_x_mono, 0, 1, b[0], b[1], b[2], b[3]);
365
+ spline3_hermite_to_monomial(_B_y_mono, 0, 1, b[4], b[5], b[6], b[7]);
366
+
367
+ build_bezout_entries(_A_x_mono, _A_y_mono, _B_x_mono, _B_y_mono);
368
+ compute_resultant();
369
+
370
+ // Detect a degenerate resultant. This happens when one (or both) input
371
+ // curves is degree < 3 in its parameter — straight axis-aligned lines are
372
+ // the canonical example. The (3,3)/(3,3) Bezout construction collapses
373
+ // because the relevant leading coefficients are zero. In that case, fall
374
+ // back to the dimension-agnostic Newton-from-grid path.
375
+ let max_resultant_mag = 0;
376
+ for (let i = 0; i < _resultant.length; i++) {
377
+ const v = Math.abs(_resultant[i]);
378
+ if (v > max_resultant_mag) max_resultant_mag = v;
379
+ }
380
+ if (max_resultant_mag < 1e-12) {
381
+ return spline3_hermite_intersection_spline3_hermite_nd(a, b, 2, result, result_offset);
382
+ }
383
+
384
+ const s_root_count = polynomial_real_roots_in_interval(
385
+ _resultant, 9, 0, 1, _root_buffer_s, 0
386
+ );
387
+
388
+ // Look for a true intersection (distance² = 0).
389
+ for (let i = 0; i < s_root_count; i++) {
390
+ const s = _root_buffer_s[i];
391
+ const t = recover_t(a, b, s);
392
+ if (t >= 0) {
393
+ result[result_offset] = s;
394
+ result[result_offset + 1] = t;
395
+ return 0;
396
+ }
397
+ }
398
+
399
+ // Otherwise the global min is on the boundary. Test all four edges + four
400
+ // corners. The corners are picked up automatically by `nearest_t_on_curve`
401
+ // since it tests t = 0 and t = 1 for the free parameter.
402
+
403
+ let best_s = 0;
404
+ let best_t = 0;
405
+ let best_d2 = Number.POSITIVE_INFINITY;
406
+
407
+ // Edge s = 0: minimise ‖A(0) − B(t)‖² over t.
408
+ {
409
+ const px = a[0], py = a[4];
410
+ const r = nearest_t_on_curve(_B_x_mono, _B_y_mono, px, py);
411
+ if (r[1] < best_d2) {
412
+ best_d2 = r[1];
413
+ best_s = 0;
414
+ best_t = r[0];
415
+ }
416
+ }
417
+ // Edge s = 1.
418
+ {
419
+ const px = a[1], py = a[5];
420
+ const r = nearest_t_on_curve(_B_x_mono, _B_y_mono, px, py);
421
+ if (r[1] < best_d2) {
422
+ best_d2 = r[1];
423
+ best_s = 1;
424
+ best_t = r[0];
425
+ }
426
+ }
427
+ // Edge t = 0: minimise ‖A(s) − B(0)‖² over s.
428
+ {
429
+ const px = b[0], py = b[4];
430
+ const r = nearest_t_on_curve(_A_x_mono, _A_y_mono, px, py);
431
+ if (r[1] < best_d2) {
432
+ best_d2 = r[1];
433
+ best_s = r[0];
434
+ best_t = 0;
435
+ }
436
+ }
437
+ // Edge t = 1.
438
+ {
439
+ const px = b[1], py = b[5];
440
+ const r = nearest_t_on_curve(_A_x_mono, _A_y_mono, px, py);
441
+ if (r[1] < best_d2) {
442
+ best_d2 = r[1];
443
+ best_s = r[0];
444
+ best_t = 1;
445
+ }
446
+ }
447
+
448
+ result[result_offset] = best_s;
449
+ result[result_offset + 1] = best_t;
450
+ return best_d2;
451
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * ND specialization (dim ≥ 3). See module preamble for algorithmic notes.
3
+ *
4
+ * @param {Float64Array|number[]} a length 4*dim
5
+ * @param {Float64Array|number[]} b length 4*dim
6
+ * @param {number} dim ≥ 3 (also correct for dim ≥ 2 but slower than the 2D path)
7
+ * @param {Float64Array|number[]} result writes [s, t]
8
+ * @param {number} result_offset
9
+ * @returns {number} squared distance at closest approach
10
+ */
11
+ export function spline3_hermite_intersection_spline3_hermite_nd(a: Float64Array | number[], b: Float64Array | number[], dim: number, result: Float64Array | number[], result_offset: number): number;
12
+ //# sourceMappingURL=spline3_hermite_intersection_spline3_hermite_nd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spline3_hermite_intersection_spline3_hermite_nd.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js"],"names":[],"mappings":"AAmPA;;;;;;;;;GASG;AACH,mEAPW,YAAY,GAAC,MAAM,EAAE,KACrB,YAAY,GAAC,MAAM,EAAE,OACrB,MAAM,UACN,YAAY,GAAC,MAAM,EAAE,iBACrB,MAAM,GACJ,MAAM,CAuFlB"}