flo-mat 4.1.4 → 4.1.5

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 (57) hide show
  1. package/__tests__/cp-node/circle-identity.spec.ts +56 -0
  2. package/__tests__/find-2-prong/get-medial/dd-get-medial-point-coeffs-same-curve.spec.ts +7 -5
  3. package/__tests__/find-2-prong/get-medial/dd-get-medial-point-coeffs.spec.ts +4 -2
  4. package/browser/index.js +2606 -2161
  5. package/browser/index.min.js +1 -1
  6. package/node/add-n-prong.ts/join-spokes.js +3 -2
  7. package/node/add-n-prong.ts/join-spokes.js.map +1 -1
  8. package/node/cp-node/fs/enhance-cp-node.d.ts +9 -9
  9. package/node/cp-node/fs/get-angle-between-mat-curves.d.ts +1 -1
  10. package/node/cp-node/fs/get-angle-between-mat-curves.js +2 -1
  11. package/node/cp-node/fs/get-angle-between-mat-curves.js.map +1 -1
  12. package/node/cp-node/fs/get-edge-direction.js +3 -2
  13. package/node/cp-node/fs/get-edge-direction.js.map +1 -1
  14. package/node/cp-node/fs/get-implied-boundary-bezier-between.d.ts +1 -1
  15. package/node/cp-node/fs/get-implied-boundary-bezier-between.js +3 -2
  16. package/node/cp-node/fs/get-implied-boundary-bezier-between.js.map +1 -1
  17. package/node/cp-node/fs/get-mat-curve-between.d.ts +1 -0
  18. package/node/cp-node/fs/get-mat-curve-between.js +1 -0
  19. package/node/cp-node/fs/get-mat-curve-between.js.map +1 -1
  20. package/node/cp-node/fs/is-fully-terminating.d.ts +1 -1
  21. package/node/cp-node/fs/is-fully-terminating.js +3 -5
  22. package/node/cp-node/fs/is-fully-terminating.js.map +1 -1
  23. package/node/cp-node/fs/is-on-same-circle.d.ts +3 -0
  24. package/node/cp-node/fs/is-on-same-circle.js +4 -4
  25. package/node/cp-node/fs/is-on-same-circle.js.map +1 -1
  26. package/node/cp-node/stringification/from-stringifyable.js +16 -0
  27. package/node/cp-node/stringification/from-stringifyable.js.map +1 -1
  28. package/node/find-2-prong/add-2-prong.js +6 -2
  29. package/node/find-2-prong/add-2-prong.js.map +1 -1
  30. package/node/find-2-prong/calc-seperation-tolerance.js +2 -2
  31. package/node/find-2-prong/calc-seperation-tolerance.js.map +1 -1
  32. package/node/find-3-prong/find-3-prong-for-delta3s.js +1 -1
  33. package/node/find-3-prong/find-3-prong-for-delta3s.js.map +1 -1
  34. package/node/geometry/get-closest-squared-distance-to-rotated-rect.js +2 -1
  35. package/node/geometry/get-closest-squared-distance-to-rotated-rect.js.map +1 -1
  36. package/node/mat/get-closeby-cp-if-exist.js +2 -1
  37. package/node/mat/get-closeby-cp-if-exist.js.map +1 -1
  38. package/node/point-on-shape/point-on-shape.d.ts +5 -0
  39. package/node/reconstruct-from-mat/reconstruct-from-mat.js.map +1 -1
  40. package/package.json +12 -12
  41. package/src/add-n-prong.ts/join-spokes.ts +4 -2
  42. package/src/cp-node/fs/get-angle-between-mat-curves.ts +4 -2
  43. package/src/cp-node/fs/get-edge-direction.ts +4 -2
  44. package/src/cp-node/fs/get-implied-boundary-bezier-between.ts +6 -6
  45. package/src/cp-node/fs/get-mat-curve-between.ts +1 -0
  46. package/src/cp-node/fs/is-fully-terminating.ts +3 -7
  47. package/src/cp-node/fs/is-on-same-circle.ts +6 -7
  48. package/src/cp-node/stringification/from-stringifyable.ts +17 -0
  49. package/src/find-2-prong/add-2-prong.ts +7 -2
  50. package/src/find-2-prong/calc-seperation-tolerance.ts +2 -2
  51. package/src/find-3-prong/find-3-prong-for-delta3s.ts +1 -1
  52. package/src/geometry/get-closest-squared-distance-to-rotated-rect.ts +4 -4
  53. package/src/mat/get-closeby-cp-if-exist.ts +3 -1
  54. package/src/point-on-shape/point-on-shape.ts +5 -0
  55. package/src/utils/deg-to-rad.ts +4 -2
  56. package/src/utils/rad-to-deg.ts +4 -1
  57. package/webpack.config.cjs +7 -2
