@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.
Files changed (147) hide show
  1. package/editor/tools/GridPaintTool.js +1 -1
  2. package/editor/tools/paint/TerrainPaintTool.js +1 -1
  3. package/editor/view/GridPickCoordinateView.js +1 -1
  4. package/package.json +1 -1
  5. package/src/core/UUID.js +2 -0
  6. package/src/core/assert.js +4 -1
  7. package/src/core/binary/ctz32.js +1 -1
  8. package/src/core/binary/operations/bitCount.spec.js +19 -0
  9. package/src/core/binary/uint82float.spec.js +7 -0
  10. package/src/core/bvh2/binary/IndexedBinaryBVH.spec.js +7 -0
  11. package/src/core/bvh2/bvh3/EBBVHLeafProxy.js +3 -0
  12. package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +5 -4
  13. package/src/core/bvh2/transform/RotationOptimizer.spec.js +161 -155
  14. package/src/core/codegen/LineBuilder.js +12 -3
  15. package/src/core/codegen/LineBuilder.spec.js +7 -0
  16. package/src/core/collection/CuckooFilter.js +12 -12
  17. package/src/core/collection/HashMap.js +486 -237
  18. package/src/core/collection/HashMap.spec.js +110 -1
  19. package/src/core/collection/array/{typedArrayToDataType.js → typed/typedArrayToDataType.js} +1 -1
  20. package/src/core/collection/array/weightedRandomFromArray.spec.js +20 -0
  21. package/src/core/debug/matchers/AnyOf.js +1 -2
  22. package/src/core/geom/2d/aabb/AABB2.spec.js +1 -1
  23. package/src/core/geom/2d/aabb/aabb2_compute_center_from_multiple.js +19 -0
  24. package/src/core/geom/2d/quad-tree/qt_collect_by_circle.js +3 -3
  25. package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.js +7 -9
  26. package/src/core/geom/3d/aabb/aabb3_compute_plane_side.js +17 -15
  27. package/src/core/geom/3d/aabb/aabb3_compute_plane_side.spec.js +25 -0
  28. package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.js +1 -1
  29. package/src/core/geom/3d/aabb/aabb3_from_v3_array.js +3 -0
  30. package/src/core/geom/3d/aabb/aabb3_from_v3_array.spec.js +32 -0
  31. package/src/core/geom/3d/aabb/aabb3_intersects_aabb3.spec.js +115 -0
  32. package/src/core/geom/3d/aabb/aabb3_raycast.js +6 -1
  33. package/src/core/geom/3d/aabb/serializeAABB3Encoded_v0.js +6 -6
  34. package/src/core/geom/3d/{CircleMath.js → compute_circle_bounding_box.js} +1 -1
  35. package/src/core/geom/3d/decompose_matrix_4_array.js +18 -19
  36. package/src/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +1 -1
  37. package/src/{engine/graphics/ecs/mesh-v2 → core/geom/3d/matrix}/allocate_transform_m4.js +1 -1
  38. package/src/core/geom/3d/normal/hemioct/decode_hemioct_to_unit.js +26 -0
  39. package/src/core/geom/3d/normal/hemioct/encode_unit3_hemioct.js +0 -26
  40. package/src/core/geom/3d/normal/hemioct/unit_hemioct.spec.js +2 -1
  41. package/src/core/geom/3d/plane/computePlaneLineIntersection.js +51 -0
  42. package/src/core/geom/3d/plane/computePlanePlaneIntersection.js +77 -0
  43. package/src/core/geom/3d/plane/computePlaneRayIntersection.js +55 -0
  44. package/src/core/geom/3d/plane/plane3_computeLineSegmentIntersection.js +50 -0
  45. package/src/core/geom/3d/plane/planeRayIntersection.js +14 -0
  46. package/src/core/geom/3d/{tetrahedra/in_sphere_fast.js → sphere/in_sphere3d_fast.js} +1 -1
  47. package/src/core/geom/3d/{tetrahedra/in_sphere_robust.js → sphere/in_sphere3d_robust.js} +1 -1
  48. package/src/core/geom/3d/sphere/sphere_array_intersects_point.js +2 -2
  49. package/src/core/geom/3d/sphere/{sphereIntersectsPoint.js → sphere_intersects_point.js} +7 -4
  50. package/src/core/geom/3d/sphere/sphere_intersects_point.spec.js +134 -0
  51. package/src/core/geom/3d/sphere/sphere_intersects_ray.spec.js +49 -0
  52. package/src/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.js +11 -7
  53. package/src/core/geom/3d/tetrahedra/delaunay/{debug_validate_mesh.js → debug/debug_validate_mesh.js} +1 -1
  54. package/src/core/geom/3d/tetrahedra/delaunay/{push_boundary_with_validation.js → debug/push_boundary_with_validation.js} +1 -1
  55. package/src/core/geom/3d/tetrahedra/delaunay/{validate_cavity_boundary.js → debug/validate_cavity_boundary.js} +2 -2
  56. package/src/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_compute_cavity.js +2 -2
  57. package/src/core/geom/3d/triangle/computeTriangleRayIntersection.js +0 -164
  58. package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js +87 -0
  59. package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentricEdge.js +81 -0
  60. package/src/core/geom/{rayTriangleIntersection.js → 3d/triangle/rayTriangleIntersection.js} +2 -2
  61. package/src/core/geom/ConicRay.js +160 -152
  62. package/src/core/geom/Matrix4.js +2 -0
  63. package/src/core/geom/Quaternion.js +19 -1
  64. package/src/core/geom/packing/max-rect/MaxRectangles.js +4 -214
  65. package/src/core/geom/packing/max-rect/cost/costByBestShortSide.js +11 -0
  66. package/src/core/geom/packing/max-rect/cost/costByRemainingArea.js +14 -0
  67. package/src/core/geom/packing/max-rect/cutArea.js +79 -0
  68. package/src/core/geom/packing/max-rect/findBestContainer.js +58 -0
  69. package/src/core/geom/packing/max-rect/packOneBox.js +49 -0
  70. package/src/core/geom/packing/miniball/Miniball.js +12 -12
  71. package/src/core/geom/packing/miniball/Quality.js +2 -2
  72. package/src/core/geom/packing/miniball/Subspan.js +13 -13
  73. package/src/core/geom/v3_dot.js +1 -1
  74. package/src/core/graph/layout/CircleLayout.js +1 -1
  75. package/src/core/graph/layout/{BoxLayouter.js → box/BoxLayouter.js} +6 -50
  76. package/src/core/graph/layout/box/applyCentralGravityAABB2.js +29 -0
  77. package/src/core/json/resolvePath.spec.js +14 -0
  78. package/src/core/land/reactive/{compiler/ReactiveCompiler.spec.js → compileReactiveExpression.spec.js} +17 -17
  79. package/src/core/math/random/MersenneTwister.spec.js +19 -0
  80. package/src/core/math/random/randomGaussian.spec.js +9 -0
  81. package/src/core/math/statistics/computeStatisticalMean.js +2 -2
  82. package/src/core/model/reactive/model/arithmetic/ReactiveAdd.js +1 -1
  83. package/src/core/model/reactive/model/arithmetic/ReactiveDivide.js +3 -1
  84. package/src/core/model/reactive/model/arithmetic/ReactiveMultiply.js +1 -1
  85. package/src/core/model/reactive/model/arithmetic/ReactiveNegate.js +3 -1
  86. package/src/core/model/reactive/model/arithmetic/ReactiveSubtract.js +1 -1
  87. package/src/core/model/reactive/model/comparative/ReactiveEquals.js +1 -1
  88. package/src/core/model/reactive/model/comparative/ReactiveGreaterThan.js +3 -1
  89. package/src/core/model/reactive/model/comparative/ReactiveGreaterThanOrEqual.js +3 -1
  90. package/src/core/model/reactive/model/comparative/ReactiveLessThan.js +3 -1
  91. package/src/core/model/reactive/model/comparative/ReactiveLessThanOrEqual.js +3 -1
  92. package/src/core/model/reactive/model/comparative/ReactiveNotEquals.js +1 -1
  93. package/src/core/model/reactive/model/logic/ReactiveAnd.js +1 -1
  94. package/src/core/model/reactive/model/logic/ReactiveNot.js +3 -1
  95. package/src/core/model/reactive/model/logic/ReactiveOr.js +1 -1
  96. package/src/core/primitives/numbers/computeHashFloat.spec.js +7 -0
  97. package/src/core/process/task/util/iteratorTask.js +3 -1
  98. package/src/engine/animation/curve/AnimationCurve.js +34 -5
  99. package/src/engine/animation/curve/AnimationCurve.spec.js +100 -0
  100. package/src/engine/asset/AssetTransformer.js +1 -0
  101. package/src/engine/computeStridedIntegerArrayHash.js +4 -2
  102. package/src/engine/ecs/components/Renderable.d.ts +1 -1
  103. package/src/{ecs → engine/ecs}/grid/pick.js +4 -4
  104. package/src/engine/ecs/parent/entity_node_compute_bounding_box.js +1 -1
  105. package/src/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.js +1 -18
  106. package/src/engine/ecs/systems/MotionSystem.js +7 -1
  107. package/src/engine/ecs/systems/SynchronizePositionSystem.js +8 -2
  108. package/src/engine/ecs/transform/Transform.js +1 -1
  109. package/src/engine/graphics/camera/makeScreenScissorFrustum.js +3 -3
  110. package/src/engine/graphics/camera/testClippingPlaneComputation.js +13 -13
  111. package/src/engine/graphics/ecs/camera/Camera.js +1 -1
  112. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMesh.js +1 -1
  113. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshSystem.js +9 -0
  114. package/src/engine/graphics/geometry/MikkT/MikkTSpace.js +1 -1
  115. package/src/engine/graphics/geometry/MikkT/STSpace.js +1 -1
  116. package/src/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +1 -1
  117. package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +1 -1
  118. package/src/engine/graphics/particles/particular/engine/MovingBoundingBox.js +1 -1
  119. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js +1 -0
  120. package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -1
  121. package/src/engine/graphics/postprocess/threejs/postprocessing/TexturePass.js +2 -2
  122. package/src/engine/graphics/sh3/path_tracer/GeometryBVHBatched.js +2 -2
  123. package/src/engine/graphics/texture/sampler/Sampler2D.js +1 -1
  124. package/src/engine/graphics/texture/sampler/sampler2d_compute_texel_value_conversion_scale_to_uint8.js +1 -1
  125. package/src/engine/intelligence/behavior/Behavior.spec.js +15 -0
  126. package/src/engine/intelligence/mcts/MoveEdge.js +1 -1
  127. package/src/engine/reference/v1/ReferenceManager.js +3 -0
  128. package/src/engine/reference/v2/Reference.js +33 -37
  129. package/src/engine/sound/sopra/README.md +6 -0
  130. package/src/generation/automata/CaveGeneratorCellularAutomata.js +10 -7
  131. package/src/generation/automata/CaveGeneratorCellularAutomata.spec.js +12 -0
  132. package/src/generation/automata/CellularAutomata.js +5 -4
  133. package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +25 -9
  134. package/src/view/minimap/dom/MinimapCameraView.js +1 -1
  135. package/src/core/geom/Plane.js +0 -250
  136. package/src/core/land/reactive/ReactiveLexer.js +0 -158
  137. package/src/core/land/reactive/ReactiveLexer.ts +0 -181
  138. package/src/core/land/reactive/ReactiveListener.ts +0 -323
  139. package/src/core/land/reactive/ReactiveParser.js +0 -1573
  140. package/src/core/land/reactive/ReactiveParser.ts +0 -1776
  141. package/src/core/land/reactive/ReactiveVisitor.js +0 -1
  142. package/src/core/land/reactive/ReactiveVisitor.ts +0 -218
  143. package/src/core/land/reactive/compiler/ReactiveCompiler.js +0 -350
  144. package/src/core/land/reactive/compiler/ReactiveNearlyCompiler.js +0 -166
  145. package/src/core/land/reactive/compiler/ReactiveParser.js +0 -34
  146. package/src/core/land/reactive/nearley/ReactiveNearley.js +0 -187
  147. /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 {@code pts} is assumed to be immutable during the computation. That
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 {@code points.size() == 0}
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: {@code !isEmpty()}
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 {@code radius() * radius()}.
130
+ * This is equivalent to `radius() * radius()`.
131
131
  * <p>
