@woosh/meep-engine 2.48.23 → 2.49.1
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/editor/tools/GridPaintTool.js +1 -1
- package/editor/tools/paint/TerrainPaintTool.js +1 -1
- package/editor/view/GridPickCoordinateView.js +1 -1
- package/package.json +1 -1
- package/src/core/UUID.js +2 -0
- package/src/core/assert.js +4 -1
- package/src/core/binary/ctz32.js +1 -1
- package/src/core/binary/operations/bitCount.spec.js +19 -0
- package/src/core/binary/uint82float.spec.js +7 -0
- package/src/core/bvh2/binary/IndexedBinaryBVH.spec.js +7 -0
- package/src/core/bvh2/bvh3/EBBVHLeafProxy.js +3 -0
- package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +5 -4
- package/src/core/bvh2/transform/RotationOptimizer.spec.js +161 -155
- package/src/core/codegen/LineBuilder.js +12 -3
- package/src/core/codegen/LineBuilder.spec.js +7 -0
- package/src/core/collection/CuckooFilter.js +12 -12
- package/src/core/collection/HashMap.js +486 -237
- package/src/core/collection/HashMap.spec.js +110 -1
- package/src/core/collection/array/{typedArrayToDataType.js → typed/typedArrayToDataType.js} +1 -1
- package/src/core/collection/array/weightedRandomFromArray.spec.js +20 -0
- package/src/core/debug/matchers/AnyOf.js +1 -2
- package/src/core/geom/2d/aabb/AABB2.spec.js +1 -1
- package/src/core/geom/2d/aabb/aabb2_compute_center_from_multiple.js +19 -0
- package/src/core/geom/2d/quad-tree/qt_collect_by_circle.js +3 -3
- package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.js +7 -9
- package/src/core/geom/3d/aabb/aabb3_compute_plane_side.js +17 -15
- package/src/core/geom/3d/aabb/aabb3_compute_plane_side.spec.js +25 -0
- package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.js +1 -1
- package/src/core/geom/3d/aabb/aabb3_from_v3_array.js +3 -0
- package/src/core/geom/3d/aabb/aabb3_from_v3_array.spec.js +32 -0
- package/src/core/geom/3d/aabb/aabb3_intersects_aabb3.spec.js +115 -0
- package/src/core/geom/3d/aabb/aabb3_raycast.js +6 -1
- package/src/core/geom/3d/aabb/serializeAABB3Encoded_v0.js +6 -6
- package/src/core/geom/3d/{CircleMath.js → compute_circle_bounding_box.js} +1 -1
- package/src/core/geom/3d/decompose_matrix_4_array.js +18 -19
- package/src/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +1 -1
- package/src/{engine/graphics/ecs/mesh-v2 → core/geom/3d/matrix}/allocate_transform_m4.js +1 -1
- package/src/core/geom/3d/normal/hemioct/decode_hemioct_to_unit.js +26 -0
- package/src/core/geom/3d/normal/hemioct/encode_unit3_hemioct.js +0 -26
- package/src/core/geom/3d/normal/hemioct/unit_hemioct.spec.js +2 -1
- package/src/core/geom/3d/plane/computePlaneLineIntersection.js +51 -0
- package/src/core/geom/3d/plane/computePlanePlaneIntersection.js +77 -0
- package/src/core/geom/3d/plane/computePlaneRayIntersection.js +55 -0
- package/src/core/geom/3d/plane/plane3_computeLineSegmentIntersection.js +50 -0
- package/src/core/geom/3d/plane/planeRayIntersection.js +14 -0
- package/src/core/geom/3d/{tetrahedra/in_sphere_fast.js → sphere/in_sphere3d_fast.js} +1 -1
- package/src/core/geom/3d/{tetrahedra/in_sphere_robust.js → sphere/in_sphere3d_robust.js} +1 -1
- package/src/core/geom/3d/sphere/sphere_array_intersects_point.js +2 -2
- package/src/core/geom/3d/sphere/{sphereIntersectsPoint.js → sphere_intersects_point.js} +7 -4
- package/src/core/geom/3d/sphere/sphere_intersects_point.spec.js +134 -0
- package/src/core/geom/3d/sphere/sphere_intersects_ray.spec.js +49 -0
- package/src/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.js +11 -7
- package/src/core/geom/3d/tetrahedra/delaunay/{debug_validate_mesh.js → debug/debug_validate_mesh.js} +1 -1
- package/src/core/geom/3d/tetrahedra/delaunay/{push_boundary_with_validation.js → debug/push_boundary_with_validation.js} +1 -1
- package/src/core/geom/3d/tetrahedra/delaunay/{validate_cavity_boundary.js → debug/validate_cavity_boundary.js} +2 -2
- package/src/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_compute_cavity.js +2 -2
- package/src/core/geom/3d/triangle/computeTriangleRayIntersection.js +0 -164
- package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js +87 -0
- package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentricEdge.js +81 -0
- package/src/core/geom/{rayTriangleIntersection.js → 3d/triangle/rayTriangleIntersection.js} +2 -2
- package/src/core/geom/ConicRay.js +160 -152
- package/src/core/geom/Matrix4.js +2 -0
- package/src/core/geom/Quaternion.js +19 -1
- package/src/core/geom/packing/max-rect/MaxRectangles.js +4 -214
- package/src/core/geom/packing/max-rect/cost/costByBestShortSide.js +11 -0
- package/src/core/geom/packing/max-rect/cost/costByRemainingArea.js +14 -0
- package/src/core/geom/packing/max-rect/cutArea.js +79 -0
- package/src/core/geom/packing/max-rect/findBestContainer.js +58 -0
- package/src/core/geom/packing/max-rect/packOneBox.js +49 -0
- package/src/core/geom/packing/miniball/Miniball.js +12 -12
- package/src/core/geom/packing/miniball/Quality.js +2 -2
- package/src/core/geom/packing/miniball/Subspan.js +13 -13
- package/src/core/geom/v3_dot.js +1 -1
- package/src/core/graph/layout/CircleLayout.js +1 -1
- package/src/core/graph/layout/{BoxLayouter.js → box/BoxLayouter.js} +6 -50
- package/src/core/graph/layout/box/applyCentralGravityAABB2.js +29 -0
- package/src/core/json/resolvePath.spec.js +14 -0
- package/src/core/land/reactive/{compiler/ReactiveCompiler.spec.js → compileReactiveExpression.spec.js} +17 -17
- package/src/core/math/random/MersenneTwister.spec.js +19 -0
- package/src/core/math/random/randomGaussian.spec.js +9 -0
- package/src/core/math/statistics/computeStatisticalMean.js +2 -2
- package/src/core/model/reactive/model/arithmetic/ReactiveAdd.js +1 -1
- package/src/core/model/reactive/model/arithmetic/ReactiveDivide.js +3 -1
- package/src/core/model/reactive/model/arithmetic/ReactiveMultiply.js +1 -1
- package/src/core/model/reactive/model/arithmetic/ReactiveNegate.js +3 -1
- package/src/core/model/reactive/model/arithmetic/ReactiveSubtract.js +1 -1
- package/src/core/model/reactive/model/comparative/ReactiveEquals.js +1 -1
- package/src/core/model/reactive/model/comparative/ReactiveGreaterThan.js +3 -1
- package/src/core/model/reactive/model/comparative/ReactiveGreaterThanOrEqual.js +3 -1
- package/src/core/model/reactive/model/comparative/ReactiveLessThan.js +3 -1
- package/src/core/model/reactive/model/comparative/ReactiveLessThanOrEqual.js +3 -1
- package/src/core/model/reactive/model/comparative/ReactiveNotEquals.js +1 -1
- package/src/core/model/reactive/model/logic/ReactiveAnd.js +1 -1
- package/src/core/model/reactive/model/logic/ReactiveNot.js +3 -1
- package/src/core/model/reactive/model/logic/ReactiveOr.js +1 -1
- package/src/core/primitives/numbers/computeHashFloat.spec.js +7 -0
- package/src/core/process/task/util/iteratorTask.js +3 -1
- package/src/engine/animation/curve/AnimationCurve.js +34 -5
- package/src/engine/animation/curve/AnimationCurve.spec.js +100 -0
- package/src/engine/asset/AssetTransformer.js +1 -0
- package/src/engine/computeStridedIntegerArrayHash.js +4 -2
- package/src/engine/ecs/components/Renderable.d.ts +1 -1
- package/src/{ecs → engine/ecs}/grid/pick.js +4 -4
- package/src/engine/ecs/parent/entity_node_compute_bounding_box.js +1 -1
- package/src/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.js +1 -18
- package/src/engine/ecs/systems/MotionSystem.js +7 -1
- package/src/engine/ecs/systems/SynchronizePositionSystem.js +8 -2
- package/src/engine/ecs/transform/Transform.js +1 -1
- package/src/engine/graphics/camera/makeScreenScissorFrustum.js +3 -3
- package/src/engine/graphics/camera/testClippingPlaneComputation.js +13 -13
- package/src/engine/graphics/ecs/camera/Camera.js +1 -1
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMesh.js +1 -1
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshSystem.js +9 -0
- package/src/engine/graphics/geometry/MikkT/MikkTSpace.js +1 -1
- package/src/engine/graphics/geometry/MikkT/STSpace.js +1 -1
- package/src/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +1 -1
- package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +1 -1
- package/src/engine/graphics/particles/particular/engine/MovingBoundingBox.js +1 -1
- package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js +1 -0
- package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -1
- package/src/engine/graphics/postprocess/threejs/postprocessing/TexturePass.js +2 -2
- package/src/engine/graphics/sh3/path_tracer/GeometryBVHBatched.js +2 -2
- package/src/engine/graphics/texture/sampler/Sampler2D.js +1 -1
- package/src/engine/graphics/texture/sampler/sampler2d_compute_texel_value_conversion_scale_to_uint8.js +1 -1
- package/src/engine/intelligence/behavior/Behavior.spec.js +15 -0
- package/src/engine/intelligence/mcts/MoveEdge.js +1 -1
- package/src/engine/reference/v1/ReferenceManager.js +3 -0
- package/src/engine/reference/v2/Reference.js +33 -37
- package/src/engine/sound/sopra/README.md +6 -0
- package/src/generation/automata/CaveGeneratorCellularAutomata.js +10 -7
- package/src/generation/automata/CaveGeneratorCellularAutomata.spec.js +12 -0
- package/src/generation/automata/CellularAutomata.js +5 -4
- package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +25 -9
- package/src/view/minimap/dom/MinimapCameraView.js +1 -1
- package/src/core/geom/Plane.js +0 -250
- package/src/core/land/reactive/ReactiveLexer.js +0 -158
- package/src/core/land/reactive/ReactiveLexer.ts +0 -181
- package/src/core/land/reactive/ReactiveListener.ts +0 -323
- package/src/core/land/reactive/ReactiveParser.js +0 -1573
- package/src/core/land/reactive/ReactiveParser.ts +0 -1776
- package/src/core/land/reactive/ReactiveVisitor.js +0 -1
- package/src/core/land/reactive/ReactiveVisitor.ts +0 -218
- package/src/core/land/reactive/compiler/ReactiveCompiler.js +0 -350
- package/src/core/land/reactive/compiler/ReactiveNearlyCompiler.js +0 -166
- package/src/core/land/reactive/compiler/ReactiveParser.js +0 -34
- package/src/core/land/reactive/nearley/ReactiveNearley.js +0 -187
- /package/src/{engine/graphics/ecs/mesh-v2 → core/geom/3d/vector}/allocate_v3.js +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { max2 } from "../../../math/max2.js";
|
|
2
|
+
import { min2 } from "../../../math/min2.js";
|
|
3
|
+
import { QuadTreeDatum } from "../../2d/quad-tree/QuadTreeDatum.js";
|
|
4
|
+
import { removeRedundantBoxesArray } from "./removeRedundantBoxesArray.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Cut out a region from given set of boxes
|
|
8
|
+
* @param {AABB2} scissor area to be cut out
|
|
9
|
+
* @param {QuadTreeNode} boxes
|
|
10
|
+
*/
|
|
11
|
+
export function cutArea(scissor, boxes) {
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @type {QuadTreeDatum[]}
|
|
16
|
+
*/
|
|
17
|
+
const additions = [];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @type {QuadTreeDatum[]}
|
|
22
|
+
*/
|
|
23
|
+
const removals = [];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* @param {QuadTreeDatum} box
|
|
28
|
+
*/
|
|
29
|
+
function visitOverlap(box) {
|
|
30
|
+
removals.push(box);
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
//compute overlap region
|
|
34
|
+
const x0 = max2(scissor.x0, box.x0);
|
|
35
|
+
const x1 = min2(scissor.x1, box.x1);
|
|
36
|
+
|
|
37
|
+
const y0 = max2(scissor.y0, box.y0);
|
|
38
|
+
const y1 = min2(scissor.y1, box.y1);
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
//create 4 boxes around overlap
|
|
42
|
+
if (x0 > box.x0) {
|
|
43
|
+
//add left box
|
|
44
|
+
additions.push(new QuadTreeDatum(box.x0, box.y0, x0, box.y1));
|
|
45
|
+
}
|
|
46
|
+
if (x1 < box.x1) {
|
|
47
|
+
//add right box
|
|
48
|
+
additions.push(new QuadTreeDatum(x1, box.y0, box.x1, box.y1));
|
|
49
|
+
}
|
|
50
|
+
if (y0 > box.y0) {
|
|
51
|
+
//add top box
|
|
52
|
+
additions.push(new QuadTreeDatum(box.x0, box.y0, box.x1, y0));
|
|
53
|
+
}
|
|
54
|
+
if (y1 < box.y1) {
|
|
55
|
+
//add bottom box
|
|
56
|
+
additions.push(new QuadTreeDatum(box.x0, y1, box.x1, box.y1));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
boxes.traverseRectangleIntersections(scissor.x0, scissor.y0, scissor.x1, scissor.y1, visitOverlap);
|
|
62
|
+
|
|
63
|
+
let i, l;
|
|
64
|
+
//perform removals
|
|
65
|
+
for (i = 0, l = removals.length; i < l; i++) {
|
|
66
|
+
const removal = removals[i];
|
|
67
|
+
removal.disconnect();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//drop potential overlaps between additions
|
|
71
|
+
removeRedundantBoxesArray(additions);
|
|
72
|
+
|
|
73
|
+
//perform additions
|
|
74
|
+
for (i = 0, l = additions.length; i < l; i++) {
|
|
75
|
+
const addition = additions[i];
|
|
76
|
+
|
|
77
|
+
boxes.insertDatum(addition);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {number} width
|
|
4
|
+
* @param {number} height
|
|
5
|
+
* @param {QuadTreeNode} boxes
|
|
6
|
+
* @param {function(containerWidth:number, containerHeight:number, childWidth:number, childHeight:number):number} costFunction
|
|
7
|
+
* @returns {QuadTreeDatum} suitable container box
|
|
8
|
+
*/
|
|
9
|
+
export function findBestContainer(width, height, boxes, costFunction) {
|
|
10
|
+
let best = null;
|
|
11
|
+
let bestScore = Number.POSITIVE_INFINITY;
|
|
12
|
+
|
|
13
|
+
const visitor = (node) => {
|
|
14
|
+
|
|
15
|
+
if (node.getWidth() < width) {
|
|
16
|
+
//too small, don't traverse deeper
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (node.getHeight() < height) {
|
|
21
|
+
//too small, don't traverse deeper
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const data = node.data;
|
|
26
|
+
const numBoxes = data.length;
|
|
27
|
+
|
|
28
|
+
for (let i = 0; i < numBoxes; i++) {
|
|
29
|
+
const box = data[i];
|
|
30
|
+
|
|
31
|
+
const bW = box.getWidth();
|
|
32
|
+
|
|
33
|
+
if (bW < width) {
|
|
34
|
+
//too small
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const bH = box.getHeight();
|
|
39
|
+
|
|
40
|
+
if (bH < height) {
|
|
41
|
+
//too small
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const cost = costFunction(bW, bH, width, height);
|
|
46
|
+
if (cost < bestScore) {
|
|
47
|
+
bestScore = cost;
|
|
48
|
+
best = box;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return true;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
boxes.traversePreOrder(visitor);
|
|
56
|
+
|
|
57
|
+
return best;
|
|
58
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { findBestContainer } from "./findBestContainer.js";
|
|
2
|
+
import { costByRemainingArea } from "./cost/costByRemainingArea.js";
|
|
3
|
+
import { cutArea } from "./cutArea.js";
|
|
4
|
+
import { QuadTreeDatum } from "../../2d/quad-tree/QuadTreeDatum.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param {AABB2} box
|
|
9
|
+
* @param {QuadTreeNode} free
|
|
10
|
+
* @returns {boolean}
|
|
11
|
+
*/
|
|
12
|
+
export function packOneBox(box, free) {
|
|
13
|
+
const w = box.getWidth();
|
|
14
|
+
const h = box.getHeight();
|
|
15
|
+
|
|
16
|
+
const container = findBestContainer(w, h, free, costByRemainingArea);
|
|
17
|
+
|
|
18
|
+
if (container === null) {
|
|
19
|
+
//couldn't find a place for box
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//remove container from free set
|
|
24
|
+
container.disconnect();
|
|
25
|
+
|
|
26
|
+
//place box at bottom left of the container
|
|
27
|
+
const y0 = container.y0;
|
|
28
|
+
const x0 = container.x0;
|
|
29
|
+
|
|
30
|
+
box.set(x0, y0, x0 + w, y0 + h);
|
|
31
|
+
|
|
32
|
+
//update remaining set by removing this box area from free set
|
|
33
|
+
cutArea(box, free);
|
|
34
|
+
|
|
35
|
+
//split remaining space
|
|
36
|
+
if (box.y1 !== container.y1) {
|
|
37
|
+
const splitA = new QuadTreeDatum(container.x0, box.y1, container.x1, container.y1);
|
|
38
|
+
|
|
39
|
+
free.insertDatum(splitA);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (box.x1 !== container.x1) {
|
|
43
|
+
const splitB = new QuadTreeDatum(box.x1, container.y0, container.x1, container.y1);
|
|
44
|
+
free.insertDatum(splitB);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
@@ -33,7 +33,7 @@ const MAX_ITERATIONS = 10000;
|
|
|
33
33
|
/**
|
|
34
34
|
* Computes the miniball of the given point set.
|
|
35
35
|
*
|
|
36
|
-
* Notice that the point set
|
|
36
|
+
* Notice that the point set `pts` is assumed to be immutable during the computation. That
|
|
37
37
|
* is, if you add, remove, or change points in the point set, you have to create a new instance of
|
|
38
38
|
* {@link Miniball}.
|
|
39
39
|
*
|
|
@@ -102,7 +102,7 @@ class Miniball {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
|
-
* Whether or not the miniball is the empty set, equivalently, whether
|
|
105
|
+
* Whether or not the miniball is the empty set, equivalently, whether `points.size() == 0`
|
|
106
106
|
* was true when this miniball instance was constructed.
|
|
107
107
|
*
|
|
108
108
|
* Notice that the miniball of a point set <i>S</i> is empty if and only if <i>S={}</i>.
|
|
@@ -116,7 +116,7 @@ class Miniball {
|
|
|
116
116
|
/**
|
|
117
117
|
* The radius of the miniball.
|
|
118
118
|
* <p>
|
|
119
|
-
* Precondition:
|
|
119
|
+
* Precondition: `!isEmpty()`
|
|
120
120
|
*
|
|
121
121
|
* @return {number} the radius of the miniball, a number ≥ 0
|
|
122
122
|
*/
|
|
@@ -127,9 +127,9 @@ class Miniball {
|
|
|
127
127
|
/**
|
|
128
128
|
* The squared radius of the miniball.
|
|
129
129
|
* <p>
|
|
130
|
-
* This is equivalent to
|
|
130
|
+
* This is equivalent to `radius() * radius()`.
|
|
131
131
|
* <p>
|
|
132
|
-
* Precondition:
|
|
132
|
+
* Precondition: `!isEmpty()`
|
|
133
133
|
*
|
|
134
134
|
* @return {number} the squared radius of the miniball
|
|
135
135
|
*/
|
|
@@ -140,7 +140,7 @@ class Miniball {
|
|
|
140
140
|
/**
|
|
141
141
|
* The Euclidean coordinates of the center of the miniball.
|
|
142
142
|
* <p>
|
|
143
|
-
* Precondition:
|
|
143
|
+
* Precondition: `!isEmpty()`
|
|
144
144
|
*
|
|
145
145
|
* @return {number[]} an array holding the coordinates of the center of the miniball
|
|
146
146
|
*/
|
|
@@ -151,8 +151,8 @@ class Miniball {
|
|
|
151
151
|
/**
|
|
152
152
|
* The number of input points.
|
|
153
153
|
*
|
|
154
|
-
* @return {number} the number of points in the original point set, i.e.,
|
|
155
|
-
*
|
|
154
|
+
* @return {number} the number of points in the original point set, i.e., `pts.size()` where
|
|
155
|
+
* `pts` was the {@link PointSet} instance passed to the constructor of this
|
|
156
156
|
* instance
|
|
157
157
|
*/
|
|
158
158
|
size() {
|
|
@@ -179,7 +179,7 @@ class Miniball {
|
|
|
179
179
|
* the points farthest from center in the support. So the current ball contains all points of
|
|
180
180
|
* <i>S</i> and has radius at most twice as large as the minball.
|
|
181
181
|
* <p>
|
|
182
|
-
* Precondition:
|
|
182
|
+
* Precondition: `size > 0`
|
|
183
183
|
* @return {Subspan}
|
|
184
184
|
* @private
|
|
185
185
|
*/
|
|
@@ -334,10 +334,10 @@ class Miniball {
|
|
|
334
334
|
}
|
|
335
335
|
|
|
336
336
|
/**
|
|
337
|
-
* Given the center of the current enclosing ball and the walking direction
|
|
337
|
+
* Given the center of the current enclosing ball and the walking direction `centerToAff`,
|
|
338
338
|
* determine how much we can walk into this direction without losing a point from <i>S</i>. The
|
|
339
|
-
* (positive) factor by which we can walk along
|
|
340
|
-
*
|
|
339
|
+
* (positive) factor by which we can walk along `centerToAff` is returned. Further,
|
|
340
|
+
* `stopper` is set to the index of the most restricting point and to -1 if no such point
|
|
341
341
|
* was found.
|
|
342
342
|
* @return {number}
|
|
343
343
|
* @private
|
|
@@ -57,7 +57,7 @@ class Quality {
|
|
|
57
57
|
* the miniball ("over-length"). The returned number is the maximal such over-length, divided by
|
|
58
58
|
* the radius of the computed miniball.
|
|
59
59
|
* <p>
|
|
60
|
-
* Notice that
|
|
60
|
+
* Notice that `getMaxOverlength() == 0` if and only if all points are contained in the
|
|
61
61
|
* miniball.
|
|
62
62
|
*
|
|
63
63
|
* @return {number} the maximal over-length, a number ≥ 0
|
|
@@ -74,7 +74,7 @@ class Quality {
|
|
|
74
74
|
* this point towards the boundary of the miniball ("under-length"). The returned number is the
|
|
75
75
|
* maximal such under-length, divided by the radius of the computed miniball.
|
|
76
76
|
* <p>
|
|
77
|
-
* Notice that in theory
|
|
77
|
+
* Notice that in theory `getMaxUnderlength()` should be zero, otherwise the computed
|
|
78
78
|
* miniball is enclosing but not minimal.
|
|
79
79
|
*
|
|
80
80
|
* @return {number} the maximal under-length, a number ≥ 0
|
|
@@ -117,7 +117,7 @@ export class Subspan {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
/**
|
|
120
|
-
* The size of the instance's set <i>M</i>, a number between 0 and
|
|
120
|
+
* The size of the instance's set <i>M</i>, a number between 0 and `dim+1`.
|
|
121
121
|
* <p>
|
|
122
122
|
* Complexity: O(1).
|
|
123
123
|
*
|
|
@@ -143,9 +143,9 @@ export class Subspan {
|
|
|
143
143
|
/**
|
|
144
144
|
* The global index (into <i>S</i>) of an arbitrary element of <i>M</i>.
|
|
145
145
|
* <p>
|
|
146
|
-
* Precondition:
|
|
146
|
+
* Precondition: `size()>0`
|
|
147
147
|
* <p>
|
|
148
|
-
* Postcondition:
|
|
148
|
+
* Postcondition: `isMember(anyMember())`
|
|
149
149
|
* @returns {number}
|
|
150
150
|
*/
|
|
151
151
|
anyMember() {
|
|
@@ -160,7 +160,7 @@ export class Subspan {
|
|
|
160
160
|
* Complexity: O(1)
|
|
161
161
|
*
|
|
162
162
|
* @param {number} i
|
|
163
|
-
* the "local" index, 0 ≤ i <
|
|
163
|
+
* the "local" index, 0 ≤ i < `size()`
|
|
164
164
|
* @return {number} <i>j</i> such that <i>S[j]</i> equals the <i>i</i>th point of M
|
|
165
165
|
*/
|
|
166
166
|
globalIndex(i) {
|
|
@@ -184,7 +184,7 @@ export class Subspan {
|
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
/**
|
|
187
|
-
* The point
|
|
187
|
+
* The point `members[r]` is called the <i>origin</i>.
|
|
188
188
|
*
|
|
189
189
|
* @return {number} index into <i>S</i> of the origin.
|
|
190
190
|
* @private
|
|
@@ -207,7 +207,7 @@ export class Subspan {
|
|
|
207
207
|
* <p>
|
|
208
208
|
* Note that the code of this class sometimes does not call this method but only mentions it in a
|
|
209
209
|
* comment. The reason for this is performance; Java does not allow an efficient way of returning
|
|
210
|
-
* a pair of doubles, so we sometimes manually "inline"
|
|
210
|
+
* a pair of doubles, so we sometimes manually "inline" `givens()` for the sake of
|
|
211
211
|
* performance.
|
|
212
212
|
* @param {number} a
|
|
213
213
|
* @param {number} b
|
|
@@ -234,7 +234,7 @@ export class Subspan {
|
|
|
234
234
|
* the index of the column used now for insertion; <i>r</i> is not altered by this routine and
|
|
235
235
|
* should be changed by the caller afterwards.
|
|
236
236
|
* <p>
|
|
237
|
-
* Precondition:
|
|
237
|
+
* Precondition: `r<dim`
|
|
238
238
|
* @private
|
|
239
239
|
*/
|
|
240
240
|
appendColumn() {
|
|
@@ -269,7 +269,7 @@ export class Subspan {
|
|
|
269
269
|
/**
|
|
270
270
|
* Adds the point <i>S[index]</i> to the instance's set <i>M</i>.
|
|
271
271
|
* <p>
|
|
272
|
-
* Precondition:
|
|
272
|
+
* Precondition: `!isMember(index)`
|
|
273
273
|
* <p>
|
|
274
274
|
* Complexity: O(dim^2).
|
|
275
275
|
*
|
|
@@ -302,7 +302,7 @@ export class Subspan {
|
|
|
302
302
|
* Computes the vector <i>w</i> directed from point <i>p</i> to <i>v</i>, where <i>v</i> is the
|
|
303
303
|
* point in <i>aff(M)</i> that lies nearest to <i>p</i>.
|
|
304
304
|
* <p>
|
|
305
|
-
* Precondition:
|
|
305
|
+
* Precondition: `size()>0`
|
|
306
306
|
* <p>
|
|
307
307
|
* Complexity: O(dim^2)
|
|
308
308
|
*
|
|
@@ -389,11 +389,11 @@ export class Subspan {
|
|
|
389
389
|
}
|
|
390
390
|
|
|
391
391
|
/**
|
|
392
|
-
* Calculates the
|
|
392
|
+
* Calculates the `size()`-many coefficients in the representation of <i>p</i> as an affine
|
|
393
393
|
* combination of the points <i>M</i>.
|
|
394
394
|
* <p>
|
|
395
|
-
* The <i>i</i>th computed coefficient
|
|
396
|
-
* <i>M</i>, or, in other words, to the point in <i>S</i> with index
|
|
395
|
+
* The <i>i</i>th computed coefficient `lambdas[i] `corresponds to the <i>i</i>th point in
|
|
396
|
+
* <i>M</i>, or, in other words, to the point in <i>S</i> with index `globalIndex(i)`.
|
|
397
397
|
* <p>
|
|
398
398
|
* Complexity: O(dim^2)
|
|
399
399
|
* <p>
|
|
@@ -441,7 +441,7 @@ export class Subspan {
|
|
|
441
441
|
}
|
|
442
442
|
|
|
443
443
|
/**
|
|
444
|
-
* Given <i>R</i> in lower Hessenberg form with subdiagonal entries 0 to
|
|
444
|
+
* Given <i>R</i> in lower Hessenberg form with subdiagonal entries 0 to `pos-1` already all
|
|
445
445
|
* zero, clears the remaining subdiagonal entries via Givens rotations.
|
|
446
446
|
* @param {number} pos
|
|
447
447
|
* @private
|
package/src/core/geom/v3_dot.js
CHANGED
|
@@ -10,10 +10,10 @@ import { line2SegmentsIntersect } from "../../geom/2d/LineSegment2.js";
|
|
|
10
10
|
import Vector2, { v2_distance } from "../../geom/Vector2.js";
|
|
11
11
|
import { max2 } from "../../math/max2.js";
|
|
12
12
|
import { min2 } from "../../math/min2.js";
|
|
13
|
-
import { applyCentralGravityAABB2 } from "./BoxLayouter.js";
|
|
14
13
|
import { computeDisconnectedSubGraphs } from "./computeDisconnectedSubGraphs.js";
|
|
15
14
|
import { Connection } from "./Connection.js";
|
|
16
15
|
import { resolveAABB2Overlap } from "./box/resolveAABB2Overlap.js";
|
|
16
|
+
import { applyCentralGravityAABB2 } from "./box/applyCentralGravityAABB2.js";
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
import AABB2 from "
|
|
8
|
-
import Vector2 from "
|
|
9
|
-
import { computeDisconnectedSubGraphs } from "
|
|
10
|
-
import { Connection } from "
|
|
11
|
-
import { resolveAABB2Overlap } from "./
|
|
7
|
+
import AABB2 from "../../../geom/2d/aabb/AABB2.js";
|
|
8
|
+
import Vector2 from "../../../geom/Vector2.js";
|
|
9
|
+
import { computeDisconnectedSubGraphs } from "../computeDisconnectedSubGraphs.js";
|
|
10
|
+
import { Connection } from "../Connection.js";
|
|
11
|
+
import { resolveAABB2Overlap } from "./resolveAABB2Overlap.js";
|
|
12
|
+
import { applyCentralGravityAABB2 } from "./applyCentralGravityAABB2.js";
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -181,51 +182,6 @@ function applyPull(edges, strength) {
|
|
|
181
182
|
}
|
|
182
183
|
}
|
|
183
184
|
|
|
184
|
-
/**
|
|
185
|
-
*
|
|
186
|
-
* @param {Array.<AABB2>} boxes
|
|
187
|
-
* @returns {Vector2}
|
|
188
|
-
*/
|
|
189
|
-
function computeCenter(boxes) {
|
|
190
|
-
const numBoxes = boxes.length;
|
|
191
|
-
|
|
192
|
-
const center = new Vector2();
|
|
193
|
-
for (let i = 0; i < numBoxes; i++) {
|
|
194
|
-
const box = boxes[i];
|
|
195
|
-
center._add(box.midX(), box.midY());
|
|
196
|
-
}
|
|
197
|
-
center.multiplyScalar(1 / numBoxes);
|
|
198
|
-
|
|
199
|
-
return center;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
*
|
|
204
|
-
* @param {Array.<AABB2>} boxes
|
|
205
|
-
* @param {number} strength
|
|
206
|
-
*/
|
|
207
|
-
export function applyCentralGravityAABB2(boxes, strength) {
|
|
208
|
-
const numBoxes = boxes.length;
|
|
209
|
-
|
|
210
|
-
const center = computeCenter(boxes);
|
|
211
|
-
|
|
212
|
-
const delta = new Vector2();
|
|
213
|
-
for (let i = 0; i < numBoxes; i++) {
|
|
214
|
-
const box = boxes[i];
|
|
215
|
-
|
|
216
|
-
if (box.locked === true) {
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
delta.copy(center);
|
|
221
|
-
delta._sub(box.midX(), box.midY());
|
|
222
|
-
|
|
223
|
-
delta.multiplyScalar(strength);
|
|
224
|
-
|
|
225
|
-
box.move(delta.x, delta.y);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
185
|
|
|
230
186
|
function resolveBoxConnectionOverlaps(boxes, connections, maxSteps) {
|
|
231
187
|
for (let i = 0; i < maxSteps; i++) {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { aabb2_compute_center_from_multiple } from "../../../geom/2d/aabb/aabb2_compute_center_from_multiple.js";
|
|
2
|
+
import Vector2 from "../../../geom/Vector2.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {(AABB2|{locked:boolean})[]} boxes
|
|
7
|
+
* @param {number} strength
|
|
8
|
+
*/
|
|
9
|
+
export function applyCentralGravityAABB2(boxes, strength) {
|
|
10
|
+
const numBoxes = boxes.length;
|
|
11
|
+
|
|
12
|
+
const center = aabb2_compute_center_from_multiple(boxes);
|
|
13
|
+
|
|
14
|
+
const delta = new Vector2();
|
|
15
|
+
for (let i = 0; i < numBoxes; i++) {
|
|
16
|
+
const box = boxes[i];
|
|
17
|
+
|
|
18
|
+
if (box.locked === true) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
delta.copy(center);
|
|
23
|
+
delta._sub(box.midX(), box.midY());
|
|
24
|
+
|
|
25
|
+
delta.multiplyScalar(strength);
|
|
26
|
+
|
|
27
|
+
box.move(delta.x, delta.y);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { resolvePath } from "./resolvePath.js";
|
|
2
|
+
|
|
3
|
+
test("resolve global path", () => {
|
|
4
|
+
const root = {};
|
|
5
|
+
expect(resolvePath(root, '')).toBe(root);
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
test("resolve nested path", () => {
|
|
9
|
+
const nested_child = {};
|
|
10
|
+
|
|
11
|
+
const root = { a: { b: nested_child } };
|
|
12
|
+
|
|
13
|
+
expect(resolvePath(root, '/a/b')).toBe(nested_child);
|
|
14
|
+
});
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { ReactiveAdd } from "
|
|
2
|
-
import { ReactiveDivide } from "
|
|
3
|
-
import { ReactiveMultiply } from "
|
|
4
|
-
import { ReactiveNegate } from "
|
|
5
|
-
import { ReactiveSubtract } from "
|
|
6
|
-
import { ReactiveEquals } from "
|
|
7
|
-
import { ReactiveGreaterThan } from "
|
|
8
|
-
import { ReactiveGreaterThanOrEqual } from "
|
|
9
|
-
import { ReactiveLessThan } from "
|
|
10
|
-
import { ReactiveLessThanOrEqual } from "
|
|
11
|
-
import { ReactiveNotEquals } from "
|
|
12
|
-
import { ReactiveAnd } from "
|
|
13
|
-
import { ReactiveNot } from "
|
|
14
|
-
import { ReactiveOr } from "
|
|
15
|
-
import { ReactiveLiteralNumber } from "
|
|
16
|
-
import { ReactiveReference } from "
|
|
17
|
-
import { compileReactiveExpression } from "
|
|
1
|
+
import { ReactiveAdd } from "../../model/reactive/model/arithmetic/ReactiveAdd.js";
|
|
2
|
+
import { ReactiveDivide } from "../../model/reactive/model/arithmetic/ReactiveDivide.js";
|
|
3
|
+
import { ReactiveMultiply } from "../../model/reactive/model/arithmetic/ReactiveMultiply.js";
|
|
4
|
+
import { ReactiveNegate } from "../../model/reactive/model/arithmetic/ReactiveNegate.js";
|
|
5
|
+
import { ReactiveSubtract } from "../../model/reactive/model/arithmetic/ReactiveSubtract.js";
|
|
6
|
+
import { ReactiveEquals } from "../../model/reactive/model/comparative/ReactiveEquals.js";
|
|
7
|
+
import { ReactiveGreaterThan } from "../../model/reactive/model/comparative/ReactiveGreaterThan.js";
|
|
8
|
+
import { ReactiveGreaterThanOrEqual } from "../../model/reactive/model/comparative/ReactiveGreaterThanOrEqual.js";
|
|
9
|
+
import { ReactiveLessThan } from "../../model/reactive/model/comparative/ReactiveLessThan.js";
|
|
10
|
+
import { ReactiveLessThanOrEqual } from "../../model/reactive/model/comparative/ReactiveLessThanOrEqual.js";
|
|
11
|
+
import { ReactiveNotEquals } from "../../model/reactive/model/comparative/ReactiveNotEquals.js";
|
|
12
|
+
import { ReactiveAnd } from "../../model/reactive/model/logic/ReactiveAnd.d.ts";
|
|
13
|
+
import { ReactiveNot } from "../../model/reactive/model/logic/ReactiveNot.js";
|
|
14
|
+
import { ReactiveOr } from "../../model/reactive/model/logic/ReactiveOr.js";
|
|
15
|
+
import { ReactiveLiteralNumber } from "../../model/reactive/model/terminal/ReactiveLiteralNumber.js";
|
|
16
|
+
import { ReactiveReference } from "../../model/reactive/model/terminal/ReactiveReference.d.ts";
|
|
17
|
+
import { compileReactiveExpression } from "./compileReactiveExpression.js";
|
|
18
18
|
|
|
19
19
|
test('compile: REFERENCE', () => {
|
|
20
20
|
const expression = compileReactiveExpression('a');
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { MersenneTwister } from "./MersenneTwister.js";
|
|
2
|
+
|
|
3
|
+
test("constructor does not throw", () => {
|
|
4
|
+
expect(() => new MersenneTwister(0)).not.toThrow();
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
test("from seed of 0, first 3 values are within 0..1 range", () => {
|
|
8
|
+
const rng = new MersenneTwister(0);
|
|
9
|
+
|
|
10
|
+
for (let i = 0; i < 3; i++) {
|
|
11
|
+
|
|
12
|
+
const value = rng.random();
|
|
13
|
+
|
|
14
|
+
expect(value).toBeLessThanOrEqual(1)
|
|
15
|
+
expect(value).toBeGreaterThanOrEqual(0)
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { makeSequenceLoop } from "../makeSequenceLoop.js";
|
|
2
|
+
import { randomGaussian } from "./randomGaussian.js";
|
|
3
|
+
|
|
4
|
+
test("sample is average of rolls", () => {
|
|
5
|
+
|
|
6
|
+
const random = makeSequenceLoop([0, 1, 2, 11]);
|
|
7
|
+
|
|
8
|
+
expect(randomGaussian(random, 4)).toBe(3.5);
|
|
9
|
+
});
|
|
@@ -12,7 +12,7 @@ export function computeStatisticalMean(values, start = 0, end = values.length) {
|
|
|
12
12
|
|
|
13
13
|
let total = 0;
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const sample_count = end - start;
|
|
16
16
|
|
|
17
17
|
for (let i = 0; i < end; i++) {
|
|
18
18
|
const value = values[i];
|
|
@@ -20,5 +20,5 @@ export function computeStatisticalMean(values, start = 0, end = values.length) {
|
|
|
20
20
|
total += value;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
return total /
|
|
23
|
+
return total / sample_count;
|
|
24
24
|
}
|
|
@@ -23,9 +23,11 @@ export class ReactiveDivide extends ReactiveBinaryExpression {
|
|
|
23
23
|
|
|
24
24
|
return r;
|
|
25
25
|
}
|
|
26
|
+
|
|
26
27
|
equals(other) {
|
|
27
|
-
return other.isReactiveDivide && super.equals(other);
|
|
28
|
+
return (other.isReactiveDivide === true) && super.equals(other);
|
|
28
29
|
}
|
|
30
|
+
|
|
29
31
|
toCode() {
|
|
30
32
|
return `( ${this.left.toCode()} / ${this.right.toCode()} )`
|
|
31
33
|
}
|
|
@@ -22,9 +22,11 @@ export class ReactiveNegate extends ReactiveUnaryExpression {
|
|
|
22
22
|
|
|
23
23
|
return r;
|
|
24
24
|
}
|
|
25
|
+
|
|
25
26
|
equals(other) {
|
|
26
|
-
return other.isReactiveNegate && super.equals(other);
|
|
27
|
+
return (other.isReactiveNegate === true) && super.equals(other);
|
|
27
28
|
}
|
|
29
|
+
|
|
28
30
|
toCode() {
|
|
29
31
|
return `-${this.source.toCode()}`
|
|
30
32
|
}
|