flo-mat 3.0.10 → 3.0.12
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/__tests__/jsog/check-jsog-eql-calc.spec.ts +81 -0
- package/__tests__/jsog/decode-jsog.ts +85 -0
- package/__tests__/jsog/get-mats1.ts +41 -0
- package/__tests__/{cp-node/fs → jsog}/mat-dummys.ts +51 -564
- package/__tests__/jsog/to-jsog-breath-first.ts +107 -0
- package/__tests__/jsog/to-jsog-depth-first.ts +55 -0
- package/browser/index.js +126 -84
- package/browser/index.min.js +1 -1
- package/node/add-n-prong.ts/join-spokes.js.map +1 -1
- package/node/closest-boundary-point/dd-deflate-with-running-error.js.map +1 -1
- package/node/closest-boundary-point/get-close-boundary-points-certified.js.map +1 -1
- package/node/contact-point/contact-point.js.map +1 -1
- package/node/corner/get-corner.js.map +1 -1
- package/node/corner/get-interface-ccw.js.map +1 -1
- package/node/cp-node/cp-node-fs.d.ts +2 -1
- package/node/cp-node/cp-node-fs.js +1 -2
- package/node/cp-node/cp-node-fs.js.map +1 -1
- package/node/cp-node/fs/cp-node-comparator.d.ts +3 -0
- package/node/cp-node/fs/cp-node-comparator.js +6 -0
- package/node/cp-node/fs/cp-node-comparator.js.map +1 -0
- package/node/cp-node/fs/find-first.js.map +1 -1
- package/node/cp-node/fs/get-all-on-loop.js.map +1 -1
- package/node/cp-node/fs/get-branch-beziers.js.map +1 -1
- package/node/cp-node/fs/get-branch.js.map +1 -1
- package/node/cp-node/fs/get-children.js.map +1 -1
- package/node/cp-node/fs/get-first-exit.js.map +1 -1
- package/node/cp-node/fs/get-mat-curve-to-next.js.map +1 -1
- package/node/cp-node/fs/get-mat-curves-between.js.map +1 -1
- package/node/cp-node/fs/get-prong-count.js.map +1 -1
- package/node/cp-node/fs/get-real-prong-count.js.map +1 -1
- package/node/cp-node/fs/get-vertex-forward-children.js.map +1 -1
- package/node/cp-node/fs/is-fully-terminating.d.ts +1 -1
- package/node/cp-node/fs/is-fully-terminating.js.map +1 -1
- package/node/cp-node/fs/is-one-prong.js.map +1 -1
- package/node/cp-node/fs/is-sharp.js.map +1 -1
- package/node/cp-node/fs/is-terminating.js.map +1 -1
- package/node/cp-node/fs/traverse-cp.js.map +1 -1
- package/node/cp-node/fs/traverse-edges.js.map +1 -1
- package/node/cp-node/fs/traverse-vertices.js.map +1 -1
- package/node/debug/functions/draw-elem/bounding-hull.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-cp-node.js +1 -1
- package/node/debug/functions/draw-elem/draw-cp-node.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-cull.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-dull-corner.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-elem.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-leaves.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-loose-bounding-box.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-max-vertex.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-min-y.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-one-prong-at-dull-corner.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-one-prong.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-sharp-corner.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-speed.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-three-prong.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-tight-bounding-box.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-two-prong.js.map +1 -1
- package/node/debug/functions/draw-elem/draw-vertex.js.map +1 -1
- package/node/debug/functions/general.js.map +1 -1
- package/node/find-2-prong/add-1-prong.js.map +1 -1
- package/node/find-2-prong/find-2-prong.d.ts +1 -0
- package/node/find-2-prong/find-2-prong.js +2 -1
- package/node/find-2-prong/find-2-prong.js.map +1 -1
- package/node/find-2-prong/find-equidistant-point-on-line-dd.js.map +1 -1
- package/node/find-3-prong.ts/find-3-prong.js.map +1 -1
- package/node/find-3-prong.ts/find-and-add-3-prong.js.map +1 -1
- package/node/find-3-prong.ts/find-and-add-3-prongs.js.map +1 -1
- package/node/find-mat/find-mats.js.map +1 -1
- package/node/find-mat/mat-options.js +1 -1
- package/node/find-mat/mat-options.js.map +1 -1
- package/node/geometry/get-closest-square-distance-to-rect.js.map +1 -1
- package/node/geometry/get-closest-squared-distance-to-rotated-rect.js.map +1 -1
- package/node/index.d.ts +35 -1
- package/node/index.js +36 -1
- package/node/index.js.map +1 -1
- package/node/mat/create-new-cp-tree.js.map +1 -1
- package/node/mat/get-largest-vertex.js.map +1 -1
- package/node/mat/trim-mat.js.map +1 -1
- package/node/memoize-primitive.js.map +1 -1
- package/node/sat/add-debug-info.js.map +1 -1
- package/node/sat/get-leaves.js.map +1 -1
- package/node/svg/get-loop-bounds.js.map +1 -1
- package/node/svg/get-min-y-pos.js.map +1 -1
- package/node/sweep-line/sweep-line.js.map +1 -1
- package/package.json +4 -4
- package/src/add-n-prong.ts/join-spokes.ts +11 -11
- package/src/closest-boundary-point/dd-deflate-with-running-error.ts +22 -22
- package/src/closest-boundary-point/get-close-boundary-points-certified.ts +38 -38
- package/src/contact-point/contact-point.ts +13 -13
- package/src/corner/get-corner.ts +39 -39
- package/src/corner/get-interface-ccw.ts +3 -3
- package/src/cp-node/cp-node-fs.ts +132 -135
- package/src/cp-node/cp-node.ts +30 -30
- package/src/cp-node/fs/clone.ts +4 -4
- package/src/cp-node/fs/cp-node-comparator.ts +13 -0
- package/src/cp-node/fs/find-first.ts +6 -6
- package/src/cp-node/fs/get-all-on-loop.ts +1 -1
- package/src/cp-node/fs/get-branch-beziers.ts +1 -1
- package/src/cp-node/fs/get-branch.ts +1 -1
- package/src/cp-node/fs/get-children.ts +8 -8
- package/src/cp-node/fs/get-first-exit.ts +11 -11
- package/src/cp-node/fs/get-mat-curve-to-next.ts +1 -1
- package/src/cp-node/fs/get-mat-curves-between.ts +1 -1
- package/src/cp-node/fs/get-prong-count.ts +8 -8
- package/src/cp-node/fs/get-real-prong-count.ts +3 -3
- package/src/cp-node/fs/get-vertex-forward-children.ts +10 -10
- package/src/cp-node/fs/is-fully-terminating.ts +3 -3
- package/src/cp-node/fs/is-one-prong.ts +8 -8
- package/src/cp-node/fs/is-sharp.ts +1 -1
- package/src/cp-node/fs/is-terminating.ts +1 -1
- package/src/cp-node/fs/iterate-all-on-loop.ts +6 -6
- package/src/cp-node/fs/traverse-all-forward.ts +11 -11
- package/src/cp-node/fs/traverse-cp.ts +19 -17
- package/src/cp-node/fs/traverse-edges.ts +10 -10
- package/src/cp-node/fs/traverse-vertices.ts +17 -17
- package/src/curve/curve.ts +26 -26
- package/src/debug/functions/cmp-cp-on-delta.ts +1 -1
- package/src/debug/functions/draw-elem/bounding-hull.ts +2 -2
- package/src/debug/functions/draw-elem/culls.ts +2 -2
- package/src/debug/functions/draw-elem/draw-cp-node.ts +30 -30
- package/src/debug/functions/draw-elem/draw-cull.ts +2 -2
- package/src/debug/functions/draw-elem/draw-dull-corner.ts +7 -7
- package/src/debug/functions/draw-elem/draw-elem.ts +28 -28
- package/src/debug/functions/draw-elem/draw-leaves.ts +12 -12
- package/src/debug/functions/draw-elem/draw-loose-bounding-box.ts +7 -7
- package/src/debug/functions/draw-elem/draw-max-vertex.ts +2 -2
- package/src/debug/functions/draw-elem/draw-min-y.ts +2 -2
- package/src/debug/functions/draw-elem/draw-one-prong-at-dull-corner.ts +1 -1
- package/src/debug/functions/draw-elem/draw-one-prong.ts +1 -1
- package/src/debug/functions/draw-elem/draw-sharp-corner.ts +6 -6
- package/src/debug/functions/draw-elem/draw-speed.ts +2 -2
- package/src/debug/functions/draw-elem/draw-three-prong.ts +28 -28
- package/src/debug/functions/draw-elem/draw-tight-bounding-box.ts +4 -4
- package/src/debug/functions/draw-elem/draw-two-prong.ts +51 -51
- package/src/debug/functions/draw-elem/draw-vertex.ts +12 -12
- package/src/debug/functions/draw-elem/dull-corner.ts +7 -7
- package/src/debug/functions/draw-elem/leaves.ts +2 -2
- package/src/debug/functions/draw-elem/loose-bounding-box.ts +7 -7
- package/src/debug/functions/draw-elem/max-vertex.ts +2 -2
- package/src/debug/functions/draw-elem/min-y.ts +2 -2
- package/src/debug/functions/draw-elem/one-prong-at-dull-corner.ts +1 -1
- package/src/debug/functions/draw-elem/one-prong.ts +1 -1
- package/src/debug/functions/draw-elem/sharp-corner.ts +6 -6
- package/src/debug/functions/draw-elem/three-prong.ts +19 -19
- package/src/debug/functions/draw-elem/tight-bounding-box.ts +4 -4
- package/src/debug/functions/draw-elem/two-prong.ts +34 -34
- package/src/debug/functions/draw-elem/vertex.ts +28 -28
- package/src/debug/functions/general.ts +18 -18
- package/src/debug/functions/three-prong.ts +184 -184
- package/src/debug/functions/two-prong.ts +112 -112
- package/src/find-2-prong/add-1-prong.ts +25 -25
- package/src/find-2-prong/find-2-prong.ts +158 -157
- package/src/find-2-prong/find-equidistant-point-on-line-dd.ts +50 -50
- package/src/find-2-prong/find-equidistant-point-on-line.ts +27 -27
- package/src/find-3-prong.ts/find-3-prong-for-delta3s.ts +1 -1
- package/src/find-3-prong.ts/find-3-prong.ts +23 -23
- package/src/find-3-prong.ts/find-and-add-3-prong.ts +37 -37
- package/src/find-3-prong.ts/find-and-add-3-prongs.ts +30 -30
- package/src/find-mat/add-2-prongs-by-error.ts +1 -1
- package/src/find-mat/find-mats.ts +49 -49
- package/src/find-mat/fix-ordering.ts +2 -2
- package/src/find-mat/get-total-by.ts +12 -12
- package/src/find-mat/mat-options.ts +1 -1
- package/src/geometry/get-closest-square-distance-to-rect.ts +37 -37
- package/src/geometry/get-closest-squared-distance-to-rotated-rect.ts +14 -14
- package/src/get-curve/get-curve-between.ts +1 -1
- package/src/index.ts +40 -3
- package/src/mat/cmp-cp-on-delta.ts +1 -1
- package/src/mat/create-new-cp-tree.ts +12 -12
- package/src/mat/get-edges-as-array.ts +9 -9
- package/src/mat/get-largest-3-prong.ts +8 -8
- package/src/mat/get-largest-three-prong.ts +5 -5
- package/src/mat/get-largest-vertex.ts +6 -6
- package/src/mat/get-two-prong-type.ts +3 -3
- package/src/mat/trim-mat.ts +1 -1
- package/src/memoize-primitive.ts +14 -14
- package/src/sat/add-debug-info.ts +4 -4
- package/src/sat/cull-by-salience.ts +1 -1
- package/src/sat/get-leaves.ts +0 -1
- package/src/svg/get-extreme.ts +8 -8
- package/src/svg/get-loop-bounds.ts +84 -84
- package/src/svg/get-min-y-pos.ts +1 -1
- package/src/sweep-line/sweep-line.ts +23 -23
- package/__tests__/cp-node/fs/check-jsog-eql-calc.spec.ts +0 -30
|
@@ -31,7 +31,8 @@ const { ceil, log2, max, sqrt, abs, sin, cos } = Math;
|
|
|
31
31
|
* "The starting point of this algorithm is a choice of a circle Br(x)
|
|
32
32
|
* centered at an interior point x which contains two boundary portions c and
|
|
33
33
|
* d of dΩ as in Fig. 19."
|
|
34
|
-
* In fact, we (and they) start by fixing one point on the boundary beforehand.
|
|
34
|
+
* In fact, we (and they) start by fixing one point on the boundary beforehand.
|
|
35
|
+
*
|
|
35
36
|
* @param loops A shape represented by path loops
|
|
36
37
|
* @param maxCoordinate The extreme coordinate value of the shape
|
|
37
38
|
* @param squaredDiagonalLength The squared diagonal length of the shape
|
|
@@ -41,166 +42,166 @@ const { ceil, log2, max, sqrt, abs, sin, cos } = Math;
|
|
|
41
42
|
* @param loopIdx The loop array index
|
|
42
43
|
*/
|
|
43
44
|
function find2Prong(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
y: PointOnShape): { circle: Circle,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
45
|
+
meta: MatMeta,
|
|
46
|
+
isHoleClosing: boolean,
|
|
47
|
+
for1Prong: boolean,
|
|
48
|
+
angle: number,
|
|
49
|
+
y: PointOnShape): { circle: Circle, zs: PointOnShape[] } | undefined {
|
|
50
|
+
|
|
51
|
+
const { loops, maxCoordinate, squaredDiagonalLength } = meta;
|
|
52
|
+
|
|
53
|
+
const loop = y.curve.loop;
|
|
54
|
+
|
|
55
|
+
const MAX_ITERATIONS = 25;
|
|
56
|
+
const minSquaredSeperationTolerance = ((2**-21)*maxCoordinate)**2;
|
|
57
|
+
const errorTolerance = (2**-46)*maxCoordinate;
|
|
58
|
+
// const errorTolerance = (2**-28)*maxCoordinate;
|
|
59
|
+
const maxOsculatingCircleRadius = sqrt(squaredDiagonalLength);
|
|
60
|
+
const minCurvature = 1/maxOsculatingCircleRadius;
|
|
61
|
+
const oneProngTolerance = (2**-16)*maxCoordinate;
|
|
62
|
+
|
|
63
|
+
const [xO,rO] = getO(
|
|
64
|
+
angle, isHoleClosing, maxOsculatingCircleRadius, minCurvature, y
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const p = y.p;
|
|
68
|
+
|
|
69
|
+
// The boundary piece that should contain the other point of
|
|
70
|
+
// the 2-prong circle. (Defined by start and end points).
|
|
71
|
+
let curvePieces = getInitialCurvePieces(
|
|
72
|
+
angle, isHoleClosing, loop, loops, meta, y, { center: xO, radius: rO }
|
|
73
|
+
);
|
|
74
|
+
// console.log(curvePieces.length);
|
|
75
|
+
|
|
76
|
+
/** The center of the two-prong (successively refined) */
|
|
77
|
+
let x = xO;
|
|
78
|
+
|
|
79
|
+
// The lines below is an optimization.
|
|
80
|
+
const r_ = sqrt(reduceRadius(maxCoordinate, curvePieces, p, xO));
|
|
81
|
+
if (rO > r_) {
|
|
82
|
+
x = interpolate(p, xO, r_/rO);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** The antipode of the two-prong (successively refined) */
|
|
86
|
+
let zs: PointOnShape[] = undefined!;
|
|
87
|
+
let z: PointOnShape = undefined!;
|
|
88
|
+
|
|
89
|
+
let i = 0;
|
|
90
|
+
while (i < MAX_ITERATIONS) {
|
|
91
|
+
const xy = squaredDistanceBetweenDd(x, y.p);
|
|
92
|
+
|
|
93
|
+
if (i < 2) { curvePieces = cullCurvePieces2(curvePieces, x, xy); }
|
|
94
|
+
const pow = max(0,ceil(log2(maxCoordinate/xy))) + 1; // determines accuracy
|
|
95
|
+
// console.log(pow);
|
|
96
|
+
const _zs = getCloseBoundaryPointsCertified(
|
|
97
|
+
pow, curvePieces, x, y.curve, y.t,
|
|
98
|
+
for1Prong && i == 0 && rO !== 1/minCurvature,
|
|
99
|
+
angle
|
|
100
|
+
).map(info => createPos(info.curve, info.t, false));
|
|
101
|
+
|
|
102
|
+
let maxD = Number.NEGATIVE_INFINITY;
|
|
103
|
+
let maxPos: PointOnShape = undefined!;
|
|
104
|
+
zs = [];
|
|
105
|
+
for (const z of _zs) {
|
|
106
|
+
if (z === undefined) { continue; }
|
|
107
|
+
const _yz = squaredDistanceBetweenDd(y.p, z.p);
|
|
108
|
+
if (_yz > maxD) {
|
|
109
|
+
maxD = _yz;
|
|
110
|
+
maxPos = z;
|
|
111
|
+
}
|
|
112
|
+
if (_yz !== 0) {
|
|
113
|
+
zs.push(z);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// z = zs[0];
|
|
117
|
+
const yz = maxD;
|
|
118
|
+
z = maxPos;
|
|
119
|
+
|
|
120
|
+
if (z === undefined || yz === 0) {
|
|
121
|
+
// addDebugInfo2(isHoleClosing);
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const xz = squaredDistanceBetweenDd(x, z.p);
|
|
126
|
+
|
|
127
|
+
// if on first try
|
|
128
|
+
if (i === 0) {
|
|
129
|
+
if (rO < (1 - oneProngTolerance)*sqrt(xz)) {
|
|
130
|
+
// console.log('1prong');
|
|
131
|
+
add1Prong(meta, rO, xO, y);
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// if (typeof _debug_ !== 'undefined') { xs.push({ x, y, z: createPos(z.curve, z.t, false), t: y.t }); }
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
if (!isHoleClosing) {
|
|
140
|
+
const squaredSeperationTolerance = max(calcSeperationTolerance(
|
|
141
|
+
rO, sqrt(xz), 2**2*errorTolerance
|
|
142
|
+
), minSquaredSeperationTolerance);
|
|
143
|
+
if (yz <= squaredSeperationTolerance) {
|
|
144
|
+
// if (typeof _debug_ !== 'undefined') { console.log(`failed: seperation too small - ${sqrt(yz)}`); }
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Find the point on the line connecting y with x that is
|
|
150
|
+
// equidistant from y and z. This will be our next x.
|
|
151
|
+
const nextX = findEquidistantPointOnLineDd(x, y.p, z.p);
|
|
152
|
+
const error = abs(sqrt(xy) - sqrt(xz));
|
|
153
|
+
// if (xy < xz) { return undefined; }
|
|
154
|
+
|
|
155
|
+
x = nextX;
|
|
156
|
+
|
|
157
|
+
if (error < errorTolerance) {
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
i++;
|
|
162
|
+
|
|
163
|
+
if (i === MAX_ITERATIONS) {
|
|
164
|
+
// Convergence was too slow.
|
|
165
|
+
// if (typeof _debug_ !== 'undefined') { console.log('failed (slow): max iterations reached'); }
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const circle = { center: x, radius: distanceBetween(x, z.p) };
|
|
171
|
+
|
|
172
|
+
// if (typeof _debug_ !== 'undefined') { addDebugInfo(curvePieces, false, x, y, z, circle!, δ!, xs, isHoleClosing); }
|
|
173
|
+
|
|
174
|
+
// return { circle, zs };
|
|
175
|
+
// zs = zs.filter(z => z !== undefined)
|
|
176
|
+
return { circle, zs: [z] };
|
|
176
177
|
}
|
|
177
178
|
|
|
178
179
|
|
|
179
180
|
function getO(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
181
|
+
angle: number,
|
|
182
|
+
isHoleClosing: boolean,
|
|
183
|
+
maxOsculatingCircleRadius: number,
|
|
184
|
+
minCurvature: number,
|
|
185
|
+
y: PointOnShape) {
|
|
186
|
+
|
|
187
|
+
let xO: number[]; // the original x to mitigate drift
|
|
188
|
+
const p = y.p;
|
|
189
|
+
let rO: number;
|
|
190
|
+
if (isHoleClosing) {
|
|
191
|
+
xO = [p[0], p[1] - maxOsculatingCircleRadius];
|
|
192
|
+
rO = maxOsculatingCircleRadius;
|
|
193
|
+
} else {
|
|
194
|
+
if (angle === 0) {
|
|
195
|
+
({ center: xO, radius: rO } = getOsculatingCircle(minCurvature, y));
|
|
196
|
+
} else {
|
|
197
|
+
({ center: xO, radius: rO } = getOsculatingCircle(minCurvature, y, true));
|
|
198
|
+
const v = fromTo(y.p, xO);
|
|
199
|
+
const v_ = rotate(sin(angle), cos(angle))(v);
|
|
200
|
+
xO = translate(y.p)(v_);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return [xO,rO] as [number[],number];
|
|
204
205
|
}
|
|
205
206
|
|
|
206
207
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
twoDiff, twoSum, twoProduct, doubleDivDouble, ddDivDd,
|
|
3
|
+
ddAddDd, ddDiffDd, ddMultDd, ddMultBy2, ddMultDouble1
|
|
4
4
|
} from "double-double";
|
|
5
5
|
|
|
6
6
|
|
|
@@ -20,57 +20,57 @@ const tp = twoProduct;
|
|
|
20
20
|
* @param z
|
|
21
21
|
*/
|
|
22
22
|
function findEquidistantPointOnLineDd(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
23
|
+
x: number[],
|
|
24
|
+
y: number[],
|
|
25
|
+
z: number[]) {
|
|
26
|
+
// Some basic algebra (not shown) finds the required point.
|
|
27
|
+
|
|
28
|
+
// Swap axes if x and y are more aligned to y-axis than to x-axis.
|
|
29
|
+
const swapAxes = abs(x[1] - y[1]) > abs(x[0] - y[0]);
|
|
30
|
+
|
|
31
|
+
// Cache
|
|
32
|
+
let x1: number;
|
|
33
|
+
let x2: number;
|
|
34
|
+
let y1: number;
|
|
35
|
+
let y2: number;
|
|
36
|
+
let z1: number;
|
|
37
|
+
let z2: number;
|
|
38
|
+
|
|
39
|
+
if (swapAxes) {
|
|
40
|
+
x1 = x[1]; x2 = x[0];
|
|
41
|
+
y1 = y[1]; y2 = y[0];
|
|
42
|
+
z1 = z[1]; z2 = z[0];
|
|
43
|
+
} else {
|
|
44
|
+
x1 = x[0]; x2 = x[1];
|
|
45
|
+
y1 = y[0]; y2 = y[1];
|
|
46
|
+
z1 = z[0]; z2 = z[1];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// a <= 1 (due to swapped axes)
|
|
50
|
+
// const a = (x2 - y2) / (x1 - y1);
|
|
51
|
+
// const b = y2 - a*y1;
|
|
52
|
+
// const c = (y1*y1 + y2*y2 - z1*z1 - z2*z2) + 2*b*(z2 - y2);
|
|
53
|
+
// const d = y1 - z1 + a*(y2 - z2);
|
|
54
|
+
// const t1 = c/(2*d);
|
|
55
|
+
// const t2 = a*t1 + b;
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
|
|
58
|
+
const a = ddDivDd(td(x2,y2),td(x1,y1));
|
|
59
|
+
const b = ddDiffDd([0,y2], ddMultDouble1(y1,a));
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
const c = ddAddDd(
|
|
62
|
+
(ddDiffDd(
|
|
63
|
+
ddAddDd(tp(y1,y1), tp(y2,y2)),
|
|
64
|
+
ddAddDd(tp(z1,z1), tp(z2,z2))
|
|
65
|
+
)),
|
|
66
|
+
ddMultBy2(ddMultDd(b,(td(z2,y2))))
|
|
67
|
+
);
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
const d = ddAddDd(td(y1,z1), ddMultDd(a,td(y2,z2)));
|
|
70
|
+
const t1 = ddDivDd(c,ddMultBy2(d));
|
|
71
|
+
const t2 = ddAddDd(ddMultDd(a,t1), b);
|
|
72
|
+
|
|
73
|
+
return swapAxes ? [t2[1],t1[1]] : [t1[1],t2[1]];
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
|
|
@@ -7,33 +7,33 @@
|
|
|
7
7
|
* @returns The point on the line from y to x that is equidistant from y and z.
|
|
8
8
|
*/
|
|
9
9
|
function findEquidistantPointOnLine(x: number[], y: number[], z: number[]) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
10
|
+
// Some basic algebra (not shown) finds the required point.
|
|
11
|
+
|
|
12
|
+
// Swap axes if x and y are more aligned to y-axis than to x-axis.
|
|
13
|
+
const swapAxes = Math.abs((x[1] - y[1]) / (x[0] - y[0])) > 1;
|
|
14
|
+
|
|
15
|
+
// Cache
|
|
16
|
+
let x1, x2, y1, y2, z1, z2;
|
|
17
|
+
|
|
18
|
+
if (swapAxes) {
|
|
19
|
+
x1 = x[1]; x2 = x[0];
|
|
20
|
+
y1 = y[1]; y2 = y[0];
|
|
21
|
+
z1 = z[1]; z2 = z[0];
|
|
22
|
+
} else {
|
|
23
|
+
x1 = x[0]; x2 = x[1];
|
|
24
|
+
y1 = y[0]; y2 = y[1];
|
|
25
|
+
z1 = z[0]; z2 = z[1];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// a <= 1 (due to swapped axes)
|
|
29
|
+
const a = (x2 - y2) / (x1 - y1);
|
|
30
|
+
const b = y2 - a*y1;
|
|
31
|
+
const c = (y1*y1 + y2*y2 - z1*z1 - z2*z2) + 2*b*(z2 - y2);
|
|
32
|
+
const d = y1 - z1 + a*(y2 - z2);
|
|
33
|
+
const t1 = c/(2*d);
|
|
34
|
+
const t2 = a*t1 + b;
|
|
35
|
+
|
|
36
|
+
return swapAxes ? [t2,t1] : [t1,t2];
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
|
|
@@ -13,35 +13,35 @@ import { getBoundaryPieceBeziers } from '../mat/get-boundary-piece-beziers.js';
|
|
|
13
13
|
* tolerances.
|
|
14
14
|
*/
|
|
15
15
|
function find3Prong(
|
|
16
|
-
|
|
16
|
+
δs: CpNode[][], extreme: number) {
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
const curvePiecess = δs.map(getBoundaryPieceBeziers);
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
// The best candidate amongst the different 'permutations' of the given δs.
|
|
21
|
+
let threeProng: {
|
|
22
22
|
circle: Circle,
|
|
23
23
|
poss: PointOnShape[],
|
|
24
24
|
δ3s: CpNode[][]
|
|
25
25
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
26
|
+
let smallestError = Number.POSITIVE_INFINITY;
|
|
27
|
+
for (let i=1; i<δs.length-1; i++) {
|
|
28
|
+
for (let k=0; k<3; k++) {
|
|
29
|
+
const threeProngInfo =
|
|
30
|
+
find3ProngForDelta3s(δs, i, k, curvePiecess, extreme);
|
|
31
|
+
if (!threeProngInfo) { continue; }
|
|
32
|
+
|
|
33
|
+
const { circle, poss: poss, error, δ3s } = threeProngInfo;
|
|
34
|
+
|
|
35
|
+
if (error < smallestError) {
|
|
36
|
+
smallestError = error;
|
|
37
|
+
|
|
38
|
+
threeProng = { circle, poss: poss as PointOnShape[], δ3s };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
return threeProng!;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
|
|
@@ -18,43 +18,43 @@ import { getProngCount } from '../cp-node/fs/get-prong-count.js';
|
|
|
18
18
|
* tolerances.
|
|
19
19
|
*/
|
|
20
20
|
function findAndAdd3Prong(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
21
|
+
meta: MatMeta,
|
|
22
|
+
visitedCps: CpNode[]) {
|
|
23
|
+
|
|
24
|
+
const δs: [CpNode, CpNode][] = [];
|
|
25
|
+
for (const visitedCp of visitedCps) {
|
|
26
|
+
δs.push([visitedCp, visitedCp.next]);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const threeProngInfo = find3Prong(δs, meta.maxCoordinate);
|
|
30
|
+
|
|
31
|
+
const { circle, poss, δ3s } = threeProngInfo;
|
|
32
|
+
|
|
33
|
+
const orders: number[] = [];
|
|
34
|
+
for (let i=0; i<3; i++) {
|
|
35
|
+
orders.push(calcPosOrder(circle, poss[i]));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const closeBysFor3Prong: CpNode[] = [];
|
|
39
|
+
for (let i=0; i<poss.length; i++) {
|
|
40
|
+
const pos = poss[i];
|
|
41
|
+
const order = orders[i];
|
|
42
|
+
const closeBy = getCloseByCpIfExist(meta, pos, circle, order, 0, 3);
|
|
43
|
+
if (closeBy !== undefined) {
|
|
44
|
+
const prongCount = getProngCount(closeBy);
|
|
45
|
+
if (prongCount <= 2 && !closeBy.isHoleClosing) {
|
|
46
|
+
closeBysFor3Prong.push(closeBy);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const cpNodes = closeBysFor3Prong.length === 0
|
|
52
|
+
? addToCpTree(
|
|
53
|
+
true, false, circle, orders, meta, poss, δ3s.map(v => v[0])
|
|
54
|
+
).cpNodes
|
|
55
|
+
: [];
|
|
56
|
+
|
|
57
|
+
return { closeBysFor3Prong, cpNodes: cpNodes as CpNode[] };
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
|