flo-mat 2.0.4 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/browser/index.js +75 -53
  2. package/browser/index.min.js +1 -1
  3. package/node/debug/functions/draw-elem/three-prong.js +1 -1
  4. package/node/debug/functions/draw-elem/two-prong.js +2 -2
  5. package/node/debug/functions/draw-elem/two-prong.js.map +1 -1
  6. package/node/mat/closest-boundary-point/closest-points-on-curve.js +9 -6
  7. package/node/mat/closest-boundary-point/closest-points-on-curve.js.map +1 -1
  8. package/node/mat/closest-boundary-point/get-close-boundary-points.js +0 -4
  9. package/node/mat/closest-boundary-point/get-close-boundary-points.js.map +1 -1
  10. package/node/mat/closest-boundary-point/get-closest-boundary-point.js.map +1 -1
  11. package/node/mat/find-mat/add-3-prong.js +16 -12
  12. package/node/mat/find-mat/add-3-prong.js.map +1 -1
  13. package/node/mat/find-mat/create-get-interesting-points-on-loop.js +5 -4
  14. package/node/mat/find-mat/create-get-interesting-points-on-loop.js.map +1 -1
  15. package/node/mat/find-mat/find-2-prong/find-2-prong.js +37 -7
  16. package/node/mat/find-mat/find-2-prong/find-2-prong.js.map +1 -1
  17. package/node/mat/find-mat/find-2-prong/find-equidistant-point-on-line-dd.d.ts +9 -0
  18. package/node/mat/find-mat/find-2-prong/find-equidistant-point-on-line-dd.js +58 -0
  19. package/node/mat/find-mat/find-2-prong/find-equidistant-point-on-line-dd.js.map +1 -0
  20. package/node/mat/find-mat/find-3-prong/find-3-prong-for-delta3s.js.map +1 -1
  21. package/node/mat/find-mat/get-sharp-corners.js +0 -1
  22. package/node/mat/find-mat/get-sharp-corners.js.map +1 -1
  23. package/node/mat/is-another-cp-closeby.js +5 -16
  24. package/node/mat/is-another-cp-closeby.js.map +1 -1
  25. package/node/point-on-shape.js.map +1 -1
  26. package/package.json +2 -2
  27. package/src/debug/functions/draw-elem/three-prong.ts +1 -1
  28. package/src/debug/functions/draw-elem/two-prong.ts +2 -2
  29. package/src/mat/closest-boundary-point/closest-points-on-curve.ts +12 -8
  30. package/src/mat/closest-boundary-point/get-close-boundary-points.ts +1 -5
  31. package/src/mat/closest-boundary-point/get-closest-boundary-point-dd.ts +62 -0
  32. package/src/mat/closest-boundary-point/get-closest-boundary-point.ts +7 -7
  33. package/src/mat/cmp-cp-on-delta.ts +3 -0
  34. package/src/mat/find-mat/add-3-prong.ts +23 -13
  35. package/src/mat/find-mat/create-get-interesting-points-on-loop.ts +5 -4
  36. package/src/mat/find-mat/find-2-prong/find-2-prong.ts +44 -9
  37. package/src/mat/find-mat/find-2-prong/find-equidistant-point-on-line-dd.ts +79 -0
  38. package/src/mat/find-mat/find-3-prong/find-3-prong-for-delta3s.ts +1 -1
  39. package/src/mat/find-mat/get-sharp-corners.ts +0 -1
  40. package/src/mat/is-another-cp-closeby.ts +8 -24
  41. package/src/point-on-shape.ts +2 -1
  42. package/src/mat/closest-boundary-point/closest-point-on-curve-old.ts_ +0 -88
  43. package/src/mat/closest-boundary-point/closest-point-on-curve.ts_ +0 -95