@@ -0,0 +1,56 @@
1
+ import { expect, test } from '@jest/globals';
2
+ import type { CpNode } from '../../src/cp-node/cp-node.js';
3
+ import type { Circle } from '../../src/geometry/circle.js';
4
+ import { getPathsFromStr } from 'flo-boolean';
5
+ import { findMats } from '../../src/find-mat/find-mats.js';
6
+ import { getAllOnCircle } from '../../src/cp-node/fs/get-all-on-circle.js';
7
+ import { getAllOnLoop_ByLoop } from '../../src/cp-node/fs/get-all-on-loop-by-loop.js';
8
+ import { toStringifyable } from '../../src/cp-node/stringification/to-stringifyable.js';
9
+ import { fromStringifyable } from '../../src/cp-node/stringification/from-stringifyable.js';
10
+
11
+
12
+ /**
13
+ * Checks the `PointOnShape.circle` invariant: one `Circle` object per
14
+ * on-circle ring, shared by all of the ring's `CpNode`s and by no other ring.
15
+ */
16
+ function checkCircleIdentity(cpStart: CpNode): void {
17
+ const cpNodes = getAllOnLoop_ByLoop(cpStart).flat();
18
+
19
+ const ringOfCircle = new Map<Circle, CpNode[]>();
20
+ const seen = new Set<CpNode>();
21
+ for (const cpNode of cpNodes) {
22
+ if (seen.has(cpNode)) { continue; }
23
+
24
+ const ring = getAllOnCircle(cpNode);
25
+ const { circle } = cpNode.pointOnShape;
26
+ for (const cp of ring) {
27
+ seen.add(cp);
28
+ // shared by all of the ring's CpNodes
29
+ expect(cp.pointOnShape.circle).toBe(circle);
30
+ }
31
+
32
+ // ...and by no other ring
33
+ expect(ringOfCircle.has(circle)).toBe(false);
34
+ ringOfCircle.set(circle, ring);
35
+ }
36
+ }
37
+
38
+
39
+ test('one `Circle` object per on-circle ring (incl. hole closers)', function() {
40
+ // a square with a square hole - forces hole-closing 2-prongs
41
+ const loops = getPathsFromStr(
42
+ 'M0 0 L100 0 L100 100 L0 100 Z ' +
43
+ 'M30 30 L30 70 L70 70 L70 30 Z'
44
+ );
45
+ const { cpNode } = findMats(loops, {})[0];
46
+
47
+ // the test is only meaningful if hole closers were actually created
48
+ const cpNodes = getAllOnLoop_ByLoop(cpNode).flat();
49
+ expect(cpNodes.some(cp => cp.holeCloserTwin !== undefined)).toBe(true);
50
+
51
+ checkCircleIdentity(cpNode);
52
+
53
+ // ...and the invariant survives a (JSON) stringification round trip
54
+ const json = JSON.stringify(toStringifyable(cpNode));
55
+ checkCircleIdentity(fromStringifyable(JSON.parse(json)));
56
+ });
@@ -5,6 +5,8 @@ import { ddGetMedialPointCoeffsBez2_SameCurve } from '../../../src/get-medial-po
5
5
  import { ddGetMedialPointCoeffsBez3_SameCurve } from '../../../src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3-same-curve.js';
6
6
  import { ddNormal } from 'flo-bezier3';
7
7
 
8
+ const { abs, floor } = Math;
9
+
8
10
 
