flo-mat 2.0.3 → 2.0.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 (43) hide show
  1. package/browser/index.js +298 -226
  2. package/browser/index.min.js +1 -1
  3. package/node/debug/functions/draw-elem/three-prong.js +1 -1
  4. package/node/debug/functions/draw-elem/two-prong.js +2 -2
  5. package/node/debug/functions/draw-elem/two-prong.js.map +1 -1
  6. package/node/mat/closest-boundary-point/closest-points-on-curve.js +9 -6
  7. package/node/mat/closest-boundary-point/closest-points-on-curve.js.map +1 -1
  8. package/node/mat/closest-boundary-point/get-close-boundary-points.js +0 -4
  9. package/node/mat/closest-boundary-point/get-close-boundary-points.js.map +1 -1
  10. package/node/mat/closest-boundary-point/get-closest-boundary-point.js.map +1 -1
  11. package/node/mat/find-mat/add-3-prong.js +16 -12
  12. package/node/mat/find-mat/add-3-prong.js.map +1 -1
  13. package/node/mat/find-mat/create-get-interesting-points-on-loop.js +5 -4
  14. package/node/mat/find-mat/create-get-interesting-points-on-loop.js.map +1 -1
  15. package/node/mat/find-mat/find-2-prong/find-2-prong.js +37 -7
  16. package/node/mat/find-mat/find-2-prong/find-2-prong.js.map +1 -1
  17. package/node/mat/find-mat/find-2-prong/find-equidistant-point-on-line-dd.d.ts +9 -0
  18. package/node/mat/find-mat/find-2-prong/find-equidistant-point-on-line-dd.js +58 -0
  19. package/node/mat/find-mat/find-2-prong/find-equidistant-point-on-line-dd.js.map +1 -0
  20. package/node/mat/find-mat/find-3-prong/find-3-prong-for-delta3s.js.map +1 -1
  21. package/node/mat/find-mat/get-sharp-corners.js +0 -1
  22. package/node/mat/find-mat/get-sharp-corners.js.map +1 -1
  23. package/node/mat/is-another-cp-closeby.js +5 -16
  24. package/node/mat/is-another-cp-closeby.js.map +1 -1
  25. package/node/point-on-shape.js.map +1 -1
  26. package/package.json +14 -14
  27. package/src/debug/functions/draw-elem/three-prong.ts +1 -1
  28. package/src/debug/functions/draw-elem/two-prong.ts +2 -2
  29. package/src/mat/closest-boundary-point/closest-points-on-curve.ts +12 -8
  30. package/src/mat/closest-boundary-point/get-close-boundary-points.ts +1 -5
  31. package/src/mat/closest-boundary-point/get-closest-boundary-point-dd.ts +62 -0
  32. package/src/mat/closest-boundary-point/get-closest-boundary-point.ts +7 -7
  33. package/src/mat/cmp-cp-on-delta.ts +3 -0
  34. package/src/mat/find-mat/add-3-prong.ts +23 -13
  35. package/src/mat/find-mat/create-get-interesting-points-on-loop.ts +5 -4
  36. package/src/mat/find-mat/find-2-prong/find-2-prong.ts +44 -9
  37. package/src/mat/find-mat/find-2-prong/find-equidistant-point-on-line-dd.ts +79 -0
  38. package/src/mat/find-mat/find-3-prong/find-3-prong-for-delta3s.ts +1 -1
  39. package/src/mat/find-mat/get-sharp-corners.ts +0 -1
  40. package/src/mat/is-another-cp-closeby.ts +8 -24
  41. package/src/point-on-shape.ts +2 -1
  42. package/src/mat/closest-boundary-point/closest-point-on-curve-old.ts_ +0 -88
  43. package/src/mat/closest-boundary-point/closest-point-on-curve.ts_ +0 -95
package/browser/index.js CHANGED
@@ -24,32 +24,32 @@ var __webpack_exports__ = {};
24
24
 
25
25
  // EXPORTS
26
26
  __webpack_require__.d(__webpack_exports__, {
27
- "M1": () => (/* reexport */ CpNode),
28
- "bt": () => (/* reexport */ PointOnShape),
29
- "A3": () => (/* reexport */ beziersToSvgPathStr),
30
- "zh": () => (/* reexport */ drawBranch),
31
- "Ls": () => (/* reexport */ drawElemFunctions),
32
- "CU": () => (/* reexport */ drawMat),
33
- "gM": () => (/* reexport */ enableDebugForMat),
34
- "SQ": () => (/* reexport */ findMats),
35
- "BG": () => (/* reexport */ getBoundaryBezierPartsToNext),
36
- "Ij": () => (/* reexport */ getBoundaryBeziersToNext),
37
- "tQ": () => (/* reexport */ getBoundaryPieceBeziers),
38
- "C_": () => (/* reexport */ getBranches),
39
- "aS": () => (/* reexport */ getClosestBoundaryPoint),
40
- "DZ": () => (/* reexport */ getClosestSquareDistanceToRect),
41
- "wH": () => (/* reexport */ getCurveBetween),
42
- "N0": () => (/* reexport */ getCurveToNext),
43
- "Jt": () => (/* reexport */ getPathsFromStr),
44
- "tO": () => (/* reexport */ getShapeBounds),
45
- "bQ": () => (/* reexport */ loop_loopFromBeziers),
46
- "UW": () => (/* reexport */ simplifyMat),
47
- "_T": () => (/* reexport */ simplifyMatMapOnly),
48
- "Dw": () => (/* reexport */ sweep_line_sweepLine),
49
- "xs": () => (/* reexport */ toScaleAxis),
50
- "y9": () => (/* reexport */ traverseEdges),
51
- "Fw": () => (/* reexport */ traverseVertices),
52
- "QE": () => (/* reexport */ trimMat)
27
+ M1: () => (/* reexport */ CpNode),
28
+ bt: () => (/* reexport */ PointOnShape),
29
+ A3: () => (/* reexport */ beziersToSvgPathStr),
30
+ zh: () => (/* reexport */ drawBranch),
31
+ Ls: () => (/* reexport */ drawElemFunctions),
32
+ CU: () => (/* reexport */ drawMat),
33
+ gM: () => (/* reexport */ enableDebugForMat),
34
+ SQ: () => (/* reexport */ findMats),
35
+ BG: () => (/* reexport */ getBoundaryBezierPartsToNext),
36
+ Ij: () => (/* reexport */ getBoundaryBeziersToNext),
37
+ tQ: () => (/* reexport */ getBoundaryPieceBeziers),
38
+ C_: () => (/* reexport */ getBranches),
39
+ aS: () => (/* reexport */ getClosestBoundaryPoint),
40
+ DZ: () => (/* reexport */ getClosestSquareDistanceToRect),
41
+ wH: () => (/* reexport */ getCurveBetween),
42
+ N0: () => (/* reexport */ getCurveToNext),
43
+ Jt: () => (/* reexport */ getPathsFromStr),
44
+ tO: () => (/* reexport */ getShapeBounds),
45
+ bQ: () => (/* reexport */ loop_loopFromBeziers),
46
+ UW: () => (/* reexport */ simplifyMat),
47
+ _T: () => (/* reexport */ simplifyMatMapOnly),
48
+ Dw: () => (/* reexport */ sweep_line_sweepLine),
49
+ xs: () => (/* reexport */ toScaleAxis),
50
+ y9: () => (/* reexport */ traverseEdges),
51
+ Fw: () => (/* reexport */ traverseVertices),
52
+ QE: () => (/* reexport */ trimMat)
53
53
  });