package/browser/index.js CHANGED
@@ -23278,8 +23278,6 @@ function evaluate(ps, t) {
23278
23278
 
23279
23279
  //# sourceMappingURL=evaluate.js.map
23280
23280
  ;// CONCATENATED MODULE: ./src/mat/closest-boundary-point/closest-points-on-curve.ts
23281
- // qqq import { deflateQuad, allRootsMultiWithErrBounds, RootInterval } from 'flo-poly';
23282
- // qqq import { getTangentPolyFromPointExact, evalDeCasteljau, evaluate, getFootpointPolyExact } from 'flo-bezier3';
23283
23281
 
23284
23282
 
23285
23283
  /**
@@ -23291,13 +23289,10 @@ function evaluate(ps, t) {
23291
23289
  * @param t The t value of the bezier that locates p
23292
23290
  */
23293
23291
  function closestPointsOnCurve(curve, p, [tS, tE] = [0, 1], touchedCurve, t) {
23294
- // qqq let poly = getTangentPolyFromPointExact(curve.ps, p);
23295
23292
  const _poly = getFootpointPolyDd(curve.ps, p);
23296
- // qqq poly = deflateQuad(poly, t);
23297
23293
  const poly = curve === touchedCurve
23298
23294
  ? ddDeflate(_poly, t)
23299
23295
  : _poly;
23300
- // let roots: Omit<RootInterval,'multiplicity'>[] = allRootsMultiWithErrBounds(
23301
23296
  const roots = allRootsCertified(poly, tS, tE);
23302
23297
  // Also test the endpoints
23303
23298
  let push0 = true;
@@ -23344,8 +23339,16 @@ function closestPointsOnCurve(curve, p, [tS, tE] = [0, 1], touchedCurve, t) {
23344
23339
  ? 0
23345
23340
  : tE > 1 ? 1 : (tS + tE) / 2;
23346
23341
  // TODO - why does evalDeCasteljau not work here?
23347
- return { p: evaluate(curve.ps, t), t };
23348
23342
  //return { p: evalDeCasteljau(curve.ps,t), t }
23343
+ // TODO2 - will make it slower
23344
+ // const aa = evaluate(curve.ps,t);
23345
+ // const bb = evalDeCasteljauDd(curve.ps,[0,t]).map(v => v[1]);
23346
+ // if (aa[0] !== bb[0] || aa[1] !== bb[1]) {
23347
+ // console.log(aa);
23348
+ // console.log(bb);
23349
+ // }
23350
+ return { p: evaluate(curve.ps, t), t };
23351
+ // return { p: evalDeCasteljauDd(curve.ps,[0,t]).map(v => v[1]), t }
23349
23352
  });
23350
23353
  return ps;
23351
23354
  }
