flo-mat 4.0.1 → 4.0.2

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 (132) hide show
  1. package/README.md +1 -1
  2. package/__tests__/find-2-prong/get-medial/get-closest-points.spec.ts +49 -0
  3. package/browser/index.js +1153 -1205
  4. package/browser/index.min.js +1 -1
  5. package/node/closest-boundary-point/foot-and-endpoint-info.d.ts +0 -3
  6. package/node/closest-boundary-point/get-close-boundary-points-certified.d.ts +1 -1
  7. package/node/closest-boundary-point/get-close-boundary-points-certified.js +2 -2
  8. package/node/closest-boundary-point/get-close-boundary-points-certified.js.map +1 -1
  9. package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.d.ts +1 -2
  10. package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.js +34 -24
  11. package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.js.map +1 -1
  12. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.d.ts +1 -1
  13. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.js +6 -9
  14. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.js.map +1 -1
  15. package/node/cp-node/fs/insert-cp-node.d.ts +2 -2
  16. package/node/cp-node/fs/insert-cp-node.js.map +1 -1
  17. package/node/cp-node/fs/is-order-correct.d.ts +2 -2
  18. package/node/cp-node/fs/is-order-correct.js.map +1 -1
  19. package/node/cp-node/fs/traverse-cp.js.map +1 -1
  20. package/node/cp-node/fs/traverse-vertices.d.ts +1 -1
  21. package/node/cp-node/fs/traverse-vertices.js.map +1 -1
  22. package/node/debug/functions/draw-elem/draw-branch.d.ts +1 -1
  23. package/node/debug/functions/draw-elem/draw-branch.js.map +1 -1
  24. package/node/debug/functions/draw-elem/draw-cp-node.d.ts +1 -1
  25. package/node/debug/functions/draw-elem/draw-cp-node.js +2 -2
  26. package/node/debug/functions/draw-elem/draw-cp-node.js.map +1 -1
  27. package/node/debug/functions/draw-elem/draw-leaves.d.ts +1 -1
  28. package/node/debug/functions/draw-elem/draw-leaves.js +2 -2
  29. package/node/debug/functions/draw-elem/draw-leaves.js.map +1 -1
  30. package/node/debug/functions/draw-elem/draw-mat.d.ts +1 -1
  31. package/node/debug/functions/draw-elem/draw-mat.js +1 -2
  32. package/node/debug/functions/draw-elem/draw-mat.js.map +1 -1
  33. package/node/debug/functions/draw-elem/draw-min-y.d.ts +1 -1
  34. package/node/debug/functions/draw-elem/draw-min-y.js.map +1 -1
  35. package/node/debug/functions/draw-elem/draw-three-prong.d.ts +1 -1
  36. package/node/debug/functions/draw-elem/draw-three-prong.js +2 -2
  37. package/node/debug/functions/draw-elem/draw-three-prong.js.map +1 -1
  38. package/node/debug/functions/draw-elem/draw-vertex.d.ts +1 -1
  39. package/node/debug/functions/draw-elem/draw-vertex.js +0 -2
  40. package/node/debug/functions/draw-elem/draw-vertex.js.map +1 -1
  41. package/node/error-analysis/gamma.d.ts +32 -0
  42. package/node/error-analysis/gamma.js +39 -0
  43. package/node/error-analysis/gamma.js.map +1 -0
  44. package/node/find-2-prong/find-2-prong.js +5 -5
  45. package/node/find-2-prong/find-2-prong.js.map +1 -1
  46. package/node/find-2-prong/get-medial/get-closest-points.js +27 -23
  47. package/node/find-2-prong/get-medial/get-closest-points.js.map +1 -1
  48. package/node/find-3-prong/calc-better-x.d.ts +1 -1
  49. package/node/find-3-prong/calc-better-x.js +6 -4
  50. package/node/find-3-prong/calc-better-x.js.map +1 -1
  51. package/node/find-3-prong/calc-initial-3-prong-center.d.ts +1 -1
  52. package/node/find-3-prong/calc-initial-3-prong-center.js +4 -3
  53. package/node/find-3-prong/calc-initial-3-prong-center.js.map +1 -1
  54. package/node/find-3-prong/find-3-prong-for-delta3s.js +22 -5
  55. package/node/find-3-prong/find-3-prong-for-delta3s.js.map +1 -1
  56. package/node/find-3-prong/find-and-add-3-prong.d.ts +2 -2
  57. package/node/find-3-prong/find-and-add-3-prong.js +15 -0
  58. package/node/find-3-prong/find-and-add-3-prong.js.map +1 -1
  59. package/node/find-3-prong/find-and-add-3-prongs-on-loop.js +8 -21
  60. package/node/find-3-prong/find-and-add-3-prongs-on-loop.js.map +1 -1
  61. package/node/find-3-prong/find-and-add-3-prongs.d.ts +1 -4
  62. package/node/find-3-prong/find-and-add-3-prongs.js +1 -2
  63. package/node/find-3-prong/find-and-add-3-prongs.js.map +1 -1
  64. package/node/find-3-prong/get-closest-points.d.ts +1 -1
  65. package/node/find-3-prong/get-closest-points.js +2 -2
  66. package/node/find-3-prong/get-closest-points.js.map +1 -1
  67. package/node/find-3-prong/timed-cc.d.ts +3 -0
  68. package/node/find-3-prong/timed-cc.js +5 -0
  69. package/node/find-3-prong/timed-cc.js.map +1 -0
  70. package/node/find-mat/create-initial-cp-tree.d.ts +2 -2
  71. package/node/find-mat/create-initial-cp-tree.js +2 -2
  72. package/node/find-mat/create-initial-cp-tree.js.map +1 -1
  73. package/node/find-mat/find-mat.d.ts +4 -4
  74. package/node/find-mat/find-mat.js.map +1 -1
  75. package/node/find-mat/find-mats.js +2 -2
  76. package/node/find-mat/find-mats.js.map +1 -1
  77. package/node/find-mat/get-meta.d.ts +2 -2
  78. package/node/find-mat/get-meta.js +1 -0
  79. package/node/find-mat/get-meta.js.map +1 -1
  80. package/node/index.d.ts +1 -0
  81. package/node/index.js +1 -0
  82. package/node/index.js.map +1 -1
  83. package/node/mat/create-new-cp-trees.d.ts +2 -2
  84. package/node/mat/create-new-cp-trees.js +2 -2
  85. package/node/mat/create-new-cp-trees.js.map +1 -1
  86. package/node/mat/get-cp-node-to-left-or-same.d.ts +2 -2
  87. package/node/mat/get-cp-node-to-left-or-same.js +2 -1
  88. package/node/mat/get-cp-node-to-left-or-same.js.map +1 -1
  89. package/node/mat/mat-meta.d.ts +2 -2
  90. package/node/point-on-shape/get-osculating-circle.js +2 -1
  91. package/node/point-on-shape/get-osculating-circle.js.map +1 -1
  92. package/package.json +5 -6
  93. package/src/closest-boundary-point/foot-and-endpoint-info.ts +0 -3
  94. package/src/closest-boundary-point/get-close-boundary-points-certified.ts +0 -2
  95. package/src/closest-boundary-point/get-potential-closest-points-on-curve-certified.ts +41 -27
  96. package/src/closest-boundary-point/root-interval-to-distance-squared-interval.ts +5 -10
  97. package/src/cp-node/fs/insert-cp-node.ts +2 -2
  98. package/src/cp-node/fs/is-order-correct.ts +2 -2
  99. package/src/cp-node/fs/traverse-cp.ts +1 -1
  100. package/src/cp-node/fs/traverse-vertices.ts +1 -2
  101. package/src/debug/functions/check-ordering.ts +0 -1
  102. package/src/debug/functions/draw-elem/draw-branch.ts +1 -3
  103. package/src/debug/functions/draw-elem/draw-cp-node.ts +3 -4
  104. package/src/debug/functions/draw-elem/draw-leaves.ts +3 -3
  105. package/src/debug/functions/draw-elem/draw-mat.ts +2 -5
  106. package/src/debug/functions/draw-elem/draw-min-y.ts +2 -2
  107. package/src/debug/functions/draw-elem/draw-three-prong.ts +3 -3
  108. package/src/debug/functions/draw-elem/draw-vertex.ts +1 -4
  109. package/src/error-analysis/gamma.ts +9 -2
  110. package/src/find-2-prong/find-2-prong.ts +7 -6
  111. package/src/find-2-prong/get-medial/get-closest-points.ts +24 -26
  112. package/src/find-3-prong/calc-better-x.ts +7 -4
  113. package/src/find-3-prong/calc-initial-3-prong-center.ts +2 -3
  114. package/src/find-3-prong/find-3-prong-for-delta3s.ts +23 -5
  115. package/src/find-3-prong/find-and-add-3-prong.ts +18 -4
  116. package/src/find-3-prong/find-and-add-3-prongs-on-loop.ts +7 -23
  117. package/src/find-3-prong/find-and-add-3-prongs.ts +5 -3
  118. package/src/find-3-prong/get-closest-points.ts +0 -2
  119. package/src/find-3-prong/timed-cc.ts +9 -0
  120. package/src/find-mat/create-initial-cp-tree.ts +3 -3
  121. package/src/find-mat/find-mat.ts +5 -6
  122. package/src/find-mat/find-mats.ts +4 -2
  123. package/src/find-mat/get-meta.ts +3 -3
  124. package/src/index.ts +2 -1
  125. package/src/mat/create-new-cp-trees.ts +3 -3
  126. package/src/mat/get-cp-node-to-left-or-same.ts +4 -3
  127. package/src/mat/mat-meta.ts +2 -2
  128. package/src/point-on-shape/get-osculating-circle.ts +2 -1
  129. package/wallaby.mjs +1 -0
  130. package/node/closest-boundary-point/get-p-from-box.d.ts +0 -3
  131. package/node/closest-boundary-point/get-p-from-box.js +0 -11
  132. package/node/closest-boundary-point/get-p-from-box.js.map +0 -1