54
54
 
55
55
  ;// CONCATENATED MODULE: ./node_modules/flo-boolean/node/svg/beziers-to-svg-path-str.js
@@ -937,52 +937,33 @@ function dot(a, b) {
937
937
  }
938
938
 
939
939
  //# sourceMappingURL=dot.js.map
940
- ;// CONCATENATED MODULE: ./node_modules/flo-memoize/node/index.js
941
-
942
-
943
- const SUPPORTED = typeof WeakMap === 'function';
944
- /**
945
- * Memoize (by reference on the input parameter) the given arity 1 function.
946
- */
947
- function memoize(f) {
948
- if (!SUPPORTED) {
949
- return f;
950
- }
951
- const results = new WeakMap();
952
- return function (a) {
953
- let result = results.get(a);
954
- if (result !== undefined) {
955
- //console.log('cache hit');
956
- return result;
957
- }
958
- //console.log('cache miss');
959
- result = f(a);
960
- results.set(a, result);
961
- return result;
962
- };
963
- }
964
- /**
965
- * Memoize (by reference on the ordered input parameters) the given arity 2 function.
966
- */
967
- function memoize2(f) {
968
- if (!SUPPORTED) {
969
- return f;
970
- }
971
- const results = new WeakMap();
972
- return function (a, b) {
973
- let result = pairMap_get(results, a, b);
974
- if (result !== undefined) {
975
- //console.log('cache hit');
976
- return result;
977
- }
978
- //console.log('cache miss');
979
- result = f(a, b);
980
- pairMap_set(results, a, b, result);
981
- return result;
982
- };
983
- }
984
-
985
- //# sourceMappingURL=index.js.map
940
+ ;// CONCATENATED MODULE: ./node_modules/flo-memoize/node/memoize.js
941
+ /**
942
+ * Memoize (by reference on the input parameter) the given arity 1 function.
943
+ *
944
+ * * the input parameter must be an `object` (so it can be used as a key to
945
+ * `WeakMap` and thus garbage collected later; this is especially important
946
+ * in functional programming where a lot of garbage collection takes place;
947
+ *
948
+ * * use `memoizePrimitive` instead if it is not important that the keys
949
+ * will *never* be garbage collected
950
+ */
951
+ function memoize(f) {
952
+ const results = new WeakMap();
953
+ return function (t) {
954
+ let r = results.get(t);
955
+ if (r !== undefined) {
956
+ //console.log('cache hit');
957
+ return r;
958
+ }
959
+ //console.log('cache miss');
960
+ r = f(t);
961
+ results.set(t, r);
962
+ return r;
963
+ };
964
+ }
965
+
966
+ //# sourceMappingURL=memoize.js.map
986
967
  ;// CONCATENATED MODULE: ./node_modules/flo-bezier3/node/local-properties-at-t/evaluate/double/eval-de-casteljau.js
987
968
  /**
988
969
  * Returns the resulting point of evaluating the given bezier curve at the
@@ -9840,6 +9821,7 @@ function completeLoop(expMax, takenOuts, out) {
9840
9821
  // Move immediately to the outgoing start of the loop
9841
9822
  let out_ = out;
9842
9823
  let additionalBezier;
9824
+ // console.log(out_);
9843
9825
  do {
9844
9826
  takenOuts.add(out_); // Mark this intersection as taken
9845
9827
  const { beziers: additionalBeziers, in_, inBez } = getBeziersToNextContainer(expMax, out_);
@@ -10939,43 +10921,53 @@ function getLoopsFromTree(root) {
10939
10921
  }
10940
10922
 
10941
10923
  //# sourceMappingURL=get-loops-from-tree.js.map
10942
- ;// CONCATENATED MODULE: ./node_modules/flo-bezier3/node/boxes/are-boxes-intersecting.js
10943
- /**
10944
- * Returns `true` if the 2 given axis-aligned rectangular boxes intersect.
10945
- *
10946
- * * **exact**: not susceptible to floating point round-off
10947
- *
10948
- * @param closed if `true`, interpret boxes as being closed (i.e. they contain
10949
- * their border), otherwise open.
10950
- * @param a an axis-aligned rectangular box (given by an array of two points,
10951
- * e.g. `[[1,2], [3,4]]`)
10952
- * @param b another axis-aligned rectangular box
10953
- *
10954
- * @doc mdx
10955
- */
10956
- function areBoxesIntersecting(closed, a, b) {
10957
- let [[ax0, ay0], [ax1, ay1]] = a;
10958
- let [[bx0, by0], [bx1, by1]] = b;
10959
- // Swap so smaller coordinate comes first
10960
- if (ay0 > ay1) {
10961
- [ay0, ay1] = [ay1, ay0];
10962
- }
10963
- if (by0 > by1) {
10964
- [by0, by1] = [by1, by0];
10965
- }
10966
- if (ax0 > ax1) {
10967
- [ax0, ax1] = [ax1, ax0];
10968
- }
10969
- if (bx0 > bx1) {
10970
- [bx0, bx1] = [bx1, bx0];
10971
- }
10972
- return closed
10973
- ? ax0 <= bx1 && ax1 >= bx0 &&
10974
- by0 <= ay1 && by1 >= ay0
10975
- : ax0 < bx1 && ax1 > bx0 &&
10976
- by0 < ay1 && by1 > ay0;
10977
- }
10978
-
10924
+ ;// CONCATENATED MODULE: ./node_modules/flo-boolean/node/are-boxes-intersecting.js
10925
+ /**
10926
+ * Returns `true` if the 2 given axis-aligned rectangular boxes intersect.
10927
+ *
10928
+ * * **exact**: not susceptible to floating point round-off
10929
+ *
10930
+ * @param closed if `true`, interpret boxes as being closed (i.e. they contain
10931
+ * their border), otherwise open.
10932
+ * @param a an axis-aligned rectangular box (given by an array of two points,
10933
+ * e.g. `[[1,2], [3,4]]`)
10934
+ * @param b another axis-aligned rectangular box
10935
+ *
10936
+ * @doc mdx
10937
+ */
10938
+ function areBoxesIntersecting(closed, a, b) {
10939
+ let [[ax0, ay0], [ax1, ay1]] = a;
10940
+ let [[bx0, by0], [bx1, by1]] = b;
10941
+ // Swap so smaller coordinate comes first
10942
+ if (ay0 > ay1) {
10943
+ [ay0, ay1] = [ay1, ay0];
10944
+ }
10945
+ if (by0 > by1) {
10946
+ [by0, by1] = [by1, by0];
10947
+ }
10948
+ if (ax0 > ax1) {
10949
+ [ax0, ax1] = [ax1, ax0];
10950
+ }
10951
+ if (bx0 > bx1) {
10952
+ [bx0, bx1] = [bx1, bx0];
10953
+ }
10954
+ const closedX = closed || (ax0 === ax1 && bx0 === bx1);
10955
+ const closedY = closed || (ay0 === ay1 && by0 === by1);
10956
+ return ((closedX ? ax0 <= bx1 : ax0 < bx1) &&
10957
+ (closedX ? ax1 >= bx0 : ax1 > bx0) &&
10958
+ (closedY ? by0 <= ay1 : by0 < ay1) &&
10959
+ (closedY ? by1 >= ay0 : by1 > ay0));
10960
+ // return closed
10961
+ // ? ax0 <= bx1 &&
10962
+ // ax1 >= bx0 &&
10963
+ // by0 <= ay1 &&
10964
+ // by1 >= ay0
10965
+ // : ax0 < bx1 &&
10966
+ // ax1 > bx0 &&
10967
+ // by0 < ay1 &&
10968
+ // by1 > ay0
10969
+ }
10970
+
10979
10971
  //# sourceMappingURL=are-boxes-intersecting.js.map