@@ -23854,12 +23857,7 @@ function addToCpGraph(circle, orders, cpTrees, poss, neighbors) {
23854
23857
 
23855
23858
 
23856
23859
  /** @hidden */
23857
- //const ANGLE_THRESHOLD = Math.cos(3 * (Math.PI / 180)); // 3 degrees
23858
- const ANGLE_THRESHOLD = 0.9986295347545738; // === Math.cos(3 degrees)
23859
- //const ANGLE_THRESHOLD = 0.9848077530122080; // === Math.cos(10 degrees)
23860
- //const ANGLE_THRESHOLD = 0.9998476951563913; // === Math.cos(1 degrees)
23861
- //const ANGLE_THRESHOLD = 0.9999984769132877; // === Math.cos(0.1 degrees)
23862
- //const ANGLE_THRESHOLD = 0.9999999847691291 // === Math.cos(0.01 degrees)
23860
+ const ANGLE_THRESHOLD = Math.cos(15 * (Math.PI / 180)); // 15 degrees
23863
23861
  /**
23864
23862
  * @hidden
23865
23863
  * Returns true if another CpNode is close to the given implied (via pos, order
@@ -23874,15 +23872,7 @@ const ANGLE_THRESHOLD = 0.9986295347545738; // === Math.cos(3 degrees)
23874
23872
  * @param color Used for debugging only
23875
23873
  */
23876
23874
  function isAnotherCpCloseby(cpTrees, pos, circle, order, order2, extreme, color) {
23877
- //console.log(extreme)
23878
- //const DISTANCE_THRESHOLD = extreme * 1e-1;
23879
- //const DISTANCE_THRESHOLD = extreme * 1e-1;
23880
23875
  const DISTANCE_THRESHOLD = extreme * 1e-4;
23881
- //const DISTANCE_THRESHOLD = extreme * 1e-4; - was this
23882
- //const DISTANCE_THRESHOLD = extreme * 1e-6;
23883
- //const DISTANCE_THRESHOLD = extreme * 1e-12;
23884
- // It seems this can be zero else the ordering should be correct
23885
- //const DISTANCE_THRESHOLD = 0;
23886
23876
  const cpTree = cpTrees.get(pos.curve.loop);
23887
23877
  const cpNodes = getNeighbouringPoints(cpTree, pos, order, order2);
23888
23878
  if (!cpNodes[0]) {
@@ -23895,11 +23885,13 @@ function isAnotherCpCloseby(cpTrees, pos, circle, order, order2, extreme, color)
23895
23885
  if (distanceBetween(p1, p2) > DISTANCE_THRESHOLD) {
23896
23886
  continue;
23897
23887
  }
23898
- const v1 = toUnitVector(fromTo(cpNode.cp.pointOnShape.p, cpNode.cp.circle.center));
23888
+ // TODO2
23889
+ return true;
23890
+ const v1 = toUnitVector(fromTo(p2, cpNode.cp.circle.center));
23899
23891
  const v2 = toUnitVector(fromTo(p1, circle.center));
23900
23892
  const cosTheta = dot(v1, v2);
23901
23893
  if (cosTheta > ANGLE_THRESHOLD) {
23902
- //console.log(`%c${cosTheta} - ${distanceBetween(p1,p2)}`, `color: ${color}`);
23894
+ // console.log(`%c${cosTheta} - ${distanceBetween(p1,p2)}`, `color: ${color}`);
23903
23895
  return true;
23904
23896
  }
23905
23897
  }
@@ -23924,24 +23916,27 @@ function add3Prong(cpTrees, orders, threeProng) {
23924
23916
  /*
23925
23917
  if (typeof _debug_ !== 'undefined') {
23926
23918
  for (let i=0; i<3; i++) {
23927
- let cpBef = threeProng.δ3s[i][0].cp;
23928
- let cpAft = threeProng.δ3s[i][1].cp;
23929
- //let cmpBef = PointOnShape.compareInclOrder(cpBef.pointOnShape, ps[i], cpBef.order, orders[i]);
23930
- //let cmpAft = PointOnShape.compareInclOrder(cpAft.pointOnShape, ps[i], cpAft.order, orders[i]);
23919
+ const cpBef = threeProng.δ3s[i][0].cp;
23920
+ const cpAft = threeProng.δ3s[i][1].cp;
23931
23921
 
23932
- let cmpBef = PointOnShape.compare(cpBef.pointOnShape, ps[i]);
23933
- let cmpAft = PointOnShape.compare(cpAft.pointOnShape, ps[i]);
23922
+ //let cmpBef = PointOnShape.compareInclOrder(cpBef.pointOnShape, poss[i], cpBef.order, orders[i]);
23923
+ //let cmpAft = PointOnShape.compareInclOrder(cpAft.pointOnShape, poss[i], cpAft.order, orders[i]);
23924
+ const cmpBef = compareCps(cpBef, { pointOnShape: poss[i], order: orders[i], order2: 0, circle: undefined });
23925
+ const cmpAft = compareCps(cpAft, { pointOnShape: poss[i], order: orders[i], order2: 0, circle: undefined });
23926
+
23927
+ // const cmpBef = comparePoss(cpBef.pointOnShape, poss[i]);
23928
+ // const cmpAft = comparePoss(cpAft.pointOnShape, poss[i]);
23934
23929
 
23935
23930
  // len is used by debug functions to reference a particular
23936
23931
  // three-prong.
23937
- let len = _debug_.generated.elems.threeProng.length-1;
23932
+ const len = _debug_.generated.elems.threeProng.length-1;
23938
23933
  if (cmpBef > 0) {
23939
23934
  console.log('----------------------------------------');
23940
23935
  console.log(`3-prong order is wrong (bef) : i: ${i} - cmp: ${cmpBef} - n: ${len}`);
23941
23936
  console.log(threeProng);
23942
23937
  console.log(cpBef);
23943
23938
  console.log(cpAft);
23944
- console.log(ps[i]);
23939
+ console.log(poss[i]);
23945
23940
  }
23946
23941
  if (cmpAft < 0) {
23947
23942
  console.log('----------------------------------------');
@@ -23949,15 +23944,16 @@ function add3Prong(cpTrees, orders, threeProng) {
23949
23944
  console.log(threeProng);
23950
23945
  console.log(cpBef);
23951
23946
  console.log(cpAft);
23952
- console.log(ps[i]);
23947
+ console.log(poss[i]);
23953
23948
  }
23954
23949
  }
23955
23950
  }
23956
23951
  */
23957
23952
  // TODO - replace 1000 below with correct value
23958
- isAnotherCpCloseby(cpTrees, poss[0], circle, orders[0], 0, 1000, 'blue');
23959
- isAnotherCpCloseby(cpTrees, poss[1], circle, orders[1], 0, 1000, 'blue');
23960
- isAnotherCpCloseby(cpTrees, poss[2], circle, orders[2], 0, 1000, 'blue');
23953
+ const c1 = isAnotherCpCloseby(cpTrees, poss[0], circle, orders[0], 0, 1000, 'blue');
23954
+ const c2 = isAnotherCpCloseby(cpTrees, poss[1], circle, orders[1], 0, 1000, 'blue');
23955
+ const c3 = isAnotherCpCloseby(cpTrees, poss[2], circle, orders[2], 0, 1000, 'blue');
23956
+ // console.log(c1,c2,c3);
23961
23957
  addToCpGraph(circle, orders, cpTrees, poss, δ3s);
23962
23958
  return circle;
23963
23959
  }
@@ -24803,7 +24799,6 @@ function getSharpCorners(possPerLoop) {
24803
24799
  for (const poss of possPerLoop) {
24804
24800
  const sharpCorners = [];
24805
24801
  for (const pos of poss) {
24806
- //if (PointOnShape.isQuiteSharpCorner(pos)) {
24807
24802
  if (isPosQuiteSharpCorner(pos)) {
24808
24803
  sharpCorners.push(pos);
24809
24804
  }
@@ -25170,11 +25165,7 @@ function getCloseBoundaryPoints(bezierPieces, point, y, distance) {
25170
25165
  // comparing closeness!
25171
25166
  const indexesToCheck = [];
25172
25167
  for (let i = 0; i < posInfos.length; i++) {
25173
- const pi = posInfos[i];
25174
- // Only check if they are close to the edges. Why??
25175
- //if (pi.pos.t < 1e-2 || 1-pi.pos.t < 1e-2) {
25176
25168
  indexesToCheck.push(i);
25177
- //}
25178
25169
  }
25179
25170
  const indexesToRemove = [];
25180
25171
  for (let i = 0; i < indexesToCheck.length; i++) {
@@ -25241,9 +25232,11 @@ const find_2_prong_evalDeCasteljau = evalDeCasteljau;
25241
25232
  */
25242
25233
  function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClosing, k) {
25243
25234
  const MAX_ITERATIONS = 25;
25244
- const squaredSeperationTolerance = (1e-6 * extreme) ** 2;
25235
+ const squaredSeperationTolerance = (1e-5 * extreme) ** 2;
25245
25236
  // TODO - base deltas on theory or remove
25246
25237
  const oneProngTolerance = (1e-4) ** 2;
25238
+ // const oneProngTolerance = (1e-5)**2;
25239
+ // const oneProngTolerance = 0;
25247
25240
  const squaredErrorTolerance = 1e-2 * squaredSeperationTolerance;
25248
25241
  const maxOsculatingCircleRadiusSquared = squaredDiagonalLength;
25249
25242
  // The boundary piece that should contain the other point of
@@ -25261,7 +25254,6 @@ function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClo
25261
25254
  }
25262
25255
  else {
25263
25256
  p = y.p;
25264
- //x = PointOnShape.getOsculatingCircle(maxOsculatingCircleRadiusSquared, y).center;
25265
25257
  x = getOsculatingCircle(maxOsculatingCircleRadiusSquared, y).center;
25266
25258
  r = squared_distance_between_squaredDistanceBetween(p, x);
25267
25259
  }
@@ -25282,8 +25274,8 @@ function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClo
25282
25274
  do {
25283
25275
  i++;
25284
25276
  /** squared distance between source boundary point and circle center */
25285
- const r = squared_distance_between_squaredDistanceBetween(x, y.p);
25286
- bezierPieces_ = cull_bezier_pieces_cullBezierPieces(bezierPieces_, x, r);
25277
+ const xy = squared_distance_between_squaredDistanceBetween(x, y.p);
25278
+ bezierPieces_ = cull_bezier_pieces_cullBezierPieces(bezierPieces_, x, xy);
25287
25279
  z = getClosestBoundaryPoint(bezierPieces_, x, y.curve, y.t);
25288
25280
  if (z === undefined) {
25289
25281
  if (typeof _debug_ !== 'undefined') {
@@ -25303,16 +25295,18 @@ function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClo
25303
25295
  xs.push({ x, y, z: z.pos, t: y.t });
25304
25296
  }
25305
25297
  /** squared distance between anti-pode boundary point and circle center */
25306
- const d = squared_distance_between_squaredDistanceBetween(x, z.pos.p);
25298
+ const xz = squared_distance_between_squaredDistanceBetween(x, z.pos.p);
25307
25299
  //if (i === 1 && d*oneProngTolerance >= r) {
25308
- if (i === 1 && r < d + oneProngTolerance) {
25300
+ if (i === 1 && xy < xz + oneProngTolerance) {
25309
25301
  // It is a 1-prong.
25302
+ // TODO2 - below line was removed (maybe)
25310
25303
  add1Prong(Math.sqrt(maxOsculatingCircleRadiusSquared), cpTrees, y);
25311
25304
  return undefined;
25312
25305
  }
25313
25306
  // TODO - squaredSeperationTolerance should in future be replaced with
25314
25307
  // a relative error, i.e. distance between y (or z) / length(y (or z)).
25315
- if (!isHoleClosing && squared_distance_between_squaredDistanceBetween(y.p, z.pos.p) <= squaredSeperationTolerance) {
25308
+ const yz = squared_distance_between_squaredDistanceBetween(y.p, z.pos.p);
25309
+ if (!isHoleClosing && yz <= squaredSeperationTolerance) {
25316
25310
  if (typeof _debug_ !== 'undefined') {
25317
25311
  /*
25318
25312
  let elems = _debug_.generated.elems;
@@ -25334,8 +25328,10 @@ function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClo
25334
25328
  // nextX, but rather (distance from x to y) - (distance from x to z)
25335
25329
  // Find the point on the line connecting y with x that is
25336
25330
  // equidistant from y and z. This will be our next x.
25331
+ // const nextX = findEquidistantPointOnLineDd(x, y.p, z.pos.p);
25337
25332
  const nextX = findEquidistantPointOnLine(x, y.p, z.pos.p);
25338
25333
  const squaredError = squared_distance_between_squaredDistanceBetween(x, nextX);
25334
+ // const squaredError = Math.abs(xy - xz);
25339
25335
  x = nextX;
25340
25336
  if (squaredError < squaredErrorTolerance) {
25341
25337
  done++; // Do one more iteration
@@ -25346,6 +25342,29 @@ function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClo
25346
25342
  break; // We're done
25347
25343
  }
25348
25344
  } while (done < 1);
25345
+ /************************************************************************ */
25346
+ /* Do one more double-double precision iteration
25347
+ /************************************************************************ */
25348
+ /*
25349
+ z = getClosestBoundaryPoint(
25350
+ bezierPieces_, x, y.curve, y.t
25351
+ );
25352
+
25353
+ if (z === undefined) {
25354
+ failed = true;
25355
+ }
25356
+
25357
+ if (typeof _debug_ !== 'undefined') {
25358
+ xs.push({ x, y, z: z.pos, t: y.t });
25359
+ }
25360
+
25361
+ if (!isHoleClosing && squaredDistanceBetween(y.p, z.pos.p) <= squaredSeperationTolerance) {
25362
+ failed = true;
25363
+ } else {
25364
+ x = findEquidistantPointOnLineDd(x, y.p, z.pos.p);
25365
+ }
25366
+ /************************************************************************ */
25367
+ /************************************************************************ */
25349
25368
  // TODO - Optimization: only do this if second closest point is within the
25350
25369
  // tolerance which can be checked in getClosestBoundaryPoint algorithm
25351
25370
  let zs = [];
@@ -25360,6 +25379,8 @@ function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClo
25360
25379
  if (z !== undefined) {
25361
25380
  circle = { center: x, radius: distanceBetween(x, z.pos.p) };
25362
25381
  }
25382
+ // TODO2
25383
+ // if (Math.random() > 0.8 && !isHoleClosing) { return undefined; }
25363
25384
  if (typeof _debug_ !== 'undefined' && !failed) {
25364
25385
  xs.push({ x, y, z: z.pos, t: y.t });
25365
25386
  addDebugInfo(bezierPieces, failed, y, circle, z.pos, δ, xs, isHoleClosing);
@@ -26137,10 +26158,11 @@ function getInterestingPointsOnLoop(minBezLength, maxCurviness, maxLength) {
26137
26158
  // qqq let maxAbsCurvatures = [...maxCurvatureTs, ...maxNegativeCurvatureTs].map(t => new PointOnShape(curve, t));
26138
26159
  const maxAbsCurvatures = [...maxima].map(t => new PointOnShape(curve, t));
26139
26160
  allPoints.push(...getContactCirclesAtInterface(curve), ...maxAbsCurvatures);
26140
- let ts = splitByCurvatureAndLength(curve.ps, maxCurviness, maxLength);
26141
- if (ts.length === 2) {
26142
- ts = [0, 0.5, 1];
26143
- }
26161
+ const ts = splitByCurvatureAndLength(curve.ps, maxCurviness, maxLength);
26162
+ // if (ts.length > 10) { console.log(ts); }
26163
+ // if (ts.length === 2) {
26164
+ // ts = [0, 0.5, 1];
26165
+ // }
26144
26166
  for (let i = 1; i < ts.length - 1; i++) {
26145
26167
  allPoints.push(new PointOnShape(curve, ts[i]));
26146
26168
  }
@@ -28345,7 +28367,7 @@ function drawOneProng(g, pos, classes, delay = 0) {
28345
28367
 
28346
28368
  /** @hidden */
28347
28369
  function twoProng(g, twoProng) {
28348
- const scaleFactor = 0.3;
28370
+ const scaleFactor = 0.01;
28349
28371
  let $failedDot = [];
28350
28372
  let $center = [];
28351
28373
  let $circle = [];
@@ -28369,7 +28391,7 @@ function twoProng(g, twoProng) {
28369
28391
  $failedDot = drawFs.dot(g, twoProng.pos.p, 1 * scaleFactor, 'black');
28370
28392
  }
28371
28393
  else if (!twoProng.failed) {
28372
- $center = drawFs.dot(g, twoProng.circle.center, 1 * scaleFactor, 'yellow');
28394
+ $center = drawFs.dot(g, twoProng.circle.center, 0.02 * scaleFactor, 'yellow');
28373
28395
  $circle = drawFs.circle(g, twoProng.circle, color + 'thin' + thin + ' nofill');
28374
28396
  $cp1 = drawFs.dot(g, twoProng.pos.p, 0.035 * scaleFactor, color);
28375
28397
  $cp2 = drawFs.dot(g, twoProng.z, 0.07 * scaleFactor, color);
@@ -28382,7 +28404,7 @@ function twoProng(g, twoProng) {
28382
28404
 
28383
28405
 
28384
28406
  /** @hidden */
28385
- const three_prong_scaleFactor = 0.3;
28407
+ const three_prong_scaleFactor = 0.1;
28386
28408
  /** @hidden */
28387
28409
  function threeProng(g, threeProng) {
28388
28410
  const circle = scaleCircle(threeProng.circle, 1);