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