132
- * Precondition: {@code !isEmpty()}
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: {@code !isEmpty()}
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., {@code pts.size()} where
155
- * {@code pts} was the {@link PointSet} instance passed to the constructor of this
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: {@code size > 0}
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 {@code centerToAff},
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 {@code centerToAff} is returned. Further,
340
- * {@code stopper} is set to the index of the most restricting point and to -1 if no such point
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 {@code getMaxOverlength() == 0} if and only if all points are contained in the
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 {@code getMaxUnderlength()} should be zero, otherwise the computed
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 {@code dim+1}.
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: {@code size()>0}
146
+ * Precondition: `size()>0`
147
147
  * <p>
148
- * Postcondition: {@code isMember(anyMember())}
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 < {@code size()}
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 {@code members[r]} is called the <i>origin</i>.
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" {@code givens()} for the sake of
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: {@code r<dim}
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: {@code !isMember(index)}
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: {@code size()}>0
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 {@code size()}-many coefficients in the representation of <i>p</i> as an affine
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 {@code 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 {@code globalIndex(i)}.
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 {@code pos-1} already all
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
@@ -1,5 +1,5 @@
1
1
  /**
2
- *
2
+ * Compute vector dot product in 3d
3
3
  * @param {number} x0
4
4
  * @param {number} y0
5
5
  * @param {number} z0
@@ -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 "../../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 "./box/resolveAABB2Overlap.js";
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 "../../../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.js";
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.js";
17
- import { compileReactiveExpression } from "../compileReactiveExpression.js";
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 sampleSize = end - start;
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 / sampleSize;
23
+ return total / sample_count;
24
24
  }
@@ -25,7 +25,7 @@ export class ReactiveAdd extends ReactiveBinaryExpression {
25
25
  }
26
26
 
27
27
  equals(other) {
28
- return other.isReactiveAdd && super.equals(other);
28
+ return (other.isReactiveAdd === true) && super.equals(other);
29
29
  }
30
30
 
31
31
  toCode() {
@@ -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
  }
@@ -25,7 +25,7 @@ export class ReactiveMultiply extends ReactiveBinaryExpression {
25
25
  }
26
26
 
27
27
  equals(other) {
28
- return other.isReactiveMultiply && super.equals(other);
28
+ return (other.isReactiveMultiply === true) && super.equals(other);
29
29
  }
30
30
 
31
31
  toCode() {
@@ -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
  }
@@ -25,7 +25,7 @@ export class ReactiveSubtract extends ReactiveBinaryExpression {
25
25
  }
26
26
 
27
27
  equals(other) {
28
- return other.isReactiveSubtract && super.equals(other);
28
+ return (other.isReactiveSubtract === true) && super.equals(other);
29
29
  }
30
30
 
31
31
  toCode() {