9
11
  function toDdVec(v: number[]): number[][] {
10
12
  return v.map(x => [0, x]);
@@ -17,7 +19,7 @@ function ddPolyToDouble(poly: number[][]): number[] {
17
19
  function normalizedPoly(poly: number[]): number[] {
18
20
  let m = 0;
19
21
  for (const x of poly) {
20
- const ax = Math.abs(x);
22
+ const ax = abs(x);
21
23
  if (ax > m) { m = ax; }
22
24
  }
23
25
 
@@ -34,8 +36,8 @@ function randomNumberIn01(seed: number): number {
34
36
 
35
37
  function randomSignedValue(seed: number): number {
36
38
  const sign = randomNumberIn01(seed) < 0.5 ? -1 : 1;
37
- const exponent = Math.floor(randomNumberIn01(seed + 1) * 61) - 30;
38
- const mantissa = 1 + Math.floor(randomNumberIn01(seed + 2) * 2**20);
39
+ const exponent = floor(randomNumberIn01(seed + 1) * 61) - 30;
40
+ const mantissa = 1 + floor(randomNumberIn01(seed + 2) * 2**20);
39
41
 
40
42
  return sign * mantissa * 2**exponent;
41
43
  }
@@ -67,7 +69,7 @@ test.skip('dd same-curve coefficients match flo-bezier3 double coefficients', fu
67
69
 
68
70
  const n2Dd = ddNormal(ps2, t);
69
71
  let v2 = [n2Dd[0][1], n2Dd[1][1]];
70
- if (Math.abs(v2[0]) + Math.abs(v2[1]) < 2**-20) {
72
+ if (abs(v2[0]) + abs(v2[1]) < 2**-20) {
71
73
  v2 = [v2[0] + 1, v2[1] - 1];
72
74
  }
73
75
  const v2Dd = toDdVec(v2);
@@ -89,7 +91,7 @@ test.skip('dd same-curve coefficients match flo-bezier3 double coefficients', fu
89
91
 
90
92
  const n3Dd = ddNormal(ps3, t);
91
93
  let v3 = [n3Dd[0][1], n3Dd[1][1]];
92
- if (Math.abs(v3[0]) + Math.abs(v3[1]) < 2**-20) {
94
+ if (abs(v3[0]) + abs(v3[1]) < 2**-20) {
93
95
  v3 = [v3[0] + 1, v3[1] - 1];
94
96
  }
95
97
  const v3Dd = toDdVec(v3);
@@ -3,6 +3,8 @@ import { getMedialPointCoeffs } from 'flo-bezier3';
3
3
  import { ddGetMedialPointCoeffs } from '../../../src/get-medial-points/double-double/dd-get-medial-point-coeffs.js';
4
4
  import { squares } from 'squares-rng';
5
5
 
6
+ const { floor, abs } = Math;
7
+
6
8
 
7
9
  function toDdVec(v: number[]): number[][] {
8
10
  return v.map(x => [0, x]);
@@ -19,7 +21,7 @@ function randomNumberIn01(seed: number): number {
19
21
 
20
22
  function randomSignedValue(seed: number): number {
21
23
  const sign = randomNumberIn01(seed) < 0.5 ? -1 : 1;
22
- const exponent = Math.floor(randomNumberIn01(seed + 1) * 81) - 40;
24
+ const exponent = floor(randomNumberIn01(seed + 1) * 81) - 40;
23
25
  const mantissa = 1 + randomNumberIn01(seed + 2);
24
26
 
25
27
  return sign * mantissa * 2**exponent;
@@ -46,7 +48,7 @@ test('ddGetMedialPointCoeffs matches flo-bezier3 double coefficients', function(
46
48
  let v = randomPoint(seed); seed += 11;
47
49
 
48
50
  // Keep the direction away from near-zero vectors.
49
- if (Math.abs(v[0]) + Math.abs(v[1]) < 2**-20) {
51
+ if (abs(v[0]) + abs(v[1]) < 2**-20) {
50
52
  v = [v[0] + 1, v[1] - 1];
51
53
  }
52
54