package/browser/index.js CHANGED
@@ -2693,8 +2693,6 @@ function twoDiff(a, b) {
2693
2693
  //# sourceMappingURL=two-diff.js.map
2694
2694
  ;// ./node_modules/big-float-ts/node/double-expansion/fast-expansion-sum.js
2695
2695
  // import { eCompress } from "./e-compress.js";
2696
- // We *have* to do the below❗ The assignee is a getter❗ The assigned is a pure function❗
2697
- // const compress = eCompress;
2698
2696
  /**
2699
2697
  * Returns the result of adding two expansions.
2700
2698
  *
@@ -2837,20 +2835,7 @@ function merge(e, f) {
2837
2835
 
2838
2836
  //# sourceMappingURL=fast-expansion-sum.js.map
2839
2837
  ;// ./node_modules/big-float-ts/node/double-expansion/scale-expansion.js
2840
- /* unused harmony import specifier */ var twoProduct;
2841
- /* unused harmony import specifier */ var twoSum;
2842
- /* unused harmony import specifier */ var fastTwoSum;
2843
- /* unused harmony import specifier */ var eCompress;
2844
-
2845
-
2846
-
2847
-
2848
2838
  const f = 134217729; // 2**27 + 1;
2849
- // We *have* to do the below❗ The assignee is a getter❗ The assigned is a pure function❗
2850
- const tp = (/* unused pure expression or super */ null && (twoProduct));
2851
- const ts = (/* unused pure expression or super */ null && (twoSum));
2852
- const fts = (/* unused pure expression or super */ null && (fastTwoSum));
2853
- const compress = (/* unused pure expression or super */ null && (eCompress));
2854
2839
  /**
2855
2840
  * Returns the result of multiplying an expansion by a double.
2856
2841
  *
@@ -3012,18 +2997,13 @@ function scaleExpansion2(b, e) {
3012
2997
 
3013
2998
  //# sourceMappingURL=scale-expansion.js.map
3014
2999
  ;// ./node_modules/big-float-ts/node/double-expansion/expansion-product.js
3015
- /* unused harmony import specifier */ var expansion_product_eCompress;
3016
3000
 
3017
3001
 
3018
-
3019
- // We *have* to do the below❗ The assignee is a getter❗ The assigned is a pure function❗
3020
- const multByDouble = scaleExpansion;
3021
- const add = fastExpansionSum;
3022
- const expansion_product_compress = (/* unused pure expression or super */ null && (expansion_product_eCompress));
3023
3002
  /**
3024
3003
  * Returns the product of two double floating point expansions.
3025
3004
  *
3026
3005
  * * see [Shewchuk](https://people.eecs.berkeley.edu/~jrs/papers/robustr.pdf)
3006
+ * * the result is not compressed, call `eCompress` on the result if required.
3027
3007
  *
3028
3008
  * As per Shewchuk in the above paper: "To find the product of two expansions
3029
3009
  * e and f, use SCALE-EXPANSION (with zero elimination) to form the expansions
@@ -3040,9 +3020,8 @@ const expansion_product_compress = (/* unused pure expression or super */ null &
3040
3020
  function expansionProduct(e, f) {
3041
3021
  let sum = [0];
3042
3022
  for (let i = 0; i < e.length; i++) {
3043
- sum = add(sum, multByDouble(f, e[i]));
3023
+ sum = fastExpansionSum(sum, scaleExpansion(f, e[i]));
3044
3024
  }
3045
- //return compress(sum);
3046
3025
  return sum;
3047
3026
  }
3048
3027
 
@@ -3091,9 +3070,6 @@ function eNegativeOf(e) {
3091
3070
  ;// ./node_modules/big-float-ts/node/double-expansion/e-diff.js
3092
3071
 
3093
3072
 
3094
- // We *have* to do the below❗ The assignee is a getter❗ The assigned is a pure function❗
3095
- const negativeOf = eNegativeOf;
3096
- const e_diff_add = fastExpansionSum;
3097
3073
  /**
3098
3074
  * Returns the difference between two floating point expansions, i.e. e - f.
3099
3075
  *
@@ -3103,8 +3079,8 @@ const e_diff_add = fastExpansionSum;
3103
3079
  * @param f another floating point expansion
3104
3080
  */
3105
3081
  function eDiff(e, f) {
3106
- const g = negativeOf(f);
3107
- return e_diff_add(e, g);
3082
+ const g = eNegativeOf(f);
3083
+ return fastExpansionSum(e, g);
3108
3084
  }
3109
3085
 
3110
3086
  //# sourceMappingURL=e-diff.js.map
@@ -3197,7 +3173,7 @@ function tangentAt0Exact(ps) {
3197
3173
  *
3198
3174
  * See https://people.eecs.berkeley.edu/~jrs/papers/robustr.pdf
3199
3175
  */
3200
- function two_sum_twoSum(a, b) {
3176
+ function twoSum(a, b) {
3201
3177
  const x = a + b;
3202
3178
  const bv = x - a;
3203
3179
  return [(a - (x - bv)) + (b - bv), x];
@@ -3207,10 +3183,6 @@ function two_sum_twoSum(a, b) {
3207
3183
 
3208
3184
  //# sourceMappingURL=two-sum.js.map
3209
3185
  ;// ./node_modules/big-float-ts/node/double-expansion/grow-expansion.js
3210
- /* unused harmony import specifier */ var grow_expansion_eCompress;
3211
-
3212
- // We *have* to do the below❗ The assignee is a getter❗ The assigned is a pure function❗
3213
- const grow_expansion_compress = (/* unused pure expression or super */ null && (grow_expansion_eCompress));
3214
3186
  /**
3215
3187
  * Returns the result of adding a double to an expansion.
3216
3188
  *
@@ -3256,7 +3228,7 @@ function growExpansion(e, b) {
3256
3228
  //# sourceMappingURL=grow-expansion.js.map
3257
3229
  ;// ./node_modules/flo-bezier3/node/local-properties-at-t/evaluate-2nd-derivative/exact/evaluate-2nd-derivative-at-0-exact.js
3258
3230
 
3259
- const evaluate_2nd_derivative_at_0_exact_ts = two_sum_twoSum;
3231
+ const ts = twoSum;
3260
3232
  const evaluate_2nd_derivative_at_0_exact_sce = scaleExpansion2;
3261
3233
  const ge = growExpansion;
3262
3234
  /**
@@ -3271,15 +3243,15 @@ function evaluate2ndDerivativeAt0Exact(ps) {
3271
3243
  if (ps.length === 4) {
3272
3244
  const [[x0, y0], [x1, y1], [x2, y2]] = ps;
3273
3245
  return [
3274
- evaluate_2nd_derivative_at_0_exact_sce(6, ge(evaluate_2nd_derivative_at_0_exact_ts(x2, x0), -2 * x1)),
3275
- evaluate_2nd_derivative_at_0_exact_sce(6, ge(evaluate_2nd_derivative_at_0_exact_ts(y2, y0), -2 * y1))
3246
+ evaluate_2nd_derivative_at_0_exact_sce(6, ge(ts(x2, x0), -2 * x1)),
3247
+ evaluate_2nd_derivative_at_0_exact_sce(6, ge(ts(y2, y0), -2 * y1))
3276
3248
  ];
3277
3249
  }
3278
3250
  if (ps.length === 3) {
3279
3251
  const [[x0, y0], [x1, y1], [x2, y2]] = ps;
3280
3252
  return [
3281
- ge(evaluate_2nd_derivative_at_0_exact_ts(2 * x2, 2 * x0), -4 * x1),
3282
- ge(evaluate_2nd_derivative_at_0_exact_ts(2 * y2, 2 * y0), -4 * y1)
3253
+ ge(ts(2 * x2, 2 * x0), -4 * x1),
3254
+ ge(ts(2 * y2, 2 * y0), -4 * y1)
3283
3255
  ];
3284
3256
  }
3285
3257
  if (ps.length <= 2) {
@@ -4151,6 +4123,7 @@ const GAUSS_CONSTANTS = {
4151
4123
  ;// ./node_modules/flo-bezier3/node/local-properties-at-t/ds.js
4152
4124
 
4153
4125
 
4126
+ const { sqrt } = Math;
4154
4127
  /**
4155
4128
  * Returns `ds` (the length differential) for a linear, quadratic or cubic
4156
4129
  * bezier curve.
@@ -4167,13 +4140,13 @@ function ds(ps) {
4167
4140
  return function (t) {
4168
4141
  const dx = Horner(dX, t);
4169
4142
  const dy = Horner(dY, t);
4170
- return Math.sqrt(dx * dx + dy * dy);
4143
+ return sqrt(dx * dx + dy * dy);
4171
4144
  };
4172
4145
  }
4173
4146
 
4174
4147
  //# sourceMappingURL=ds.js.map
4175
4148
  ;// ./node_modules/flo-bezier3/node/transformation/split/from-to/from-to-2-incl-error-bound.js
4176
- const from_to_2_incl_error_bound_abs = Math.abs;
4149
+ const { abs: from_to_2_incl_error_bound_abs } = Math;
4177
4150
  /** error free error bounds */
4178
4151
  const psErrorFree = [[0, 0], [0, 0], [0, 0]];
4179
4152
  /**
@@ -4456,7 +4429,7 @@ const two_product_f = 134217729; // 2**27 + 1;
4456
4429
  * @param a A double
4457
4430
  * @param b Another double
4458
4431
  */
4459
- function two_product_twoProduct(a, b) {
4432
+ function twoProduct(a, b) {
4460
4433
  const x = a * b;
4461
4434
  //const [ah, al] = split(a);
4462
4435
  const c = two_product_f * a;
@@ -4558,7 +4531,7 @@ function ddDiffDd(x, y) {
4558
4531
 
4559
4532
 
4560
4533
  const { atan2 } = Math;
4561
- const get_interface_rotation_tp = two_product_twoProduct;
4534
+ const tp = twoProduct;
4562
4535
  /**
4563
4536
  * Returns the rotation angle (-𝜋 <= θ <= 𝜋 *guaranteed*) from some vector to
4564
4537
  * another vector considering them to both start at the same point.
@@ -4580,9 +4553,9 @@ function getInterfaceRotation(a, b) {
4580
4553
  const w1 = b[0];
4581
4554
  const w2 = b[1];
4582
4555
  // w2*v1 - w1*v2;
4583
- const A = ddDiffDd(get_interface_rotation_tp(w2, v1), get_interface_rotation_tp(w1, v2))[1];
4556
+ const A = ddDiffDd(tp(w2, v1), tp(w1, v2))[1];
4584
4557
  // w1*v1 + w2*v2;
4585
- const B = ddAddDd(get_interface_rotation_tp(w1, v1), get_interface_rotation_tp(w2, v2))[1];
4558
+ const B = ddAddDd(tp(w1, v1), tp(w2, v2))[1];
4586
4559
  return atan2(A, B);
4587
4560
  }
4588
4561
 
@@ -4677,6 +4650,7 @@ function splitByCurvature(ps, maxCurviness = 0.4, minTSpan = 2 ** -16) {
4677
4650
 
4678
4651
 
4679
4652
 
4653
+ const { sqrt: length_bez2_sqrt, log } = Math;
4680
4654
  /**
4681
4655
  * Returns the curve length of the given quadratic bezier curve within the
4682
4656
  * specified parameter interval.
@@ -4747,22 +4721,22 @@ function lengthBez2(interval: number[], ps: number[][]) {
4747
4721
  const B = 4 * (ax*bx + ay*by);
4748
4722
  const C = bx*bx + by*by;
4749
4723
 
4750
- const Sabc = 2*Math.sqrt(A+B+C);
4751
- const A_2 = Math.sqrt(A);
4724
+ const Sabc = 2*sqrt(A+B+C);
4725
+ const A_2 = sqrt(A);
4752
4726
  const A_32 = 2*A*A_2;
4753
- const C_2 = 2*Math.sqrt(C);
4727
+ const C_2 = 2*sqrt(C);
4754
4728
  const BA = B/A_2;
4755
4729
 
4756
4730
  return (
4757
4731
  A_32*Sabc + A_2*B*(Sabc - C_2) +
4758
- (4*C*A - B*B)*Math.log((2*A_2 + BA + Sabc) / (BA + C_2))
4732
+ (4*C*A - B*B)*log((2*A_2 + BA + Sabc) / (BA + C_2))
4759
4733
  ) / (4*A_32);
4760
4734
  }
4761
4735
  */
4762
4736
 
4763
4737
  //# sourceMappingURL=length-bez2.js.map
4764
4738
  ;// ./node_modules/flo-bezier3/node/transformation/split/from-to/from-to-3-incl-error-bound.js
4765
- const from_to_3_incl_error_bound_abs = Math.abs;
4739
+ const { abs: from_to_3_incl_error_bound_abs } = Math;
4766
4740
  /** error free error bounds */
4767
4741
  const from_to_3_incl_error_bound_psErrorFree = [[0, 0], [0, 0], [0, 0], [0, 0]];
4768
4742
  /**
@@ -5802,23 +5776,23 @@ function removeLeadingZeroCoeffs(pDd, pDd_, getPExact, errorMultiplier) {
5802
5776
  //# sourceMappingURL=remove-leading-zero-coeffs.js.map
5803
5777
  ;// ./node_modules/big-float-ts/node/double-expansion/e-compress.js
5804
5778
  /**
5805
- * Returns the result of compressing the given floating point expansion.
5806
- *
5807
- * * primarily for internal library use
5779
+ * Returns the result of compressing the given Shewchuk floating point expansion.
5808
5780
  *
5809
5781
  * * see [Shewchuk](https://people.eecs.berkeley.edu/~jrs/papers/robustr.pdf)
5810
5782
  *
5811
- * Theorem 23 (Shewchuck): Let e = sum_(i=1)^m(e_i) be a nonoverlapping
5812
- * expansion of m p-bit components, where m >= 3. Suppose that the components of
5813
- * e are sorted in order of increasing magnitude, except that any of the e_i may
5814
- * be zero. Then the following algorithm will produce a nonoverlapping expansion
5783
+ * Theorem 23 (Shewchuk): Let `e = sum_(i=1)^m(e_i)` be a nonoverlapping
5784
+ * expansion of m p-bit components, where m >= 3.
5785
+ *
5786
+ * Suppose that the components of `e` are sorted in order of increasing magnitude,
5787
+ * except that any of the e_i may be zero.
5788
+ *
5789
+ * Then the following algorithm will produce a nonoverlapping expansion
5815
5790
  * (nonadjacent if round-to even tiebreaking is used) such that
5816
- * h = sum_(i=1)^n(h_i) = e, where the components h_i are in order of increasing
5817
- * magnitude. If h != 0, none of the h_i will be zero. Furthermore, the largest
5818
- * component h_n approximates h with an error smaller than ulp(h_n).
5791
+ * `h = sum_(i=1)^n(h_i) = e`, where the components `h_i` are in order of increasing
5792
+ * magnitude. If `h != 0`, none of the `h_i` will be zero. Furthermore, the largest
5793
+ * component `h_n` approximates `h` with an error smaller than `ulp(h_n)`.
5819
5794
  */
5820
- function e_compress_eCompress(e) {
5821
- //return e;
5795
+ function eCompress(e) {
5822
5796
  const e_ = e.slice();
5823
5797
  const m = e_.length;
5824
5798
  if (m === 1) {
@@ -6324,7 +6298,7 @@ function eTaylorShift(p, h) {
6324
6298
  const q = p.slice();
6325
6299
  for (let k = 0; k <= n; k++) {
6326
6300
  for (let i = 1; i <= n - k; i++) {
6327
- q[i] = e_compress_eCompress(fastExpansionSum(q[i], scaleExpansion(q[i - 1], h)));
6301
+ q[i] = eCompress(fastExpansionSum(q[i], scaleExpansion(q[i - 1], h)));
6328
6302
  }
6329
6303
  }
6330
6304
  return q;
@@ -6582,7 +6556,7 @@ const basic_two_product_f = 134217729; // 2**27 + 1;
6582
6556
  * @param a A double
6583
6557
  * @param b Another double
6584
6558
  */
6585
- function basic_two_product_twoProduct(a, b) {
6559
+ function two_product_twoProduct(a, b) {
6586
6560
  const x = a * b;
6587
6561
  //const [ah, al] = split(a);
6588
6562
  const c = basic_two_product_f * a;
@@ -6632,8 +6606,8 @@ function EFTHorner(p, x) {
6632
6606
  let σ;
6633
6607
  let r̂ = p[0];
6634
6608
  for (let i = 1; i < p.length; i++) {
6635
- const [π, pi] = basic_two_product_twoProduct(r̂, x);
6636
- [σ, r̂] = two_sum_twoSum(pi, p[i]);
6609
+ const [π, pi] = two_product_twoProduct(r̂, x);
6610
+ [σ, r̂] = twoSum(pi, p[i]);
6637
6611
  // inlined
6638
6612
  //r̂ = pi + p[i]; const bv = r̂ - pi; σ = (pi - (x-bv)) + (p[i]-bv);
6639
6613
  pπ.push(π);
@@ -7284,7 +7258,7 @@ function eAdmissablePoint(pE, a, b) {
7284
7258
  d *= 2;
7285
7259
  for (let j = 1; j < d; j += 2) {
7286
7260
  const t = a + (b - a) * (d + 2 * j) / (4 * d);
7287
- const T = e_compress_eCompress(eHorner(pE, t)); // no error
7261
+ const T = eCompress(eHorner(pE, t)); // no error
7288
7262
  const $T = T[T.length - 1];
7289
7263
  // If we can certify the sign of `p(t)` then don't waste time
7290
7264
  // looking for the best point.
@@ -9034,7 +9008,7 @@ function ddMultByNeg2(f) {
9034
9008
  //# sourceMappingURL=dd-mult-by-neg-2.js.map
9035
9009
  ;// ./node_modules/flo-boolean/node_modules/flo-bezier3/node/simultaneous-properties/closest-and-furthest-point-on-bezier/get-coeffs/double-double/get-footpoint-poly-1-dd.js
9036
9010
 
9037
- const get_footpoint_poly_1_dd_tp = two_product_twoProduct;
9011
+ const get_footpoint_poly_1_dd_tp = twoProduct;
9038
9012
  const get_footpoint_poly_1_dd_qaq = ddAddDd;
9039
9013
  const qmn2 = ddMultByNeg2;
9040
9014
  /**
@@ -9207,7 +9181,7 @@ function getFootpointPoly3Exact(ps, p) {
9207
9181
  const t0a = eDiff(x01, get_footpoint_poly_3_exact_sce(6, x00));
9208
9182
  const t0b = eDiff(y01, get_footpoint_poly_3_exact_sce(6, y00));
9209
9183
  const t0 = fastExpansionSum(t0a, t0b);
9210
- return [t5, t4, t3, t2, t1, t0].map(e_compress_eCompress);
9184
+ return [t5, t4, t3, t2, t1, t0].map(eCompress);
9211
9185
  }
9212
9186
 
9213
9187
  //# sourceMappingURL=get-footpoint-poly-3-exact.js.map
@@ -9293,7 +9267,7 @@ function getFootpointPoly2Exact(ps, p) {
9293
9267
  const t0a = eDiff(y01, y00);
9294
9268
  const t0b = eDiff(x01, x00);
9295
9269
  const t0 = fastExpansionSum(t0a, t0b);
9296
- return [t3, t2, t1, t0].map(e_compress_eCompress);
9270
+ return [t3, t2, t1, t0].map(eCompress);
9297
9271
  }
9298
9272
 
9299
9273
  //# sourceMappingURL=get-footpoint-poly-2-exact.js.map
@@ -9336,7 +9310,7 @@ function getFootpointPoly1Exact(ps, p) {
9336
9310
  const t1 = fastExpansionSum(fastExpansionSum(x11, y11), fastExpansionSum(get_footpoint_poly_1_exact_emn2(s1), s2));
9337
9311
  //const t0 = s1 - s2;
9338
9312
  const t0 = eDiff(s1, s2);
9339
- return [t1, t0].map(e_compress_eCompress);
9313
+ return [t1, t0].map(eCompress);
9340
9314
  }
9341
9315
 
9342
9316
  //# sourceMappingURL=get-footpoint-poly-1-exact.js.map
@@ -9701,7 +9675,7 @@ function getFootPointsOnBezierPolysCertified(ps, p) {
9701
9675
 
9702
9676
 
9703
9677
 
9704
- const { sqrt } = Math;
9678
+ const { sqrt: closest_point_on_bezier_certified_sqrt } = Math;
9705
9679
  /**
9706
9680
  * Returns the closest point(s) (and parameter `t` value(s)) on the given
9707
9681
  * bezier curve to the given point (with `t ∈ [0,1]`).
@@ -9736,7 +9710,7 @@ function closestPointOnBezierCertified(ps, p, lb = 0, ub = 1) {
9736
9710
  return {
9737
9711
  p: getPFromBox(box),
9738
9712
  t: ri.t,
9739
- d: (sqrt(dSquaredI[0]) + sqrt(dSquaredI[1])) / 2,
9713
+ d: (closest_point_on_bezier_certified_sqrt(dSquaredI[0]) + closest_point_on_bezier_certified_sqrt(dSquaredI[1])) / 2,
9740
9714
  dSquaredI,
9741
9715
  box,
9742
9716
  ri
@@ -9823,19 +9797,20 @@ function containerIsBasic(container) {
9823
9797
  //# sourceMappingURL=container.js.map
9824
9798
  ;// ./node_modules/big-float-ts/node/double-expansion/e-to-double-double.js
9825
9799
 
9826
- // We *have* to do the below❗ The assignee is a getter❗ The assigned is a pure function❗
9827
- const e_to_double_double_compress = e_compress_eCompress;
9828
9800
  /**
9829
9801
  * Returns the result of converting a floating point expansion to a
9830
9802
  * double-double precision floating point number.
9803
+ *
9804
+ * * uses truncation to convert thus accurate to within 1 ulp on low double;
9805
+ * (a slower summing method could reduce the max error to 1/2 ulp)
9831
9806
  */
9832
9807
  function eToDd(e) {
9833
- e = e_to_double_double_compress(e);
9808
+ e = eCompress(e);
9834
9809
  const len = e.length;
9835
9810
  if (len === 2) {
9836
9811
  return e; // already a double-double
9837
9812
  }
9838
- else if (len === 1) {
9813
+ else if (len <= 1) {
9839
9814
  return [0, e[0]]; // double-doubles have a fixed length of 2
9840
9815
  }
9841
9816
  return [e[len - 2], e[len - 1]]; // return only most significant parts
@@ -9920,8 +9895,8 @@ function refineK1(ri, p) {
9920
9895
  const ris = [];
9921
9896
  for (const riLo of risLo) {
9922
9897
  ris.push({
9923
- tS: two_sum_twoSum(tS, riLo.tS * δ),
9924
- tE: two_sum_twoSum(tS, riLo.tE * δ),
9898
+ tS: twoSum(tS, riLo.tS * δ),
9899
+ tE: twoSum(tS, riLo.tE * δ),
9925
9900
  multiplicity: riLo.multiplicity
9926
9901
  });
9927
9902
  }
@@ -12139,7 +12114,7 @@ function getImplicitForm2DdWithRunningError(ps) {
12139
12114
 
12140
12115
 
12141
12116
 
12142
- const get_coeffs_bez2_bez1_dd_tp = two_product_twoProduct;
12117
+ const get_coeffs_bez2_bez1_dd_tp = twoProduct;
12143
12118
  const get_coeffs_bez2_bez1_dd_qm2 = ddMultBy2;
12144
12119
  const get_coeffs_bez2_bez1_dd_qmd = ddMultDouble2;
12145
12120
  const get_coeffs_bez2_bez1_dd_qmq = ddMultDd;
@@ -12638,7 +12613,7 @@ function getImplicitForm3DdWithRunningError(ps) {
12638
12613
 
12639
12614
 
12640
12615
 
12641
- const get_coeffs_bez3_bez1_dd_tp = two_product_twoProduct;
12616
+ const get_coeffs_bez3_bez1_dd_tp = twoProduct;
12642
12617
  const get_coeffs_bez3_bez1_dd_qm2 = ddMultBy2;
12643
12618
  const get_coeffs_bez3_bez1_dd_qmd = ddMultDouble2;
12644
12619
  const get_coeffs_bez3_bez1_dd_qmq = ddMultDd;
@@ -13046,7 +13021,7 @@ function getCoeffsBez1Bez2Dd(ps1, ps2) {
13046
13021
 
13047
13022
 
13048
13023
 
13049
- const get_coeffs_bez2_bez2_dd_tp = two_product_twoProduct;
13024
+ const get_coeffs_bez2_bez2_dd_tp = twoProduct;
13050
13025
  const get_coeffs_bez2_bez2_dd_qm2 = ddMultBy2;
13051
13026
  const get_coeffs_bez2_bez2_dd_qmd = ddMultDouble2;
13052
13027
  const get_coeffs_bez2_bez2_dd_qmq = ddMultDd;
@@ -13347,7 +13322,7 @@ function getCoeffsBez2Bez2Dd(ps1, ps2) {
13347
13322
 
13348
13323
 
13349
13324
 
13350
- const get_coeffs_bez3_bez2_dd_tp = two_product_twoProduct;
13325
+ const get_coeffs_bez3_bez2_dd_tp = twoProduct;
13351
13326
  const get_coeffs_bez3_bez2_dd_qm2 = ddMultBy2;
13352
13327
  const get_coeffs_bez3_bez2_dd_qmd = ddMultDouble2;
13353
13328
  const get_coeffs_bez3_bez2_dd_qmq = ddMultDd;
@@ -14154,7 +14129,7 @@ function getCoeffsBez1Bez3Dd(ps1, ps2) {
14154
14129
 
14155
14130
 
14156
14131
 
14157
- const get_coeffs_bez2_bez3_dd_tp = two_product_twoProduct;
14132
+ const get_coeffs_bez2_bez3_dd_tp = twoProduct;
14158
14133
  const get_coeffs_bez2_bez3_dd_qm2 = ddMultBy2;
14159
14134
  const get_coeffs_bez2_bez3_dd_qmd = ddMultDouble2;
14160
14135
  const get_coeffs_bez2_bez3_dd_qmq = ddMultDd;
@@ -14592,7 +14567,7 @@ function getCoeffsBez2Bez3Dd(ps1, ps2) {
14592
14567
 
14593
14568
 
14594
14569
 
14595
- const get_coeffs_bez3_bez3_dd_tp = two_product_twoProduct;
14570
+ const get_coeffs_bez3_bez3_dd_tp = twoProduct;
14596
14571
  const get_coeffs_bez3_bez3_dd_qm2 = ddMultBy2;
14597
14572
  const get_coeffs_bez3_bez3_dd_qmd = ddMultDouble2;
14598
14573
  const get_coeffs_bez3_bez3_dd_qmq = ddMultDd;
@@ -15853,7 +15828,7 @@ function getCoeffsBez3Bez3Dd(ps1, ps2) {
15853
15828
  ;// ./node_modules/flo-boolean/node_modules/flo-bezier3/node/to-power-basis/to-power-basis/exact/to-power-basis-exact.js
15854
15829
 
15855
15830
  const to_power_basis_exact_td = twoDiff;
15856
- const to_power_basis_exact_ts = two_sum_twoSum;
15831
+ const to_power_basis_exact_ts = twoSum;
15857
15832
  const to_power_basis_exact_sce = scaleExpansion2;
15858
15833
  const to_power_basis_exact_ge = growExpansion;
15859
15834
  /**
@@ -15902,7 +15877,7 @@ function toPowerBasis3Exact(ps) {
15902
15877
  to_power_basis_exact_sce(3, to_power_basis_exact_td(x1, x0)),
15903
15878
  // x0
15904
15879
  [x0]
15905
- ].map(e_compress_eCompress),
15880
+ ].map(eCompress),
15906
15881
  [
15907
15882
  //ge(ge(sce(3, td(y1, y2)), y3), -y0),
15908
15883
  fastExpansionSum(to_power_basis_exact_td(y3, y0), to_power_basis_exact_sce(3, to_power_basis_exact_td(y1, y2))),
@@ -15910,7 +15885,7 @@ function toPowerBasis3Exact(ps) {
15910
15885
  to_power_basis_exact_sce(3, to_power_basis_exact_ge(to_power_basis_exact_ts(y2, y0), -2 * y1)),
15911
15886
  to_power_basis_exact_sce(3, to_power_basis_exact_td(y1, y0)),
15912
15887
  [y0]
15913
- ].map(e_compress_eCompress)
15888
+ ].map(eCompress)
15914
15889
  ];
15915
15890
  }
15916
15891
  /** @internal */
@@ -15992,7 +15967,7 @@ function getImplicitForm1ExactPb(pspb) {
15992
15967
  const vₓ = get_implicit_form1_exact_eno(b1);
15993
15968
  const vᵧ = a1;
15994
15969
  //const v = a1*b0 - a0*b1;
15995
- const v = e_compress_eCompress(eDiff(get_implicit_form1_exact_sce(a0, b1), get_implicit_form1_exact_sce(b0, a1)));
15970
+ const v = eCompress(eDiff(get_implicit_form1_exact_sce(a0, b1), get_implicit_form1_exact_sce(b0, a1)));
15996
15971
  return { vₓ, vᵧ, v };
15997
15972
  }
15998
15973
 
@@ -16050,7 +16025,7 @@ function getCoeffsBez1Bez1Exact(ps1, ps2) {
16050
16025
  const p5 = fes(p3, p4);
16051
16026
  const v0 = fes(p5, v);
16052
16027
  const r = [v1, v0];
16053
- return r.map(e_compress_eCompress);
16028
+ return r.map(eCompress);
16054
16029
  }
16055
16030
 
16056
16031
  //# sourceMappingURL=get-coeffs-bez1-bez1-exact.js.map
@@ -16109,29 +16084,29 @@ function getImplicitForm2ExactPb(pspb) {
16109
16084
  // -a1*q1*y - a2**2*y**2 + 2*a2*b2*x*y + 2*a2*q2*y + b1*q1*x - b2**2*x**2 - 2*b2*q2*x + q1*q3 - q2**2
16110
16085
  // b2**2*x**2
16111
16086
  // -b2**2 *x**2
16112
- const vₓₓ = e_compress_eCompress(get_implicit_form2_exact_eno(b2b2));
16087
+ const vₓₓ = eCompress(get_implicit_form2_exact_eno(b2b2));
16113
16088
  // -2*a2*b2*x*y
16114
16089
  // 2*a2*b2 *x*y
16115
- const vₓᵧ = e_compress_eCompress(get_implicit_form2_exact_em2(a2b2));
16090
+ const vₓᵧ = eCompress(get_implicit_form2_exact_em2(a2b2));
16116
16091
  // a2**2*y**2
16117
16092
  // -a2**2 *y**2
16118
- const vᵧᵧ = e_compress_eCompress(get_implicit_form2_exact_eno(a2a2));
16093
+ const vᵧᵧ = eCompress(get_implicit_form2_exact_eno(a2a2));
16119
16094
  // -2*a0*b2**2 + a1*b1*b2 + 2*a2*b0*b2 - a2*b1**2
16120
16095
  // (b1*q1 + -2*b2*q2) *x
16121
16096
  //const vₓ = b1*q1 - 2*b2*q2;
16122
16097
  const w1 = get_implicit_form2_exact_epr(b1, q1);
16123
16098
  const w2 = get_implicit_form2_exact_em2(get_implicit_form2_exact_epr(b2, q2));
16124
- const vₓ = e_compress_eCompress(edif(w1, w2));
16099
+ const vₓ = eCompress(edif(w1, w2));
16125
16100
  // 2*a0*a2*b2 - a1**2*b2 + a1*a2*b1 - 2*a2**2*b0
16126
16101
  // (-a1*q1 + 2*a2*q2) *y
16127
16102
  const w3 = get_implicit_form2_exact_em2(get_implicit_form2_exact_epr(a2, q2));
16128
16103
  const w4 = get_implicit_form2_exact_epr(a1, q1);
16129
- const vᵧ = e_compress_eCompress(edif(w3, w4));
16104
+ const vᵧ = eCompress(edif(w3, w4));
16130
16105
  // a0**2*b2**2 - a0*a1*b1*b2 - 2*a0*a2*b0*b2 + a0*a2*b1**2 + a1**2*b0*b2 - a1*a2*b0*b1 + a2**2*b0**2
16131
16106
  // q1*q3 + -q2**2
16132
16107
  const w5 = get_implicit_form2_exact_epr(q1, q3);
16133
16108
  const w6 = get_implicit_form2_exact_epr(q2, q2);
16134
- const v = e_compress_eCompress(edif(w5, w6));
16109
+ const v = eCompress(edif(w5, w6));
16135
16110
  //console.log({ vₓₓ, vₓᵧ, vᵧᵧ, vₓ, vᵧ, v })
16136
16111
  return { vₓₓ, vₓᵧ, vᵧᵧ, vₓ, vᵧ, v };
16137
16112
  }
@@ -16142,7 +16117,7 @@ function getImplicitForm2ExactPb(pspb) {
16142
16117
 
16143
16118
 
16144
16119
 
16145
- const get_coeffs_bez2_bez1_exact_tp = basic_two_product_twoProduct; // error -> 0
16120
+ const get_coeffs_bez2_bez1_exact_tp = two_product_twoProduct; // error -> 0
16146
16121
  const get_coeffs_bez2_bez1_exact_sce = scaleExpansion2;
16147
16122
  const get_coeffs_bez2_bez1_exact_epr = expansionProduct;
16148
16123
  const get_coeffs_bez2_bez1_exact_fes = fastExpansionSum;
@@ -16224,7 +16199,7 @@ function getCoeffsBez2Bez1Exact(ps1, ps2) {
16224
16199
  const pm = get_coeffs_bez2_bez1_exact_fes(pi, pl);
16225
16200
  const v0 = get_coeffs_bez2_bez1_exact_fes(pm, v);
16226
16201
  const r = [v2, v1, v0];
16227
- return r.map(e_compress_eCompress);
16202
+ return r.map(eCompress);
16228
16203
  }
16229
16204
 
16230
16205
  //# sourceMappingURL=get-coeffs-bez2-bez1-exact.js.map
@@ -16233,7 +16208,7 @@ function getCoeffsBez2Bez1Exact(ps1, ps2) {
16233
16208
  const cubic_to_quadratic_epr = expansionProduct;
16234
16209
  const cubic_to_quadratic_td = twoDiff;
16235
16210
  const cubic_to_quadratic_sce = scaleExpansion;
16236
- const cubic_to_quadratic_ts = two_sum_twoSum;
16211
+ const cubic_to_quadratic_ts = twoSum;
16237
16212
  /**
16238
16213
  * Returns a quadratic approximation to the given cubic bezier curve.
16239
16214
  *
@@ -16422,30 +16397,30 @@ function getImplicitForm3ExactPb(pspb) {
16422
16397
  const q3q4 = get_implicit_form3_exact_epr(q3, q4);
16423
16398
  const q3q5 = get_implicit_form3_exact_epr(q3, q5);
16424
16399
  const q3q6 = get_implicit_form3_exact_epr(q3, q6);
16425
- const vₓₓₓ = e_compress_eCompress(get_implicit_form3_exact_epr(get_implicit_form3_exact_eno(b3), b3b3));
16426
- const vₓₓᵧ = e_compress_eCompress(get_implicit_form3_exact_epr(get_implicit_form3_exact_sce(3, a3), b3b3));
16427
- const vₓᵧᵧ = e_compress_eCompress(get_implicit_form3_exact_epr(get_implicit_form3_exact_sce(-3, b3), a3a3));
16428
- const vᵧᵧᵧ = e_compress_eCompress(get_implicit_form3_exact_epr(a3, a3a3));
16400
+ const vₓₓₓ = eCompress(get_implicit_form3_exact_epr(get_implicit_form3_exact_eno(b3), b3b3));
16401
+ const vₓₓᵧ = eCompress(get_implicit_form3_exact_epr(get_implicit_form3_exact_sce(3, a3), b3b3));
16402
+ const vₓᵧᵧ = eCompress(get_implicit_form3_exact_epr(get_implicit_form3_exact_sce(-3, b3), a3a3));
16403
+ const vᵧᵧᵧ = eCompress(get_implicit_form3_exact_epr(a3, a3a3));
16429
16404
  const u1 = get_implicit_form3_exact_edif(get_implicit_form3_exact_sce(-3, q1), q5);
16430
16405
  //const vₓₓ = (u1*b3b3 + q3*(b1b3 - b2b2)) + tq2*b2b3;
16431
16406
  const w1 = get_implicit_form3_exact_epr(u1, b3b3);
16432
16407
  const w2 = get_implicit_form3_exact_epr(q3, t1);
16433
16408
  const w3 = get_implicit_form3_exact_fes(w1, w2);
16434
16409
  const w4 = get_implicit_form3_exact_epr(tq2, b2b3);
16435
- const vₓₓ = e_compress_eCompress(get_implicit_form3_exact_fes(w3, w4));
16410
+ const vₓₓ = eCompress(get_implicit_form3_exact_fes(w3, w4));
16436
16411
  //const vᵧᵧ = (u1*a3a3 + q3*t2) + tq2*a2a3;
16437
16412
  const w5 = get_implicit_form3_exact_epr(u1, a3a3);
16438
16413
  const w6 = get_implicit_form3_exact_epr(q3, t2);
16439
16414
  const w7 = get_implicit_form3_exact_fes(w5, w6);
16440
16415
  const w8 = get_implicit_form3_exact_epr(tq2, a2a3);
16441
- const vᵧᵧ = e_compress_eCompress(get_implicit_form3_exact_fes(w7, w8));
16416
+ const vᵧᵧ = eCompress(get_implicit_form3_exact_fes(w7, w8));
16442
16417
  //const vₓᵧ = 2*(q3*(a2b2 - p2/2) - (u1*a3b3 + q2*p1));
16443
16418
  const wa = get_implicit_form3_exact_edif(a2b2, ed2(p2));
16444
16419
  const wb = get_implicit_form3_exact_epr(u1, a3b3);
16445
16420
  const wc = get_implicit_form3_exact_epr(q2, p1);
16446
16421
  const wd = get_implicit_form3_exact_fes(wb, wc);
16447
16422
  const wq = get_implicit_form3_exact_epr(q3, wa);
16448
- const vₓᵧ = e_compress_eCompress(get_implicit_form3_exact_em2(get_implicit_form3_exact_edif(wq, wd)));
16423
+ const vₓᵧ = eCompress(get_implicit_form3_exact_em2(get_implicit_form3_exact_edif(wq, wd)));
16449
16424
  //const s1 = (-3*q1q1 - 2*q1q5) + (tq2q4 + q3q6);
16450
16425
  const wr = get_implicit_form3_exact_sce(-3, q1q1);
16451
16426
  const we = get_implicit_form3_exact_edif(wr, get_implicit_form3_exact_em2(q1q5));
@@ -16461,13 +16436,13 @@ function getImplicitForm3ExactPb(pspb) {
16461
16436
  const ws = get_implicit_form3_exact_epr(b2, s2);
16462
16437
  const wt = get_implicit_form3_exact_epr(b1, s3);
16463
16438
  const wn = get_implicit_form3_exact_fes(ws, wt);
16464
- const vₓ = e_compress_eCompress(get_implicit_form3_exact_fes(wm, wn));
16439
+ const vₓ = eCompress(get_implicit_form3_exact_fes(wm, wn));
16465
16440
  //const vᵧ = -a3*s1 - (a2*s2 + a1*s3);
16466
16441
  const wo = get_implicit_form3_exact_epr(a3, s1);
16467
16442
  const wu = get_implicit_form3_exact_epr(a2, s2);
16468
16443
  const wv = get_implicit_form3_exact_epr(a1, s3);
16469
16444
  const wp = get_implicit_form3_exact_fes(wu, wv);
16470
- const vᵧ = e_compress_eCompress(get_implicit_form3_exact_eno(get_implicit_form3_exact_fes(wo, wp)));
16445
+ const vᵧ = eCompress(get_implicit_form3_exact_eno(get_implicit_form3_exact_fes(wo, wp)));
16471
16446
  const v3 = get_implicit_form3_exact_edif(tq2q4, q1q1);
16472
16447
  const v1 = get_implicit_form3_exact_edif(v3, q1q5);
16473
16448
  const v4 = get_implicit_form3_exact_epr(s3, q6);
@@ -16475,7 +16450,7 @@ function getImplicitForm3ExactPb(pspb) {
16475
16450
  const v2 = get_implicit_form3_exact_edif(v4, v5);
16476
16451
  const v6 = get_implicit_form3_exact_epr(q1, v1);
16477
16452
  //const v = q1*(tq2q4 - q1q1 - q1q5) + s3*q6 - q3q4*q4;
16478
- const v = e_compress_eCompress(get_implicit_form3_exact_fes(v6, v2));
16453
+ const v = eCompress(get_implicit_form3_exact_fes(v6, v2));
16479
16454
  return { vₓₓₓ, vₓₓᵧ, vₓᵧᵧ, vᵧᵧᵧ, vₓₓ, vₓᵧ, vᵧᵧ, vₓ, vᵧ, v };
16480
16455
  }
16481
16456
 
@@ -16486,7 +16461,7 @@ function getImplicitForm3ExactPb(pspb) {
16486
16461
 
16487
16462
 
16488
16463
 
16489
- const get_coeffs_bez3_bez1_exact_tp = basic_two_product_twoProduct; // error -> 0
16464
+ const get_coeffs_bez3_bez1_exact_tp = two_product_twoProduct; // error -> 0
16490
16465
  const get_coeffs_bez3_bez1_exact_sce = scaleExpansion2;
16491
16466
  const get_coeffs_bez3_bez1_exact_epr = expansionProduct;
16492
16467
  const get_coeffs_bez3_bez1_exact_fes = fastExpansionSum;
@@ -16635,7 +16610,7 @@ function getCoeffsBez3Bez1Exact(ps1, ps2) {
16635
16610
  const fd = get_coeffs_bez3_bez1_exact_fes(f9, fc);
16636
16611
  const v0 = get_coeffs_bez3_bez1_exact_fes(fd, v);
16637
16612
  const r = [v3, v2, v1, v0];
16638
- return r.map(e_compress_eCompress);
16613
+ return r.map(eCompress);
16639
16614
  }
16640
16615
 
16641
16616
  //# sourceMappingURL=get-coeffs-bez3-bez1-exact.js.map
@@ -16701,7 +16676,7 @@ function getCoeffsBez1Bez2Exact(ps1, ps2) {
16701
16676
  const p7 = get_coeffs_bez1_bez2_exact_fes(p5, p6);
16702
16677
  const v0 = get_coeffs_bez1_bez2_exact_fes(p7, v);
16703
16678
  const r = [v2, v1, v0];
16704
- return r.map(e_compress_eCompress);
16679
+ return r.map(eCompress);
16705
16680
  }
16706
16681
 
16707
16682
  //# sourceMappingURL=get-coeffs-bez1-bez2-exact.js.map
@@ -16711,7 +16686,7 @@ function getCoeffsBez1Bez2Exact(ps1, ps2) {
16711
16686
 
16712
16687
 
16713
16688
 
16714
- const get_coeffs_bez2_bez2_exact_tp = basic_two_product_twoProduct; // error -> 0
16689
+ const get_coeffs_bez2_bez2_exact_tp = two_product_twoProduct; // error -> 0
16715
16690
  const get_coeffs_bez2_bez2_exact_sce = scaleExpansion2;
16716
16691
  const get_coeffs_bez2_bez2_exact_epr = expansionProduct;
16717
16692
  const get_coeffs_bez2_bez2_exact_fes = fastExpansionSum;
@@ -16853,7 +16828,7 @@ function getCoeffsBez2Bez2Exact(ps1, ps2) {
16853
16828
  const q4 = get_coeffs_bez2_bez2_exact_fes(q2, q3);
16854
16829
  const v0 = get_coeffs_bez2_bez2_exact_fes(q4, v);
16855
16830
  const r = [v4, v3, v2, v1, v0];
16856
- return r.map(e_compress_eCompress);
16831
+ return r.map(eCompress);
16857
16832
  }
16858
16833
 
16859
16834
  //# sourceMappingURL=get-coeffs-bez2-bez2-exact.js.map
@@ -16864,7 +16839,7 @@ function getCoeffsBez2Bez2Exact(ps1, ps2) {
16864
16839
 
16865
16840
 
16866
16841
 
16867
- const get_coeffs_bez3_bez2_exact_tp = basic_two_product_twoProduct; // error -> 0
16842
+ const get_coeffs_bez3_bez2_exact_tp = two_product_twoProduct; // error -> 0
16868
16843
  const get_coeffs_bez3_bez2_exact_sce = scaleExpansion2;
16869
16844
  const get_coeffs_bez3_bez2_exact_epr = expansionProduct;
16870
16845
  const get_coeffs_bez3_bez2_exact_fes = fastExpansionSum;
@@ -17175,7 +17150,7 @@ function getCoeffsBez3Bez2Exact(ps1, ps2) {
17175
17150
  const ub = get_coeffs_bez3_bez2_exact_fes(u9, ua);
17176
17151
  const v0 = get_coeffs_bez3_bez2_exact_fes(ub, v);
17177
17152
  const r = [v6, v5, v4, v3, v2, v1, v0];
17178
- return r.map(e_compress_eCompress);
17153
+ return r.map(eCompress);
17179
17154
  }
17180
17155
 
17181
17156
  //# sourceMappingURL=get-coeffs-bez3-bez2-exact.js.map
@@ -17246,7 +17221,7 @@ function getCoeffsBez1Bez3Exact(ps1, ps2) {
17246
17221
  const p9 = get_coeffs_bez1_bez3_exact_fes(p7, p8);
17247
17222
  const v0 = get_coeffs_bez1_bez3_exact_fes(p9, v);
17248
17223
  const r = [v3, v2, v1, v0];
17249
- return r.map(e_compress_eCompress);
17224
+ return r.map(eCompress);
17250
17225
  }
17251
17226
 
17252
17227
  //# sourceMappingURL=get-coeffs-bez1-bez3-exact.js.map
@@ -17257,7 +17232,7 @@ function getCoeffsBez1Bez3Exact(ps1, ps2) {
17257
17232
 
17258
17233
 
17259
17234
 
17260
- const get_coeffs_bez2_bez3_exact_tp = basic_two_product_twoProduct; // error -> 0
17235
+ const get_coeffs_bez2_bez3_exact_tp = two_product_twoProduct; // error -> 0
17261
17236
  const get_coeffs_bez2_bez3_exact_sce = scaleExpansion2;
17262
17237
  const get_coeffs_bez2_bez3_exact_epr = expansionProduct;
17263
17238
  const get_coeffs_bez2_bez3_exact_fes = fastExpansionSum;
@@ -17449,7 +17424,7 @@ function getCoeffsBez2Bez3Exact(ps1, ps2) {
17449
17424
  const rm = get_coeffs_bez2_bez3_exact_fes(rk, rl);
17450
17425
  const v0 = get_coeffs_bez2_bez3_exact_fes(rm, v);
17451
17426
  const r = [v6, v5, v4, v3, v2, v1, v0];
17452
- return r.map(e_compress_eCompress);
17427
+ return r.map(eCompress);
17453
17428
  }
17454
17429
 
17455
17430
  //# sourceMappingURL=get-coeffs-bez2-bez3-exact.js.map
@@ -17460,7 +17435,7 @@ function getCoeffsBez2Bez3Exact(ps1, ps2) {
17460
17435
 
17461
17436
 
17462
17437
 
17463
- const get_coeffs_bez3_bez3_exact_tp = basic_two_product_twoProduct; // error -> 0
17438
+ const get_coeffs_bez3_bez3_exact_tp = two_product_twoProduct; // error -> 0
17464
17439
  const get_coeffs_bez3_bez3_exact_sce = scaleExpansion2;
17465
17440
  const get_coeffs_bez3_bez3_exact_epr = expansionProduct;
17466
17441
  const get_coeffs_bez3_bez3_exact_fes = fastExpansionSum;
@@ -17899,7 +17874,7 @@ function getCoeffsBez3Bez3Exact(ps1, ps2) {
17899
17874
  const pb = get_coeffs_bez3_bez3_exact_fes(p9, pa);
17900
17875
  const v0 = get_coeffs_bez3_bez3_exact_fes(pb, v);
17901
17876
  const r = [v9, v8, v7, v6, v5, v4, v3, v2, v1, v0];
17902
- return r.map(e_compress_eCompress);
17877
+ return r.map(eCompress);
17903
17878
  }
17904
17879
 
17905
17880
  //# sourceMappingURL=get-coeffs-bez3-bez3-exact.js.map
@@ -19038,7 +19013,7 @@ function orient2dAdapt(A, B, C, detsum) {
19038
19013
  const bcx = B[0] - C[0];
19039
19014
  const acy = A[1] - C[1];
19040
19015
  const bcy = B[1] - C[1];
19041
- const b = eDiff(basic_two_product_twoProduct(acx, bcy), basic_two_product_twoProduct(acy, bcx));
19016
+ const b = eDiff(two_product_twoProduct(acx, bcy), two_product_twoProduct(acy, bcx));
19042
19017
  let det = eEstimate(b);
19043
19018
  if (Math.abs(det) >= ccwerrboundB * detsum) {
19044
19019
  // Anti-clockwise or clockwise
@@ -19058,13 +19033,13 @@ function orient2dAdapt(A, B, C, detsum) {
19058
19033
  if (Math.abs(det) >= errbound) {
19059
19034
  return det;
19060
19035
  }
19061
- const a = eDiff(basic_two_product_twoProduct(acxtail, bcy), basic_two_product_twoProduct(acytail, bcx));
19036
+ const a = eDiff(two_product_twoProduct(acxtail, bcy), two_product_twoProduct(acytail, bcx));
19062
19037
  const c = fastExpansionSum(b, a);
19063
- const d = eDiff(basic_two_product_twoProduct(acx, bcytail), basic_two_product_twoProduct(acy, bcxtail));
19038
+ const d = eDiff(two_product_twoProduct(acx, bcytail), two_product_twoProduct(acy, bcxtail));
19064
19039
  const e = fastExpansionSum(c, d);
19065
- const f = eDiff(basic_two_product_twoProduct(acxtail, bcytail), basic_two_product_twoProduct(acytail, bcxtail));
19040
+ const f = eDiff(two_product_twoProduct(acxtail, bcytail), two_product_twoProduct(acytail, bcxtail));
19066
19041
  let D = fastExpansionSum(e, f);
19067
- D = e_compress_eCompress(D);
19042
+ D = eCompress(D);
19068
19043
  return D[D.length - 1];
19069
19044
  }
19070
19045
 
@@ -20235,8 +20210,8 @@ function isPointOnBezierExtension(ps, p) {
20235
20210
  return isPointOnBezierExtension1(ps, p);
20236
20211
  }
20237
20212
  if (ps.length === 1) {
20238
- const x = e_compress_eCompress(p[0]);
20239
- const y = e_compress_eCompress(p[1]);
20213
+ const x = eCompress(p[0]);
20214
+ const y = eCompress(p[1]);
20240
20215
  return (x.length === 1 && y.length === 1 &&
20241
20216
  x[0] === ps[0][0] && y[0] === ps[0][1]);
20242
20217
  }
@@ -20429,7 +20404,7 @@ function doConvexPolygonsIntersect(polygonA, polygonB, closed) {
20429
20404
  //# sourceMappingURL=do-convex-polygons-intersect.js.map
20430
20405
  ;// ./node_modules/flo-boolean/node_modules/flo-bezier3/node/global-properties/classification/is-cubic-really-quad.js
20431
20406
 
20432
- const is_cubic_really_quad_tp = basic_two_product_twoProduct;
20407
+ const is_cubic_really_quad_tp = two_product_twoProduct;
20433
20408
  const is_cubic_really_quad_fes = fastExpansionSum;
20434
20409
  const is_cubic_really_quad_u = Number.EPSILON / 2;
20435
20410
  const is_cubic_really_quad_abs = Math.abs;
@@ -20489,7 +20464,7 @@ function isCubicReallyQuad(ps) {
20489
20464
  //# sourceMappingURL=is-cubic-really-quad.js.map
20490
20465
  ;// ./node_modules/flo-boolean/node_modules/flo-bezier3/node/global-properties/classification/is-quad-really-line.js
20491
20466
 
20492
- const is_quad_really_line_ts = two_sum_twoSum;
20467
+ const is_quad_really_line_ts = twoSum;
20493
20468
  const { abs: is_quad_really_line_abs } = Math;
20494
20469
  /**
20495
20470
  * Returns `true` if the given quadratic bezier curve is really a linear curve
@@ -20825,9 +20800,6 @@ function reduceSignificand(a, bits) {
20825
20800
 
20826
20801
 
20827
20802
 
20828
- // We *have* to do the below❗ The assignee is a getter❗ The assigned is a pure function❗
20829
- const e_to_bitlength_sign = eSign;
20830
- const e_to_bitlength_compress = e_compress_eCompress;
20831
20803
  /**
20832
20804
  * Returns a floating point expansion accurate to the given number of bits.
20833
20805
  * Extraneous bits are discarded.
@@ -20836,8 +20808,8 @@ const e_to_bitlength_compress = e_compress_eCompress;
20836
20808
  */
20837
20809
  // TODO - make faster
20838
20810
  function eToBitlength(a, l) {
20839
- a = e_to_bitlength_compress(a);
20840
- if (e_to_bitlength_sign(a) === 0) {
20811
+ a = eCompress(a);
20812
+ if (eSign(a) === 0) {
20841
20813
  return [0];
20842
20814
  }
20843
20815
  const maxMsb = msbExponent(a[a.length - 1]);
@@ -20883,7 +20855,7 @@ function bitLength(a) {
20883
20855
  * @param a A double precision floating point expansion
20884
20856
  */
20885
20857
  function expBitLength(a) {
20886
- const a_ = e_compress_eCompress(a);
20858
+ const a_ = eCompress(a);
20887
20859
  if (eSign(a_) === 0) {
20888
20860
  return 0;
20889
20861
  }
@@ -20899,12 +20871,6 @@ function expBitLength(a) {
20899
20871
 
20900
20872
 
20901
20873
 
20902
- // We *have* to do the below❗ The assignee is a getter❗ The assigned is a pure function❗
20903
- const mult = expansionProduct;
20904
- const toBitlength = eToBitlength;
20905
- const e_div_bitLength = expBitLength;
20906
- const e_div_diff = eDiff;
20907
- const estimate = eEstimate;
20908
20874
  /**
20909
20875
  * Returns the result of a/b using Goldschmidt division.
20910
20876
  *
@@ -20927,18 +20893,18 @@ function eDiv(N, D, expansionLength) {
20927
20893
  let exact = false;
20928
20894
  let resultBitlengthUpperBound = 0;
20929
20895
  if (!expansionLength) {
20930
- const bitlengthN = e_div_bitLength(N_);
20931
- const bitlengthD = e_div_bitLength(D_);
20896
+ const bitlengthN = expBitLength(N_);
20897
+ const bitlengthD = expBitLength(D_);
20932
20898
  // resultBitlengthUpperBound is only valid if the division is known
20933
20899
  // to be exact
20934
20900
  resultBitlengthUpperBound = bitlengthN - bitlengthD + 1;
20935
20901
  expansionLength = (resultBitlengthUpperBound / 53) + 1;
20936
20902
  exact = true;
20937
20903
  }
20938
- let F = [1 / estimate(D_)]; // Initial guess - out by 1/2 upls
20904
+ let F = [1 / eEstimate(D_)]; // Initial guess - out by 1/2 upls
20939
20905
  let i = 1;
20940
20906
  while (true) {
20941
- N_ = mult(N_, F);
20907
+ N_ = expansionProduct(N_, F);
20942
20908
  // The precision bitlength doubles on each iteration
20943
20909
  if (i > expansionLength) {
20944
20910
  // we now have roughly double the needed precision - we actually
@@ -20948,7 +20914,7 @@ function eDiv(N, D, expansionLength) {
20948
20914
  // We must throw away bits known to be zero.
20949
20915
  // Any bits > expansionLength * 53 must be thrown away as they
20950
20916
  // are wrong - all other bits are exact.
20951
- N_ = toBitlength(N_, resultBitlengthUpperBound);
20917
+ N_ = eToBitlength(N_, resultBitlengthUpperBound);
20952
20918
  // TODO - below is just for testing - remove later
20953
20919
  //if (compare(mult(D, N_), N) !== 0) {
20954
20920
  // console.log(mult(D, N_))
@@ -20959,8 +20925,8 @@ function eDiv(N, D, expansionLength) {
20959
20925
  // Returning only significant bits helps with sign determination later on.
20960
20926
  return N_.slice(N_.length - expansionLength, N_.length);
20961
20927
  }
20962
- D_ = mult(D_, F);
20963
- F = e_div_diff([2], D_);
20928
+ D_ = expansionProduct(D_, F);
20929
+ F = eDiff([2], D_);
20964
20930
  i *= 2;
20965
20931
  }
20966
20932
  }
@@ -21248,7 +21214,7 @@ function bigintToExpansion(b) {
21248
21214
  b = q;
21249
21215
  i++;
21250
21216
  }
21251
- return e_compress_eCompress(e);
21217
+ return eCompress(e);
21252
21218
  }
21253
21219
 
21254
21220
  //# sourceMappingURL=bigint-to-expansion.js.map
@@ -22042,8 +22008,6 @@ function setIntersectionNextValues(xPairs) {
22042
22008
  //# sourceMappingURL=set-intersection-next-values.js.map
22043
22009
  ;// ./node_modules/big-float-ts/node/double-expansion/e-abs.js
22044
22010
 
22045
- // We *have* to do the below❗ The assignee is a getter❗ The assigned is a pure function❗
22046
- const e_abs_negativeOf = eNegativeOf;
22047
22011
  /**
22048
22012
  * Returns the absolute value of the given floating point expansion.
22049
22013
  *
@@ -22053,7 +22017,7 @@ const e_abs_negativeOf = eNegativeOf;
22053
22017
  */
22054
22018
  function eAbs(e) {
22055
22019
  if (e[e.length - 1] < 0) {
22056
- return e_abs_negativeOf(e);
22020
+ return eNegativeOf(e);
22057
22021
  }
22058
22022
  return e;
22059
22023
  }
@@ -22072,7 +22036,7 @@ function eAbs(e) {
22072
22036
  *
22073
22037
  * See https://people.eecs.berkeley.edu/~jrs/papers/robustr.pdf
22074
22038
  */
22075
- function basic_two_sum_twoSum(a, b) {
22039
+ function two_sum_twoSum(a, b) {
22076
22040
  const x = a + b;
22077
22041
  const bv = x - a;
22078
22042
  return [(a - (x - bv)) + (b - bv), x];
@@ -22477,7 +22441,7 @@ const bezier_self_intersection_edif = eDiff;
22477
22441
  const bezier_self_intersection_epr = expansionProduct;
22478
22442
  const bezier_self_intersection_sce = scaleExpansion2;
22479
22443
  const bezier_self_intersection_td = two_diff_twoDiff;
22480
- const bezier_self_intersection_ts = basic_two_sum_twoSum;
22444
+ const bezier_self_intersection_ts = two_sum_twoSum;
22481
22445
  const bezier_self_intersection_qno = ddNegativeOf;
22482
22446
  const bezier_self_intersection_qaq = ddAddDd;
22483
22447
  const bezier_self_intersection_qm2 = ddMultBy2;
@@ -24247,7 +24211,7 @@ const { min: add_min, max: add_max } = Math;
24247
24211
  *
24248
24212
  * @doc
24249
24213
  */
24250
- function add_add(p1, p2) {
24214
+ function add(p1, p2) {
24251
24215
  // Initialize result array
24252
24216
  const d1 = p1.length - 1;
24253
24217
  const d2 = p2.length - 1;
@@ -24297,7 +24261,7 @@ function getShapeArea(pss) {
24297
24261
  const [dx, dy] = to_power_basis_1st_derivative_toPowerBasis_1stDerivative(ps);
24298
24262
  const xdy = multiply(x, dy);
24299
24263
  const ydx = negate(multiply(y, dx));
24300
- const poly = integrate(add_add(xdy, ydx), 0);
24264
+ const poly = integrate(add(xdy, ydx), 0);
24301
24265
  const area = Horner(poly, 1);
24302
24266
  totalArea += area;
24303
24267
  }
@@ -24546,7 +24510,7 @@ function bezierToBezierPiece(bezier) {
24546
24510
 
24547
24511
 
24548
24512
  const { atan2: get_interface_rotation_atan2 } = Math;
24549
- const simultaneous_properties_get_interface_rotation_tp = two_product_twoProduct;
24513
+ const get_interface_rotation_tp = twoProduct;
24550
24514
  /**
24551
24515
  * Returns the rotation angle (-𝜋 <= θ <= 𝜋 *guaranteed*) from some vector to
24552
24516
  * another vector considering them to both start at the same point.
@@ -24568,9 +24532,9 @@ function get_interface_rotation_getInterfaceRotation(a, b) {
24568
24532
  const w1 = b[0];
24569
24533
  const w2 = b[1];
24570
24534
  // w2*v1 - w1*v2;
24571
- const A = ddDiffDd(simultaneous_properties_get_interface_rotation_tp(w2, v1), simultaneous_properties_get_interface_rotation_tp(w1, v2))[1];
24535
+ const A = ddDiffDd(get_interface_rotation_tp(w2, v1), get_interface_rotation_tp(w1, v2))[1];
24572
24536
  // w1*v1 + w2*v2;
24573
- const B = ddAddDd(simultaneous_properties_get_interface_rotation_tp(w1, v1), simultaneous_properties_get_interface_rotation_tp(w2, v2))[1];
24537
+ const B = ddAddDd(get_interface_rotation_tp(w1, v1), get_interface_rotation_tp(w2, v2))[1];
24574
24538
  return get_interface_rotation_atan2(A, B);
24575
24539
  }
24576
24540
 
@@ -24580,7 +24544,7 @@ function get_interface_rotation_getInterfaceRotation(a, b) {
24580
24544
 
24581
24545
  const is_cubic_really_line_sce = scaleExpansion;
24582
24546
  const ediff = eDiff;
24583
- const is_cubic_really_line_ts = two_sum_twoSum;
24547
+ const is_cubic_really_line_ts = twoSum;
24584
24548
  const esign = eSign;
24585
24549
  /**
24586
24550
  * Returns `true` if the given bezier curve has all control points collinear
@@ -24637,7 +24601,7 @@ const classify_edif = eDiff;
24637
24601
  const classify_epr = expansionProduct;
24638
24602
  const classify_sce = scaleExpansion2;
24639
24603
  const classify_td = two_diff_twoDiff;
24640
- const classify_ts = basic_two_sum_twoSum;
24604
+ const classify_ts = two_sum_twoSum;
24641
24605
  const classify_fes = fastExpansionSum;
24642
24606
  const classify_ge = growExpansion;
24643
24607
  const classify_abs = Math.abs;
@@ -25761,6 +25725,7 @@ function furthestPointOnBezier(ps, p) {
25761
25725
 
25762
25726
  //# sourceMappingURL=furthest-point-on-bezier.js.map
25763
25727
  ;// ./node_modules/flo-bezier3/node/error-analysis/max-abs-coordinate.js
25728
+ const { abs: max_abs_coordinate_abs } = Math;
25764
25729
  /**
25765
25730
  * Returns the maximum absolute value of the coordinates of the control points
25766
25731
  * of the given bezier curve.
@@ -25774,8 +25739,8 @@ function maxAbsCoordinate(ps) {
25774
25739
  let m = Number.NEGATIVE_INFINITY;
25775
25740
  for (let i = 0; i < ps.length; i++) {
25776
25741
  const p = ps[i];
25777
- const absX = Math.abs(p[0]);
25778
- const absY = Math.abs(p[1]);
25742
+ const absX = max_abs_coordinate_abs(p[0]);
25743
+ const absY = max_abs_coordinate_abs(p[1]);
25779
25744
  if (absX > m) {
25780
25745
  m = absX;
25781
25746
  }
@@ -25788,9 +25753,10 @@ function maxAbsCoordinate(ps) {
25788
25753
 
25789
25754
  //# sourceMappingURL=max-abs-coordinate.js.map
25790
25755
  ;// ./node_modules/flo-bezier3/node/simultaneous-properties/hausdorff-distance/get-max-hausdorff.js
25756
+ const { max: get_max_hausdorff_max } = Math;
25791
25757
  /** @internal */
25792
25758
  function getMaxHausdorff(i) {
25793
- return Math.max(i.hL + i.hEL, i.hR + i.hER);
25759
+ return get_max_hausdorff_max(i.hL + i.hEL, i.hR + i.hER);
25794
25760
  }
25795
25761
 
25796
25762
  //# sourceMappingURL=get-max-hausdorff.js.map
@@ -25902,7 +25868,7 @@ class Heap {
25902
25868
 
25903
25869
 
25904
25870
  /** @internal */
25905
- const hausdorff_distance_one_sided_max = Math.max;
25871
+ const { max: hausdorff_distance_one_sided_max } = Math;
25906
25872
  // We need to calculate `H(A,B)`, the two sided Hausdorff distance between
25907
25873
  // the bezier curves `A` and `B` which equals `max(h(A,B), h(B,A))`, where
25908
25874
  // `h(A,B)` is the one sided Hausdorff distance from `A` to `B`
@@ -25928,7 +25894,7 @@ const hausdorff_distance_one_sided_max = Math.max;
25928
25894
  * control points e.g. `[[0,0],[1,1],[2,1],[2,0]]`
25929
25895
  * @param B a bezier curve (the 'to' curve) given by an ordered array of its
25930
25896
  * control points e.g. `[[0,0],[1,1],[2,1],[2,0]]`
25931
- * @param tolerance optional; defaults to `Math.max(maxAbsCoordinate(A),maxAbsCoordinate(B))/1000_000`;
25897
+ * @param tolerance optional; defaults to `max(maxAbsCoordinate(A),maxAbsCoordinate(B))/1000_000`;
25932
25898
  * if the calculated absolute error bound is less than this, the result is
25933
25899
  * returned; this is *not* a hard tolerance and the bound can be less
25934
25900
  * accurate in hard cases (due to the `maxIterations` parameter). Luckily
@@ -26098,578 +26064,336 @@ function getBranches(cpNode) {
26098
26064
  }
26099
26065
 
26100
26066
 
26101
- ;// ./node_modules/flo-ll-rb-tree/node/tree.js
26102
- // Concise, Destructive, Left Leaning Red Black Tree implementation.
26103
- // See: https://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf
26104
- // See: https://en.wikipedia.org/wiki/Left-leaning_red%E2%80%93black_tree
26105
- // See: http://www.teachsolaisgames.com/articles/balanced_left_leaning.html
26106
- const LEFT = -1;
26107
- const RIGHT = 1;
26067
+ ;// ./node_modules/flo-ll-rb-tree/node/rb-tree/rb-tree.js
26108
26068
  const BLACK = 1;
26109
26069
  const RED = 0;
26110
- /**
26111
- * Red Black Tree node.
26112
- */
26113
26070
  class Node {
26114
26071
  datum;
26115
26072
  color = RED;
26116
26073
  parent;
26117
- extras;
26118
- "-1";
26119
- "1";
26074
+ left;
26075
+ right;
26120
26076
  constructor(datum) {
26121
26077
  this.datum = datum;
26122
26078
  }
26123
26079
  }
26124
- function isRed(node) {
26125
- return !!node && node.color === RED;
26126
- }
26127
- class LlRbTree {
26080
+ class RbTree {
26128
26081
  compare;
26129
- duplicatesAllowed;
26130
26082
  root;
26131
- /**
26132
- * The number of nodes in the tree (that equals the number of values in the
26133
- * tree not counting duplicates).
26134
- */
26135
- nodeCount;
26136
- /**
26137
- * The number of values in the tree.
26138
- */
26139
- valueCount;
26140
- /**
26141
- * @param compare a comparator function
26142
- * @param duplicatesAllowed defaults to `true`; if `false` then if a
26143
- * duplicate is inserted (as per the equivalence relation induced by the
26144
- * compare function) then replace it; if `true` then instead still insert
26145
- * it (so there can be multiple nodes with the same value in the tree)
26146
- * @param data an optional initial array of data
26147
- */
26148
- constructor(compare, duplicatesAllowed = true, data) {
26083
+ constructor(compare) {
26149
26084
  this.compare = compare;
26150
- this.duplicatesAllowed = duplicatesAllowed;
26151
26085
  this.root = undefined;
26152
- this.nodeCount = 0;
26153
- this.valueCount = 0;
26154
- if (!data) {
26155
- return;
26156
- }
26157
- for (const datum of data) {
26158
- this.insert(datum);
26159
- }
26160
26086
  }
26161
- isEmpty() { return !this.root; }
26162
- /**
26163
- * Find and returns the (first) node in the tree with the given datum using
26164
- * the tree compare function. Returns `undefined` if the node was not found.
26165
- */
26087
+ isEmpty() {
26088
+ return this.root === undefined;
26089
+ }
26166
26090
  find(datum) {
26167
- const tree = this;
26168
26091
  let node = this.root;
26169
26092
  while (node) {
26170
- const c = tree.compare(datum, node.datum);
26093
+ const c = this.compare(datum, node.datum);
26171
26094
  if (c === 0) {
26172
26095
  return node;
26173
26096
  }
26174
- node = node[c > 0 ? RIGHT : LEFT];
26097
+ node = c < 0 ? node.left : node.right;
26175
26098
  }
26176
26099
  return undefined;
26177
26100
  }
26178
- /**
26179
- * Returns an ordered (by the tree compare function) array of data as
26180
- * contained in the nodes of the tree by doing an in order traversal.
26181
- */
26182
- toArrayInOrder() {
26183
- const values = [];
26184
- f(this.root);
26185
- function f(node) {
26186
- if (!node) {
26101
+ insert(datum) {
26102
+ if (this.root === undefined) {
26103
+ this.root = new Node(datum);
26104
+ this.root.color = BLACK;
26105
+ return;
26106
+ }
26107
+ let parent;
26108
+ let node = this.root;
26109
+ while (node) {
26110
+ parent = node;
26111
+ const c = this.compare(datum, node.datum);
26112
+ if (c === 0) {
26113
+ node.datum = datum;
26187
26114
  return;
26188
26115
  }
26189
- f(node[LEFT]);
26190
- values.push(node.datum);
26191
- if (node.extras !== undefined) {
26192
- values.push(...node.extras);
26193
- }
26194
- f(node[RIGHT]);
26116
+ node = c < 0 ? node.left : node.right;
26117
+ }
26118
+ const inserted = new Node(datum);
26119
+ inserted.parent = parent;
26120
+ if (this.compare(datum, parent.datum) < 0) {
26121
+ parent.left = inserted;
26122
+ }
26123
+ else {
26124
+ parent.right = inserted;
26195
26125
  }
26196
- return values;
26126
+ this.fixInsert(inserted);
26197
26127
  }
26198
- insertMulti(data) {
26199
- const tree = this;
26200
- for (const datum of data) {
26201
- tree.insert(datum);
26128
+ remove(datum, _all = false, _compareStrict) {
26129
+ const node = this.find(datum);
26130
+ if (node === undefined) {
26131
+ return undefined;
26202
26132
  }
26133
+ const removed = node.datum;
26134
+ this.removeNode(node);
26135
+ return removed;
26203
26136
  }
26204
- /**
26205
- * Inserts a node with the given datum into the tree.
26206
- */
26207
- insert(datum) {
26208
- const tree = this;
26209
- tree.root = f(tree.root, datum);
26210
- tree.root.color = BLACK;
26211
- tree.root.parent = undefined;
26212
- function f(h, datum) {
26213
- if (h === undefined) {
26214
- tree.valueCount++;
26215
- tree.nodeCount++;
26216
- return new Node(datum);
26217
- }
26218
- const c = tree.compare(datum, h.datum);
26219
- if (c === 0) {
26220
- if (tree.duplicatesAllowed) {
26221
- tree.valueCount++;
26222
- if (h.extras === undefined) {
26223
- h.extras = [datum];
26224
- }
26225
- else {
26226
- h.extras.push(datum);
26227
- }
26228
- }
26229
- else {
26230
- h.datum = datum; // replace old value
26231
- }
26232
- }
26233
- if (c !== 0) {
26234
- const dir = c > 0 ? RIGHT : LEFT;
26235
- h[dir] = f(h[dir], datum);
26236
- h[dir].parent = h;
26237
- }
26238
- if (isRed(h[RIGHT]) && !isRed(h[LEFT])) {
26239
- h = tree_rotate(LEFT, h);
26240
- }
26241
- if (isRed(h[LEFT]) && isRed(h[LEFT][LEFT])) {
26242
- h = tree_rotate(RIGHT, h);
26137
+ findBounds(datum) {
26138
+ let node = this.root;
26139
+ const bounds = [undefined, undefined];
26140
+ while (node) {
26141
+ const c = this.compare(datum, node.datum);
26142
+ if (c >= 0) {
26143
+ bounds[0] = node;
26144
+ node = node.right;
26243
26145
  }
26244
- if (isRed(h[LEFT]) && isRed(h[RIGHT])) {
26245
- flipColors(h);
26146
+ else {
26147
+ bounds[1] = node;
26148
+ node = node.left;
26246
26149
  }
26247
- return h;
26248
26150
  }
26151
+ return bounds;
26249
26152
  }
26250
- /**
26251
- * Removes an item from the tree based on the given datum and returns the
26252
- * item that was removed or `undefined` if nothing was removed.
26253
- *
26254
- * @param datum
26255
- * @param all defaults to `false`; if `true` and duplicates exist, remove all
26256
- * @param compareStrict if provided then only delete an item if it passes the
26257
- * strict comparison function, i.e. if `compareStrict(item,node_value) === true`.
26258
- */
26259
- remove(datum, all = false, compareStrict) {
26260
- const tree = this;
26261
- if (tree.root === undefined) {
26262
- return undefined;
26153
+ getMinNode(node) {
26154
+ let curr = node === undefined ? this.root : node;
26155
+ while (curr && curr.left) {
26156
+ curr = curr.left;
26263
26157
  }
26264
- let removed = undefined;
26265
- const root = f(tree.root, datum);
26266
- if (root === null) {
26267
- return undefined;
26158
+ return curr;
26159
+ }
26160
+ getMaxNode(node) {
26161
+ let curr = node === undefined ? this.root : node;
26162
+ while (curr && curr.right) {
26163
+ curr = curr.right;
26268
26164
  }
26269
- tree.root = root;
26270
- if (tree.root !== undefined) {
26271
- tree.root.color = BLACK;
26272
- tree.root.parent = undefined;
26165
+ return curr;
26166
+ }
26167
+ removeNode(z) {
26168
+ let y = z;
26169
+ let yOriginalColor = y.color;
26170
+ let x;
26171
+ let xParent;
26172
+ if (z.left === undefined) {
26173
+ x = z.right;
26174
+ xParent = z.parent;
26175
+ this.transplant(z, z.right);
26273
26176
  }
26274
- return removed;
26275
- function f(h, datum) {
26276
- const theresExtras = tree.duplicatesAllowed && h.extras !== undefined;
26277
- let c = tree.compare(datum, h.datum);
26278
- if ((c < 0 && !h[LEFT]) || (c > 0 && !h[RIGHT])) {
26279
- return h; // end reached - no match
26280
- }
26281
- if (c < 0) {
26282
- if (!isRed(h[LEFT]) &&
26283
- !isRed(h[LEFT][LEFT])) {
26284
- h = moveRedLeft(h);
26285
- }
26286
- const g = f(h[LEFT], datum);
26287
- if (g === null) {
26288
- return null;
26289
- }
26290
- h[LEFT] = g;
26291
- if (h[LEFT]) {
26292
- h[LEFT].parent = h;
26177
+ else if (z.right === undefined) {
26178
+ x = z.left;
26179
+ xParent = z.parent;
26180
+ this.transplant(z, z.left);
26181
+ }
26182
+ else {
26183
+ y = this.getMinNode(z.right);
26184
+ yOriginalColor = y.color;
26185
+ x = y.right;
26186
+ if (y.parent === z) {
26187
+ xParent = y;
26188
+ if (x) {
26189
+ x.parent = y;
26293
26190
  }
26294
- return fixUp(h);
26295
26191
  }
26296
- if (isRed(h[LEFT])) {
26297
- h = tree_rotate(RIGHT, h);
26298
- c = tree.compare(datum, h.datum);
26192
+ else {
26193
+ xParent = y.parent;
26194
+ this.transplant(y, y.right);
26195
+ y.right = z.right;
26196
+ y.right.parent = y;
26299
26197
  }
26300
- if (c === 0 && !h[RIGHT]) {
26301
- if (theresExtras && !all) {
26302
- // There are multiple items at this node.
26303
- if (compareStrict === undefined ||
26304
- (compareStrict(datum, h.datum) === true)) {
26305
- removed = h.datum;
26306
- h.datum = h.extras.pop();
26307
- tree.valueCount--;
26308
- if (h.extras.length === 0) {
26309
- h.extras = undefined;
26310
- }
26311
- return h;
26312
- }
26313
- else {
26314
- const extras = h.extras;
26315
- for (let i = 0; i < extras.length; i++) {
26316
- if (compareStrict(datum, extras[i]) === true) {
26317
- removed = extras.splice(i, 1)[0];
26318
- tree.valueCount--;
26319
- if (extras.length === 0) {
26320
- h.extras = undefined;
26321
- }
26322
- return h;
26323
- }
26324
- }
26325
- return null;
26198
+ this.transplant(z, y);
26199
+ y.left = z.left;
26200
+ y.left.parent = y;
26201
+ y.color = z.color;
26202
+ }
26203
+ if (yOriginalColor === BLACK) {
26204
+ this.fixDelete(x, xParent);
26205
+ }
26206
+ }
26207
+ fixInsert(z) {
26208
+ let node = z;
26209
+ while (node.parent && node.parent.color === RED) {
26210
+ const parent = node.parent;
26211
+ const grandParent = parent.parent;
26212
+ if (parent === grandParent.left) {
26213
+ const uncle = grandParent.right;
26214
+ if (this.colorOf(uncle) === RED) {
26215
+ parent.color = BLACK;
26216
+ uncle.color = BLACK;
26217
+ grandParent.color = RED;
26218
+ node = grandParent;
26219
+ }
26220
+ else {
26221
+ if (node === parent.right) {
26222
+ node = parent;
26223
+ this.rotateLeft(node);
26326
26224
  }
26225
+ node.parent.color = BLACK;
26226
+ grandParent.color = RED;
26227
+ this.rotateRight(grandParent);
26327
26228
  }
26328
- if (compareStrict === undefined ||
26329
- (compareStrict(datum, h.datum) === true)) {
26330
- removed = h.datum;
26331
- tree.valueCount -= 1 + (theresExtras ? h.extras.length : 0);
26332
- tree.nodeCount--;
26333
- return undefined;
26229
+ }
26230
+ else {
26231
+ const uncle = grandParent.left;
26232
+ if (this.colorOf(uncle) === RED) {
26233
+ parent.color = BLACK;
26234
+ uncle.color = BLACK;
26235
+ grandParent.color = RED;
26236
+ node = grandParent;
26334
26237
  }
26335
26238
  else {
26336
- return null; // no match
26239
+ if (node === parent.left) {
26240
+ node = parent;
26241
+ this.rotateRight(node);
26242
+ }
26243
+ node.parent.color = BLACK;
26244
+ grandParent.color = RED;
26245
+ this.rotateLeft(grandParent);
26337
26246
  }
26338
26247
  }
26339
- if (!isRed(h[RIGHT]) &&
26340
- !isRed(h[RIGHT][LEFT])) {
26341
- h = moveRedRight(h);
26342
- c = tree.compare(datum, h.datum);
26248
+ }
26249
+ this.root.color = BLACK;
26250
+ }
26251
+ fixDelete(x, parent) {
26252
+ let node = x;
26253
+ let nodeParent = parent;
26254
+ while (node !== this.root && this.colorOf(node) === BLACK) {
26255
+ if (nodeParent === undefined) {
26256
+ break;
26343
26257
  }
26344
- if (c === 0) {
26345
- if (theresExtras && !all) {
26346
- // There are multiple items at this node.
26347
- if (compareStrict === undefined ||
26348
- (compareStrict(datum, h.datum) === true)) {
26349
- removed = h.datum;
26350
- h.datum = h.extras.pop();
26351
- tree.valueCount--;
26352
- if (h.extras.length === 0) {
26353
- h.extras = undefined;
26354
- }
26355
- //// const g = f(h[RIGHT]!, datum);
26356
- // if (g === null) { return null; }
26357
- //// h[RIGHT] = g!;
26358
- }
26359
- else {
26360
- const extras = h.extras;
26361
- let found = false;
26362
- for (let i = 0; i < extras.length; i++) {
26363
- if (compareStrict(datum, extras[i]) === true) {
26364
- removed = extras.splice(i, 1)[0];
26365
- tree.valueCount--;
26366
- if (extras.length === 0) {
26367
- h.extras = undefined;
26368
- }
26369
- //// const g = f(h[RIGHT]!, extras[i]);
26370
- // if (g === null) { return null; }
26371
- //// h[RIGHT] = g!;
26372
- found = true;
26373
- break;
26374
- }
26375
- }
26376
- if (!found) {
26377
- return null;
26378
- }
26258
+ if (node === nodeParent?.left) {
26259
+ let sibling = nodeParent.right;
26260
+ if (this.colorOf(sibling) === RED) {
26261
+ sibling.color = BLACK;
26262
+ nodeParent.color = RED;
26263
+ this.rotateLeft(nodeParent);
26264
+ sibling = nodeParent.right;
26265
+ }
26266
+ if (this.colorOf(sibling?.left) === BLACK && this.colorOf(sibling?.right) === BLACK) {
26267
+ if (sibling) {
26268
+ sibling.color = RED;
26379
26269
  }
26270
+ node = nodeParent;
26271
+ nodeParent = node?.parent;
26380
26272
  }
26381
26273
  else {
26382
- if (compareStrict === undefined ||
26383
- (compareStrict(datum, h.datum) === true)) {
26384
- tree.valueCount -= 1 + (theresExtras ? h.extras.length : 0);
26385
- removed = h.datum;
26386
- const minNode = tree.getMinNode(h[RIGHT]);
26387
- // eslint-disable-next-line
26388
- h.datum = minNode?.datum;
26389
- // eslint-disable-next-line
26390
- if (tree.duplicatesAllowed) {
26391
- h.extras = minNode?.extras;
26274
+ if (this.colorOf(sibling?.right) === BLACK) {
26275
+ if (sibling?.left) {
26276
+ sibling.left.color = BLACK;
26392
26277
  }
26393
- h[RIGHT] = removeMin(h[RIGHT]);
26394
- tree.nodeCount--;
26278
+ if (sibling) {
26279
+ sibling.color = RED;
26280
+ this.rotateRight(sibling);
26281
+ }
26282
+ sibling = nodeParent.right;
26283
+ }
26284
+ if (sibling) {
26285
+ sibling.color = nodeParent.color;
26395
26286
  }
26396
- else {
26397
- return null; // no match
26287
+ nodeParent.color = BLACK;
26288
+ if (sibling?.right) {
26289
+ sibling.right.color = BLACK;
26398
26290
  }
26291
+ this.rotateLeft(nodeParent);
26292
+ node = this.root;
26293
+ nodeParent = undefined;
26399
26294
  }
26400
26295
  }
26401
26296
  else {
26402
- const g = f(h[RIGHT], datum);
26403
- if (g === null) {
26404
- return null;
26297
+ let sibling = nodeParent?.left;
26298
+ if (this.colorOf(sibling) === RED) {
26299
+ sibling.color = BLACK;
26300
+ nodeParent.color = RED;
26301
+ this.rotateRight(nodeParent);
26302
+ sibling = nodeParent.left;
26303
+ }
26304
+ if (this.colorOf(sibling?.left) === BLACK && this.colorOf(sibling?.right) === BLACK) {
26305
+ if (sibling) {
26306
+ sibling.color = RED;
26307
+ }
26308
+ node = nodeParent;
26309
+ nodeParent = nodeParent?.parent;
26310
+ }
26311
+ else {
26312
+ if (this.colorOf(sibling?.left) === BLACK) {
26313
+ if (sibling?.right) {
26314
+ sibling.right.color = BLACK;
26315
+ }
26316
+ if (sibling) {
26317
+ sibling.color = RED;
26318
+ this.rotateLeft(sibling);
26319
+ }
26320
+ sibling = nodeParent?.left;
26321
+ }
26322
+ if (sibling) {
26323
+ sibling.color = nodeParent.color;
26324
+ }
26325
+ nodeParent.color = BLACK;
26326
+ if (sibling?.left) {
26327
+ sibling.left.color = BLACK;
26328
+ }
26329
+ this.rotateRight(nodeParent);
26330
+ node = this.root;
26331
+ nodeParent = undefined;
26405
26332
  }
26406
- h[RIGHT] = g;
26407
- }
26408
- if (h[RIGHT]) {
26409
- h[RIGHT].parent = h;
26410
26333
  }
26411
- return fixUp(h);
26334
+ }
26335
+ if (node) {
26336
+ node.color = BLACK;
26412
26337
  }
26413
26338
  }
26414
- /**
26415
- * Returns the two ordered nodes bounding the datum.
26416
- *
26417
- * * If the datum falls on a node, that node and the next (to the right) is
26418
- * returned.
26419
- * * If the given datum is smaller than all nodes then the first item in the
26420
- * bounds array is `undefined` and the next is the smallest node
26421
- * * If the given datum is larger than all nodes then the second item in the
26422
- * bounds array is `undefined` and the first item is the largest node
26423
- *
26424
- */
26425
- findBounds(datum) {
26426
- const tree = this;
26427
- let node = tree.root;
26428
- const bounds = [undefined, undefined];
26429
- if (node === undefined) {
26430
- return bounds;
26339
+ transplant(u, v) {
26340
+ if (u.parent === undefined) {
26341
+ this.root = v;
26431
26342
  }
26432
- while (node) {
26433
- const c = tree.compare(datum, node.datum);
26434
- if (c >= 0) {
26435
- bounds[0] = node;
26436
- }
26437
- else {
26438
- bounds[1] = node;
26439
- }
26440
- node = node[c >= 0 ? RIGHT : LEFT];
26343
+ else if (u === u.parent.left) {
26344
+ u.parent.left = v;
26441
26345
  }
26442
- return bounds;
26443
- }
26444
- /**
26445
- * Returns the two ordered nodes bounding the datum.
26446
- *
26447
- * * If the datum falls on a node, returns the nodes before and after this
26448
- * one.
26449
- * * If the given datum is smaller than all nodes then the first item in the
26450
- * bounds array is `undefined` and the next is the smallest node
26451
- * * If the given datum is larger than all nodes then the second item in the
26452
- * bounds array is `undefined` and the first item is the largest node
26453
- *
26454
- * @param tree
26455
- * @param datum
26456
- */
26457
- findBoundsExcl(datum) {
26458
- const tree = this;
26459
- const node = tree.root;
26460
- const bounds = [undefined, undefined];
26461
- if (node === undefined) {
26462
- return bounds;
26463
- }
26464
- f(node);
26465
- function f(node) {
26466
- while (node) {
26467
- const c = tree.compare(datum, node.datum);
26468
- if (c === 0) {
26469
- // Search on both sides
26470
- f(node[LEFT]);
26471
- f(node[RIGHT]);
26472
- return;
26473
- }
26474
- if (c > 0) {
26475
- bounds[0] = node;
26476
- }
26477
- else if (c < 0) {
26478
- bounds[1] = node;
26479
- }
26480
- node = node[c > 0 ? RIGHT : LEFT];
26481
- }
26346
+ else {
26347
+ u.parent.right = v;
26482
26348
  }
26483
- return bounds;
26484
- }
26485
- /**
26486
- * Returns an array of all matching data found.
26487
- *
26488
- * If duplicates are not allowed it's better to just use `find`.
26489
- *
26490
- * @param datum
26491
- */
26492
- findAll(datum) {
26493
- const tree = this;
26494
- let node = this.root;
26495
- while (node) {
26496
- const c = tree.compare(datum, node.datum);
26497
- if (c === 0) {
26498
- return [
26499
- node.datum,
26500
- ...(node.extras ? node.extras : [])
26501
- ];
26502
- }
26503
- node = node[c > 0 ? RIGHT : LEFT];
26349
+ if (v) {
26350
+ v.parent = u.parent;
26504
26351
  }
26505
- return [];
26506
- }
26507
- /** @internal */
26508
- getMinOrMaxNode(dir) {
26509
- return (node) => {
26510
- if (node === undefined) {
26511
- node = this.root;
26512
- }
26513
- if (!node) {
26514
- return undefined;
26515
- }
26516
- while (node[dir]) {
26517
- node = node[dir];
26518
- }
26519
- return node;
26520
- };
26521
26352
  }
26522
- // eslint-disable-next-line
26523
- getMinNode = this.getMinOrMaxNode(LEFT);
26524
- // eslint-disable-next-line
26525
- getMaxNode = this.getMinOrMaxNode(RIGHT);
26526
- /**
26527
- * Returns the minimum value in the tree starting at the given node. If the
26528
- * tree is empty, `undefined` will be returned.
26529
- *
26530
- * If the min value is required for the entire tree call this function
26531
- * as `tree.min(tree.root)`
26532
- *
26533
- * @param node
26534
- */
26535
- min(node) {
26536
- if (node === undefined) {
26537
- node = this.root;
26353
+ rotateLeft(x) {
26354
+ const y = x.right;
26355
+ x.right = y.left;
26356
+ if (y.left) {
26357
+ y.left.parent = x;
26538
26358
  }
26539
- const minNode = this.getMinNode(node);
26540
- if (minNode !== undefined) {
26541
- return minNode.datum;
26359
+ y.parent = x.parent;
26360
+ if (x.parent === undefined) {
26361
+ this.root = y;
26542
26362
  }
26543
- return undefined;
26544
- }
26545
- /**
26546
- * Returns the maximum value in the tree starting at the given node. If the
26547
- * tree is empty, `undefined` will be returned.
26548
- *
26549
- * If the max value is required for the entire tree call this function
26550
- * as `tree.max(tree.root)`
26551
- *
26552
- * @param node
26553
- */
26554
- max(node) {
26555
- if (node === undefined) {
26556
- node = this.root;
26363
+ else if (x === x.parent.left) {
26364
+ x.parent.left = y;
26557
26365
  }
26558
- const maxNode = this.getMaxNode(node);
26559
- if (maxNode !== undefined) {
26560
- return maxNode.datum;
26366
+ else {
26367
+ x.parent.right = y;
26561
26368
  }
26562
- return undefined;
26563
- }
26564
- }
26565
- /**
26566
- * Returns the node that is at the top after the rotation.
26567
- *
26568
- * Destructively rotates the given node, say h, in the
26569
- * given direction as far as tree rotations go.
26570
- *
26571
- * @param dir
26572
- * @param h
26573
- *
26574
- * @internal
26575
- */
26576
- function tree_rotate(dir, h) {
26577
- const x = h[-dir];
26578
- h[-dir] = x[dir];
26579
- if (x[dir]) {
26580
- x[dir].parent = h;
26581
- }
26582
- x[dir] = h;
26583
- h.parent = x;
26584
- x.color = h.color;
26585
- h.color = RED;
26586
- return x;
26587
- }
26588
- /**
26589
- * @param h
26590
- *
26591
- * @internal
26592
- */
26593
- function removeMin(h) {
26594
- if (!h[LEFT]) {
26595
- return undefined;
26596
- }
26597
- if (!isRed(h[LEFT]) &&
26598
- !isRed(h[LEFT][LEFT])) {
26599
- h = moveRedLeft(h);
26600
- }
26601
- h[LEFT] = removeMin(h[LEFT]);
26602
- if (h[LEFT]) {
26603
- h[LEFT].parent = h;
26604
- }
26605
- return fixUp(h);
26606
- }
26607
- /**
26608
- * Destructively flips the color of the given node and both
26609
- * it's childrens' colors.
26610
- *
26611
- * @param h
26612
- *
26613
- * @internal
26614
- */
26615
- function flipColors(h) {
26616
- h.color = (h.color + 1) % 2;
26617
- h[LEFT].color = (h[LEFT].color + 1) % 2;
26618
- h[RIGHT].color = (h[RIGHT].color + 1) % 2;
26619
- }
26620
- /**
26621
- * @param h
26622
- *
26623
- * @internal
26624
- */
26625
- function moveRedLeft(h) {
26626
- flipColors(h);
26627
- if (isRed(h[RIGHT][LEFT])) {
26628
- const a = tree_rotate(RIGHT, h[RIGHT]);
26629
- h[RIGHT] = a;
26630
- a.parent = h;
26631
- h = tree_rotate(LEFT, h);
26632
- flipColors(h);
26633
- }
26634
- return h;
26635
- }
26636
- /**
26637
- * Returns the node that is at the top after the move.
26638
- *
26639
- * @param h
26640
- *
26641
- * @internal
26642
- */
26643
- function moveRedRight(h) {
26644
- flipColors(h);
26645
- if (isRed(h[LEFT][LEFT])) {
26646
- h = tree_rotate(RIGHT, h);
26647
- flipColors(h);
26648
- }
26649
- return h;
26650
- }
26651
- /**
26652
- * Returns the node that is at the top after the fix.
26653
- *
26654
- * Fix right-leaning red nodes.
26655
- *
26656
- * @internal
26657
- */
26658
- function fixUp(h) {
26659
- if (isRed(h[RIGHT])) {
26660
- h = tree_rotate(LEFT, h);
26369
+ y.left = x;
26370
+ x.parent = y;
26661
26371
  }
26662
- if (isRed(h[LEFT]) && isRed(h[LEFT][LEFT])) {
26663
- h = tree_rotate(RIGHT, h);
26372
+ rotateRight(x) {
26373
+ const y = x.left;
26374
+ x.left = y.right;
26375
+ if (y.right) {
26376
+ y.right.parent = x;
26377
+ }
26378
+ y.parent = x.parent;
26379
+ if (x.parent === undefined) {
26380
+ this.root = y;
26381
+ }
26382
+ else if (x === x.parent.right) {
26383
+ x.parent.right = y;
26384
+ }
26385
+ else {
26386
+ x.parent.left = y;
26387
+ }
26388
+ y.right = x;
26389
+ x.parent = y;
26664
26390
  }
26665
- // Split 4-nodes.
26666
- if (isRed(h[LEFT]) && isRed(h[RIGHT])) {
26667
- flipColors(h);
26391
+ colorOf(node) {
26392
+ return node ? node.color : BLACK;
26668
26393
  }
26669
- return h;
26670
26394
  }
26671
26395
 
26672
- //# sourceMappingURL=tree.js.map
26396
+ //# sourceMappingURL=rb-tree.js.map
26673
26397
  ;// ./src/mat/create-new-cp-trees.ts
26674
26398
 
26675
26399
 
@@ -26686,7 +26410,7 @@ function createNewCpTrees(cpNode) {
26686
26410
  const loop = cpNode.pointOnShape.curve.loop;
26687
26411
  let cpTree = cpTrees_.get(loop);
26688
26412
  if (!cpTree) {
26689
- cpTree = new LlRbTree(cpNodeComparator, false);
26413
+ cpTree = new RbTree(cpNodeComparator);
26690
26414
  cpTrees_.set(loop, cpTree);
26691
26415
  }
26692
26416
  cpTree.insert(cpNode);
@@ -27196,6 +26920,16 @@ function calcPosOrder(circleCenter, pos) {
27196
26920
  }
27197
26921
 
27198
26922
 
26923
+ ;// ./node_modules/flo-vector2d/node/distance-and-length/len.js
26924
+ /**
26925
+ * Returns the length of the given 2-vector.
26926
+ * @param p a 2d vector
26927
+ */
26928
+ function len(p) {
26929
+ return Math.sqrt(p[0] * p[0] + p[1] * p[1]);
26930
+ }
26931
+
26932
+ //# sourceMappingURL=len.js.map
27199
26933
  ;// ./node_modules/flo-vector2d/node/distance-and-length/length-squared.js
27200
26934
  /**
27201
26935
  * Returns the squared length of the given 2-vector.
@@ -27227,7 +26961,7 @@ function det3(x, y, z) {
27227
26961
  * Returns the circumcenter of the given 2d triangle.
27228
26962
  * @param triangle
27229
26963
  */
27230
- function circum_center_circumCenter(triangle) {
26964
+ function circumCenter(triangle) {
27231
26965
  // See wikipedia
27232
26966
  const p1 = triangle[0];
27233
26967
  const p2 = triangle[1];
@@ -27240,16 +26974,12 @@ function circum_center_circumCenter(triangle) {
27240
26974
  }
27241
26975
 
27242
26976
  //# sourceMappingURL=circum-center.js.map
27243
- ;// ./node_modules/flo-vector2d/node/distance-and-length/len.js
27244
- /**
27245
- * Returns the length of the given 2-vector.
27246
- * @param p a 2d vector
27247
- */
27248
- function len(p) {
27249
- return Math.sqrt(p[0] * p[0] + p[1] * p[1]);
27250
- }
26977
+ ;// ./src/find-3-prong/timed-cc.ts
26978
+
26979
+ // const timeCircumCenter = timeFunctionCalls(circumCenter);
26980
+ const timeCircumCenter = circumCenter;
26981
+
27251
26982
 
27252
- //# sourceMappingURL=len.js.map
27253
26983
  ;// ./node_modules/flo-bezier3/node/simultaneous-properties/closest-and-furthest-point-on-bezier/get-coeffs/double-double/get-footpoint-poly-3-dd.js
27254
26984
 
27255
26985
  const double_double_get_footpoint_poly_3_dd_td = two_diff_twoDiff;
@@ -27408,7 +27138,7 @@ function get_footpoint_poly_2_dd_getFootpointPoly2Dd(ps, p) {
27408
27138
  //# sourceMappingURL=get-footpoint-poly-2-dd.js.map
27409
27139
  ;// ./node_modules/flo-bezier3/node/simultaneous-properties/closest-and-furthest-point-on-bezier/get-coeffs/double-double/get-footpoint-poly-1-dd.js
27410
27140
 
27411
- const double_double_get_footpoint_poly_1_dd_tp = two_product_twoProduct;
27141
+ const double_double_get_footpoint_poly_1_dd_tp = twoProduct;
27412
27142
  const double_double_get_footpoint_poly_1_dd_qaq = ddAddDd;
27413
27143
  const get_footpoint_poly_1_dd_qmn2 = ddMultByNeg2;
27414
27144
  /**
@@ -27547,7 +27277,7 @@ function get_footpoint_poly_3_exact_getFootpointPoly3Exact(ps, p) {
27547
27277
  const t0a = eDiff(x01, exact_get_footpoint_poly_3_exact_sce(6, x00));
27548
27278
  const t0b = eDiff(y01, exact_get_footpoint_poly_3_exact_sce(6, y00));
27549
27279
  const t0 = fastExpansionSum(t0a, t0b);
27550
- return [t5, t4, t3, t2, t1, t0].map(e_compress_eCompress);
27280
+ return [t5, t4, t3, t2, t1, t0].map(eCompress);
27551
27281
  }
27552
27282
 
27553
27283
  //# sourceMappingURL=get-footpoint-poly-3-exact.js.map
@@ -27633,7 +27363,7 @@ function get_footpoint_poly_2_exact_getFootpointPoly2Exact(ps, p) {
27633
27363
  const t0a = eDiff(y01, y00);
27634
27364
  const t0b = eDiff(x01, x00);
27635
27365
  const t0 = fastExpansionSum(t0a, t0b);
27636
- return [t3, t2, t1, t0].map(e_compress_eCompress);
27366
+ return [t3, t2, t1, t0].map(eCompress);
27637
27367
  }
27638
27368
 
27639
27369
  //# sourceMappingURL=get-footpoint-poly-2-exact.js.map
@@ -27676,12 +27406,12 @@ function get_footpoint_poly_1_exact_getFootpointPoly1Exact(ps, p) {
27676
27406
  const t1 = fastExpansionSum(fastExpansionSum(x11, y11), fastExpansionSum(exact_get_footpoint_poly_1_exact_emn2(s1), s2));
27677
27407
  //const t0 = s1 - s2;
27678
27408
  const t0 = eDiff(s1, s2);
27679
- return [t1, t0].map(e_compress_eCompress);
27409
+ return [t1, t0].map(eCompress);
27680
27410
  }
27681
27411
 
27682
27412
  //# sourceMappingURL=get-footpoint-poly-1-exact.js.map
27683
27413
  ;// ./node_modules/flo-bezier3/node/simultaneous-properties/closest-and-furthest-point-on-bezier/get-coeffs/get-closest-on-bezier-from-point-error-counters.js
27684
- const get_coeffs_get_closest_on_bezier_from_point_error_counters_abs = Math.abs;
27414
+ const { abs: get_coeffs_get_closest_on_bezier_from_point_error_counters_abs } = Math;
27685
27415
  /**
27686
27416
  * Returns a representation of the error when calculating the polynomial whose
27687
27417
  * roots are all the `t` values on the given bezier curve such that the line
@@ -28034,7 +27764,7 @@ function get_foot_points_polys_on_bezier_certified_getFootPointsOnBezierPolysCer
28034
27764
 
28035
27765
  //# sourceMappingURL=get-foot-points-polys-on-bezier-certified.js.map
28036
27766
  ;// ./node_modules/flo-bezier3/node/local-properties-at-t/evaluate/eval-de-casteljau-error.js
28037
- const evaluate_eval_de_casteljau_error_abs = Math.abs;
27767
+ const { abs: evaluate_eval_de_casteljau_error_abs } = Math;
28038
27768
  /**
28039
27769
  * Returns a representation of the error (from which an absolute error bound
28040
27770
  * can be calculated) when evaluating the given bezier curve at the parameter `t`
@@ -28235,7 +27965,7 @@ function flo_bezier3_node_error_analysis_error_analysis_(n) {
28235
27965
 
28236
27966
  //# sourceMappingURL=error-analysis.js.map
28237
27967
  ;// ./node_modules/flo-bezier3/node/transformation/split/from-to/from-to-1-incl-error-bound.js
28238
- const from_to_from_to_1_incl_error_bound_abs = Math.abs;
27968
+ const { abs: from_to_from_to_1_incl_error_bound_abs } = Math;
28239
27969
  /** error free error bounds */
28240
27970
  const from_to_from_to_1_incl_error_bound_psErrorFree = [[0, 0], [0, 0]];
28241
27971
  /**
@@ -28447,9 +28177,7 @@ function from_to_from_to_1_incl_error_bound_splitAtBoth1(ps, tS, tE) {
28447
28177
 
28448
28178
 
28449
28179
 
28450
- const get_interval_box_get_interval_box_eps = Number.EPSILON;
28451
- const get_interval_box_get_interval_box_u = get_interval_box_get_interval_box_eps / 2;
28452
- const get_interval_box_get_interval_box_1 = node_error_analysis_error_analysis_(1);
28180
+ const { min: get_interval_box_min, max: get_interval_box_max } = Math;
28453
28181
  /**
28454
28182
  * Returns an axis-aligned-box that is guaranteed to engulf the entire
28455
28183
  * given bezier curve from t1 to t2. The returned box is given as a pair
@@ -28495,22 +28223,22 @@ function get_interval_box_getIntervalBox3(ps, ts) {
28495
28223
  const x1 = psI[1][0];
28496
28224
  const x2 = psI[2][0];
28497
28225
  const x3 = psI[3][0];
28498
- const _x0 = 9 * get_interval_box_get_interval_box_u * _psI[0][0];
28499
- const _x1 = 9 * get_interval_box_get_interval_box_u * _psI[1][0];
28500
- const _x2 = 9 * get_interval_box_get_interval_box_u * _psI[2][0];
28501
- const _x3 = 9 * get_interval_box_get_interval_box_u * _psI[3][0];
28226
+ const _x0 = 9 * error_analysis_error_analysis_u * _psI[0][0];
28227
+ const _x1 = 9 * error_analysis_error_analysis_u * _psI[1][0];
28228
+ const _x2 = 9 * error_analysis_error_analysis_u * _psI[2][0];
28229
+ const _x3 = 9 * error_analysis_error_analysis_u * _psI[3][0];
28502
28230
  const y0 = psI[0][1];
28503
28231
  const y1 = psI[1][1];
28504
28232
  const y2 = psI[2][1];
28505
28233
  const y3 = psI[3][1];
28506
- const _y0 = 9 * get_interval_box_get_interval_box_u * _psI[0][1];
28507
- const _y1 = 9 * get_interval_box_get_interval_box_u * _psI[1][1];
28508
- const _y2 = 9 * get_interval_box_get_interval_box_u * _psI[2][1];
28509
- const _y3 = 9 * get_interval_box_get_interval_box_u * _psI[3][1];
28510
- const minX = Math.min(x0 - _x0, x1 - _x1, x2 - _x2, x3 - _x3);
28511
- const maxX = Math.max(x0 + _x0, x1 + _x1, x2 + _x2, x3 + _x3);
28512
- const minY = Math.min(y0 - _y0, y1 - _y1, y2 - _y2, y3 - _y3);
28513
- const maxY = Math.max(y0 + _y0, y1 + _y1, y2 + _y2, y3 + _y3);
28234
+ const _y0 = 9 * error_analysis_error_analysis_u * _psI[0][1];
28235
+ const _y1 = 9 * error_analysis_error_analysis_u * _psI[1][1];
28236
+ const _y2 = 9 * error_analysis_error_analysis_u * _psI[2][1];
28237
+ const _y3 = 9 * error_analysis_error_analysis_u * _psI[3][1];
28238
+ const minX = get_interval_box_min(x0 - _x0, x1 - _x1, x2 - _x2, x3 - _x3);
28239
+ const maxX = get_interval_box_max(x0 + _x0, x1 + _x1, x2 + _x2, x3 + _x3);
28240
+ const minY = get_interval_box_min(y0 - _y0, y1 - _y1, y2 - _y2, y3 - _y3);
28241
+ const maxY = get_interval_box_max(y0 + _y0, y1 + _y1, y2 + _y2, y3 + _y3);
28514
28242
  return [[minX, minY], [maxX, maxY]];
28515
28243
  }
28516
28244
  /**
@@ -28531,19 +28259,19 @@ function get_interval_box_getIntervalBox2(ps, ts) {
28531
28259
  const x0 = psI[0][0];
28532
28260
  const x1 = psI[1][0];
28533
28261
  const x2 = psI[2][0];
28534
- const _x0 = 5 * get_interval_box_get_interval_box_u * _psI[0][0];
28535
- const _x1 = 5 * get_interval_box_get_interval_box_u * _psI[1][0];
28536
- const _x2 = 5 * get_interval_box_get_interval_box_u * _psI[2][0];
28262
+ const _x0 = 5 * error_analysis_error_analysis_u * _psI[0][0];
28263
+ const _x1 = 5 * error_analysis_error_analysis_u * _psI[1][0];
28264
+ const _x2 = 5 * error_analysis_error_analysis_u * _psI[2][0];
28537
28265
  const y0 = psI[0][1];
28538
28266
  const y1 = psI[1][1];
28539
28267
  const y2 = psI[2][1];
28540
- const _y0 = 5 * get_interval_box_get_interval_box_u * _psI[0][1];
28541
- const _y1 = 5 * get_interval_box_get_interval_box_u * _psI[1][1];
28542
- const _y2 = 5 * get_interval_box_get_interval_box_u * _psI[2][1];
28543
- const minX = Math.min(x0 - _x0, x1 - _x1, x2 - _x2);
28544
- const maxX = Math.max(x0 + _x0, x1 + _x1, x2 + _x2);
28545
- const minY = Math.min(y0 - _y0, y1 - _y1, y2 - _y2);
28546
- const maxY = Math.max(y0 + _y0, y1 + _y1, y2 + _y2);
28268
+ const _y0 = 5 * error_analysis_error_analysis_u * _psI[0][1];
28269
+ const _y1 = 5 * error_analysis_error_analysis_u * _psI[1][1];
28270
+ const _y2 = 5 * error_analysis_error_analysis_u * _psI[2][1];
28271
+ const minX = get_interval_box_min(x0 - _x0, x1 - _x1, x2 - _x2);
28272
+ const maxX = get_interval_box_max(x0 + _x0, x1 + _x1, x2 + _x2);
28273
+ const minY = get_interval_box_min(y0 - _y0, y1 - _y1, y2 - _y2);
28274
+ const maxY = get_interval_box_max(y0 + _y0, y1 + _y1, y2 + _y2);
28547
28275
  return [[minX, minY], [maxX, maxY]];
28548
28276
  }
28549
28277
  /**
@@ -28565,16 +28293,16 @@ function get_interval_box_getIntervalBox1(ps, ts) {
28565
28293
  const { ps: psI, _ps: _psI } = from_to_1_incl_error_bound_fromTo1InclErrorBound(ps, ts[0], ts[1]);
28566
28294
  const x0 = psI[0][0];
28567
28295
  const x1 = psI[1][0];
28568
- const _x0 = 3 * get_interval_box_get_interval_box_u * _psI[0][0];
28569
- const _x1 = 3 * get_interval_box_get_interval_box_u * _psI[1][0];
28296
+ const _x0 = 3 * error_analysis_error_analysis_u * _psI[0][0];
28297
+ const _x1 = 3 * error_analysis_error_analysis_u * _psI[1][0];
28570
28298
  const y0 = psI[0][1];
28571
28299
  const y1 = psI[1][1];
28572
- const _y0 = 3 * get_interval_box_get_interval_box_u * _psI[0][1];
28573
- const _y1 = 3 * get_interval_box_get_interval_box_u * _psI[1][1];
28574
- const minX = Math.min(x0 - _x0, x1 - _x1);
28575
- const maxX = Math.max(x0 + _x0, x1 + _x1);
28576
- const minY = Math.min(y0 - _y0, y1 - _y1);
28577
- const maxY = Math.max(y0 + _y0, y1 + _y1);
28300
+ const _y0 = 3 * error_analysis_error_analysis_u * _psI[0][1];
28301
+ const _y1 = 3 * error_analysis_error_analysis_u * _psI[1][1];
28302
+ const minX = get_interval_box_min(x0 - _x0, x1 - _x1);
28303
+ const maxX = get_interval_box_max(x0 + _x0, x1 + _x1);
28304
+ const minY = get_interval_box_min(y0 - _y0, y1 - _y1);
28305
+ const maxY = get_interval_box_max(y0 + _y0, y1 + _y1);
28578
28306
  return [[minX, minY], [maxX, maxY]];
28579
28307
  }
28580
28308
  /**
@@ -28595,13 +28323,13 @@ function get_interval_box_getIntervalBoxAtT(ps, t) {
28595
28323
  const p = eval_de_casteljau_evalDeCasteljau(ps, t);
28596
28324
  let pE;
28597
28325
  if (ps.length === 4) {
28598
- pE = eval_de_casteljau_error_evalDeCasteljauError(ps, [0, t]).map(c_ => 8 * get_interval_box_get_interval_box_1 * c_);
28326
+ pE = eval_de_casteljau_error_evalDeCasteljauError(ps, [0, t]).map(c_ => 8 * error_analysis_error_analysis_1 * c_);
28599
28327
  }
28600
28328
  else if (ps.length === 3) {
28601
- pE = eval_de_casteljau_error_evalDeCasteljauError(ps, [0, t]).map(c_ => 5 * get_interval_box_get_interval_box_1 * c_);
28329
+ pE = eval_de_casteljau_error_evalDeCasteljauError(ps, [0, t]).map(c_ => 5 * error_analysis_error_analysis_1 * c_);
28602
28330
  }
28603
28331
  else if (ps.length === 2) {
28604
- pE = eval_de_casteljau_error_evalDeCasteljauError(ps, [0, t]).map(c_ => 2 * get_interval_box_get_interval_box_1 * c_);
28332
+ pE = eval_de_casteljau_error_evalDeCasteljauError(ps, [0, t]).map(c_ => 2 * error_analysis_error_analysis_1 * c_);
28605
28333
  }
28606
28334
  else if (ps.length === 1) {
28607
28335
  return [p, p];
@@ -28612,17 +28340,81 @@ function get_interval_box_getIntervalBoxAtT(ps, t) {
28612
28340
  ];
28613
28341
  }
28614
28342
 
28615
- // 416
28616
28343
  //# sourceMappingURL=get-interval-box.js.map
28617
- ;// ./src/closest-boundary-point/root-interval-to-distance-squared-interval.ts
28618
- /* unused harmony import specifier */ var root_interval_to_distance_squared_interval_eEstimate;
28344
+ ;// ./node_modules/flo-bezier3/node/local-properties-at-t/evaluate/double-double/eval-de-casteljau-dd.js
28345
+
28346
+ const double_double_eval_de_casteljau_dd_qmq = ddMultDd;
28347
+ const double_double_eval_de_casteljau_dd_qaq = ddAddDd;
28348
+ const double_double_eval_de_casteljau_dd_qdq = ddDiffDd;
28349
+ const double_double_eval_de_casteljau_dd_td = two_diff_twoDiff;
28350
+ const double_double_eval_de_casteljau_dd_qad = ddAddDouble;
28351
+ /**
28352
+ * Returns the resulting point (in double-double precision) of evaluating the
28353
+ * given bezier curve at the given parameter `t` (given as a double-double
28354
+ * precision floating point number).
28355
+ *
28356
+ * * uses [De Casteljau's algorithm](https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm)
28357
+ * with intermediate calculations done in double-double precision floating point
28358
+ * arithmetic.
28359
+ *
28360
+ * * to get an absolute error bound on the result call [[evalDeCasteljauError]]
28361
+ *
28362
+ * @param ps an order 1,2 or 3 bezier curve, e.g. `[[0,0],[1,1],[2,1],[2,0]]`
28363
+ * @param t the parameter value where the bezier should be evaluated (given in
28364
+ * double-double precision)
28365
+ *
28366
+ * @doc mdx
28367
+ **/
28368
+ function eval_de_casteljau_dd_evalDeCasteljauDd(ps, t) {
28369
+ if (t[0] === 0 && t[1] === 0) {
28370
+ return ps[0].map(c => [0, c]);
28371
+ }
28372
+ else if (t[0] === 0 && t[1] === 1) {
28373
+ return ps[ps.length - 1].map(c => [0, c]);
28374
+ }
28375
+ if (ps.length === 4) {
28376
+ const [[x0, y0], [x1, y1], [x2, y2], [x3, y3]] = ps;
28377
+ const a01 = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(x1, x0), t), x0);
28378
+ const a11 = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(x2, x1), t), x1);
28379
+ const a21 = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(x3, x2), t), x2);
28380
+ const a02 = double_double_eval_de_casteljau_dd_qaq(a01, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(a11, a01), t));
28381
+ const a12 = double_double_eval_de_casteljau_dd_qaq(a11, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(a21, a11), t));
28382
+ const x = double_double_eval_de_casteljau_dd_qaq(a02, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(a12, a02), t));
28383
+ const b01 = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(y1, y0), t), y0);
28384
+ const b11 = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(y2, y1), t), y1);
28385
+ const b21 = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(y3, y2), t), y2);
28386
+ const b02 = double_double_eval_de_casteljau_dd_qaq(b01, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(b11, b01), t));
28387
+ const b12 = double_double_eval_de_casteljau_dd_qaq(b11, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(b21, b11), t));
28388
+ const y = double_double_eval_de_casteljau_dd_qaq(b02, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(b12, b02), t));
28389
+ return [x, y];
28390
+ }
28391
+ if (ps.length === 3) {
28392
+ const [[x0, y0], [x1, y1], [x2, y2]] = ps;
28393
+ const a01 = double_double_eval_de_casteljau_dd_qaq([0, x0], double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(x1, x0), t));
28394
+ const a11 = double_double_eval_de_casteljau_dd_qaq([0, x1], double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(x2, x1), t));
28395
+ const x = double_double_eval_de_casteljau_dd_qaq(a01, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(a11, a01), t));
28396
+ const b01 = double_double_eval_de_casteljau_dd_qaq([0, y0], double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(y1, y0), t));
28397
+ const b11 = double_double_eval_de_casteljau_dd_qaq([0, y1], double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(y2, y1), t));
28398
+ const y = double_double_eval_de_casteljau_dd_qaq(b01, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(b11, b01), t));
28399
+ return [x, y];
28400
+ }
28401
+ if (ps.length === 2) {
28402
+ const [[x0, y0], [x1, y1]] = ps;
28403
+ const x = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(x1, x0), t), x0);
28404
+ const y = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(y1, y0), t), y0);
28405
+ return [x, y];
28406
+ }
28407
+ if (ps.length === 1) {
28408
+ const [x, y] = ps[0];
28409
+ return [[0, x], [0, y]];
28410
+ }
28411
+ throw new Error('The given bezier curve must be of order <= 3.');
28412
+ }
28619
28413
 
28414
+ //# sourceMappingURL=eval-de-casteljau-dd.js.map
28415
+ ;// ./src/closest-boundary-point/root-interval-to-distance-squared-interval.ts
28620
28416
 
28621
- // We *have* to do the below to improve performance with bundlers❗ The assignee is a getter❗ The assigned is a pure function❗
28622
- const root_interval_to_distance_squared_interval_estimate = (/* unused pure expression or super */ null && (root_interval_to_distance_squared_interval_eEstimate));
28623
- const closest_boundary_point_root_interval_to_distance_squared_interval_td = twoDiff;
28624
- // const emult = eMult;
28625
- // const eadd = eAdd;
28417
+ const closest_boundary_point_root_interval_to_distance_squared_interval_td = two_diff_twoDiff;
28626
28418
  const root_interval_to_distance_squared_interval_qmq = ddMultDd;
28627
28419
  const root_interval_to_distance_squared_interval_qaq = ddAddDd;
28628
28420
  const closest_boundary_point_root_interval_to_distance_squared_interval_eps = Number.EPSILON;
@@ -28637,7 +28429,7 @@ const closest_boundary_point_root_interval_to_distance_squared_interval_eps = Nu
28637
28429
  *
28638
28430
  * @internal
28639
28431
  */
28640
- function root_interval_to_distance_squared_interval_rootIntervalToDistanceSquaredInterval(maxCoordPowerOf2, box, p) {
28432
+ function root_interval_to_distance_squared_interval_rootIntervalToDistanceSquaredInterval(box, p) {
28641
28433
  const bl = box[0];
28642
28434
  const tr = box[1];
28643
28435
  const minX = bl[0];
@@ -28666,8 +28458,10 @@ function root_interval_to_distance_squared_interval_rootIntervalToDistanceSquare
28666
28458
  // const dc1 = estimate(dc1Exact);
28667
28459
  const dc1Dd = root_interval_to_distance_squared_interval_qaq(root_interval_to_distance_squared_interval_qmq(ax, ax), root_interval_to_distance_squared_interval_qmq(by, by)); // ax**2 + bx**2
28668
28460
  const dc1 = dc1Dd[1];
28669
- const dc1Min = dc1 * (1 - 2 ** maxCoordPowerOf2 * closest_boundary_point_root_interval_to_distance_squared_interval_eps); // distance minus max error
28670
- const dc1Max = dc1 * (1 + 2 ** maxCoordPowerOf2 * closest_boundary_point_root_interval_to_distance_squared_interval_eps); // distance plus max error
28461
+ // const dc1Min = dc1*(1 - 2**maxCoordPowerOf2*eps); // distance minus max error
28462
+ // const dc1Max = dc1*(1 + 2**maxCoordPowerOf2*eps); // distance plus max error
28463
+ const dc1Min = dc1 * (1 - closest_boundary_point_root_interval_to_distance_squared_interval_eps); // distance minus max error
28464
+ const dc1Max = dc1 * (1 + closest_boundary_point_root_interval_to_distance_squared_interval_eps); // distance plus max error
28671
28465
  if (dc1Min <= minDSquared) {
28672
28466
  minDSquared = dc1Min;
28673
28467
  }
@@ -28679,15 +28473,61 @@ function root_interval_to_distance_squared_interval_rootIntervalToDistanceSquare
28679
28473
  }
28680
28474
 
28681
28475
 
28682
- ;// ./src/closest-boundary-point/get-p-from-box.ts
28683
- /** @internal */
28684
- function get_p_from_box_getPFromBox(box) {
28685
- const tl = box[0];
28686
- const br = box[1];
28687
- return [
28688
- (tl[0] + br[0]) / 2,
28689
- (tl[1] + br[1]) / 2,
28690
- ];
28476
+ ;// ./src/find-2-prong/squared-distance-between-dd.ts
28477
+
28478
+ function squaredDistanceBetweenDd(x, y) {
28479
+ const [x0, y0] = x;
28480
+ const [x1, y1] = y;
28481
+ // xd = x0 - x1;
28482
+ // yd = y0 - y1;
28483
+ // xx = xd**2;
28484
+ // yy = yd**2;
28485
+ // return xx + yy
28486
+ const xd = two_diff_twoDiff(x0, x1);
28487
+ const yd = two_diff_twoDiff(y0, y1);
28488
+ const xx = ddMultDd(xd, xd);
28489
+ const yy = ddMultDd(yd, yd);
28490
+ return ddAddDd(xx, yy)[1];
28491
+ }
28492
+
28493
+
28494
+ ;// ./src/error-analysis/gamma.ts
28495
+ /** `2 * 2^-53` -> 2x the standard round-of unit `=== Number.EPSILON` */
28496
+ const gamma_eps = Number.EPSILON;
28497
+ /** `2^-53` -> the standard round-of unit `=== eps/2` */
28498
+ const gamma_u = gamma_eps / 2;
28499
+ /** `2^-106` -> the standard round-of unit for double-double precision `=== (eps/2)**2` */
28500
+ const gamma_uu = gamma_u * gamma_u;
28501
+ /**
28502
+ * The canonical floating point error function, γ.
28503
+ *
28504
+ * * roughly `=== n * (Number.EPSILON / 2)`
28505
+ * * see e.g. [Algorithms for Accurate, Validated and Fast Polynomial Evaluation](https://hal.archives-ouvertes.fr/hal-00285603/document)
28506
+ * @param n the parameter - typically a small positive integer, e.g. for
28507
+ * polynomial evaluation this === 2*d + 1, where d is the degree of the
28508
+ * polynomial
28509
+ *
28510
+ * @doc
28511
+ */
28512
+ function gamma_(n) {
28513
+ const nu = n * gamma_u;
28514
+ return nu / (1 - nu);
28515
+ }
28516
+ /**
28517
+ * The canonical, once compensated (implying double-double precision),
28518
+ * floating point error function.
28519
+ *
28520
+ * * roughly `=== n * (Number.EPSILON / 2)**2`
28521
+ * * see e.g. [Algorithms for Accurate, Validated and Fast Polynomial Evaluation](https://hal.archives-ouvertes.fr/hal-00285603/document)
28522
+ * @param n the parameter - typically a small positive integer, e.g. for
28523
+ * polynomial evaluation this === 2*d + 1, where d is the degree of the
28524
+ * polynomial
28525
+ *
28526
+ * @doc
28527
+ */
28528
+ function error_analysis_gamma_(n) {
28529
+ const nuu = n * gamma_uu;
28530
+ return nuu / (1 - nuu);
28691
28531
  }
28692
28532
 
28693
28533
 
@@ -28696,41 +28536,51 @@ function get_p_from_box_getPFromBox(box) {
28696
28536
 
28697
28537
 
28698
28538
 
28699
- const { sqrt: get_potential_closest_points_on_curve_certified_sqrt } = Math;
28539
+
28700
28540
  /**
28701
28541
  * @internal
28702
28542
  *
28703
- * @param maxCoordPowerOf2
28704
28543
  * @param curve the curve
28705
28544
  * @param x the point from which to check
28706
28545
  * @param tRange The allowed t range
28707
28546
  */
28708
- function getPotentialClosestPointsOnCurveCertified(maxCoordPowerOf2, curve, x, tRange) {
28547
+ function getPotentialClosestPointsOnCurveCertified(curve, x, tRange) {
28709
28548
  const [tS, tE] = tRange;
28710
- const ps = curve.ps;
28711
- let { polyDd: pDd, polyE: pDd_, getPolyExact } = get_foot_points_polys_on_bezier_certified_getFootPointsOnBezierPolysCertified(ps, x);
28712
- const ris = roots(pDd, tS, tE, pDd_, getPolyExact) || [];
28713
- ris.push(createRootExact(tS));
28714
- ris.push(createRootExact(tE));
28715
- const infos = ris
28716
- .map(ri => {
28717
- const { tS: ts, tE: te } = ri;
28718
- const _t = (ts + te) / 2;
28719
- const t = _t < 0 ? 0 : _t > 1 ? 1 : _t;
28720
- const box = get_interval_box_getIntervalBox(ps, [ts, te]);
28721
- const p_ = get_p_from_box_getPFromBox(box);
28722
- const dSquaredI = root_interval_to_distance_squared_interval_rootIntervalToDistanceSquaredInterval(maxCoordPowerOf2, box, x);
28549
+ const { ps } = curve;
28550
+ const infos = [];
28551
+ if (tS !== tE) {
28552
+ const { polyDd: pDd, polyE: pDd_, getPolyExact } = get_foot_points_polys_on_bezier_certified_getFootPointsOnBezierPolysCertified(ps, x);
28553
+ const ris = roots(pDd, tS, tE, pDd_, getPolyExact) || [];
28554
+ infos.push(...ris.map(ri => {
28555
+ const { tS: ts, tE: te, t: _t } = ri;
28556
+ const t = _t < 0 ? 0 : _t > 1 ? 1 : _t;
28557
+ const box = get_interval_box_getIntervalBox(ps, [ts, te]);
28558
+ const dSquaredI = root_interval_to_distance_squared_interval_rootIntervalToDistanceSquaredInterval(box, x);
28559
+ const t_ = t === 0 ? 1 : t;
28560
+ const curve_ = t === 0 ? curve.prev : curve;
28561
+ return {
28562
+ curve: curve_,
28563
+ t: t_,
28564
+ dSquaredI
28565
+ };
28566
+ }));
28567
+ }
28568
+ const ts = tRange.slice();
28569
+ if (tS === tE) {
28570
+ ts.push(tS);
28571
+ }
28572
+ infos.push(...ts.map(t => {
28573
+ const p = eval_de_casteljau_dd_evalDeCasteljauDd(ps, [0, t]).map(v => v[0] + v[1]);
28574
+ const d = squaredDistanceBetweenDd(p, x);
28575
+ const dSquaredI = [d * (1 - gamma_eps), d * (1 + gamma_eps)];
28723
28576
  const t_ = t === 0 ? 1 : t;
28724
28577
  const curve_ = t === 0 ? curve.prev : curve;
28725
28578
  return {
28726
28579
  curve: curve_,
28727
- p: p_,
28728
28580
  t: t_,
28729
- d: (get_potential_closest_points_on_curve_certified_sqrt(dSquaredI[0]) + get_potential_closest_points_on_curve_certified_sqrt(dSquaredI[1])) / 2,
28730
- dSquaredI,
28731
- box
28581
+ dSquaredI
28732
28582
  };
28733
- });
28583
+ }));
28734
28584
  return infos;
28735
28585
  }
28736
28586
 
@@ -28964,6 +28814,7 @@ function cullByLooseBoundingBox(curvePieces, xO, xy2) {
28964
28814
 
28965
28815
 
28966
28816
 
28817
+ const { sqrt: get_bounding_box_tight_sqrt } = Math;
28967
28818
  /**
28968
28819
  * Returns a **non-certified**, **rotated**, **tight** bounding box of the given
28969
28820
  * bezier curve as four ordered points of a rotated rectangle (with each given
@@ -28983,12 +28834,12 @@ function get_bounding_box_tight_getBoundingBoxTight(ps) {
28983
28834
  const len = control_point_lines_length_controlPointLinesLength(ps);
28984
28835
  if (squaredDistanceBetween(ps[0], ps[ps.length - 1]) * 2 ** 8 < len * len) {
28985
28836
  const [xE_, yE_] = eval_de_casteljau_evalDeCasteljau(ps, 0.5);
28986
- const hypotenuse = Math.sqrt((xE_ - xS) * (xE_ - xS) + (yE_ - yS) * (yE_ - yS));
28837
+ const hypotenuse = get_bounding_box_tight_sqrt((xE_ - xS) * (xE_ - xS) + (yE_ - yS) * (yE_ - yS));
28987
28838
  sinθ = (yE_ - yS) / hypotenuse;
28988
28839
  cosθ = (xE_ - xS) / hypotenuse;
28989
28840
  }
28990
28841
  else {
28991
- const hypotenuse = Math.sqrt((xE - xS) * (xE - xS) + (yE - yS) * (yE - yS));
28842
+ const hypotenuse = get_bounding_box_tight_sqrt((xE - xS) * (xE - xS) + (yE - yS) * (yE - yS));
28992
28843
  sinθ = (yE - yS) / hypotenuse;
28993
28844
  cosθ = (xE - xS) / hypotenuse;
28994
28845
  }
@@ -29110,77 +28961,6 @@ function cullCurvePieces1(curvePieces, xO) {
29110
28961
  }
29111
28962
 
29112
28963
 
29113
- ;// ./node_modules/flo-bezier3/node/local-properties-at-t/evaluate/double-double/eval-de-casteljau-dd.js
29114
-
29115
- const double_double_eval_de_casteljau_dd_qmq = ddMultDd;
29116
- const double_double_eval_de_casteljau_dd_qaq = ddAddDd;
29117
- const double_double_eval_de_casteljau_dd_qdq = ddDiffDd;
29118
- const double_double_eval_de_casteljau_dd_td = two_diff_twoDiff;
29119
- const double_double_eval_de_casteljau_dd_qad = ddAddDouble;
29120
- /**
29121
- * Returns the resulting point (in double-double precision) of evaluating the
29122
- * given bezier curve at the given parameter `t` (given as a double-double
29123
- * precision floating point number).
29124
- *
29125
- * * uses [De Casteljau's algorithm](https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm)
29126
- * with intermediate calculations done in double-double precision floating point
29127
- * arithmetic.
29128
- *
29129
- * * to get an absolute error bound on the result call [[evalDeCasteljauError]]
29130
- *
29131
- * @param ps an order 1,2 or 3 bezier curve, e.g. `[[0,0],[1,1],[2,1],[2,0]]`
29132
- * @param t the parameter value where the bezier should be evaluated (given in
29133
- * double-double precision)
29134
- *
29135
- * @doc mdx
29136
- **/
29137
- function eval_de_casteljau_dd_evalDeCasteljauDd(ps, t) {
29138
- if (t[0] === 0 && t[1] === 0) {
29139
- return ps[0].map(c => [0, c]);
29140
- }
29141
- else if (t[0] === 0 && t[1] === 1) {
29142
- return ps[ps.length - 1].map(c => [0, c]);
29143
- }
29144
- if (ps.length === 4) {
29145
- const [[x0, y0], [x1, y1], [x2, y2], [x3, y3]] = ps;
29146
- const a01 = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(x1, x0), t), x0);
29147
- const a11 = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(x2, x1), t), x1);
29148
- const a21 = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(x3, x2), t), x2);
29149
- const a02 = double_double_eval_de_casteljau_dd_qaq(a01, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(a11, a01), t));
29150
- const a12 = double_double_eval_de_casteljau_dd_qaq(a11, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(a21, a11), t));
29151
- const x = double_double_eval_de_casteljau_dd_qaq(a02, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(a12, a02), t));
29152
- const b01 = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(y1, y0), t), y0);
29153
- const b11 = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(y2, y1), t), y1);
29154
- const b21 = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(y3, y2), t), y2);
29155
- const b02 = double_double_eval_de_casteljau_dd_qaq(b01, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(b11, b01), t));
29156
- const b12 = double_double_eval_de_casteljau_dd_qaq(b11, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(b21, b11), t));
29157
- const y = double_double_eval_de_casteljau_dd_qaq(b02, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(b12, b02), t));
29158
- return [x, y];
29159
- }
29160
- if (ps.length === 3) {
29161
- const [[x0, y0], [x1, y1], [x2, y2]] = ps;
29162
- const a01 = double_double_eval_de_casteljau_dd_qaq([0, x0], double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(x1, x0), t));
29163
- const a11 = double_double_eval_de_casteljau_dd_qaq([0, x1], double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(x2, x1), t));
29164
- const x = double_double_eval_de_casteljau_dd_qaq(a01, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(a11, a01), t));
29165
- const b01 = double_double_eval_de_casteljau_dd_qaq([0, y0], double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(y1, y0), t));
29166
- const b11 = double_double_eval_de_casteljau_dd_qaq([0, y1], double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(y2, y1), t));
29167
- const y = double_double_eval_de_casteljau_dd_qaq(b01, double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_qdq(b11, b01), t));
29168
- return [x, y];
29169
- }
29170
- if (ps.length === 2) {
29171
- const [[x0, y0], [x1, y1]] = ps;
29172
- const x = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(x1, x0), t), x0);
29173
- const y = double_double_eval_de_casteljau_dd_qad(double_double_eval_de_casteljau_dd_qmq(double_double_eval_de_casteljau_dd_td(y1, y0), t), y0);
29174
- return [x, y];
29175
- }
29176
- if (ps.length === 1) {
29177
- const [x, y] = ps[0];
29178
- return [[0, x], [0, y]];
29179
- }
29180
- throw new Error('The given bezier curve must be of order <= 3.');
29181
- }
29182
-
29183
- //# sourceMappingURL=eval-de-casteljau-dd.js.map
29184
28964
  ;// ./src/point-on-shape/to-p.ts
29185
28965
 
29186
28966
  /**
@@ -29209,12 +28989,12 @@ function toP(ps, t) {
29209
28989
  *
29210
28990
  * @internal
29211
28991
  */
29212
- function getCloseBoundaryPointsCertified(maxCoordPowerOf2, curvePieces, x) {
28992
+ function getCloseBoundaryPointsCertified(curvePieces, x) {
29213
28993
  curvePieces = cullCurvePieces1(curvePieces, x);
29214
28994
  const pInfos = [];
29215
28995
  for (let i = 0; i < curvePieces.length; i++) {
29216
28996
  const curvePiece = curvePieces[i];
29217
- const _pInfos = getPotentialClosestPointsOnCurveCertified(maxCoordPowerOf2, curvePiece.curve, x, curvePiece.ts);
28997
+ const _pInfos = getPotentialClosestPointsOnCurveCertified(curvePiece.curve, x, curvePiece.ts);
29218
28998
  pInfos.push(..._pInfos);
29219
28999
  }
29220
29000
  /** the minimum max interval value */
@@ -29244,7 +29024,8 @@ function getCloseBoundaryPointsCertified(maxCoordPowerOf2, curvePieces, x) {
29244
29024
 
29245
29025
 
29246
29026
  ;// ./src/find-3-prong/calc-initial-3-prong-center.ts
29247
-
29027
+ // import { circumCenter } from 'flo-vector2d';
29028
+ // TODO - testing - restore
29248
29029
 
29249
29030
  /**
29250
29031
  * Finds an initial 3-prong circle center point from which to iterate. The point
@@ -29257,16 +29038,16 @@ function getCloseBoundaryPointsCertified(maxCoordPowerOf2, curvePieces, x) {
29257
29038
  *
29258
29039
  * @internal
29259
29040
  */
29260
- function calcInitial3ProngCenter(maxCoordPowerOf2, δ3s, curvePiece3s) {
29041
+ function calcInitial3ProngCenter(δ3s, curvePiece3s) {
29261
29042
  const circle = δ3s[0][0].pointOnShape.circle;
29262
29043
  const twoProngCircleCenter = circle.center;
29263
- const pos = getCloseBoundaryPointsCertified(maxCoordPowerOf2, curvePiece3s[1], twoProngCircleCenter)[0];
29044
+ const pos = getCloseBoundaryPointsCertified(curvePiece3s[1], twoProngCircleCenter)[0];
29264
29045
  const meanPoints = [
29265
29046
  δ3s[0][0].pointOnShape.p,
29266
29047
  pos.p,
29267
29048
  δ3s[2][1].pointOnShape.p,
29268
29049
  ];
29269
- return circum_center_circumCenter(meanPoints);
29050
+ return timeCircumCenter(meanPoints);
29270
29051
  }
29271
29052
 
29272
29053
 
@@ -29279,9 +29060,9 @@ function calcInitial3ProngCenter(maxCoordPowerOf2, δ3s, curvePiece3s) {
29279
29060
  *
29280
29061
  * @internal
29281
29062
  */
29282
- function getClosestPoints(maxCoordPowerOf2, x, curvePiece3s) {
29063
+ function getClosestPoints(x, curvePiece3s) {
29283
29064
  return curvePiece3s.map(curvePieces => {
29284
- return getCloseBoundaryPointsCertified(maxCoordPowerOf2, curvePieces, x)[0];
29065
+ return getCloseBoundaryPointsCertified(curvePieces, x)[0];
29285
29066
  });
29286
29067
  }
29287
29068
 
@@ -29298,7 +29079,9 @@ function scale(p, c) {
29298
29079
 
29299
29080
  //# sourceMappingURL=scale.js.map
29300
29081
  ;// ./src/find-3-prong/calc-better-x.ts
29082
+ // import { fromTo, circumCenter, len, scale, translate } from 'flo-vector2d';
29301
29083
 
29084
+ // TODO - testing - restore
29302
29085
 
29303
29086
  /**
29304
29087
  * Find new `x` and `ps` that are better estimates of the 3-prong circle.
@@ -29314,7 +29097,7 @@ function scale(p, c) {
29314
29097
  *
29315
29098
  * @internal
29316
29099
  */
29317
- function calcBetterX(maxCoordPowerOf2, curvePiece3s, x, vectorToZeroV) {
29100
+ function calcBetterX(curvePiece3s, x, vectorToZeroV) {
29318
29101
  const V = len(vectorToZeroV);
29319
29102
  let nu = 1;
29320
29103
  let better;
@@ -29325,9 +29108,9 @@ function calcBetterX(maxCoordPowerOf2, curvePiece3s, x, vectorToZeroV) {
29325
29108
  do {
29326
29109
  const shift = scale(vectorToZeroV, nu);
29327
29110
  newX = translate(shift, x);
29328
- newPoss = getClosestPoints(maxCoordPowerOf2, newX, curvePiece3s);
29111
+ newPoss = curvePiece3s.map(curvePieces => getCloseBoundaryPointsCertified(curvePieces, x)[0]);
29329
29112
  // Point of zero V
29330
- const newCircleCenter = circum_center_circumCenter(newPoss.map(pos => pos.p));
29113
+ const newCircleCenter = timeCircumCenter(newPoss.map(pos => pos.p));
29331
29114
  const newVectorToZeroV = from_to_fromTo(newX, newCircleCenter);
29332
29115
  newV = len(newVectorToZeroV);
29333
29116
  better = newV < V;
@@ -29339,7 +29122,9 @@ function calcBetterX(maxCoordPowerOf2, curvePiece3s, x, vectorToZeroV) {
29339
29122
 
29340
29123
 
29341
29124
  ;// ./src/find-3-prong/find-3-prong-for-delta3s.ts
29125
+ // import { fromTo, circumCenter as getCircumCenter, len, distanceBetween, toUnitVector, rotate90Degrees, cross } from 'flo-vector2d';
29342
29126
 
29127
+ // TODO - testing - restore
29343
29128
 
29344
29129
 
29345
29130
 
@@ -29389,13 +29174,28 @@ function find3ProngForDelta3s(δs, idx, k, curvePiecess, maxCoordPowerOf2) {
29389
29174
  if (isSharp(δ3s[0][0])) {
29390
29175
  return undefined;
29391
29176
  }
29177
+ // TODO
29178
+ //----------------------------
29179
+ // const l1 = curvePiece3s[0].length;
29180
+ // const l2 = curvePiece3s[1].length;
29181
+ // const l3 = curvePiece3s[2].length;
29182
+ // if (l1 === 1 && l2 == 1 && l3 === 1) {
29183
+ // // console.log('aaa');
29184
+ // const A = curvePiece3s[0][0].curve.ps;
29185
+ // const B = curvePiece3s[1][0].curve.ps;
29186
+ // const C = curvePiece3s[2][0].curve.ps;
29187
+ // console.log(A.length, B.length, C.length);
29188
+ // } else {
29189
+ // // console.log('bbb');
29190
+ // }
29191
+ //----------------------------
29392
29192
  let poss = undefined;
29393
29193
  let j = 0; // Safeguard for slow convergence
29394
- let x = calcInitial3ProngCenter(maxCoordPowerOf2, δ3s, curvePiece3s);
29194
+ let x = calcInitial3ProngCenter(δ3s, curvePiece3s);
29395
29195
  let tolerance = Infinity;
29396
29196
  while (tolerance > TOLERANCE && j < MAX_ITERATIONS) {
29397
29197
  j++;
29398
- poss = getClosestPoints(maxCoordPowerOf2, x, curvePiece3s);
29198
+ poss = getClosestPoints(x, curvePiece3s);
29399
29199
  if (!Number.isFinite(x[0]) || !Number.isFinite(x[1])) {
29400
29200
  // FUTURE - the code can be cleaned up and sped up a lot if we don't
29401
29201
  // use this function as is but instead use δs[0] and δs[2] as is
@@ -29403,7 +29203,7 @@ function find3ProngForDelta3s(δs, idx, k, curvePiecess, maxCoordPowerOf2) {
29403
29203
  // loop. This check, for instance, would be eliminated completely.
29404
29204
  return undefined;
29405
29205
  }
29406
- const circumCenter = circum_center_circumCenter(poss.map(x => x.p));
29206
+ const circumCenter = timeCircumCenter(poss.map(x => x.p));
29407
29207
  const vectorToZeroV = from_to_fromTo(x, circumCenter);
29408
29208
  if (!Number.isFinite(vectorToZeroV[0]) || !Number.isFinite(vectorToZeroV[1])) {
29409
29209
  // FUTURE - the code can be cleaned up and sped up a lot if we don't
@@ -29412,7 +29212,7 @@ function find3ProngForDelta3s(δs, idx, k, curvePiecess, maxCoordPowerOf2) {
29412
29212
  // loop. This check, for instance, would be eliminated completely.
29413
29213
  return undefined;
29414
29214
  }
29415
- const upds = calcBetterX(maxCoordPowerOf2, curvePiece3s, x, vectorToZeroV);
29215
+ const upds = calcBetterX(curvePiece3s, x, vectorToZeroV);
29416
29216
  x = upds.newX;
29417
29217
  poss = upds.newPoss;
29418
29218
  const V = len(vectorToZeroV); // The 'potential'
@@ -29474,7 +29274,7 @@ function find3ProngForDelta3s(δs, idx, k, curvePiecess, maxCoordPowerOf2) {
29474
29274
  //-------------------------------------------------------------------------
29475
29275
  const closestDs = [];
29476
29276
  for (let i = 0; i < curvePiecess.length; i++) {
29477
- const pos = getCloseBoundaryPointsCertified(maxCoordPowerOf2, curvePiecess[i], x)[0];
29277
+ const pos = getCloseBoundaryPointsCertified(curvePiecess[i], x)[0];
29478
29278
  closestDs.push(distanceBetween(pos.p, x));
29479
29279
  }
29480
29280
  const closestD = find_3_prong_for_delta3s_min(...closestDs);
@@ -29712,7 +29512,8 @@ function getCpNodeToLeftOrSame(cpTree, pos, order, order2) {
29712
29512
  if (cps[0] === undefined || cps[1] === undefined) {
29713
29513
  // Smaller than all -> cptree.min() === cps[1].data OR
29714
29514
  // Larger than all -> cptree.max() === cps[0].data
29715
- return cpTree.max(cpTree.root);
29515
+ // return cpTree.max(cpTree.root);
29516
+ return cpTree.getMaxNode()?.datum;
29716
29517
  }
29717
29518
  return cps[0].datum;
29718
29519
  }
@@ -29892,6 +29693,7 @@ function getCloseByCpIfExist(meta, pos, circle, order, order2, forProngCount) {
29892
29693
 
29893
29694
 
29894
29695
 
29696
+ let find_and_add_3_prong_ii = 0;
29895
29697
  /**
29896
29698
  * @internal
29897
29699
  * Finds and add a 3-prong MAT circle to the given shape.
@@ -29905,6 +29707,20 @@ function findAndAdd3Prong(meta, visitedCps) {
29905
29707
  for (const visitedCp of visitedCps) {
29906
29708
  δs.push([visitedCp, visitedCp.next]);
29907
29709
  }
29710
+ // TODO - remove - debugging
29711
+ //-------------------------
29712
+ // ii++;
29713
+ // if (ii === 13) {
29714
+ // //@ts-ignore
29715
+ // if (_debug_.temp === undefined) { _debug_.temp = []; }
29716
+ // //@ts-ignore
29717
+ // _debug_.temp.push(δs);
29718
+ // }
29719
+ // //@ts-ignore
29720
+ // if (_debug_.temp2 === undefined) { _debug_.temp2 = []; }
29721
+ // //@ts-ignore
29722
+ // _debug_.temp2.push(δs.length);
29723
+ //-------------------------
29908
29724
  const threeProngInfo = find3Prong(δs, meta.maxCoordPowerOf2);
29909
29725
  const { circle, poss, δ3s } = threeProngInfo;
29910
29726
  const orders = [];
@@ -29954,7 +29770,6 @@ function findAndAdd3Prongs(meta, cpStart) {
29954
29770
  return { closeBysFor3Prong: undefined, addedCpNodes: [] };
29955
29771
  }
29956
29772
  const addedCpNodes = [];
29957
- let closeBysFor3Prong = undefined;
29958
29773
  do {
29959
29774
  if (cpStart === undefined) {
29960
29775
  continue;
@@ -29974,7 +29789,7 @@ function findAndAdd3Prongs(meta, cpStart) {
29974
29789
  }
29975
29790
  }
29976
29791
  } while (true);
29977
- return { closeBysFor3Prong, addedCpNodes };
29792
+ return { closeBysFor3Prong: undefined, addedCpNodes };
29978
29793
  }
29979
29794
 
29980
29795
 
@@ -29982,9 +29797,6 @@ function findAndAdd3Prongs(meta, cpStart) {
29982
29797
 
29983
29798
 
29984
29799
 
29985
- // import { LlRbTree } from 'flo-ll-rb-tree';
29986
- // import { Loop } from 'flo-boolean';
29987
- // import { drawFs } from 'flo-draw';
29988
29800
 
29989
29801
  /**
29990
29802
  * @internal
@@ -30018,7 +29830,7 @@ function findAndAdd3ProngsOnLoop(meta, cpStart) {
30018
29830
  }
30019
29831
  cpStart = getFirstItemOfSet(cpNodeGoodSet);
30020
29832
  }
30021
- return getFirstItemOfSet(cpNodeGoodSet);
29833
+ return cpStart;
30022
29834
  }
30023
29835
  // From https://stackoverflow.com/a/73281564/2010061
30024
29836
  function getFirstItemOfSet(set) {
@@ -30027,23 +29839,13 @@ function getFirstItemOfSet(set) {
30027
29839
  }
30028
29840
  return undefined;
30029
29841
  }
30030
- // Unfortunately O(n) until Javascript gives us the simple ability to
30031
- // retrieve the first or last item of a set
30032
- function getLastItemOfSet(set) {
30033
- let item;
30034
- for (item of set) { }
30035
- return item;
30036
- }
30037
- function replaceCloseBys(
30038
- // cpTrees: Map<Loop,LlRbTree<CpNode>>,
30039
- meta, closeBysFor3Prong, cpNodeSet, cpNodeGoodSet) {
30040
- for (const closeBy of [closeBysFor3Prong[0]]) {
30041
- getAllOnCircle(closeBy).forEach(v => {
30042
- cpNodeSet.delete(v);
30043
- cpNodeGoodSet.delete(v);
30044
- });
30045
- removeVertex(closeBy, meta);
30046
- }
29842
+ function replaceCloseBys(meta, closeBysFor3Prong, cpNodeSet, cpNodeGoodSet) {
29843
+ const closeBy = closeBysFor3Prong[0];
29844
+ getAllOnCircle(closeBy).forEach(v => {
29845
+ cpNodeSet.delete(v);
29846
+ cpNodeGoodSet.delete(v);
29847
+ });
29848
+ removeVertex(closeBy, meta);
30047
29849
  }
30048
29850
 
30049
29851
 
@@ -30066,7 +29868,7 @@ meta, closeBysFor3Prong, cpNodeSet, cpNodeGoodSet) {
30066
29868
  function createInitialCpTree(loops, sharpCornerss, lastInsertId) {
30067
29869
  const cpTrees = new Map();
30068
29870
  for (let k = 0; k < sharpCornerss.length; k++) {
30069
- const cpTree = new LlRbTree(cpNodeComparator, false);
29871
+ const cpTree = new RbTree(cpNodeComparator);
30070
29872
  cpTrees.set(loops[k], cpTree);
30071
29873
  const sharpCorners = sharpCornerss[k];
30072
29874
  let cpNode1 = undefined;
@@ -30109,6 +29911,7 @@ const get_bounding_hull_getBoundingHull = grahamScan;
30109
29911
 
30110
29912
  //# sourceMappingURL=get-bounding-hull.js.map
30111
29913
  ;// ./src/find-mat/get-meta.ts
29914
+ // import { TriMapFs } from '../utils/tri-map.js';
30112
29915
 
30113
29916
 
30114
29917
 
@@ -30271,56 +30074,320 @@ function getInitialCurvePieces(angle, isHoleClosing, loop, loops, meta, yPos, xO
30271
30074
  }
30272
30075
 
30273
30076
 
30274
- ;// ./node_modules/flo-poly/node/roots/deflate/deflate.js
30077
+ ;// ./node_modules/flo-bezier3/node/to-power-basis/to-power-basis/double/to-power-basis.js
30275
30078
  /**
30276
- * Deflates the given polynomial *approximately* by removing a factor `(x - r)`,
30277
- * where `r` is a root of the polynomial.
30278
- *
30279
- * * **non-exact:** the deflation is done in double precision - it is not
30280
- * possible to deflate a root exactly in most cases and round-off will thus
30281
- * occur - use only if approximate deflation is acceptable
30079
+ * Returns the power basis representation of a bezier curve of order cubic or
30080
+ * less.
30282
30081
  *
30283
- * @param p a polynomial with coefficients given densely as an array of double
30284
- * floating point numbers from highest to lowest power, e.g. `[5,-3,0]`
30285
- * represents the polynomial `5x^2 - 3x`
30286
- * @param root a root of the polynomial.
30082
+ * * intermediate calculations are done in double precision
30083
+ * * returns the resulting power basis x and y coordinate polynomials from
30084
+ * highest power to lowest, e.g. if `x(t) = at^2 + bt + c`
30085
+ * and `y(t) = dt^2 + et + f` then the result is returned
30086
+ * as `[[a,b,c],[d,e,f]]`
30287
30087
  *
30288
- * @example
30289
- * ```typescript
30290
- * // The polynomial x^3 - 5x^2 + 8x - 4 has a root at 1 and a double root at 2
30291
- * deflate([1, -5, 8, -4], 2); //=> [1, -3, 2]
30292
- * deflate([1, -3, 2], 2); //=> [1,-1]
30293
- * deflate([1, -1], 1); //=> [1]
30294
- * ```
30088
+ * @param ps an order 0,1,2 or 3 bezier curve given by an ordered array of its
30089
+ * control points, e.g. `[[0,0],[1,1],[2,1],[2,0]]`
30295
30090
  *
30296
30091
  * @doc
30297
30092
  */
30298
- function deflate(p, root) {
30299
- const d = p.length - 1;
30300
- const bs = [p[0]];
30301
- for (let i = 1; i < d; i++) {
30302
- bs.push(p[i] + root * bs[i - 1]);
30093
+ function to_power_basis_toPowerBasis(ps) {
30094
+ if (ps.length === 4) {
30095
+ return to_power_basis_toPowerBasis3(ps);
30303
30096
  }
30304
- return bs;
30097
+ if (ps.length === 3) {
30098
+ return to_power_basis_toPowerBasis2(ps);
30099
+ }
30100
+ if (ps.length === 2) {
30101
+ return to_power_basis_toPowerBasis1(ps);
30102
+ }
30103
+ if (ps.length === 1) {
30104
+ return to_power_basis_toPowerBasis0(ps);
30105
+ }
30106
+ throw new Error('The given bezier curve must be of order <= 3.');
30107
+ }
30108
+ /** @internal */
30109
+ function to_power_basis_toPowerBasis3(ps) {
30110
+ const [[x0, y0], [x1, y1], [x2, y2], [x3, y3]] = ps;
30111
+ return [[
30112
+ (x3 - x0) + 3 * (x1 - x2),
30113
+ 3 * ((x2 + x0) - 2 * x1),
30114
+ 3 * (x1 - x0),
30115
+ x0
30116
+ ], [
30117
+ (y3 - y0) + 3 * (y1 - y2),
30118
+ 3 * ((y2 + y0) - 2 * y1),
30119
+ 3 * (y1 - y0),
30120
+ y0
30121
+ ]];
30122
+ }
30123
+ /** @internal */
30124
+ function to_power_basis_toPowerBasis2(ps) {
30125
+ const [[x0, y0], [x1, y1], [x2, y2]] = ps;
30126
+ return [[
30127
+ (x2 + x0) - 2 * x1,
30128
+ 2 * (x1 - x0),
30129
+ x0
30130
+ ], [
30131
+ (y2 + y0) - 2 * y1,
30132
+ 2 * (y1 - y0),
30133
+ y0
30134
+ ]];
30135
+ }
30136
+ /** @internal */
30137
+ function to_power_basis_toPowerBasis1(ps) {
30138
+ const [[x0, y0], [x1, y1]] = ps;
30139
+ return [[
30140
+ x1 - x0,
30141
+ x0,
30142
+ ], [
30143
+ y1 - y0,
30144
+ y0,
30145
+ ]];
30146
+ }
30147
+ /** @internal */
30148
+ function to_power_basis_toPowerBasis0(ps) {
30149
+ const [[x0, y0]] = ps;
30150
+ return [[x0], [y0]];
30305
30151
  }
30306
30152
 
30307
- //# sourceMappingURL=deflate.js.map
30308
- ;// ./node_modules/flo-bezier3/node/get-medial-points/get-medial-point-coeffs-bez2.js
30153
+ //# sourceMappingURL=to-power-basis.js.map
30154
+ ;// ./node_modules/flo-bezier3/node/get-medial-points/get-medial-point-coeffs-bez2-same-curve.js
30155
+
30309
30156
  /**
30310
- * Returns polynomial coefficients for ray parameter values `t`, bezier
30311
- * parameter values `s` and medial points for points `q(t)` and b(s) (an order
30312
- * 2 bezier curve) that satisfy the medial condition with respect to `p` and `ps`:
30157
+ * Returns polynomial coefficients for the same-curve quadratic medial-point
30158
+ * case, where `p = b(t)` on the same quadratic bezier `ps` and `v` is normal
30159
+ * to the curve at that parameter `t`.
30313
30160
  *
30314
- * Let `p` be a fixed point in the plane.
30315
- * Let `v` be a direction vector defining the ray `q(t) = p + t⋅v`.
30316
- * Let `ps` be a quadratic bezier curve.
30161
+ * The returned coefficients encode:
30162
+ * * `A`, `B`: `E2(s, τ) = (s - t)^2⋅(A(s)⋅τ + B(s))`
30163
+ // * * `C`, `D`: `E1(s, τ) = C(s)⋅τ + D(s)`
30164
+ * * `H`: the reduced eliminant in `s`
30165
+ *
30166
+ * Here `τ` is the ray parameter in `q(τ) = p + τ⋅v`.
30167
+ * For a candidate root `s` of `H`, recover `τ` from
30168
+ * `A(s)⋅τ + B(s) = 0`, i.e. `τ = -B(s)/A(s)` when `A(s) ≠ 0`.
30317
30169
  *
30170
+ * In this same-curve setup, the full eliminant has the form
30171
+ * `H_full(s) = (s - t)^4*(l1*s + l0)`. This function returns only the reduced
30172
+ * factor `H(s) = l1*s + l0` (the repeated `(s - t)^4` factor is omitted).
30173
+ *
30174
+ * @param t parameter on `ps` where `p = b(t)`
30175
+ * @param v ray direction from `p`; assumed normal to `ps` at `t`
30176
+ * @param ps order 2 bezier control points, e.g. `[[0,0],[1,1],[2,1]]`
30177
+ */
30178
+ function getMedialPointCoeffsBez2_SameCurve(t, v, ps) {
30179
+ // -----------------------------------------------------
30180
+ // See get-medial-points.md for implementation details.
30181
+ // -----------------------------------------------------
30182
+ // Quadratic bezier in power basis: b(s) = a⋅s² + b⋅s + c
30183
+ const [[ax, bx], [ay, by]] = to_power_basis_toPowerBasis2(ps);
30184
+ const [vx, vy] = v;
30185
+ // Same-curve assumption with explicit parameter `t`:
30186
+ // p = b(t) => u0 = p - c = t*(a*t + b).
30187
+ const g0x = ax * t + bx;
30188
+ const g0y = ay * t + by;
30189
+ // Reuse core quadratic-form terms to reduce repeated multiplications.
30190
+ const br2 = ax * ax + ay * ay;
30191
+ const ab = ax * bx + ay * by;
30192
+ // const bb = bx*bx + by*by;
30193
+ const ag = ax * g0x + ay * g0y;
30194
+ // -----------------------------------------------------
30195
+ // E1(s,t): (u(s) + t⋅v) ⋅ b'(s) = 0
30196
+ // => C(s)⋅t + D(s) = 0
30197
+ const c1 = 2 * (vx * ax + vy * ay);
30198
+ // v is normal at parameter t, so C(t) = v⋅w(t) = 0.
30199
+ // Since C(s) = c1*s + c0, enforce c0 = -c1*t exactly.
30200
+ // const c0 = -c1*t;
30201
+ // const d3 = -2*br2;
30202
+ // const d2 = -3*ab;
30203
+ // const d1 = 2*t*ag - bb;
30204
+ // p = b(t) => D(t) = u(t)⋅w(t) = 0.
30205
+ // const d0 = -t*(t*(d3*t + d2) + d1);
30206
+ // -----------------------------------------------------
30207
+ // -----------------------------------------------------
30208
+ // E2(s,t): |t⋅v|² - |u(s) + t⋅v|² = 0
30209
+ // => 2⋅(v⋅u(s))⋅t + |u(s)|² = 0
30210
+ // => (s - t)^2⋅(A(s)⋅t + B(s)) = 0
30211
+ // Return only the reduced constant A(s) = ar0.
30212
+ const ar0 = -c1;
30213
+ // Full B(s) factorizes as: B_full(s) = (s - t)^2*B_reduced(s).
30214
+ // Return only B_reduced(s) = br2*s^2 + br1*s + br0.
30215
+ const br1 = 2 * ag;
30216
+ const br0 = g0x * g0x + g0y * g0y;
30217
+ // -----------------------------------------------------
30218
+ // Eliminate t from:
30219
+ // A(s)⋅t + B(s) = 0
30220
+ // C(s)⋅t + D(s) = 0
30221
+ // by taking A(s)⋅D(s) - B(s)⋅C(s) = 0 (degree ≤ 5 in s)
30222
+ // For this same-curve quadratic case:
30223
+ // d3 = -2*b4, d2 = -(3/2)*b3, a2 = -c1, a1 = -2*c0.
30224
+ // Therefore H5 and H4 reduce to:
30225
+ // H5 = b4*c1
30226
+ // H4 = 3*b4*c0 + (1/2)*b3*c1
30227
+ const H5 = br2 * c1;
30228
+ // In the same-curve quadratic case the full eliminant has the form
30229
+ // H_full(s) = (s - t)^4*(l1*s + l0).
30230
+ // Match the leading coefficients of H_full(s):
30231
+ // H5 = l1
30232
+ // H4 = l0 - 4*t*l1
30233
+ // const l1 = H5;
30234
+ // const l0 = H4 + 4*t*l1;
30235
+ // Using c0 = -c1*t and b3 = 2*ab, this simplifies to l0 = c1*(br2*t + ab).
30236
+ const l0 = c1 * (br2 * t + ab);
30237
+ return {
30238
+ A: [ar0],
30239
+ B: [br2, br1, br0],
30240
+ // C: [c1, c0],
30241
+ // D: [d3, d2, d1, d0],
30242
+ H: [H5, l0]
30243
+ };
30244
+ }
30245
+
30246
+ //# sourceMappingURL=get-medial-point-coeffs-bez2-same-curve.js.map
30247
+ ;// ./node_modules/flo-bezier3/node/get-medial-points/get-medial-point-coeffs-bez3-same-curve.js
30248
+
30249
+ /**
30250
+ * Returns polynomial coefficients for the same-curve cubic medial-point case,
30251
+ * where `p = b(t)` on the same cubic bezier `ps` and `v` is normal to the
30252
+ * curve at that parameter `t`.
30253
+ *
30254
+ * The returned coefficients encode:
30255
+ * * `A`, `B`: `E2(s, τ) = (s - t)^2⋅(A(s)⋅τ + B(s))`
30256
+ * * `C`, `D`: `E1(s, τ) = (s - t)⋅(C(s)⋅τ + D(s))`
30257
+ * * `H`: the reduced eliminant in `s`
30258
+ *
30259
+ * Here `τ` is the ray parameter in `q(τ) = p + τ⋅v`.
30260
+ * For a candidate root `s` of `H`, recover `τ` from `A(s)⋅τ + B(s) = 0`, i.e.
30261
+ * `τ = -B(s)/A(s)` when `A(s) ≠ 0`.
30262
+ *
30263
+ * In this same-curve setup, the full eliminant has the form
30264
+ * `H_full(s) = (s - t)^4*H(s)`. This function returns only the reduced factor
30265
+ * `H(s)` (the repeated `(s - t)^4` factor is omitted).
30266
+ *
30267
+ * @param t parameter on `ps` where `p = b(t)`
30268
+ * @param v ray direction from `p`; assumed normal to `ps` at `t`
30269
+ * @param ps order 3 bezier control points, e.g. `[[0,0],[1,1],[2,1],[3,0]]`
30270
+ */
30271
+ function getMedialPointCoeffsBez3_SameCurve(t, v, ps) {
30272
+ // -----------------------------------------------------
30273
+ // See get-medial-points.md for implementation details.
30274
+ // -----------------------------------------------------
30275
+ const [vx, vy] = v;
30276
+ // Cubic bezier in power basis: b(s) = a*s^3 + b*s^2 + c*s + d
30277
+ const [[ax, bx, cx], [ay, by, cy]] = to_power_basis_toPowerBasis3(ps);
30278
+ // Shared dot products to reduce repeated multiplications.
30279
+ const va = vx * ax + vy * ay;
30280
+ const vb = vx * bx + vy * by;
30281
+ const vc = vx * cx + vy * cy;
30282
+ const aa = ax * ax + ay * ay;
30283
+ const ab = ax * bx + ay * by;
30284
+ const ac = ax * cx + ay * cy;
30285
+ const bb = bx * bx + by * by;
30286
+ const bc = bx * cx + by * cy;
30287
+ const cc = cx * cx + cy * cy;
30288
+ const vu0 = t * (t * (t * va + vb) + vc);
30289
+ const u0a = t * (t * (t * aa + ab) + ac);
30290
+ const u0b = t * (t * (t * ab + bb) + bc);
30291
+ // -----------------------------------------------------
30292
+ // E1(s,t): (u(s) + t*v) * b'(s) = 0
30293
+ // => C(s)*t + D(s) = 0
30294
+ const c2 = 3 * va;
30295
+ const c1 = 2 * vb;
30296
+ // v is normal at parameter t, so C(t) = 0.
30297
+ // const c0 = -t*(c2*t + c1);
30298
+ // Return reduced C such that C_full(s) = (s - t)*C(s).
30299
+ const cr0 = c1 + t * c2;
30300
+ // -----------------------------------------------------
30301
+ // -----------------------------------------------------
30302
+ const d5 = -3 * aa;
30303
+ const d4 = -5 * ab;
30304
+ const d3 = -4 * ac - 2 * bb;
30305
+ const d2 = -3 * bc + 3 * u0a;
30306
+ const d1 = -cc + 2 * u0b;
30307
+ // p = b(t) => D(t) = u(t)⋅w(t) = 0.
30308
+ // Return reduced D such that D_full(s) = (s - t)*D(s).
30309
+ const dr4 = d5;
30310
+ const dr3 = d4 + t * dr4;
30311
+ const dr2 = d3 + t * dr3;
30312
+ const dr1 = d2 + t * dr2;
30313
+ const dr0 = d1 + t * dr1;
30314
+ // -----------------------------------------------------
30315
+ // -----------------------------------------------------
30316
+ // E2(s,t): |t*v|^2 - |u(s) + t*v|^2 = 0
30317
+ // => 2*(v*u(s))*t + |u(s)|^2 = 0
30318
+ // => A(s)*t + B(s) = 0
30319
+ // A'(s) = -2*C(s) identically for bezier curves, hence:
30320
+ const a3 = -2 * va;
30321
+ const a2 = -2 * vb;
30322
+ // const a1 = -2*vc;
30323
+ // p = b(t) => A(t) = 0.
30324
+ // const a0 = 2*vu0;
30325
+ // -----------------------------------------------------
30326
+ // -----------------------------------------------------
30327
+ const b6 = aa;
30328
+ const b5 = 2 * ab;
30329
+ const b4 = 2 * ac + bb;
30330
+ const b3 = 2 * bc - 2 * u0a;
30331
+ const b2 = cc - 2 * u0b;
30332
+ // -----------------------------------------------------
30333
+ // -----------------------------------------------------
30334
+ // Return reduced A and B such that:
30335
+ // A_full(s) = (s - t)^2*A(s)
30336
+ // B_full(s) = (s - t)^2*B(s)
30337
+ // where A is degree 1 and B is degree 4.
30338
+ const ar1 = a3;
30339
+ const ar0 = a2 + 2 * t * ar1;
30340
+ const br4 = b6;
30341
+ const br3 = b5 + 2 * t * br4;
30342
+ const br2 = b4 + t * (2 * br3 - t * br4);
30343
+ const br1 = b3 + t * (2 * br2 - t * br3);
30344
+ const br0 = b2 + t * (2 * br1 - t * br2);
30345
+ // -----------------------------------------------------
30346
+ // Eliminate t from:
30347
+ // A(s)*t + B(s) = 0
30348
+ // C(s)*t + D(s) = 0
30349
+ // by taking A(s)*D(s) - B(s)*C(s) = 0 (degree <= 8 in s)
30350
+ // H8 = a3*d5 - b6*c2 = (-2*va)*(-3*aa) - aa*(3*va) = 3*va*aa.
30351
+ const H8 = 3 * va * aa;
30352
+ const H7 = 4 * (va * ab + vb * aa);
30353
+ const H6 = va * b4 + 6 * vb * ab + 5 * vc * aa;
30354
+ const H5 = 2 * vb * b4 + 8 * vc * ab - 6 * vu0 * aa;
30355
+ const H4 = -va * b2 + vb * b3 + 3 * vc * b4 - 10 * vu0 * ab;
30356
+ // Reduce H_full(s) by its guaranteed (s - t)^4 factor:
30357
+ // H_full(s) = (s - t)^4*(q4*s^4 + q3*s^3 + q2*s^2 + q1*s + q0)
30358
+ // Match the high-order coefficients of H_full(s) explicitly.
30359
+ const q4 = H8;
30360
+ const q3 = H7 + 4 * t * q4;
30361
+ const q2 = H6 + t * (4 * q3 - 6 * t * q4);
30362
+ const q1 = H5 + t * (4 * q2 + t * (-6 * q3 + 4 * t * q4));
30363
+ const q0 = H4 + t * (4 * q1 + t * (-6 * q2 + t * (4 * q3 - t * q4)));
30364
+ return {
30365
+ A: [ar1, ar0],
30366
+ B: [br4, br3, br2, br1, br0],
30367
+ C: [c2, cr0],
30368
+ D: [dr4, dr3, dr2, dr1, dr0],
30369
+ H: [q4, q3, q2, q1, q0]
30370
+ };
30371
+ }
30372
+
30373
+ //# sourceMappingURL=get-medial-point-coeffs-bez3-same-curve.js.map
30374
+ ;// ./node_modules/flo-bezier3/node/get-medial-points/get-medial-point-coeffs-bez2.js
30375
+
30376
+ /**
30377
+ * Returns the polynomial coefficients for the ray parameter `t` and the
30378
+ * curve parameter `s` that encode the medial condition for `q(t) = p + t⋅v`
30379
+ * and a quadratic bezier curve `ps`.
30380
+ *
30381
+ * The returned coefficients describe the equations whose common solutions
30382
+ * satisfy:
30318
30383
  * * `q(t)` is equidistant from `p` and the nearest point on `ps`
30319
30384
  * * that common distance is locally minimal among such candidates
30320
30385
  *
30321
- * In other words, this function returns candidate ray parameters for the
30322
- * sought medial point(s). Selecting physically valid solutions (if needed)
30323
- * is done by the caller or by a later stage of this routine.
30386
+ * More specifically, this function returns:
30387
+ * * `A` and `B`: the coefficients of `E2(s,t) = A(s)⋅t + B(s)`
30388
+ * * `C` and `D`: the coefficients of `E1(s,t) = C(s)⋅t + D(s)`
30389
+ * * `H`: the eliminated polynomial `A(s)⋅D(s) - B(s)⋅C(s)` whose roots are
30390
+ * candidate `s` values for medial points
30324
30391
  *
30325
30392
  * @param p base point
30326
30393
  * @param v ray direction from `p`
@@ -30333,105 +30400,57 @@ function getMedialPointCoeffsBez2(p, v, ps) {
30333
30400
  // -----------------------------------------------------
30334
30401
  const [px, py] = p;
30335
30402
  const [vx, vy] = v;
30336
- const [[x0, y0], [x1, y1], [x2, y2]] = ps;
30403
+ const [[x0, y0]] = ps;
30337
30404
  // Quadratic bezier in power basis: b(s) = a⋅s² + b⋅s + c
30338
- const ax = x0 - 2 * x1 + x2;
30339
- const ay = y0 - 2 * y1 + y2;
30340
- const bx = -2 * x0 + 2 * x1;
30341
- const by = -2 * y0 + 2 * y1;
30342
- const cx = x0;
30343
- const cy = y0;
30405
+ const [[ax, bx], [ay, by]] = to_power_basis_toPowerBasis2(ps);
30344
30406
  // u(s) = p - b(s) = u2⋅s² + u1⋅s + u0
30345
- const u2x = -ax;
30346
- const u2y = -ay;
30347
- const u1x = -bx;
30348
- const u1y = -by;
30349
- const u0x = px - cx;
30350
- const u0y = py - cy;
30351
- // b'(s) = w(s) = w1⋅s + w0
30352
- const w1x = 2 * ax;
30353
- const w1y = 2 * ay;
30354
- const w0x = bx;
30355
- const w0y = by;
30407
+ const u0x = px - x0;
30408
+ const u0y = py - y0;
30409
+ // Shared dot products.
30410
+ const c1 = 2 * (vx * ax + vy * ay);
30411
+ const c0 = vx * bx + vy * by;
30412
+ const vu0 = vx * u0x + vy * u0y;
30413
+ const b4 = ax * ax + ay * ay;
30414
+ const ab = ax * bx + ay * by;
30415
+ const bb = bx * bx + by * by;
30416
+ const u0a = u0x * ax + u0y * ay;
30417
+ const d0 = u0x * bx + u0y * by;
30418
+ const b0 = u0x * u0x + u0y * u0y;
30356
30419
  // -----------------------------------------------------
30357
30420
  // E1(s,t): (u(s) + t⋅v) ⋅ b'(s) = 0
30358
30421
  // => C(s)⋅t + D(s) = 0
30359
- const c1 = vx * w1x + vy * w1y;
30360
- const c0 = vx * w0x + vy * w0y;
30361
30422
  // -----------------------------------------------------
30362
30423
  // -----------------------------------------------------
30363
- const d3 = u2x * w1x + u2y * w1y;
30364
- const d2 = u2x * w0x + u2y * w0y + u1x * w1x + u1y * w1y;
30365
- const d1 = u1x * w0x + u1y * w0y + u0x * w1x + u0y * w1y;
30366
- const d0 = u0x * w0x + u0y * w0y;
30424
+ const d3 = -2 * b4;
30425
+ const d2 = -3 * ab;
30426
+ const d1 = 2 * u0a - bb;
30367
30427
  // -----------------------------------------------------
30368
30428
  // -----------------------------------------------------
30369
30429
  // E2(s,t): |t⋅v|² - |u(s) + t⋅v|² = 0
30370
30430
  // => 2⋅(v⋅u(s))⋅t + |u(s)|² = 0
30371
30431
  // => A(s)⋅t + B(s) = 0
30372
- const a2 = 2 * (vx * u2x + vy * u2y);
30373
- const a1 = 2 * (vx * u1x + vy * u1y);
30374
- const a0 = 2 * (vx * u0x + vy * u0y);
30432
+ const a2 = -c1;
30433
+ const a1 = -2 * c0;
30434
+ const a0 = 2 * vu0;
30375
30435
  // -----------------------------------------------------
30376
30436
  // -----------------------------------------------------
30377
- const b4 = u2x * u2x + u2y * u2y;
30378
- const b3 = 2 * (u2x * u1x + u2y * u1y);
30379
- const b2 = 2 * (u2x * u0x + u2y * u0y) + (u1x * u1x + u1y * u1y);
30380
- const b1 = 2 * (u1x * u0x + u1y * u0y);
30381
- const b0 = u0x * u0x + u0y * u0y;
30437
+ const b3 = 2 * ab;
30438
+ const b2 = -d1;
30439
+ const b1 = -2 * d0;
30382
30440
  // -----------------------------------------------------
30383
- // const A = [a2, a1, a0]; // degree 2 in s
30384
- // const B = [b4, b3, b2, b1, b0]; // degree 4 in s
30385
- // const C = [c1, c0]; // degree 1 in s
30386
- // const D = [d3, d2, d1, d0]; // degree 3 in s
30387
30441
  // Eliminate t from:
30388
30442
  // A(s)⋅t + B(s) = 0
30389
30443
  // C(s)⋅t + D(s) = 0
30390
30444
  // by taking A(s)⋅D(s) - B(s)⋅C(s) = 0 (degree ≤ 5 in s)
30391
- // Explicit expansion of AD = multiply(A, D), descending in s.
30392
- // const AD = [
30393
- // a2*d3,
30394
- // a2*d2 + a1*d3,
30395
- // a2*d1 + a1*d2 + a0*d3,
30396
- // a2*d0 + a1*d1 + a0*d2,
30397
- // a1*d0 + a0*d1,
30398
- // a0*d0
30399
- // ];
30400
- const AD5 = a2 * d3;
30401
- const AD4 = a2 * d2 + a1 * d3;
30402
- const AD3 = a2 * d1 + a1 * d2 + a0 * d3;
30403
- const AD2 = a2 * d0 + a1 * d1 + a0 * d2;
30404
- const AD1 = a1 * d0 + a0 * d1;
30405
- const AD0 = a0 * d0;
30406
- // Explicit expansion of BC = multiply(B, C), descending in s.
30407
- // const BC = [
30408
- // b4*c1,
30409
- // b4*c0 + b3*c1,
30410
- // b3*c0 + b2*c1,
30411
- // b2*c0 + b1*c1,
30412
- // b1*c0 + b0*c1,
30413
- // b0*c0
30414
- // ];
30415
- const BC5 = b4 * c1;
30416
- const BC4 = b4 * c0 + b3 * c1;
30417
- const BC3 = b3 * c0 + b2 * c1;
30418
- const BC2 = b2 * c0 + b1 * c1;
30419
- const BC1 = b1 * c0 + b0 * c1;
30420
- const BC0 = b0 * c0;
30421
- // const H = [
30422
- // AD5 - BC5,
30423
- // AD4 - BC4,
30424
- // AD3 - BC3,
30425
- // AD2 - BC2,
30426
- // AD1 - BC1,
30427
- // AD0 - BC0
30428
- // ];
30429
- const H5 = AD5 - BC5;
30430
- const H4 = AD4 - BC4;
30431
- const H3 = AD3 - BC3;
30432
- const H2 = AD2 - BC2;
30433
- const H1 = AD1 - BC1;
30434
- const H0 = AD0 - BC0;
30445
+ // Using:
30446
+ // a2 = -c1, d3 = -2*b4, d1 = -b2, b1 = -2*d0
30447
+ // we can compute H = A⋅D - B⋅C directly.
30448
+ const H5 = b4 * c1;
30449
+ const H4 = ab * c1 + 3 * b4 * c0;
30450
+ const H3 = 4 * (ab * c0 - vu0 * b4);
30451
+ const H2 = c1 * d0 + c0 * b2 - 6 * vu0 * ab;
30452
+ const H1 = -2 * vu0 * b2 - c1 * b0;
30453
+ const H0 = 2 * vu0 * d0 - c0 * b0;
30435
30454
  return {
30436
30455
  A: [a2, a1, a0],
30437
30456
  B: [b4, b3, b2, b1, b0],
@@ -30444,23 +30463,22 @@ function getMedialPointCoeffsBez2(p, v, ps) {
30444
30463
  //# sourceMappingURL=get-medial-point-coeffs-bez2.js.map
30445
30464
  ;// ./node_modules/flo-bezier3/node/get-medial-points/get-medial-point-coeffs-bez1.js
30446
30465
  /**
30447
- * Returns polynomial coefficients for ray parameter values `t`, bezier
30448
- * parameter values `s` and medial points for points `q(t)` and b(s) (an order
30449
- * 1 bezier curve) that satisfy the medial condition with respect to `p` and `ps`:
30466
+ * Returns the polynomial coefficients used to recover ray parameter values `t`
30467
+ * for a ray `q(t) = p + t⋅v` and an order-1 bezier curve `ps`.
30450
30468
  *
30451
- * Let `p` be a fixed point in the plane.
30452
- * Let `v` be a direction vector defining the ray `q(t) = p + t⋅v`.
30453
- * Let `ps` be an order 1 bezier curve (a line segment).
30469
+ * The returned polynomials encode the medial-condition equations in `s` and
30470
+ * `t`. For any valid solution, `t` is recovered by eliminating `s` and solving
30471
+ * the resulting ray equation, or equivalently by using the linear form
30472
+ * `A(s)⋅t + B(s) = 0`, which gives `t = -B(s)/A(s)`.
30454
30473
  *
30455
- * * `q(t)` is equidistant from `p` and the nearest point on `ps`
30456
- * * that common distance is locally minimal among such candidates
30457
- *
30458
- * In other words, this function returns candidate ray parameters for the
30459
- * sought medial point(s). Selecting physically valid solutions (if needed)
30460
- * is done by the caller or by a later stage of this routine.
30474
+ * More specifically, the returned values represent:
30475
+ * * `A` and `B`: the coefficients of `E2(s,t) = A(s)⋅t + B(s)`
30476
+ * * `C` and `D`: the coefficients of `E1(s,t) = C(s)⋅t + D(s)`
30477
+ * * `H`: the eliminated polynomial `A(s)⋅D(s) - B(s)⋅C(s)` whose roots are
30478
+ * candidate `s` values for medial points
30461
30479
  *
30462
30480
  * @param p base point
30463
- * @param v ray direction from `p`
30481
+ * @param v ray direction vector starting from `p`
30464
30482
  * @param ps order 1 bezier control points, i.e. a line segment
30465
30483
  * given as an array of control points, e.g. `[[0,0],[2,1]]`
30466
30484
  */
@@ -30472,56 +30490,41 @@ function getMedialPointCoeffsBez1(p, v, ps) {
30472
30490
  const [vx, vy] = v;
30473
30491
  const [[x0, y0], [x1, y1]] = ps;
30474
30492
  // Linear bezier in power basis: b(s) = b*s + c
30475
- const bx = -x0 + x1;
30476
- const by = -y0 + y1;
30477
- const cx = x0;
30478
- const cy = y0;
30493
+ // We can also use: `const [[bx,by], [cx,cy]] = toPowerBasis1(ps)`
30494
+ const bx = x1 - x0;
30495
+ const by = y1 - y0;
30479
30496
  // u(s) = p - b(s) = u1*s + u0
30480
- const u1x = -bx;
30481
- const u1y = -by;
30482
- const u0x = px - cx;
30483
- const u0y = py - cy;
30497
+ const u0x = px - x0;
30498
+ const u0y = py - y0;
30484
30499
  // b'(s) = w(s) = w0
30485
- const w0x = bx;
30486
- const w0y = by;
30487
30500
  // -----------------------------------------------------
30488
30501
  // E1(s,t): (u(s) + t⋅v) ⋅ b'(s) = 0
30489
30502
  // => C(s)⋅t + D(s) = 0
30490
- const c0 = vx * w0x + vy * w0y;
30503
+ const c0 = vx * bx + vy * by;
30491
30504
  // -----------------------------------------------------
30492
30505
  // -----------------------------------------------------
30493
- const d1 = u1x * w0x + u1y * w0y;
30494
- const d0 = u0x * w0x + u0y * w0y;
30506
+ const d1 = -(bx * bx + by * by);
30507
+ const d0 = bx * u0x + by * u0y;
30495
30508
  // -----------------------------------------------------
30496
30509
  // -----------------------------------------------------
30497
30510
  // E2(s,t): |t⋅v|² - |u(s) + t⋅v|² = 0
30498
30511
  // => 2⋅(v⋅u(s))⋅t + |u(s)|² = 0
30499
30512
  // => A(s)⋅t + B(s) = 0
30500
- const a1 = 2 * (vx * u1x + vy * u1y);
30513
+ const a1 = -2 * c0;
30501
30514
  const a0 = 2 * (vx * u0x + vy * u0y);
30502
30515
  // -----------------------------------------------------
30503
30516
  // -----------------------------------------------------
30504
- const b2 = u1x * u1x + u1y * u1y;
30505
- const b1 = 2 * (u1x * u0x + u1y * u0y);
30517
+ const b2 = -d1;
30518
+ const b1 = -2 * d0;
30506
30519
  const b0 = u0x * u0x + u0y * u0y;
30507
30520
  // -----------------------------------------------------
30508
- // const A = [a1, a0]; // degree 1 in s
30509
- // const B = [b2, b1, b0]; // degree 2 in s
30510
- // const C = [c0]; // degree 0 in s
30511
- // const D = [d1, d0]; // degree 1 in s
30512
30521
  // Eliminate t from:
30513
30522
  // A(s)⋅t + B(s) = 0
30514
30523
  // C(s)⋅t + D(s) = 0
30515
30524
  // by taking A(s)⋅D(s) - B(s)⋅C(s) = 0 (degree ≤ 2 in s)
30516
- const AD2 = a1 * d1;
30517
- const AD1 = a1 * d0 + a0 * d1;
30518
- const AD0 = a0 * d0;
30519
- const BC2 = b2 * c0;
30520
- const BC1 = b1 * c0;
30521
- const BC0 = b0 * c0;
30522
- const H2 = AD2 - BC2;
30523
- const H1 = AD1 - BC1;
30524
- const H0 = AD0 - BC0;
30525
+ const H2 = b2 * c0;
30526
+ const H1 = a0 * d1;
30527
+ const H0 = a0 * d0 - b0 * c0;
30525
30528
  return {
30526
30529
  A: [a1, a0],
30527
30530
  B: [b2, b1, b0],
@@ -30533,21 +30536,22 @@ function getMedialPointCoeffsBez1(p, v, ps) {
30533
30536
 
30534
30537
  //# sourceMappingURL=get-medial-point-coeffs-bez1.js.map
30535
30538
  ;// ./node_modules/flo-bezier3/node/get-medial-points/get-medial-point-coeffs-bez3.js
30539
+
30536
30540
  /**
30537
- * Returns polynomial coefficients for ray parameter values `t`, bezier
30538
- * parameter values `s` and medial points for points `q(t)` and b(s) (an order
30539
- * 3 bezier curve) that satisfy the medial condition with respect to `p` and `ps`:
30540
- *
30541
- * Let `p` be a fixed point in the plane.
30542
- * Let `v` be a direction vector defining the ray `q(t) = p + t⋅v`.
30543
- * Let `ps` be a cubic bezier curve.
30541
+ * Returns the polynomial coefficients for the ray parameter `t` and the
30542
+ * curve parameter `s` that encode the medial condition for `q(t) = p + t⋅v`
30543
+ * and a cubic bezier curve `ps`.
30544
30544
  *
30545
+ * The returned coefficients describe the equations whose common solutions
30546
+ * satisfy:
30545
30547
  * * `q(t)` is equidistant from `p` and the nearest point on `ps`
30546
30548
  * * that common distance is locally minimal among such candidates
30547
30549
  *
30548
- * In other words, this function returns candidate ray parameters for the
30549
- * sought medial point(s). Selecting physically valid solutions (if needed)
30550
- * is done by the caller or by a later stage of this routine.
30550
+ * More specifically, this function returns:
30551
+ * * `A` and `B`: the coefficients of `E2(s,t) = A(s)⋅t + B(s)`
30552
+ * * `C` and `D`: the coefficients of `E1(s,t) = C(s)⋅t + D(s)`
30553
+ * * `H`: the eliminated polynomial `A(s)⋅D(s) - B(s)⋅C(s)` whose roots are
30554
+ * candidate `s` values for medial points
30551
30555
  *
30552
30556
  * @param p base point
30553
30557
  * @param v ray direction from `p`
@@ -30560,100 +30564,73 @@ function getMedialPointCoeffsBez3(p, v, ps) {
30560
30564
  // -----------------------------------------------------
30561
30565
  const [px, py] = p;
30562
30566
  const [vx, vy] = v;
30563
- const [[x0, y0], [x1, y1], [x2, y2], [x3, y3]] = ps;
30564
30567
  // Cubic bezier in power basis: b(s) = a*s^3 + b*s^2 + c*s + d
30565
- const ax = -x0 + 3 * x1 - 3 * x2 + x3;
30566
- const ay = -y0 + 3 * y1 - 3 * y2 + y3;
30567
- const bx = 3 * x0 - 6 * x1 + 3 * x2;
30568
- const by = 3 * y0 - 6 * y1 + 3 * y2;
30569
- const cx = -3 * x0 + 3 * x1;
30570
- const cy = -3 * y0 + 3 * y1;
30571
- const dx = x0;
30572
- const dy = y0;
30573
- // u(s) = p - b(s) = u3*s^3 + u2*s^2 + u1*s + u0
30574
- const u3x = -ax;
30575
- const u3y = -ay;
30576
- const u2x = -bx;
30577
- const u2y = -by;
30578
- const u1x = -cx;
30579
- const u1y = -cy;
30568
+ const [[ax, bx, cx, dx], [ay, by, cy, dy]] = to_power_basis_toPowerBasis3(ps);
30580
30569
  const u0x = px - dx;
30581
30570
  const u0y = py - dy;
30582
- // b'(s) = w(s) = w2*s^2 + w1*s + w0
30583
- const w2x = 3 * ax;
30584
- const w2y = 3 * ay;
30585
- const w1x = 2 * bx;
30586
- const w1y = 2 * by;
30587
- const w0x = cx;
30588
- const w0y = cy;
30571
+ // Reuse dot products across A, B, C, D, and H.
30572
+ const va = vx * ax + vy * ay;
30573
+ const vb = vx * bx + vy * by;
30574
+ const vc = vx * cx + vy * cy;
30575
+ const vu0 = vx * u0x + vy * u0y;
30576
+ const b6 = ax * ax + ay * ay;
30577
+ const ab = ax * bx + ay * by;
30578
+ const ac = ax * cx + ay * cy;
30579
+ const bb = bx * bx + by * by;
30580
+ const bc = bx * cx + by * cy;
30581
+ const cc = cx * cx + cy * cy;
30582
+ const au0 = ax * u0x + ay * u0y;
30583
+ const bu0 = bx * u0x + by * u0y;
30584
+ const d0 = cx * u0x + cy * u0y;
30585
+ const b0 = u0x * u0x + u0y * u0y;
30589
30586
  // -----------------------------------------------------
30590
30587
  // E1(s,t): (u(s) + t*v) * b'(s) = 0
30591
30588
  // => C(s)*t + D(s) = 0
30592
- const c2 = vx * w2x + vy * w2y;
30593
- const c1 = vx * w1x + vy * w1y;
30594
- const c0 = vx * w0x + vy * w0y;
30589
+ const c2 = 3 * va;
30590
+ const c1 = 2 * vb;
30591
+ const c0 = vc;
30595
30592
  // -----------------------------------------------------
30596
30593
  // -----------------------------------------------------
30597
- const d5 = u3x * w2x + u3y * w2y;
30598
- const d4 = u3x * w1x + u3y * w1y + u2x * w2x + u2y * w2y;
30599
- const d3 = u3x * w0x + u3y * w0y + u2x * w1x + u2y * w1y + u1x * w2x + u1y * w2y;
30600
- const d2 = u2x * w0x + u2y * w0y + u1x * w1x + u1y * w1y + u0x * w2x + u0y * w2y;
30601
- const d1 = u1x * w0x + u1y * w0y + u0x * w1x + u0y * w1y;
30602
- const d0 = u0x * w0x + u0y * w0y;
30594
+ const d5 = -3 * b6;
30595
+ const d4 = -5 * ab;
30596
+ const d3 = -4 * ac - 2 * bb;
30597
+ const d2 = 3 * au0 - 3 * bc;
30598
+ const d1 = 2 * bu0 - cc;
30603
30599
  // -----------------------------------------------------
30604
30600
  // -----------------------------------------------------
30605
30601
  // E2(s,t): |t*v|^2 - |u(s) + t*v|^2 = 0
30606
30602
  // => 2*(v*u(s))*t + |u(s)|^2 = 0
30607
30603
  // => A(s)*t + B(s) = 0
30608
- const a3 = 2 * (vx * u3x + vy * u3y);
30609
- const a2 = 2 * (vx * u2x + vy * u2y);
30610
- const a1 = 2 * (vx * u1x + vy * u1y);
30611
- const a0 = 2 * (vx * u0x + vy * u0y);
30604
+ const a3 = -2 * va;
30605
+ const a2 = -2 * vb;
30606
+ const a1 = -2 * vc;
30607
+ const a0 = 2 * vu0;
30612
30608
  // -----------------------------------------------------
30613
30609
  // -----------------------------------------------------
30614
- const b6 = u3x * u3x + u3y * u3y;
30615
- const b5 = 2 * (u3x * u2x + u3y * u2y);
30616
- const b4 = 2 * (u3x * u1x + u3y * u1y) + (u2x * u2x + u2y * u2y);
30617
- const b3 = 2 * (u3x * u0x + u3y * u0y) + 2 * (u2x * u1x + u2y * u1y);
30618
- const b2 = 2 * (u2x * u0x + u2y * u0y) + (u1x * u1x + u1y * u1y);
30619
- const b1 = 2 * (u1x * u0x + u1y * u0y);
30620
- const b0 = u0x * u0x + u0y * u0y;
30610
+ const b5 = 2 * ab;
30611
+ const b4 = 2 * ac + bb;
30612
+ const b3 = 2 * bc - 2 * au0;
30613
+ const b2 = cc - 2 * bu0;
30614
+ const b1 = -2 * d0;
30621
30615
  // -----------------------------------------------------
30622
- // const A = [a3, a2, a1, a0]; // degree 3 in s
30623
- // const B = [b6, b5, b4, b3, b2, b1, b0]; // degree 6 in s
30624
- // const C = [c2, c1, c0]; // degree 2 in s
30625
- // const D = [d5, d4, d3, d2, d1, d0]; // degree 5 in s
30626
30616
  // Eliminate t from:
30627
30617
  // A(s)*t + B(s) = 0
30628
30618
  // C(s)*t + D(s) = 0
30629
- // by taking A(s)*D(s) - B(s)*C(s) = 0 (degree <= 8 in s)
30630
- const AD8 = a3 * d5;
30631
- const AD7 = a3 * d4 + a2 * d5;
30632
- const AD6 = a3 * d3 + a2 * d4 + a1 * d5;
30633
- const AD5 = a3 * d2 + a2 * d3 + a1 * d4 + a0 * d5;
30634
- const AD4 = a3 * d1 + a2 * d2 + a1 * d3 + a0 * d4;
30635
- const AD3 = a3 * d0 + a2 * d1 + a1 * d2 + a0 * d3;
30636
- const AD2 = a2 * d0 + a1 * d1 + a0 * d2;
30637
- const AD1 = a1 * d0 + a0 * d1;
30638
- const AD0 = a0 * d0;
30639
- const BC8 = b6 * c2;
30640
- const BC7 = b6 * c1 + b5 * c2;
30641
- const BC6 = b6 * c0 + b5 * c1 + b4 * c2;
30642
- const BC5 = b5 * c0 + b4 * c1 + b3 * c2;
30643
- const BC4 = b4 * c0 + b3 * c1 + b2 * c2;
30644
- const BC3 = b3 * c0 + b2 * c1 + b1 * c2;
30645
- const BC2 = b2 * c0 + b1 * c1 + b0 * c2;
30646
- const BC1 = b1 * c0 + b0 * c1;
30647
- const BC0 = b0 * c0;
30648
- const H8 = AD8 - BC8;
30649
- const H7 = AD7 - BC7;
30650
- const H6 = AD6 - BC6;
30651
- const H5 = AD5 - BC5;
30652
- const H4 = AD4 - BC4;
30653
- const H3 = AD3 - BC3;
30654
- const H2 = AD2 - BC2;
30655
- const H1 = AD1 - BC1;
30656
- const H0 = AD0 - BC0;
30619
+ // by taking H(s) = A(s)*D(s) - B(s)*C(s) = 0 (degree <= 8 in s).
30620
+ // Using:
30621
+ // a2 = -c1, a1 = -2*c0,
30622
+ // d5 = -3*b6, d4 = -(5/2)*b5, d3 = -2*b4, d2 = -(3/2)*b3,
30623
+ // d1 = -b2, d0 = -(1/2)*b1,
30624
+ // we can compute H directly with fewer operations.
30625
+ const H8 = 3 * va * b6;
30626
+ const H7 = 4 * (va * ab + vb * b6);
30627
+ const H6 = va * b4 + 6 * vb * ab + 5 * vc * b6;
30628
+ const H5 = 2 * vb * b4 + 8 * vc * ab - 6 * vu0 * b6;
30629
+ const H4 = -va * b2 + vb * b3 + 3 * vc * b4 - 10 * vu0 * ab;
30630
+ const H3 = -2 * va * b1 + 2 * vc * b3 - 4 * vu0 * b4;
30631
+ const H2 = vc * b2 - vb * b1 - 3 * vu0 * b3 - 3 * va * b0;
30632
+ const H1 = -2 * vu0 * b2 - 2 * vb * b0;
30633
+ const H0 = -vu0 * b1 - vc * b0;
30657
30634
  return {
30658
30635
  A: [a3, a2, a1, a0],
30659
30636
  B: [b6, b5, b4, b3, b2, b1, b0],
@@ -30666,32 +30643,28 @@ function getMedialPointCoeffsBez3(p, v, ps) {
30666
30643
  //# sourceMappingURL=get-medial-point-coeffs-bez3.js.map
30667
30644
  ;// ./node_modules/flo-bezier3/node/get-medial-points/get-medial-point-coeffs-bez0.js
30668
30645
  /**
30669
- * Returns polynomial coefficients for ray parameter values `t`, bezier
30670
- * parameter values `s` and medial points for points `q(t)` and b(s) (an order
30671
- * 0 bezier curve) that satisfy the medial condition with respect to `p` and `ps`:
30646
+ * Returns the coefficients `a0` and `b0` for the linear equation
30647
+ * `a0⋅t + b0 = 0`, so the ray parameter can be recovered as `t = -b0/a0`.
30648
+ * That parameter value makes `q(t) = p + t⋅v` equidistant from `p` and `P`.
30672
30649
  *
30673
- * Let `p` be a fixed point in the plane.
30674
- * Let `v` be a direction vector defining the ray `q(t) = p + t⋅v`.
30675
- * Let `ps` be an order 0 bezier curve (a single point).
30650
+ * Let `p` be a fixed point in the plane.\
30651
+ * Let `v` be a direction vector defining the ray `q(t) = p + t⋅v`.\
30652
+ * Let `P` be another point.\
30676
30653
  *
30677
- * * `q(t)` is equidistant from `p` and the nearest point on `ps`
30678
- * * that common distance is locally minimal among such candidates
30679
- *
30680
- * In other words, this function returns candidate ray parameters for the
30681
- * sought medial point(s). Selecting physically valid solutions (if needed)
30682
- * is done by the caller or by a later stage of this routine.
30654
+ * In other words, this function returns the coefficients needed to solve for
30655
+ * the ray parameter of the medial point on the ray.
30683
30656
  *
30684
30657
  * @param p base point
30685
30658
  * @param v ray direction from `p`
30686
- * @param ps order 0 bezier control point, e.g. `[1,2]`
30659
+ * @param P another "target" point, e.g. `[1,2]`
30687
30660
  */
30688
- function getMedialPointCoeffsBez0(p, v, ps) {
30661
+ function getMedialPointCoeffsBez0(p, v, P) {
30689
30662
  // -----------------------------------------------------
30690
30663
  // See get-medial-points.md for implementation details.
30691
30664
  // -----------------------------------------------------
30692
30665
  const [px, py] = p;
30693
30666
  const [vx, vy] = v;
30694
- const [x0, y0] = ps;
30667
+ const [x0, y0] = P;
30695
30668
  // Constant bezier in power basis: b(s) = c
30696
30669
  // u(s) = p - b(s) = u0
30697
30670
  const u0x = px - x0;
@@ -30701,17 +30674,7 @@ function getMedialPointCoeffsBez0(p, v, ps) {
30701
30674
  // => A(s)⋅t + B(s) = 0
30702
30675
  const a0 = 2 * (vx * u0x + vy * u0y);
30703
30676
  const b0 = u0x * u0x + u0y * u0y;
30704
- // const A = [a0]; // degree 0 in s
30705
- // const B = [b0]; // degree 0 in s
30706
- return {
30707
- a0,
30708
- b0
30709
- // A: [a0],
30710
- // B: [b0],
30711
- // C: [], // the zero, i.e. -1 degree polynomial
30712
- // D: [], // ...
30713
- // H: [] // ...
30714
- };
30677
+ return { a0, b0 };
30715
30678
  }
30716
30679
 
30717
30680
  //# sourceMappingURL=get-medial-point-coeffs-bez0.js.map
@@ -30775,23 +30738,21 @@ function getClosestPoint(maxCoordPowerOf2, nnorm, yPos, for1Prong, angle, curveP
30775
30738
  const { curve, ts: [tS, tE] } = curvePiece;
30776
30739
  const { ps } = curve;
30777
30740
  const { curve: touchedCurve, t, p: y } = yPos;
30778
- const shouldDeflate = angle === 0 && curve === touchedCurve;
30741
+ const isTouched = curve === touchedCurve;
30742
+ const shouldDeflate = angle === 0 && isTouched;
30779
30743
  const infos = [];
30780
- // let onePushed = false;
30781
30744
  let startPushed = false;
30782
30745
  let endPushed = false;
30783
30746
  let ss;
30784
- if (tS !== tE) {
30785
- const { A, B, C, D, H } = getMedialPointCoeffs(y, nnorm, ps);
30786
- const def = shouldDeflate ? deflate(H, t) : undefined;
30787
- const def2 = for1Prong && shouldDeflate
30788
- ? deflate(def, t)
30789
- : undefined;
30790
- const def3 = for1Prong && shouldDeflate
30791
- ? deflate(def2, t)
30792
- : undefined;
30793
- const pDd = def3 ?? def ?? H;
30794
- ss = roots(pDd, tS, tE) || [];
30747
+ if (tS !== tE &&
30748
+ !(shouldDeflate && ps.length === 2) &&
30749
+ !(isTouched && ps.length === 3 && for1Prong)) {
30750
+ const { A, B, H } = shouldDeflate
30751
+ ? ps.length === 3
30752
+ ? getMedialPointCoeffsBez2_SameCurve(t, nnorm, ps)
30753
+ : getMedialPointCoeffsBez3_SameCurve(t, nnorm, ps)
30754
+ : getMedialPointCoeffs(y, nnorm, ps);
30755
+ ss = roots(H, tS, tE) || [];
30795
30756
  //-----------------------
30796
30757
  for (let i = 0; i < ss.length; i++) {
30797
30758
  const ri = ss[i];
@@ -30802,20 +30763,26 @@ function getClosestPoint(maxCoordPowerOf2, nnorm, yPos, for1Prong, angle, curveP
30802
30763
  if (sE < tS || sS > tE) {
30803
30764
  continue;
30804
30765
  } // outside curve piece
30805
- const s = _s < 0 ? 0 : _s > 1 ? 1 : _s; // clip to [0,1]
30766
+ if (sS < 0) {
30767
+ continue;
30768
+ } // outside curve piece
30769
+ // clip to [0,1]
30770
+ const s = sE > 1 ? 1 : _s;
30806
30771
  //-----------------------
30807
30772
  const AS = Horner(A, s);
30808
30773
  const BS = Horner(B, s);
30809
- const CS = Horner(C, s);
30810
- const DS = Horner(D, s);
30774
+ // const CS = Horner(C, s);
30775
+ // const DS = Horner(D, s);
30811
30776
  const _AS = get_closest_points_abs(AS);
30812
- const _CS = get_closest_points_abs(CS);
30813
- if (get_closest_points_max(_AS, _CS) < 2 ** -40) {
30777
+ // const _CS = abs(CS);
30778
+ // if (max(_AS, _CS) < 2**-40) { continue; }
30779
+ if (get_closest_points_max(_AS) < 2 ** -40) {
30814
30780
  continue;
30815
30781
  }
30816
- const w = _AS > _CS
30817
- ? -BS / AS
30818
- : -DS / CS; // alternative
30782
+ // const w = _AS > _CS
30783
+ // ? -BS / AS
30784
+ // : -DS / CS; // alternative
30785
+ const w = -BS / AS;
30819
30786
  if (w <= 0) {
30820
30787
  // If `w` is negative the circle radius is negative -> discard
30821
30788
  continue;
@@ -31006,24 +30973,6 @@ function reduceRadius(maxCoordPowerOf2, curvePieces, y, nnorm) {
31006
30973
  }
31007
30974
 
31008
30975
 
31009
- ;// ./src/find-2-prong/squared-distance-between-dd.ts
31010
-
31011
- function squaredDistanceBetweenDd(x, y) {
31012
- const [x0, y0] = x;
31013
- const [x1, y1] = y;
31014
- // xd = x0 - x1;
31015
- // yd = y0 - y1;
31016
- // xx = xd**2;
31017
- // yy = yd**2;
31018
- // return xx + yy
31019
- const xd = two_diff_twoDiff(x0, x1);
31020
- const yd = two_diff_twoDiff(y0, y1);
31021
- const xx = ddMultDd(xd, xd);
31022
- const yy = ddMultDd(yd, yd);
31023
- return ddAddDd(xx, yy)[1];
31024
- }
31025
-
31026
-
31027
30976
  ;// ./src/find-2-prong/cull-bezier-pieces.ts
31028
30977
 
31029
30978
 
@@ -31113,7 +31062,7 @@ function add1Prong(meta, radius, center, pos) {
31113
31062
 
31114
31063
  ;// ./src/find-2-prong/calc-seperation-tolerance.ts
31115
31064
 
31116
- const calc_seperation_tolerance_tp = two_product_twoProduct;
31065
+ const calc_seperation_tolerance_tp = twoProduct;
31117
31066
  const calc_seperation_tolerance_qaq = ddAddDd;
31118
31067
  const calc_seperation_tolerance_qdq = ddDiffDd;
31119
31068
  const calc_seperation_tolerance_qmd = ddMultDouble1;
@@ -31235,7 +31184,7 @@ function dd_horner_ddHorner(p, x) {
31235
31184
  //# sourceMappingURL=dd-horner.js.map
31236
31185
  ;// ./node_modules/flo-bezier3/node/to-power-basis/to-power-basis-1st-derivative/double-double/to-power-basis-1st-derivative-dd.js
31237
31186
 
31238
- const to_power_basis_1st_derivative_dd_ts = basic_two_sum_twoSum; // error -> 0
31187
+ const to_power_basis_1st_derivative_dd_ts = two_sum_twoSum; // error -> 0
31239
31188
  const to_power_basis_1st_derivative_dd_td = two_diff_twoDiff; // error -> 0
31240
31189
  const to_power_basis_1st_derivative_dd_qmd = ddMultDouble2; // error -> 3*u²
31241
31190
  const to_power_basis_1st_derivative_dd_qaq = ddAddDd;
@@ -31428,7 +31377,8 @@ function getOsculatingCircle(maxOsculatingCircleRadius, pos, norm) {
31428
31377
  const { curve, p, t } = pos;
31429
31378
  const { ps } = curve;
31430
31379
  const minCurvature = 1 / maxOsculatingCircleRadius;
31431
- const k_ = -(ddCurvature(ps, t)[1]);
31380
+ const kDd = ddCurvature(ps, t);
31381
+ const k_ = -(kDd[0] + kDd[1]);
31432
31382
  const k = k_ < minCurvature ? minCurvature : k_;
31433
31383
  const [tx, ty] = norm;
31434
31384
  const l = get_osculating_circle_sqrt(tx * tx + ty * ty);
@@ -31559,10 +31509,6 @@ function find2Prong(meta) {
31559
31509
  // The lines below is an optimization.
31560
31510
  const xy2 = reduceRadius(maxCoordPowerOf2, curvePieces, y, nnorm);
31561
31511
  const xy = find_2_prong_sqrt(xy2);
31562
- if (for1Prong && rO < (1 - oneProngTolerance) * xy) {
31563
- add1Prong(meta, rO, xO, yPos);
31564
- return undefined;
31565
- }
31566
31512
  const l = find_2_prong_sqrt(nnorm[0] ** 2 + nnorm[1] ** 2);
31567
31513
  xO = [y[0] + nnorm[0] / l * xy, y[1] + nnorm[1] / l * xy];
31568
31514
  cullCurvePieces(curvePieces, xO, xy2);
@@ -31579,6 +31525,10 @@ function find2Prong(meta) {
31579
31525
  }
31580
31526
  }
31581
31527
  const { x, d, curve, s } = antipodalPoints[0];
31528
+ if (for1Prong && rO < (1 - oneProngTolerance) * d) {
31529
+ add1Prong(meta, rO, xO, yPos);
31530
+ return undefined;
31531
+ }
31582
31532
  const z = {
31583
31533
  curve, t: s, isSource: false,
31584
31534
  p: toP(curve.ps, s)
@@ -31592,7 +31542,7 @@ function find2Prong(meta) {
31592
31542
  }
31593
31543
  // The lines below eliminate cases where the found 2-prong is too
31594
31544
  // close to a one-prong
31595
- const squaredSeperationTolerance = find_2_prong_max(calcSeperationTolerance(rO, find_2_prong_sqrt(xz), 2 ** 2 * errorTolerance), minSquaredSeperationTolerance);
31545
+ const squaredSeperationTolerance = find_2_prong_max(calcSeperationTolerance(rO, find_2_prong_sqrt(xz), (2 ** 2) * errorTolerance), minSquaredSeperationTolerance);
31596
31546
  if (yz <= squaredSeperationTolerance) {
31597
31547
  return undefined;
31598
31548
  }
@@ -32187,10 +32137,10 @@ function is_collinear_isVertical(ps) {
32187
32137
  //# sourceMappingURL=is-collinear.js.map
32188
32138
  ;// ./node_modules/flo-bezier3/node/global-properties/classification/is-cubic-really-quad.js
32189
32139
 
32190
- const classification_is_cubic_really_quad_tp = basic_two_product_twoProduct;
32140
+
32141
+ const classification_is_cubic_really_quad_tp = two_product_twoProduct;
32191
32142
  const classification_is_cubic_really_quad_fes = fastExpansionSum;
32192
- const classification_is_cubic_really_quad_u = Number.EPSILON / 2;
32193
- const classification_is_cubic_really_quad_abs = Math.abs;
32143
+ const { abs: classification_is_cubic_really_quad_abs } = Math;
32194
32144
  /**
32195
32145
  * Returns `true` if the given cubic bezier curve is really a quadratic (or
32196
32146
  * lower order) curve in disguise, i.e. it can be represent by a quadratic
@@ -32221,7 +32171,7 @@ function is_cubic_really_quad_isCubicReallyQuad(ps) {
32221
32171
  const w = u2 - v2;
32222
32172
  const w_ = u2_ + v2_ + classification_is_cubic_really_quad_abs(w); // the absolute error in w
32223
32173
  // if w cannot possibly be zero, i.e. if the error is smaller than the value
32224
- if (classification_is_cubic_really_quad_abs(w) - classification_is_cubic_really_quad_u * w_ > 0) {
32174
+ if (classification_is_cubic_really_quad_abs(w) - error_analysis_error_analysis_u * w_ > 0) {
32225
32175
  // fast filter 1 passed
32226
32176
  return false;
32227
32177
  }
@@ -32235,7 +32185,7 @@ function is_cubic_really_quad_isCubicReallyQuad(ps) {
32235
32185
  const r2_ = r1_ + classification_is_cubic_really_quad_abs(r2); // the absolute error in r2
32236
32186
  const s = q2 - r2;
32237
32187
  const s_ = q2_ + r2_ + classification_is_cubic_really_quad_abs(s); // the absolute error in s
32238
- if (classification_is_cubic_really_quad_abs(s) - classification_is_cubic_really_quad_u * s_ > 0) {
32188
+ if (classification_is_cubic_really_quad_abs(s) - error_analysis_error_analysis_u * s_ > 0) {
32239
32189
  // fast filter 2 passed
32240
32190
  return false;
32241
32191
  }
@@ -32250,7 +32200,7 @@ function is_cubic_really_quad_isCubicReallyQuad(ps) {
32250
32200
  const degree_or_type_cubic_to_quadratic_epr = expansionProduct;
32251
32201
  const degree_or_type_cubic_to_quadratic_td = twoDiff;
32252
32202
  const degree_or_type_cubic_to_quadratic_sce = scaleExpansion;
32253
- const degree_or_type_cubic_to_quadratic_ts = two_sum_twoSum;
32203
+ const degree_or_type_cubic_to_quadratic_ts = twoSum;
32254
32204
  /**
32255
32205
  * Returns a quadratic approximation to the given cubic bezier curve.
32256
32206
  *
@@ -32802,8 +32752,8 @@ function findMats(bezierLoops, options) {
32802
32752
  }
32803
32753
  mats.push(mat);
32804
32754
  }
32805
- // console.log(structuredClone(find3Prong.getStats()));
32806
- // find3Prong.resetStats();
32755
+ // console.log(structuredClone(circumCenter.getStats()));
32756
+ // circumCenter.resetStats();
32807
32757
  return mats;
32808
32758
  }
32809
32759
  /**
@@ -33688,7 +33638,7 @@ threeProng, classes, delay = 0, scaleFactor = 1) {
33688
33638
  const circle = scaleCircle(threeProng.pointOnShape.circle, 1);
33689
33639
  const { center: c, radius: r } = circle;
33690
33640
  // const poss = threeProng.poss;
33691
- const poss = CpNodeFs.getAllOnCircle(threeProng)
33641
+ const poss = getAllOnCircle(threeProng)
33692
33642
  .map(cpNode => cpNode.pointOnShape);
33693
33643
  const { dot, circle: drawCircle, crossHair } = drawFs;
33694
33644
  const $circle = drawCircle(g, circle, 'blue thin2 nofill', delay);
@@ -33706,8 +33656,6 @@ threeProng, classes, delay = 0, scaleFactor = 1) {
33706
33656
 
33707
33657
  ;// ./src/debug/functions/draw-elem/draw-vertex.ts
33708
33658
 
33709
-
33710
- const { getAllOnCircle: draw_vertex_getAllOnCircle } = CpNodeFs;
33711
33659
  /** @internal */
33712
33660
  function vertex(g, cpNode, classes, delay = 0, scaleFactor = 1) {
33713
33661
  const circle = cpNode.pointOnShape.circle;
@@ -33754,7 +33702,6 @@ function tightBoundingBox(g, box, classes = 'thin5 pinker nofill', delay = 0, sc
33754
33702
 
33755
33703
 
33756
33704
 
33757
- const { isTerminating: draw_mat_isTerminating } = CpNodeFs;
33758
33705
  const altClasses = [
33759
33706
  'thin10 blue nofill',
33760
33707
  'thin10 red nofill'
@@ -33765,13 +33712,13 @@ function drawMat(g, mat, classes_, delay = 0, scaleFactor = 1) {
33765
33712
  if (!cpNode) {
33766
33713
  return [];
33767
33714
  }
33768
- while (!draw_mat_isTerminating(cpNode)) {
33715
+ while (!isTerminating(cpNode)) {
33769
33716
  cpNode = cpNode.next;
33770
33717
  }
33771
33718
  const $svgs = [];
33772
33719
  let i = 0;
33773
33720
  traverseEdges(cpNode, cpNode => {
33774
- if (draw_mat_isTerminating(cpNode)) {
33721
+ if (isTerminating(cpNode)) {
33775
33722
  return;
33776
33723
  }
33777
33724
  const bezier = getMatCurveToNext(cpNode);
@@ -33822,7 +33769,7 @@ function drawLeaves(g, leaves, classes = 'thin10 deeppink nofill', delay = 0, sc
33822
33769
  const { circle } = cp;
33823
33770
  const { center: c, radius: r } = circle;
33824
33771
  const $center = [drawCirclePercent(g, c, 0.5, 'pinker thin5 nofill')];
33825
- const poss = CpNodeFs.getAllOnCircle(cpNode)
33772
+ const poss = getAllOnCircle(cpNode)
33826
33773
  .map(cpNode => cpNode.pointOnShape);
33827
33774
  const $ls = [];
33828
33775
  const $cps = [];
@@ -33889,7 +33836,7 @@ function drawBranch(g, branch, classes = 'thin5 purple nofill', delay = 0, scale
33889
33836
  function drawCpNode(g, cpNode, classes = 'blue thin2 nofill', delay = 0, scaleFactor = 1) {
33890
33837
  const circle = scaleCircle(cpNode.pointOnShape.circle, 1);
33891
33838
  const { center: c, radius: r } = circle;
33892
- const poss = CpNodeFs.getAllOnCircle(cpNode)
33839
+ const poss = getAllOnCircle(cpNode)
33893
33840
  .map(cpNode => cpNode.pointOnShape);
33894
33841
  const { dot, circle: drawCircle, crossHair } = drawFs;
33895
33842
  const $circle = drawCircle(g, circle, classes, delay);
@@ -34342,4 +34289,5 @@ function getHoleCloserNext(pairs, holeCloser) {
34342
34289
 
34343
34290
 
34344
34291
 
34345
- export { CpNodeFs, beziersToSvgPathStr, clone, cpNodeComparator, createInitialCpTree, debugElemNames, drawBeziersAsSinglePath, drawBranch, drawElemFs, drawElemFsDetailed, drawMat, emptyDebugElems, enableDebugForMat, enhanceCpNode, find2Prong, findAndAddHoleClosing2Prongs, findMats, floydWarshall, getAllOnCircle, getAllOnLoop, getAllVertices, getBoundaryBezierPartsToNext, getBoundaryBeziersBetween, getBoundaryBeziersToNext, getBoundaryPieceBeziers, getBranch, getBranchBeziers, getBranches, getChildren, getCloseBoundaryPointsCertified, getClosestSquareDistanceToRect, getEdgeDirection, getFirstExit, getFor2ProngsOnLoop, getGraph, getHoleClosers, getImpliedBoundaryBezierBetween, getInitialDegAngleBetweenMatCurves, getMatCurveBetween, getMatCurveToNext, getMatCurvesBetween, getPartialMeta, getPathsFromStr, getPointToCpNode, getPotentialClosestPointsOnCurveCertified, getProngCount, getRealProngCount, getSalience, getSatCulls, get_shape_bounds_getShapeBounds as getShapeBounds, getSharpCornersOnLoop, getVertexForwardChildren, isFullyTerminating, isOnSameCircle, isOneProng, isSharp, isTerminating, isTrivial, isTwoProng, isVertexSpecial, loopFromBeziers, removeVertex, simplifyMat, sweep_line_sweepLine as sweepLine, toScaleAxis, traverseCp, traverseEdges, traverseVertices, trimMat };
34292
+
34293
+ export { CpNodeFs, beziersToSvgPathStr, clone, cpNodeComparator, createInitialCpTree, debugElemNames, drawBeziersAsSinglePath, drawBranch, drawElemFs, drawElemFsDetailed, drawMat, emptyDebugElems, enableDebugForMat, enhanceCpNode, find2Prong, findAndAddHoleClosing2Prongs, findMats, floydWarshall, getAllOnCircle, getAllOnLoop, getAllVertices, getBoundaryBezierPartsToNext, getBoundaryBeziersBetween, getBoundaryBeziersToNext, getBoundaryPieceBeziers, getBranch, getBranchBeziers, getBranches, getChildren, getCloseBoundaryPointsCertified, getClosestSquareDistanceToRect, getEdgeDirection, getFirstExit, getFor2ProngsOnLoop, getGraph, getHoleClosers, getImpliedBoundaryBezierBetween, getInitialDegAngleBetweenMatCurves, getMatCurveBetween, getMatCurveToNext, getMatCurvesBetween, getPartialMeta, getPathsFromStr, getPointToCpNode, getPotentialClosestPointsOnCurveCertified, getProngCount, getRealProngCount, getSalience, getSatCulls, get_shape_bounds_getShapeBounds as getShapeBounds, getSharpCornersOnLoop, getVertexForwardChildren, isFullyTerminating, isOnSameCircle, isOneProng, isSharp, isTerminating, isTrivial, isTwoProng, isVertexSpecial, loopFromBeziers, removeVertex, scaleCircle, simplifyMat, sweep_line_sweepLine as sweepLine, toScaleAxis, traverseCp, traverseEdges, traverseVertices, trimMat };