10980
10972
  ;// CONCATENATED MODULE: ./node_modules/flo-boolean/node/calc-containers/are-containers-intersecting.js
10981
10973
 
@@ -18324,6 +18316,9 @@ function boxExpToBox(boxExp) {
18324
18316
  function getInOutsViaSides(container, ioIdx) {
18325
18317
  // We check one __X__ for each curve with an intersection within this container
18326
18318
  const xs_ = container.xs;
18319
+ //if (xs_.length === 4) {
18320
+ // console.log(xs_.map(x => x.x.kind))
18321
+ //}
18327
18322
  const inOuts = [];
18328
18323
  // get a map from each Curve to each __X__ of this container
18329
18324
  const xMap = new Map();
@@ -18496,6 +18491,7 @@ function getInOutsViaCrossing(container, ioIdx) {
18496
18491
  function getContainerInOuts(container, ioIdx) {
18497
18492
  // We check one __X__ for each curve with an intersection within this container
18498
18493
  const xs = container.xs;
18494
+ // console.log(xs);
18499
18495
  // Check nature of Xs. If Xs is the very common case where two curves cross
18500
18496
  // we can use a faster check. Also in the bit less common case where all
18501
18497
  // curves are joining at an interface we can do a fast ccw (the ccw part
@@ -20828,6 +20824,7 @@ function makeSimpleX(t, curve, kind) {
20828
20824
 
20829
20825
 
20830
20826
 
20827
+
20831
20828
  /**
20832
20829
  * Returns the pairs of intersection `t` values between the curves. Interface
20833
20830
  * intersections may not be returned - they should already be caught.
@@ -20846,7 +20843,9 @@ function getCurvesIntersections(expMax) {
20846
20843
  // curves are connected at endpoints
20847
20844
  // closed bounding boxes are guaranteed to intersect - don't check
20848
20845
  // check open bounding boxes
20849
- const aabbsIntersectOpen = areBoxesIntersecting(false, getBoundingBox_(psA), getBoundingBox_(psB));
20846
+ const aabbsIntersectOpen = areBoxesIntersecting(false,
20847
+ // const aabbsIntersectOpen = areBoxesIntersecting(true,
20848
+ getBoundingBox_(psA), getBoundingBox_(psB));
20850
20849
  if (!aabbsIntersectOpen) {
20851
20850
  return checkEndpoints(curveA, curveB);
20852
20851
  }
@@ -20924,15 +20923,18 @@ function getLineLineIntersections(curveA, curveB, expMax) {
20924
20923
  let psB = curveB.ps;
20925
20924
  const bbA = getBoundingBox_(psA);
20926
20925
  const bbB = getBoundingBox_(psB);
20926
+ // if (equal(psA,[[4,8],[4,7]]) && equal(psB,[[4,6],[4,8]])) {
20927
+ // console.log('testing');
20928
+ // }
20927
20929
  if (curveA.next !== curveB && curveB.next !== curveA) {
20928
- // the two lines are not connected at their endpoints
20930
+ // the two line curves are not consecutive in the loop
20929
20931
  if (areBoxesIntersecting(true, bbA, bbB)) {
20930
20932
  const xs = getIntersection(curveA, curveB, expMax, false);
20931
20933
  return xs.length ? xs : undefined;
20932
20934
  }
20933
20935
  return undefined;
20934
20936
  }
20935
- // the two lines are connected at their endpoints
20937
+ // the two line curves are consecutive in the loop
20936
20938
  const swap = curveB.next === curveA;
20937
20939
  if (swap) {
20938
20940
  [curveA, curveB] = [curveB, curveA];
@@ -20952,16 +20954,14 @@ function getLineLineIntersections(curveA, curveB, expMax) {
20952
20954
  }
20953
20955
  // it is a line going back on itself
20954
20956
  // - return endpoint intersections
20955
- const lenCurve1 = squared_distance_between_squaredDistanceBetween(psA[0], psA[1]);
20956
- const lenCurve2 = squared_distance_between_squaredDistanceBetween(psB[0], psB[1]);
20957
+ const lenCurveA = squared_distance_between_squaredDistanceBetween(psA[0], psA[1]);
20958
+ const lenCurveB = squared_distance_between_squaredDistanceBetween(psB[0], psB[1]);
20957
20959
  let tPair;
20958
- if (lenCurve1 > lenCurve2) {
20959
- // tPair = [inversion01Precise(psA, psB[1]), 1];
20960
+ if (lenCurveA > lenCurveB) {
20960
20961
  const t0 = mid(closestPointOnBezierCertified(psA, psB[1])[0].ri);
20961
20962
  tPair = [t0, 1];
20962
20963
  }
20963
20964
  else {
20964
- // tPair = [0, inversion01Precise(psB, psA[0])];
20965
20965
  const t1 = mid(closestPointOnBezierCertified(psB, psA[0])[0].ri);
20966
20966
  tPair = [0, t1];
20967
20967
  }
@@ -21799,6 +21799,35 @@ function compareOrderedInOut(inOutA, inOutB) {
21799
21799
  }
21800
21800
 
21801
21801
  //# sourceMappingURL=compare-in-out.js.map
21802
+ ;// CONCATENATED MODULE: ./node_modules/flo-boolean/node/calc-containers/filter-containers.js
21803
+ /**
21804
+ * Returns the containers that is the given containers filtered so that those
21805
+ * having only interface intersections or only a single (given as a pair) even
21806
+ * multiple intersection are not included.
21807
+ * @param containers
21808
+ */
21809
+ function filterContainers(containers) {
21810
+ const containers_ = containers.filter(container => {
21811
+ const xs = container.xs;
21812
+ if (container.xs.length === 2) {
21813
+ const _x_ = xs[0];
21814
+ if (_x_.x.kind === 1 && _x_.x.ri.multiplicity % 2 === 0) {
21815
+ // multiple even intersection - exclude
21816
+ return false;
21817
+ }
21818
+ }
21819
+ for (const x of container.xs) {
21820
+ if (x.x.kind !== 4) {
21821
+ // include container if any __X__ is not an interface
21822
+ return true;
21823
+ }
21824
+ }
21825
+ return false; // exclude container
21826
+ });
21827
+ return containers_;
21828
+ }
21829
+
21830
+ //# sourceMappingURL=filter-containers.js.map
21802
21831
  ;// CONCATENATED MODULE: ./node_modules/flo-boolean/node/calc-containers/get-containers.js
21803
21832
 
21804
21833
 
@@ -21813,6 +21842,7 @@ function compareOrderedInOut(inOutA, inOutB) {
21813
21842
 
21814
21843
 
21815
21844
 
21845
+
21816
21846
  /**
21817
21847
  *
21818
21848
  * @param containerDim
@@ -21826,10 +21856,10 @@ function getContainers(loops, containerDim, expMax) {
21826
21856
  const xs3 = getInterfaceIntersections(loops);
21827
21857
  const { extremes, xs: xs4 } = getExtremes(loops);
21828
21858
  let xPairs = [...xs1, ...xs2, ...xs3, ...xs4];
21829
- //console.log('general ', xs1);
21830
- //console.log('self ', xs2);
21831
- //console.log('interface', xs3);
21832
- //console.log('topmost ', xs4);
21859
+ // console.log('general ', xs1);
21860
+ // console.log('self ', xs2);
21861
+ // console.log('interface', xs3);
21862
+ // console.log('topmost ', xs4);
21833
21863
  if (typeof _debug_ !== 'undefined') {
21834
21864
  for (const xPair of xs1) {
21835
21865
  _debug_.generated.elems.intersection.push(...xPair);
@@ -21927,32 +21957,6 @@ function getContainers(loops, containerDim, expMax) {
21927
21957
  }
21928
21958
  return { extremes, containers };
21929
21959
  }
21930
- /**
21931
- * Returns the containers that is the given containers filtered so that those
21932
- * having only interface intersections or only a single (given as a pair) even
21933
- * multiple intersection are not included.
21934
- * @param containers
21935
- */
21936
- function filterContainers(containers) {
21937
- const containers_ = containers.filter(container => {
21938
- const xs = container.xs;
21939
- if (container.xs.length === 2) {
21940
- const _x_ = xs[0];
21941
- if (_x_.x.kind === 1 && _x_.x.ri.multiplicity % 2 === 0) {
21942
- // multiple even intersection - exclude
21943
- return false;
21944
- }
21945
- }
21946
- for (const x of container.xs) {
21947
- if (x.x.kind !== 4) {
21948
- // include container if any __X__ is not an interface
21949
- return true;
21950
- }
21951
- }
21952
- return false; // exclude container
21953
- });
21954
- return containers_;
21955
- }
21956
21960
  function getLeftMost(container) {
21957
21961
  return container.box[0][0];
21958
21962
  }
@@ -22227,6 +22231,33 @@ function toLength(p, length) {
22227
22231
  }
22228
22232
 
22229
22233
  //# sourceMappingURL=to-length.js.map
22234
+ ;// CONCATENATED MODULE: ./node_modules/flo-bezier3/node/simultaneous-properties/equal.js
22235
+ /**
22236
+ * Returns `true` if the two given bezier curves are exactly equal when compared
22237
+ * by value (deep equality), `false` otherwise
22238
+ *
22239
+ * @param ps1 an order 0,1,2 or 3 bezier curve given as an ordered array of its
22240
+ * control points, e.g. `[[0,0],[1,1],[2,1],[2,0]]`
22241
+ * @param ps2 another bezier curve
22242
+ *
22243
+ * @doc
22244
+ */
22245
+ function equal_equal(ps1, ps2) {
22246
+ if (ps1 === ps2) {
22247
+ return true;
22248
+ }
22249
+ if (ps1.length !== ps2.length) {
22250
+ return false;
22251
+ }
22252
+ for (let i = 0; i < ps1.length; i++) {
22253
+ if (ps1[i][0] !== ps2[i][0] || ps1[i][1] !== ps2[i][1]) {
22254
+ return false;
22255
+ }
22256
+ }
22257
+ return true;
22258
+ }
22259
+
22260
+ //# sourceMappingURL=equal.js.map
22230
22261
  ;// CONCATENATED MODULE: ./node_modules/flo-boolean/node/loop/normalize/are-all-points-different.js
22231
22262
  /**
22232
22263
  * Returns true if all points in the given array are different, false otherwise.
@@ -22257,6 +22288,9 @@ const { abs: fix_bezier_by_point_spacing_abs } = Math;
22257
22288
  * @param ps A bezier
22258
22289
  */
22259
22290
  function fixBezierByPointSpacing(ps, gridSpacing, sendToGrid) {
22291
+ if (ps === undefined) {
22292
+ return undefined;
22293
+ }
22260
22294
  // Early filter - if all points coincide, we're done - degenerate to point
22261
22295
  if (isReallyPoint(ps)) {
22262
22296
  return undefined; // Cannot fix
@@ -22276,9 +22310,8 @@ function fixBezierByPointSpacing(ps, gridSpacing, sendToGrid) {
22276
22310
  // Is the quadratic bezier overlapping onto itself?
22277
22311
  if (arePsEqual(ps[0], ps[2])) {
22278
22312
  // a quadratic with equal endpoints (and not degenerate to a point)
22279
- // The overlap is of no consequence to the algorithm so make it a
22280
- // line
22281
- return [ps[0], ps[1]];
22313
+ return undefined; // better to just remove it
22314
+ // return [ps[0], ps[1]];
22282
22315
  }
22283
22316
  // At this point not all points same and not all points different and
22284
22317
  // not endpoints coincide, so either:
@@ -22290,28 +22323,42 @@ function fixBezierByPointSpacing(ps, gridSpacing, sendToGrid) {
22290
22323
  // ---- at this point we must have a cubic
22291
22324
  // Early filter - if no points coincide, we're done - well spaced
22292
22325
  if (areAllPointsDifferent(ps)) {
22293
- return checkCubicForLineOrQuad(ps);
22326
+ const ps_ = checkCubicForLineOrQuad(ps);
22327
+ if (ps_ === undefined) {
22328
+ return undefined;
22329
+ }
22330
+ if (equal_equal(ps_, ps)) {
22331
+ return ps;
22332
+ }
22333
+ return fixBezierByPointSpacing(ps_, gridSpacing, sendToGrid);
22294
22334
  }
22295
22335
  if (arePsEqual(ps[0], ps[3])) {
22296
22336
  // we should simply handle this case for cubics - lines and quadratics
22297
22337
  // degenerate into a point and a self-overlapping curve respectively.
22298
- if (arePsEqual(ps[1], ps[2])) {
22299
- // it is a cubic degenerated to a line
22300
- return [ps[0], ps[2]];
22338
+ // if (isCollinear(ps)) { return [ps[0], ps[3]]; }
22339
+ if (isCollinear(ps)) {
22340
+ return undefined;
22301
22341
  }
22342
+ // if (arePsEqual(ps[1], ps[2])) {
22343
+ // // it is a cubic degenerated to a line
22344
+ // return [ps[0], ps[2]];
22345
+ // }
22302
22346
  // no need to fix anything - it is a loop - it cannot be a line or a
22303
22347
  // quadratic (they don't make loops)
22304
22348
  return ps;
22305
22349
  }
22350
+ if (isCollinear(ps)) {
22351
+ return [ps[0], ps[3]];
22352
+ }
22306
22353
  // At this point, either:
22307
22354
  // * point 0, 1 and 2 coincide
22308
22355
  // * point 1, 2 and 3 coincide
22309
22356
  // * points 0,1 AND points 2,3 coincide
22310
- // * only point 0 and point 1 coincides
22311
- // * only point 0 and point 2 coincides
22312
- // * only point 1 and point 2 coincides
22313
- // * only point 1 and point 3 coincides
22314
- // * only point 2 and point 3 coincides
22357
+ // * only point 0 and point 1 coincide
22358
+ // * only point 0 and point 2 coincide
22359
+ // * only point 1 and point 2 coincide
22360
+ // * only point 1 and point 3 coincide
22361
+ // * only point 2 and point 3 coincide
22315
22362
  // If point 0, 1 and 2 coincide OR point 1, 2 and 3 coincide OR
22316
22363
  // points 0,1 AND points 2,3 coincide we have a line
22317
22364
  if ((arePsEqual(ps[0], ps[1]) &&
@@ -22320,17 +22367,24 @@ function fixBezierByPointSpacing(ps, gridSpacing, sendToGrid) {
22320
22367
  arePsEqual(ps[2], ps[3])) ||
22321
22368
  (arePsEqual(ps[0], ps[1]) &&
22322
22369
  arePsEqual(ps[2], ps[3]))) {
22370
+ return fixBezierByPointSpacing([ps[0], ps[ps.length - 1]], gridSpacing, sendToGrid);
22371
+ /*
22323
22372
  // Check if first and last point are sufficiently far apart to split
22324
22373
  // the bezier into a line so that all points differ.
22325
- if (fix_bezier_by_point_spacing_abs(ps[0][0] - ps[3][0]) > (3 + 1) * gridSpacing ||
22326
- fix_bezier_by_point_spacing_abs(ps[0][1] - ps[3][1]) > (3 + 1) * gridSpacing) {
22327
- return [ps[0], ps[ps.length - 1]];
22328
- }
22329
- else {
22374
+
22375
+ // TODO2 - is below maybe not correct?
22376
+ //if ((ps[0][0] - ps[3][0]) > (3+1)*gridSpacing ||
22377
+ // (ps[0][1] - ps[3][1]) > (3+1)*gridSpacing) {
22378
+ if (abs(ps[0][0] - ps[3][0]) > (3+1)*gridSpacing ||
22379
+ abs(ps[0][1] - ps[3][1]) > (3+1)*gridSpacing) {
22380
+
22381
+ return [ps[0], ps[ps.length-1]];
22382
+ } else {
22330
22383
  // Points are not sufficiently far apart to resolve onto grid -
22331
22384
  // cannot fix it - it is basically a point.
22385
+
22332
22386
  return undefined;
22333
- }
22387
+ }*/
22334
22388
  }
22335
22389
  // At this point, either:
22336
22390
  // * only point 0 and point 1 coincides
@@ -22360,12 +22414,7 @@ function fixBezierByPointSpacing(ps, gridSpacing, sendToGrid) {
22360
22414
  // move them onto each other - this shouldn't affect the overall
22361
22415
  // accuracy of the algorithm and it ensures the move > gridSpacing.
22362
22416
  if (squared_distance_between_squaredDistanceBetween(ps[1], ps[2]) < 4 * gridSpacing) {
22363
- return [
22364
- ps[0],
22365
- ps[2],
22366
- ps[2],
22367
- ps[3]
22368
- ]; // cannot be a line or quad
22417
+ return [ps[0], ps[2], ps[2], ps[3]]; // cannot be a line or quad
22369
22418
  }
22370
22419
  else {
22371
22420
  const v = toLength(fromTo(ps[1], ps[2]), 2 * gridSpacing);
@@ -22728,10 +22777,11 @@ function simplifyPaths(bezierLoops, maxCoordinate) {
22728
22777
  * A size (based on the max value of the tangent) for the containers holding
22729
22778
  * critical points.
22730
22779
  */
22731
- const containerSizeMultiplier = 2 ** 4;
22732
- //const containerSizeMultiplier = 2**39;
22780
+ const containerSizeMultiplier = 2 ** 4; // TODO2 - put back!!
22781
+ // const containerSizeMultiplier = 2**36;
22733
22782
  const containerDim = gridSpacing * containerSizeMultiplier;
22734
22783
  bezierLoops = normalizeLoops(bezierLoops, maxBitLength, expMax, false, true);
22784
+ // console.log(bezierLoops)
22735
22785
  addDebugInfo1(bezierLoops);
22736
22786
  bezierLoops.sort(orderLoopAscendingByMinY);
22737
22787
  const loops = bezierLoops.map((loop, i) => loopFromBeziers(loop, i));
@@ -23228,8 +23278,6 @@ function evaluate(ps, t) {
23228
23278
 
23229
23279
  //# sourceMappingURL=evaluate.js.map
23230
23280
  ;// CONCATENATED MODULE: ./src/mat/closest-boundary-point/closest-points-on-curve.ts
23231
- // qqq import { deflateQuad, allRootsMultiWithErrBounds, RootInterval } from 'flo-poly';
23232
- // qqq import { getTangentPolyFromPointExact, evalDeCasteljau, evaluate, getFootpointPolyExact } from 'flo-bezier3';
23233
23281
 
23234
23282
 
23235
23283
  /**
@@ -23241,13 +23289,10 @@ function evaluate(ps, t) {
23241
23289
  * @param t The t value of the bezier that locates p
23242
23290
  */
23243
23291
  function closestPointsOnCurve(curve, p, [tS, tE] = [0, 1], touchedCurve, t) {
23244
- // qqq let poly = getTangentPolyFromPointExact(curve.ps, p);
23245
23292
  const _poly = getFootpointPolyDd(curve.ps, p);
23246
- // qqq poly = deflateQuad(poly, t);
23247
23293
  const poly = curve === touchedCurve
23248
23294
  ? ddDeflate(_poly, t)
23249
23295
  : _poly;
23250
- // let roots: Omit<RootInterval,'multiplicity'>[] = allRootsMultiWithErrBounds(
23251
23296
  const roots = allRootsCertified(poly, tS, tE);
23252
23297
  // Also test the endpoints
23253
23298
  let push0 = true;
@@ -23294,8 +23339,16 @@ function closestPointsOnCurve(curve, p, [tS, tE] = [0, 1], touchedCurve, t) {
23294
23339
  ? 0
23295
23340
  : tE > 1 ? 1 : (tS + tE) / 2;
23296
23341
  // TODO - why does evalDeCasteljau not work here?
23297
- return { p: evaluate(curve.ps, t), t };
23298
23342
  //return { p: evalDeCasteljau(curve.ps,t), t }
23343
+ // TODO2 - will make it slower
23344
+ // const aa = evaluate(curve.ps,t);
23345
+ // const bb = evalDeCasteljauDd(curve.ps,[0,t]).map(v => v[1]);
23346
+ // if (aa[0] !== bb[0] || aa[1] !== bb[1]) {
23347
+ // console.log(aa);
23348
+ // console.log(bb);
23349
+ // }
23350
+ return { p: evaluate(curve.ps, t), t };
23351
+ // return { p: evalDeCasteljauDd(curve.ps,[0,t]).map(v => v[1]), t }
23299
23352
  });
23300
23353
  return ps;
23301
23354
  }
@@ -23804,12 +23857,7 @@ function addToCpGraph(circle, orders, cpTrees, poss, neighbors) {
23804
23857
 
23805
23858
 
23806
23859
  /** @hidden */
23807
- //const ANGLE_THRESHOLD = Math.cos(3 * (Math.PI / 180)); // 3 degrees
23808
- const ANGLE_THRESHOLD = 0.9986295347545738; // === Math.cos(3 degrees)
23809
- //const ANGLE_THRESHOLD = 0.9848077530122080; // === Math.cos(10 degrees)
23810
- //const ANGLE_THRESHOLD = 0.9998476951563913; // === Math.cos(1 degrees)
23811
- //const ANGLE_THRESHOLD = 0.9999984769132877; // === Math.cos(0.1 degrees)
23812
- //const ANGLE_THRESHOLD = 0.9999999847691291 // === Math.cos(0.01 degrees)
23860
+ const ANGLE_THRESHOLD = Math.cos(15 * (Math.PI / 180)); // 15 degrees
23813
23861
  /**
23814
23862
  * @hidden
23815
23863
  * Returns true if another CpNode is close to the given implied (via pos, order
@@ -23824,15 +23872,7 @@ const ANGLE_THRESHOLD = 0.9986295347545738; // === Math.cos(3 degrees)
23824
23872
  * @param color Used for debugging only
23825
23873
  */
23826
23874
  function isAnotherCpCloseby(cpTrees, pos, circle, order, order2, extreme, color) {
23827
- //console.log(extreme)
23828
- //const DISTANCE_THRESHOLD = extreme * 1e-1;
23829
- //const DISTANCE_THRESHOLD = extreme * 1e-1;
23830
23875
  const DISTANCE_THRESHOLD = extreme * 1e-4;
23831
- //const DISTANCE_THRESHOLD = extreme * 1e-4; - was this
23832
- //const DISTANCE_THRESHOLD = extreme * 1e-6;
23833
- //const DISTANCE_THRESHOLD = extreme * 1e-12;
23834
- // It seems this can be zero else the ordering should be correct
23835
- //const DISTANCE_THRESHOLD = 0;
23836
23876
  const cpTree = cpTrees.get(pos.curve.loop);
23837
23877
  const cpNodes = getNeighbouringPoints(cpTree, pos, order, order2);
23838
23878
  if (!cpNodes[0]) {
@@ -23845,11 +23885,13 @@ function isAnotherCpCloseby(cpTrees, pos, circle, order, order2, extreme, color)
23845
23885
  if (distanceBetween(p1, p2) > DISTANCE_THRESHOLD) {
23846
23886
  continue;
23847
23887
  }
23848
- const v1 = toUnitVector(fromTo(cpNode.cp.pointOnShape.p, cpNode.cp.circle.center));
23888
+ // TODO2
23889
+ return true;
23890
+ const v1 = toUnitVector(fromTo(p2, cpNode.cp.circle.center));
23849
23891
  const v2 = toUnitVector(fromTo(p1, circle.center));
23850
23892
  const cosTheta = dot(v1, v2);
23851
23893
  if (cosTheta > ANGLE_THRESHOLD) {
23852
- //console.log(`%c${cosTheta} - ${distanceBetween(p1,p2)}`, `color: ${color}`);
23894
+ // console.log(`%c${cosTheta} - ${distanceBetween(p1,p2)}`, `color: ${color}`);
23853
23895
  return true;
23854
23896
  }
23855
23897
  }
@@ -23874,24 +23916,27 @@ function add3Prong(cpTrees, orders, threeProng) {
23874
23916
  /*
23875
23917
  if (typeof _debug_ !== 'undefined') {
23876
23918
  for (let i=0; i<3; i++) {
23877
- let cpBef = threeProng.δ3s[i][0].cp;
23878
- let cpAft = threeProng.δ3s[i][1].cp;
23879
- //let cmpBef = PointOnShape.compareInclOrder(cpBef.pointOnShape, ps[i], cpBef.order, orders[i]);
23880
- //let cmpAft = PointOnShape.compareInclOrder(cpAft.pointOnShape, ps[i], cpAft.order, orders[i]);
23919
+ const cpBef = threeProng.δ3s[i][0].cp;
23920
+ const cpAft = threeProng.δ3s[i][1].cp;
23881
23921
 
23882
- let cmpBef = PointOnShape.compare(cpBef.pointOnShape, ps[i]);
23883
- let cmpAft = PointOnShape.compare(cpAft.pointOnShape, ps[i]);
23922
+ //let cmpBef = PointOnShape.compareInclOrder(cpBef.pointOnShape, poss[i], cpBef.order, orders[i]);
23923
+ //let cmpAft = PointOnShape.compareInclOrder(cpAft.pointOnShape, poss[i], cpAft.order, orders[i]);
23924
+ const cmpBef = compareCps(cpBef, { pointOnShape: poss[i], order: orders[i], order2: 0, circle: undefined });
23925
+ const cmpAft = compareCps(cpAft, { pointOnShape: poss[i], order: orders[i], order2: 0, circle: undefined });
23926
+
23927
+ // const cmpBef = comparePoss(cpBef.pointOnShape, poss[i]);
23928
+ // const cmpAft = comparePoss(cpAft.pointOnShape, poss[i]);
23884
23929
 
23885
23930
  // len is used by debug functions to reference a particular
23886
23931
  // three-prong.
23887
- let len = _debug_.generated.elems.threeProng.length-1;
23932
+ const len = _debug_.generated.elems.threeProng.length-1;
23888
23933
  if (cmpBef > 0) {
23889
23934
  console.log('----------------------------------------');
23890
23935
  console.log(`3-prong order is wrong (bef) : i: ${i} - cmp: ${cmpBef} - n: ${len}`);
23891
23936
  console.log(threeProng);
23892
23937
  console.log(cpBef);
23893
23938
  console.log(cpAft);
23894
- console.log(ps[i]);
23939
+ console.log(poss[i]);
23895
23940
  }
23896
23941
  if (cmpAft < 0) {
23897
23942
  console.log('----------------------------------------');
@@ -23899,15 +23944,16 @@ function add3Prong(cpTrees, orders, threeProng) {
23899
23944
  console.log(threeProng);
23900
23945
  console.log(cpBef);
23901
23946
  console.log(cpAft);
23902
- console.log(ps[i]);
23947
+ console.log(poss[i]);
23903
23948
  }
23904
23949
  }
23905
23950
  }
23906
23951
  */
23907
23952
  // TODO - replace 1000 below with correct value
23908
- isAnotherCpCloseby(cpTrees, poss[0], circle, orders[0], 0, 1000, 'blue');
23909
- isAnotherCpCloseby(cpTrees, poss[1], circle, orders[1], 0, 1000, 'blue');
23910
- isAnotherCpCloseby(cpTrees, poss[2], circle, orders[2], 0, 1000, 'blue');
23953
+ const c1 = isAnotherCpCloseby(cpTrees, poss[0], circle, orders[0], 0, 1000, 'blue');
23954
+ const c2 = isAnotherCpCloseby(cpTrees, poss[1], circle, orders[1], 0, 1000, 'blue');
23955
+ const c3 = isAnotherCpCloseby(cpTrees, poss[2], circle, orders[2], 0, 1000, 'blue');
23956
+ // console.log(c1,c2,c3);
23911
23957
  addToCpGraph(circle, orders, cpTrees, poss, δ3s);
23912
23958
  return circle;
23913
23959
  }
@@ -24753,7 +24799,6 @@ function getSharpCorners(possPerLoop) {
24753
24799
  for (const poss of possPerLoop) {
24754
24800
  const sharpCorners = [];
24755
24801
  for (const pos of poss) {
24756
- //if (PointOnShape.isQuiteSharpCorner(pos)) {
24757
24802
  if (isPosQuiteSharpCorner(pos)) {
24758
24803
  sharpCorners.push(pos);
24759
24804
  }
@@ -25120,11 +25165,7 @@ function getCloseBoundaryPoints(bezierPieces, point, y, distance) {
25120
25165
  // comparing closeness!
25121
25166
  const indexesToCheck = [];
25122
25167
  for (let i = 0; i < posInfos.length; i++) {
25123
- const pi = posInfos[i];
25124
- // Only check if they are close to the edges. Why??
25125
- //if (pi.pos.t < 1e-2 || 1-pi.pos.t < 1e-2) {
25126
25168
  indexesToCheck.push(i);
25127
- //}
25128
25169
  }
25129
25170
  const indexesToRemove = [];
25130
25171
  for (let i = 0; i < indexesToCheck.length; i++) {
@@ -25191,9 +25232,11 @@ const find_2_prong_evalDeCasteljau = evalDeCasteljau;
25191
25232
  */
25192
25233
  function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClosing, k) {
25193
25234
  const MAX_ITERATIONS = 25;
25194
- const squaredSeperationTolerance = (1e-6 * extreme) ** 2;
25235
+ const squaredSeperationTolerance = (1e-5 * extreme) ** 2;
25195
25236
  // TODO - base deltas on theory or remove
25196
25237
  const oneProngTolerance = (1e-4) ** 2;
25238
+ // const oneProngTolerance = (1e-5)**2;
25239
+ // const oneProngTolerance = 0;
25197
25240
  const squaredErrorTolerance = 1e-2 * squaredSeperationTolerance;
25198
25241
  const maxOsculatingCircleRadiusSquared = squaredDiagonalLength;
25199
25242
  // The boundary piece that should contain the other point of
@@ -25211,7 +25254,6 @@ function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClo
25211
25254
  }
25212
25255
  else {
25213
25256
  p = y.p;
25214
- //x = PointOnShape.getOsculatingCircle(maxOsculatingCircleRadiusSquared, y).center;
25215
25257
  x = getOsculatingCircle(maxOsculatingCircleRadiusSquared, y).center;
25216
25258
  r = squared_distance_between_squaredDistanceBetween(p, x);
25217
25259
  }
@@ -25232,8 +25274,8 @@ function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClo
25232
25274
  do {
25233
25275
  i++;
25234
25276
  /** squared distance between source boundary point and circle center */
25235
- const r = squared_distance_between_squaredDistanceBetween(x, y.p);
25236
- bezierPieces_ = cull_bezier_pieces_cullBezierPieces(bezierPieces_, x, r);
25277
+ const xy = squared_distance_between_squaredDistanceBetween(x, y.p);
25278
+ bezierPieces_ = cull_bezier_pieces_cullBezierPieces(bezierPieces_, x, xy);
25237
25279
  z = getClosestBoundaryPoint(bezierPieces_, x, y.curve, y.t);
25238
25280
  if (z === undefined) {
25239
25281
  if (typeof _debug_ !== 'undefined') {
@@ -25253,16 +25295,18 @@ function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClo
25253
25295
  xs.push({ x, y, z: z.pos, t: y.t });
25254
25296
  }
25255
25297
  /** squared distance between anti-pode boundary point and circle center */
25256
- const d = squared_distance_between_squaredDistanceBetween(x, z.pos.p);
25298
+ const xz = squared_distance_between_squaredDistanceBetween(x, z.pos.p);
25257
25299
  //if (i === 1 && d*oneProngTolerance >= r) {
25258
- if (i === 1 && r < d + oneProngTolerance) {
25300
+ if (i === 1 && xy < xz + oneProngTolerance) {
25259
25301
  // It is a 1-prong.
25302
+ // TODO2 - below line was removed (maybe)
25260
25303
  add1Prong(Math.sqrt(maxOsculatingCircleRadiusSquared), cpTrees, y);
25261
25304
  return undefined;
25262
25305
  }
25263
25306
  // TODO - squaredSeperationTolerance should in future be replaced with
25264
25307
  // a relative error, i.e. distance between y (or z) / length(y (or z)).
25265
- if (!isHoleClosing && squared_distance_between_squaredDistanceBetween(y.p, z.pos.p) <= squaredSeperationTolerance) {
25308
+ const yz = squared_distance_between_squaredDistanceBetween(y.p, z.pos.p);
25309
+ if (!isHoleClosing && yz <= squaredSeperationTolerance) {
25266
25310
  if (typeof _debug_ !== 'undefined') {
25267
25311
  /*
25268
25312
  let elems = _debug_.generated.elems;
@@ -25284,8 +25328,10 @@ function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClo
25284
25328
  // nextX, but rather (distance from x to y) - (distance from x to z)
25285
25329
  // Find the point on the line connecting y with x that is
25286
25330
  // equidistant from y and z. This will be our next x.
25331
+ // const nextX = findEquidistantPointOnLineDd(x, y.p, z.pos.p);
25287
25332
  const nextX = findEquidistantPointOnLine(x, y.p, z.pos.p);
25288
25333
  const squaredError = squared_distance_between_squaredDistanceBetween(x, nextX);
25334
+ // const squaredError = Math.abs(xy - xz);
25289
25335
  x = nextX;
25290
25336
  if (squaredError < squaredErrorTolerance) {
25291
25337
  done++; // Do one more iteration
@@ -25296,6 +25342,29 @@ function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClo
25296
25342
  break; // We're done
25297
25343
  }
25298
25344
  } while (done < 1);
25345
+ /************************************************************************ */
25346
+ /* Do one more double-double precision iteration
25347
+ /************************************************************************ */
25348
+ /*
25349
+ z = getClosestBoundaryPoint(
25350
+ bezierPieces_, x, y.curve, y.t
25351
+ );
25352
+
25353
+ if (z === undefined) {
25354
+ failed = true;
25355
+ }
25356
+
25357
+ if (typeof _debug_ !== 'undefined') {
25358
+ xs.push({ x, y, z: z.pos, t: y.t });
25359
+ }
25360
+
25361
+ if (!isHoleClosing && squaredDistanceBetween(y.p, z.pos.p) <= squaredSeperationTolerance) {
25362
+ failed = true;
25363
+ } else {
25364
+ x = findEquidistantPointOnLineDd(x, y.p, z.pos.p);
25365
+ }
25366
+ /************************************************************************ */
25367
+ /************************************************************************ */
25299
25368
  // TODO - Optimization: only do this if second closest point is within the
25300
25369
  // tolerance which can be checked in getClosestBoundaryPoint algorithm
25301
25370
  let zs = [];
@@ -25310,6 +25379,8 @@ function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClo
25310
25379
  if (z !== undefined) {
25311
25380
  circle = { center: x, radius: distanceBetween(x, z.pos.p) };
25312
25381
  }
25382
+ // TODO2
25383
+ // if (Math.random() > 0.8 && !isHoleClosing) { return undefined; }
25313
25384
  if (typeof _debug_ !== 'undefined' && !failed) {
25314
25385
  xs.push({ x, y, z: z.pos, t: y.t });
25315
25386
  addDebugInfo(bezierPieces, failed, y, circle, z.pos, δ, xs, isHoleClosing);
@@ -26087,10 +26158,11 @@ function getInterestingPointsOnLoop(minBezLength, maxCurviness, maxLength) {
26087
26158
  // qqq let maxAbsCurvatures = [...maxCurvatureTs, ...maxNegativeCurvatureTs].map(t => new PointOnShape(curve, t));
26088
26159
  const maxAbsCurvatures = [...maxima].map(t => new PointOnShape(curve, t));
26089
26160
  allPoints.push(...getContactCirclesAtInterface(curve), ...maxAbsCurvatures);
26090
- let ts = splitByCurvatureAndLength(curve.ps, maxCurviness, maxLength);
26091
- if (ts.length === 2) {
26092
- ts = [0, 0.5, 1];
26093
- }
26161
+ const ts = splitByCurvatureAndLength(curve.ps, maxCurviness, maxLength);
26162
+ // if (ts.length > 10) { console.log(ts); }
26163
+ // if (ts.length === 2) {
26164
+ // ts = [0, 0.5, 1];
26165
+ // }
26094
26166
  for (let i = 1; i < ts.length - 1; i++) {
26095
26167
  allPoints.push(new PointOnShape(curve, ts[i]));
26096
26168
  }
@@ -28295,7 +28367,7 @@ function drawOneProng(g, pos, classes, delay = 0) {
28295
28367
 
28296
28368
  /** @hidden */
28297
28369
  function twoProng(g, twoProng) {
28298
- const scaleFactor = 0.3;
28370
+ const scaleFactor = 0.01;
28299
28371
  let $failedDot = [];
28300
28372
  let $center = [];
28301
28373
  let $circle = [];
@@ -28319,7 +28391,7 @@ function twoProng(g, twoProng) {
28319
28391
  $failedDot = drawFs.dot(g, twoProng.pos.p, 1 * scaleFactor, 'black');
28320
28392
  }
28321
28393
  else if (!twoProng.failed) {
28322
- $center = drawFs.dot(g, twoProng.circle.center, 1 * scaleFactor, 'yellow');
28394
+ $center = drawFs.dot(g, twoProng.circle.center, 0.02 * scaleFactor, 'yellow');
28323
28395
  $circle = drawFs.circle(g, twoProng.circle, color + 'thin' + thin + ' nofill');
28324
28396
  $cp1 = drawFs.dot(g, twoProng.pos.p, 0.035 * scaleFactor, color);
28325
28397
  $cp2 = drawFs.dot(g, twoProng.z, 0.07 * scaleFactor, color);
@@ -28332,7 +28404,7 @@ function twoProng(g, twoProng) {
28332
28404
 
28333
28405
 
28334
28406
  /** @hidden */
28335
- const three_prong_scaleFactor = 0.3;
28407
+ const three_prong_scaleFactor = 0.1;
28336
28408
  /** @hidden */
28337
28409
  function threeProng(g, threeProng) {
28338
28410
  const circle = scaleCircle(threeProng.circle, 1);