@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.
- package/build/bundle-worker-image-decoder.js +1 -1
- package/build/bundle-worker-terrain.js +1 -1
- package/editor/tools/v2/TransformControlsGizmo.js +1 -1
- package/editor/view/node-graph/NodeGraphEditorView.js +2 -2
- package/package.json +1 -1
- package/src/core/assert.d.ts +0 -2
- package/src/core/assert.d.ts.map +1 -1
- package/src/core/assert.js +0 -6
- package/src/core/color/Color.d.ts +0 -5
- package/src/core/color/Color.d.ts.map +1 -1
- package/src/core/color/Color.js +1 -7
- package/src/core/geom/2d/hash-grid/SpatialHashGrid.js +386 -386
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_2d.js +1 -1
- package/src/core/geom/2d/quad-tree-binary/QuadTree.js +714 -714
- package/src/core/geom/3d/triangle/computeTriangleRayIntersection.js +160 -160
- package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js +96 -96
- package/src/core/geom/packing/max-rect/MaxRectanglesPacker.js +1 -1
- package/src/core/geom/packing/max-rect/findBestContainer.js +4 -4
- package/src/core/geom/packing/max-rect/packOneBox.js +2 -2
- package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.js +1 -1
- package/src/core/graph/layout/box/BoxLayouter.js +7 -7
- package/src/core/graph/layout/box/position_box_next_to_box.js +6 -6
- package/src/core/math/computeWholeDivisorLow.js +33 -33
- package/src/core/math/linalg/eigen/eigen_values_find_spectral_gap.d.ts.map +1 -0
- package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts +10 -0
- package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts.map +1 -0
- package/src/core/{graph → math/linalg}/eigen/matrix_eigenvalues_in_place.js +8 -7
- package/src/core/math/linalg/eigen/matrix_householder_in_place.d.ts.map +1 -0
- package/src/core/{graph → math/linalg}/eigen/matrix_householder_in_place.js +11 -5
- package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts +15 -0
- package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts.map +1 -0
- package/src/core/{graph → math/linalg}/eigen/matrix_qr_in_place.js +8 -2
- package/src/core/{graph → math/linalg}/eigen/matrix_top_eigenvector_power_iteration.d.ts +0 -3
- package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +1 -0
- package/src/core/{graph → math/linalg}/eigen/matrix_top_eigenvector_power_iteration.js +0 -3
- package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts +19 -0
- package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts.map +1 -0
- package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.js +161 -0
- package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts +15 -0
- package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts.map +1 -0
- package/src/core/math/linalg/polynomial_real_roots_in_interval.js +200 -0
- package/src/core/math/solveCubic.d.ts +15 -0
- package/src/core/math/solveCubic.d.ts.map +1 -0
- package/src/core/math/solveCubic.js +82 -0
- package/src/core/math/spline/spline3_hermite_bounds_t.d.ts +23 -0
- package/src/core/math/spline/spline3_hermite_bounds_t.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_bounds_t.js +109 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts +25 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.js +44 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts +16 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.js +120 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts +11 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.js +451 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts +12 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +339 -0
- package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts +15 -0
- package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.js +21 -0
- package/src/core/math/spline/spline3_hermite_to_monomial.d.ts +24 -0
- package/src/core/math/spline/spline3_hermite_to_monomial.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_to_monomial.js +37 -0
- package/src/core/math/spline/v3_computeCatmullRomSplineUniformDistance.js +1 -1
- package/src/core/model/node-graph/visual/NodeGraphVisualData.js +1 -1
- package/src/core/model/reactive/model/util/createRandomReactiveExpression.js +185 -185
- package/src/core/process/delay.js +16 -16
- package/src/engine/animation/async/TimeSeries.js +300 -300
- package/src/engine/animation/curve/AnimationCurve.d.ts +0 -4
- package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
- package/src/engine/animation/curve/AnimationCurve.js +1 -6
- package/src/engine/animation/curve/draw/position_canvas_to_curve.js +2 -2
- package/src/engine/animation/curve/draw/position_curve_to_canvas.js +2 -2
- package/src/engine/ecs/fow/shader/FogOfWarRenderer.js +145 -145
- package/src/engine/ecs/gui/position/ViewportPositionSystem.js +2 -2
- package/src/engine/ecs/parent/entity_node_compute_bounding_box.js +1 -1
- package/src/engine/ecs/transform/Transform.d.ts +0 -10
- package/src/engine/ecs/transform/Transform.d.ts.map +1 -1
- package/src/engine/ecs/transform/Transform.js +0 -12
- package/src/engine/graphics/composit/CompositLayer.js +254 -254
- package/src/engine/graphics/ecs/mesh-v2/sg_hierarchy_compute_bounding_box_via_parent_entity.js +1 -1
- package/src/engine/graphics/ecs/path/tube/build/build_geometry_linear.js +2 -2
- package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +3 -3
- package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +201 -201
- package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -1
- package/src/engine/graphics/render/buffer/slot/parameter/ProgramValueSlotParameterSet.js +2 -2
- package/src/engine/graphics/render/forward_plus/LightManager.js +1226 -1226
- package/src/engine/graphics/render/forward_plus/model/PointLight.js +1 -1
- package/src/engine/graphics/sh3/lpv/lpv_obtain_storage_cached_volume.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +2 -2
- package/src/engine/graphics/texture/atlas/TextureAtlasDebugger.js +1 -1
- package/src/engine/graphics/texture/sampler/HarmonicDiffusionGrid.js +145 -145
- package/src/engine/graphics/texture/sampler/serialization/TextureBinaryBufferSerializer.js +2 -2
- package/src/engine/intelligence/behavior/ecs/BehaviorComponent.d.ts +2 -6
- package/src/engine/intelligence/behavior/ecs/BehaviorComponent.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/ecs/BehaviorComponent.js +0 -10
- package/src/engine/intelligence/mcts/MonteCarlo.js +275 -275
- package/src/engine/navigation/ecs/path_following/PathFollower.js +222 -222
- package/src/generation/grid/GridData.js +220 -220
- package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +385 -385
- package/src/view/elements/image/SvgImageView.js +1 -1
- package/src/view/elements/windrose/WindRoseDiagram.js +369 -369
- package/src/view/minimap/gl/MinimapFogOfWar.js +3 -3
- package/src/view/util/DomSizeObserver.js +1 -1
- package/src/core/binary/clz32.d.ts +0 -6
- package/src/core/binary/clz32.d.ts.map +0 -1
- package/src/core/binary/clz32.js +0 -5
- package/src/core/binary/type/dataTypeFromTypedArray.d.ts +0 -8
- package/src/core/binary/type/dataTypeFromTypedArray.d.ts.map +0 -1
- package/src/core/binary/type/dataTypeFromTypedArray.js +0 -11
- package/src/core/collection/array/computeHashIntegerArray.d.ts +0 -1
- package/src/core/collection/array/computeHashIntegerArray.d.ts.map +0 -1
- package/src/core/collection/array/computeHashIntegerArray.js +0 -7
- package/src/core/collection/array/typed/typedArrayToDataType.d.ts +0 -6
- package/src/core/collection/array/typed/typedArrayToDataType.d.ts.map +0 -1
- package/src/core/collection/array/typed/typedArrayToDataType.js +0 -6
- package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.d.ts +0 -6
- package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.d.ts.map +0 -1
- package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.js +0 -7
- package/src/core/graph/eigen/eigen_values_find_spectral_gap.d.ts.map +0 -1
- package/src/core/graph/eigen/matrix_eigenvalues_in_place.d.ts +0 -8
- package/src/core/graph/eigen/matrix_eigenvalues_in_place.d.ts.map +0 -1
- package/src/core/graph/eigen/matrix_householder_in_place.d.ts.map +0 -1
- package/src/core/graph/eigen/matrix_qr_in_place.d.ts +0 -9
- package/src/core/graph/eigen/matrix_qr_in_place.d.ts.map +0 -1
- package/src/core/graph/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +0 -1
- package/src/core/math/spline/cubicCurve.d.ts +0 -6
- package/src/core/math/spline/cubicCurve.d.ts.map +0 -1
- package/src/core/math/spline/cubicCurve.js +0 -6
- package/src/core/math/spline/spline_bezier2.d.ts +0 -6
- package/src/core/math/spline/spline_bezier2.d.ts.map +0 -1
- package/src/core/math/spline/spline_bezier2.js +0 -6
- package/src/core/math/spline/spline_bezier3.d.ts +0 -6
- package/src/core/math/spline/spline_bezier3.d.ts.map +0 -1
- package/src/core/math/spline/spline_bezier3.js +0 -6
- package/src/core/math/spline/spline_bezier3_bounds.d.ts +0 -6
- package/src/core/math/spline/spline_bezier3_bounds.d.ts.map +0 -1
- package/src/core/math/spline/spline_bezier3_bounds.js +0 -6
- package/src/core/math/spline/spline_hermite3.d.ts +0 -6
- package/src/core/math/spline/spline_hermite3.d.ts.map +0 -1
- package/src/core/math/spline/spline_hermite3.js +0 -6
- package/src/core/math/spline/spline_hermite3_bounds.d.ts +0 -6
- package/src/core/math/spline/spline_hermite3_bounds.d.ts.map +0 -1
- package/src/core/math/spline/spline_hermite3_bounds.js +0 -6
- package/src/core/math/spline/spline_hermite3_to_bezier.d.ts +0 -2
- package/src/core/math/spline/spline_hermite3_to_bezier.d.ts.map +0 -1
- package/src/core/math/spline/spline_hermite3_to_bezier.js +0 -6
- package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.d.ts +0 -37
- package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.d.ts.map +0 -1
- package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.js +0 -70
- /package/src/core/{graph → math/linalg}/eigen/eigen_values_find_spectral_gap.d.ts +0 -0
- /package/src/core/{graph → math/linalg}/eigen/eigen_values_find_spectral_gap.js +0 -0
- /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"}
|