flo-mat 2.0.2 → 2.0.3
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 +8230 -8229
- package/browser/index.min.js +1 -1
- package/node/circle.d.ts +20 -20
- package/node/circle.js +31 -31
- package/node/compare-curvatures-at-interface.d.ts +19 -19
- package/node/compare-curvatures-at-interface.js +124 -124
- package/node/contact-point.d.ts +26 -26
- package/node/contact-point.js +25 -25
- package/node/cp-node/clone.d.ts +8 -8
- package/node/cp-node/clone.js +31 -31
- package/node/cp-node/remove.d.ts +9 -9
- package/node/cp-node/remove.js +19 -19
- package/node/cp-node.d.ts +202 -202
- package/node/cp-node.js +320 -320
- package/node/curve.d.ts +46 -46
- package/node/curve.js +88 -88
- package/node/debug/cp-node-for-debugging.d.ts +11 -11
- package/node/debug/cp-node-for-debugging.js +1 -1
- package/node/debug/debug-elem-types.d.ts +32 -32
- package/node/debug/debug-elem-types.js +1 -1
- package/node/debug/debug.d.ts +50 -50
- package/node/debug/debug.js +75 -75
- package/node/debug/functions/draw-elem/bounding-hull.d.ts +3 -3
- package/node/debug/functions/draw-elem/bounding-hull.js +7 -7
- package/node/debug/functions/draw-elem/branch.d.ts +4 -4
- package/node/debug/functions/draw-elem/branch.js +22 -22
- package/node/debug/functions/draw-elem/culls.d.ts +4 -4
- package/node/debug/functions/draw-elem/culls.js +21 -21
- package/node/debug/functions/draw-elem/draw-circle-percent.d.ts +3 -3
- package/node/debug/functions/draw-elem/draw-circle-percent.js +12 -12
- package/node/debug/functions/draw-elem/draw-elem.d.ts +8 -8
- package/node/debug/functions/draw-elem/draw-elem.js +45 -45
- package/node/debug/functions/draw-elem/dull-corner.d.ts +4 -4
- package/node/debug/functions/draw-elem/dull-corner.js +10 -10
- package/node/debug/functions/draw-elem/leaves.d.ts +4 -4
- package/node/debug/functions/draw-elem/leaves.js +12 -12
- package/node/debug/functions/draw-elem/loop.d.ts +4 -4
- package/node/debug/functions/draw-elem/loop.js +11 -11
- package/node/debug/functions/draw-elem/loops.d.ts +4 -4
- package/node/debug/functions/draw-elem/loops.js +6 -6
- package/node/debug/functions/draw-elem/loose-bounding-box.d.ts +3 -3
- package/node/debug/functions/draw-elem/loose-bounding-box.js +9 -9
- package/node/debug/functions/draw-elem/mat.d.ts +4 -4
- package/node/debug/functions/draw-elem/mat.js +30 -30
- package/node/debug/functions/draw-elem/max-vertex.d.ts +4 -4
- package/node/debug/functions/draw-elem/max-vertex.js +8 -8
- package/node/debug/functions/draw-elem/min-y.d.ts +4 -4
- package/node/debug/functions/draw-elem/min-y.js +13 -13
- package/node/debug/functions/draw-elem/one-prong-at-dull-corner.d.ts +4 -4
- package/node/debug/functions/draw-elem/one-prong-at-dull-corner.js +12 -12
- package/node/debug/functions/draw-elem/one-prong.d.ts +4 -4
- package/node/debug/functions/draw-elem/one-prong.js +16 -16
- package/node/debug/functions/draw-elem/sharp-corner.d.ts +4 -4
- package/node/debug/functions/draw-elem/sharp-corner.js +9 -9
- package/node/debug/functions/draw-elem/three-prong.d.ts +4 -4
- package/node/debug/functions/draw-elem/three-prong.js +16 -16
- package/node/debug/functions/draw-elem/tight-bounding-box.d.ts +3 -3
- package/node/debug/functions/draw-elem/tight-bounding-box.js +7 -7
- package/node/debug/functions/draw-elem/two-prong.d.ts +4 -4
- package/node/debug/functions/draw-elem/two-prong.js +36 -36
- package/node/debug/functions/draw-elem/vertex.d.ts +4 -4
- package/node/debug/functions/draw-elem/vertex.js +27 -27
- package/node/debug/functions/general.d.ts +48 -48
- package/node/debug/functions/general.js +52 -52
- package/node/debug/functions/three-prong.d.ts +11 -11
- package/node/debug/functions/three-prong.js +184 -184
- package/node/debug/functions/two-prong.d.ts +13 -13
- package/node/debug/functions/two-prong.js +117 -117
- package/node/debug/three-prong-for-debugging.d.ts +31 -31
- package/node/debug/three-prong-for-debugging.js +20 -20
- package/node/debug/two-prong-for-debugging.d.ts +26 -26
- package/node/debug/two-prong-for-debugging.js +1 -1
- package/node/find-mats.d.ts +26 -26
- package/node/find-mats.js +122 -122
- package/node/get-boundary-bezier-parts-to-next.d.ts +9 -9
- package/node/get-boundary-bezier-parts-to-next.js +42 -42
- package/node/get-boundary-beziers-to-next.d.ts +8 -8
- package/node/get-boundary-beziers-to-next.js +44 -44
- package/node/get-bounding-box-.d.ts +2 -2
- package/node/get-bounding-box-.js +4 -4
- package/node/get-branches.d.ts +12 -12
- package/node/get-branches.js +68 -68
- package/node/get-curve/get-curve-between.d.ts +9 -9
- package/node/get-curve/get-curve-between.js +56 -56
- package/node/get-curve/get-edge-direction.d.ts +9 -9
- package/node/get-curve/get-edge-direction.js +53 -53
- package/node/get-curve-to-next.d.ts +9 -9
- package/node/get-curve-to-next.js +11 -11
- package/node/get-interface-ccw.d.ts +24 -24
- package/node/get-interface-ccw.js +97 -97
- package/node/index.d.ts +36 -36
- package/node/index.js +32 -32
- package/node/loop/get-max-coordinate.d.ts +10 -10
- package/node/loop/get-max-coordinate.js +43 -43
- package/node/loop.d.ts +16 -16
- package/node/loop.js +34 -34
- package/node/mat/add-to-cp-graph.d.ts +16 -16
- package/node/mat/add-to-cp-graph.js +30 -30
- package/node/mat/bezier-piece.d.ts +12 -12
- package/node/mat/bezier-piece.js +1 -1
- package/node/mat/closest-boundary-point/closest-points-on-curve.d.ts +14 -14
- package/node/mat/closest-boundary-point/closest-points-on-curve.js +72 -72
- package/node/mat/closest-boundary-point/cull-bezier-pieces.d.ts +9 -9
- package/node/mat/closest-boundary-point/cull-bezier-pieces.js +19 -19
- package/node/mat/closest-boundary-point/cull-by-loose-bounding-box.d.ts +11 -11
- package/node/mat/closest-boundary-point/cull-by-loose-bounding-box.js +24 -24
- package/node/mat/closest-boundary-point/cull-by-tight-boundary-box.d.ts +11 -11
- package/node/mat/closest-boundary-point/cull-by-tight-boundary-box.js +26 -26
- package/node/mat/closest-boundary-point/get-best-distance-squared.d.ts +8 -8
- package/node/mat/closest-boundary-point/get-best-distance-squared.js +24 -24
- package/node/mat/closest-boundary-point/get-close-boundary-points.d.ts +17 -17
- package/node/mat/closest-boundary-point/get-close-boundary-points.js +80 -80
- package/node/mat/closest-boundary-point/get-closest-boundary-point.d.ts +18 -18
- package/node/mat/closest-boundary-point/get-closest-boundary-point.js +40 -40
- package/node/mat/corner.d.ts +37 -37
- package/node/mat/corner.js +1 -1
- package/node/mat/create-new-cp-tree.d.ts +9 -9
- package/node/mat/create-new-cp-tree.js +23 -23
- package/node/mat/elem-type-two-prong.d.ts +3 -3
- package/node/mat/elem-type-two-prong.js +1 -1
- package/node/mat/find-mat/add-1-prong.d.ts +12 -12
- package/node/mat/find-mat/add-1-prong.js +42 -42
- package/node/mat/find-mat/add-2-prong.d.ts +21 -21
- package/node/mat/find-mat/add-2-prong.js +192 -192
- package/node/mat/find-mat/add-3-prong.d.ts +19 -19
- package/node/mat/find-mat/add-3-prong.js +54 -54
- package/node/mat/find-mat/add-debug-info.d.ts +9 -9
- package/node/mat/find-mat/add-debug-info.js +67 -67
- package/node/mat/find-mat/create-get-interesting-points-on-loop.d.ts +11 -11
- package/node/mat/find-mat/create-get-interesting-points-on-loop.js +51 -51
- package/node/mat/find-mat/create-initial-cp-graph.d.ts +12 -12
- package/node/mat/find-mat/create-initial-cp-graph.js +40 -40
- package/node/mat/find-mat/find-2-prong/add-debug-info.d.ts +8 -8
- package/node/mat/find-mat/find-2-prong/add-debug-info.js +21 -21
- package/node/mat/find-mat/find-2-prong/cull-bezier-pieces.d.ts +11 -11
- package/node/mat/find-mat/find-2-prong/cull-bezier-pieces.js +29 -29
- package/node/mat/find-mat/find-2-prong/find-2-prong.d.ts +37 -37
- package/node/mat/find-mat/find-2-prong/find-2-prong.js +232 -232
- package/node/mat/find-mat/find-2-prong/find-equidistant-point-on-line.d.ts +9 -9
- package/node/mat/find-mat/find-2-prong/find-equidistant-point-on-line.js +39 -39
- package/node/mat/find-mat/find-2-prong/get-initial-bezier-pieces.d.ts +11 -11
- package/node/mat/find-mat/find-2-prong/get-initial-bezier-pieces.js +37 -37
- package/node/mat/find-mat/find-2-prong/x-for-debugging.d.ts +9 -9
- package/node/mat/find-mat/find-2-prong/x-for-debugging.js +1 -1
- package/node/mat/find-mat/find-3-prong/calc-better-x.d.ts +19 -19
- package/node/mat/find-mat/find-3-prong/calc-better-x.js +36 -36
- package/node/mat/find-mat/find-3-prong/calc-initial-3-prong-center.d.ts +13 -13
- package/node/mat/find-mat/find-3-prong/calc-initial-3-prong-center.js +25 -25
- package/node/mat/find-mat/find-3-prong/find-3-prong-for-delta3s.d.ts +22 -22
- package/node/mat/find-mat/find-3-prong/find-3-prong-for-delta3s.js +159 -159
- package/node/mat/find-mat/find-3-prong/find-3-prong.d.ts +16 -16
- package/node/mat/find-mat/find-3-prong/find-3-prong.js +76 -76
- package/node/mat/find-mat/find-3-prong/get-closest-points.d.ts +9 -9
- package/node/mat/find-mat/find-3-prong/get-closest-points.js +16 -16
- package/node/mat/find-mat/find-and-add-2-prongs-on-all-paths.d.ts +15 -15
- package/node/mat/find-mat/find-and-add-2-prongs-on-all-paths.js +20 -20
- package/node/mat/find-mat/find-and-add-2-prongs.d.ts +16 -16
- package/node/mat/find-mat/find-and-add-2-prongs.js +73 -73
- package/node/mat/find-mat/find-and-add-3-prongs.d.ts +13 -13
- package/node/mat/find-mat/find-and-add-3-prongs.js +146 -146
- package/node/mat/find-mat/find-and-add-hole-closing-2-prongs.d.ts +14 -14
- package/node/mat/find-mat/find-and-add-hole-closing-2-prongs.js +33 -33
- package/node/mat/find-mat/get-potential-2-prongs.d.ts +4 -4
- package/node/mat/find-mat/get-potential-2-prongs.js +16 -16
- package/node/mat/find-mat/get-sharp-corners.d.ts +4 -4
- package/node/mat/find-mat/get-sharp-corners.js +17 -17
- package/node/mat/geometry/get-closest-square-distance-to-rect.d.ts +5 -5
- package/node/mat/geometry/get-closest-square-distance-to-rect.js +49 -49
- package/node/mat/geometry/get-closest-squared-distance-to-rotated-rect.d.ts +5 -5
- package/node/mat/geometry/get-closest-squared-distance-to-rotated-rect.js +15 -15
- package/node/mat/get-boundary-piece-beziers.d.ts +11 -11
- package/node/mat/get-boundary-piece-beziers.js +58 -58
- package/node/mat/get-contact-circles-at-interface.d.ts +8 -8
- package/node/mat/get-contact-circles-at-interface.js +20 -20
- package/node/mat/get-largest-vertex.d.ts +4 -4
- package/node/mat/get-largest-vertex.js +9 -9
- package/node/mat/get-leaves.d.ts +4 -4
- package/node/mat/get-leaves.js +12 -12
- package/node/mat/get-neighboring-cps.d.ts +14 -14
- package/node/mat/get-neighboring-cps.js +30 -30
- package/node/mat/get-two-prong-type.d.ts +5 -5
- package/node/mat/get-two-prong-type.js +8 -8
- package/node/mat/is-another-cp-closeby.d.ts +20 -20
- package/node/mat/is-another-cp-closeby.js +55 -55
- package/node/mat/simplify-mat-map-only.d.ts +23 -23
- package/node/mat/simplify-mat-map-only.js +80 -80
- package/node/mat/to-scale-axis/add-debug-info.d.ts +7 -7
- package/node/mat/to-scale-axis/add-debug-info.js +13 -13
- package/node/mat/to-scale-axis/cull-non-cycles.d.ts +9 -9
- package/node/mat/to-scale-axis/cull-non-cycles.js +51 -51
- package/node/mat/to-scale-axis/cull.d.ts +12 -12
- package/node/mat/to-scale-axis/cull.js +132 -132
- package/node/mat/trim-mat.d.ts +8 -8
- package/node/mat/trim-mat.js +16 -16
- package/node/mat.d.ts +22 -22
- package/node/mat.js +1 -1
- package/node/point-on-shape.d.ts +73 -73
- package/node/point-on-shape.js +167 -167
- package/node/simplify-mat.d.ts +16 -16
- package/node/simplify-mat.js +71 -71
- package/node/svg/get-loop-bounds.d.ts +12 -12
- package/node/svg/get-loop-bounds.js +80 -80
- package/node/svg/get-min-y-pos.d.ts +8 -8
- package/node/svg/get-min-y-pos.js +9 -9
- package/node/svg/get-shape-bounds.d.ts +9 -9
- package/node/svg/get-shape-bounds.js +35 -35
- package/node/sweep-line/sweep-line.d.ts +18 -18
- package/node/sweep-line/sweep-line.js +72 -72
- package/node/to-scale-axis.d.ts +16 -16
- package/node/to-scale-axis.js +74 -74
- package/node/traverse-edges.d.ts +10 -10
- package/node/traverse-edges.js +21 -21
- package/node/traverse-vertices.d.ts +12 -12
- package/node/traverse-vertices.js +27 -27
- package/package.json +11 -11
- package/tsconfig.json +0 -1
|
@@ -1,233 +1,233 @@
|
|
|
1
|
-
import { lineLineIntersection, distanceBetween, squaredDistanceBetween, interpolate, dot } from 'flo-vector2d';
|
|
2
|
-
import { evalDeCasteljau as evalDeCasteljau_ } from 'flo-bezier3';
|
|
3
|
-
import { getClosestBoundaryPoint } from '../../closest-boundary-point/get-closest-boundary-point.js';
|
|
4
|
-
import { getOsculatingCircle } from '../../../point-on-shape.js';
|
|
5
|
-
import { add1Prong } from '../add-1-prong.js';
|
|
6
|
-
import { addDebugInfo } from './add-debug-info.js';
|
|
7
|
-
import { cullBezierPieces } from './cull-bezier-pieces.js';
|
|
8
|
-
import { findEquidistantPointOnLine } from './find-equidistant-point-on-line.js';
|
|
9
|
-
import { getInitialBezierPieces } from './get-initial-bezier-pieces.js';
|
|
10
|
-
import { getCloseBoundaryPoints } from '../../closest-boundary-point/get-close-boundary-points.js';
|
|
11
|
-
const evalDeCasteljau = evalDeCasteljau_;
|
|
12
|
-
/**
|
|
13
|
-
* @hidden
|
|
14
|
-
* Adds a 2-prong to the MAT. The first point on the shape boundary is given and
|
|
15
|
-
* the second one is found by the algorithm.
|
|
16
|
-
*
|
|
17
|
-
* A 2-prong is defined as a MAT circle that touches the shape at exactly 2
|
|
18
|
-
* points.
|
|
19
|
-
*
|
|
20
|
-
* Before any 2-prongs are added the entire shape is our δΩ (1-prongs do not
|
|
21
|
-
* reduce the boundary).
|
|
22
|
-
*
|
|
23
|
-
* As per the paper by Choi, Choi, Moon and Wee:
|
|
24
|
-
* "The starting point of this algorithm is a choice of a circle Br(x)
|
|
25
|
-
* centered at an interior point x which contains two boundary portions c and
|
|
26
|
-
* d of dΩ as in Fig. 19."
|
|
27
|
-
* In fact, we (and they) start by fixing one point on the boundary beforehand.
|
|
28
|
-
* @param loops A shape represented by path loops
|
|
29
|
-
* @param extreme The extreme coordinate value of the shape
|
|
30
|
-
* @param squaredDiagonalLength The squared diagonal length of the shape
|
|
31
|
-
* bounding box.
|
|
32
|
-
* @param y The source point of the 2-prong to be found
|
|
33
|
-
* @param isHoleClosing True if this is a hole-closing two-prong, false otherwise
|
|
34
|
-
* @param k The loop array index
|
|
35
|
-
*/
|
|
36
|
-
function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClosing, k) {
|
|
37
|
-
const MAX_ITERATIONS = 25;
|
|
38
|
-
const squaredSeperationTolerance = (1e-6 * extreme) ** 2;
|
|
39
|
-
// TODO - base deltas on theory or remove
|
|
40
|
-
const oneProngTolerance = (1e-4) ** 2;
|
|
41
|
-
const squaredErrorTolerance = 1e-2 * squaredSeperationTolerance;
|
|
42
|
-
const maxOsculatingCircleRadiusSquared = squaredDiagonalLength;
|
|
43
|
-
// The boundary piece that should contain the other point of
|
|
44
|
-
// the 2-prong circle. (Defined by start and end points).
|
|
45
|
-
const { bezierPieces, δ } = getInitialBezierPieces(isHoleClosing, k, loops, cpTrees, y);
|
|
46
|
-
//console.log(bezierPieces.length)
|
|
47
|
-
/** The center of the two-prong (successively refined) */
|
|
48
|
-
let x;
|
|
49
|
-
let p;
|
|
50
|
-
let r;
|
|
51
|
-
if (isHoleClosing) {
|
|
52
|
-
p = [y.p[0], y.p[1]];
|
|
53
|
-
x = [p[0], p[1] - Math.sqrt(maxOsculatingCircleRadiusSquared)];
|
|
54
|
-
r = maxOsculatingCircleRadiusSquared;
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
p = y.p;
|
|
58
|
-
//x = PointOnShape.getOsculatingCircle(maxOsculatingCircleRadiusSquared, y).center;
|
|
59
|
-
x = getOsculatingCircle(maxOsculatingCircleRadiusSquared, y).center;
|
|
60
|
-
r = squaredDistanceBetween(p, x);
|
|
61
|
-
}
|
|
62
|
-
// The lines below is an optimization.
|
|
63
|
-
const r_ = reduceRadius(extreme, bezierPieces, p, x);
|
|
64
|
-
if (r > r_) {
|
|
65
|
-
x = interpolate(p, x, Math.sqrt(r_ / r));
|
|
66
|
-
}
|
|
67
|
-
/** Trace the convergence (for debugging). */
|
|
68
|
-
const xs = [];
|
|
69
|
-
/** The antipode of the two-prong (successively refined) */
|
|
70
|
-
let z;
|
|
71
|
-
let i = 0;
|
|
72
|
-
let done = 0;
|
|
73
|
-
let failed = false; // The failed flag is set if a 2-prong cannot be found.
|
|
74
|
-
let bezierPieces_ = bezierPieces;
|
|
75
|
-
// ---> for (let b of bezierPieces) { d.fs.draw.bezierPiece(document.getElementsByTagName('g')[0], b.curve.ps, b.ts, 'nofill thin10 red', 100); }
|
|
76
|
-
do {
|
|
77
|
-
i++;
|
|
78
|
-
/** squared distance between source boundary point and circle center */
|
|
79
|
-
const r = squaredDistanceBetween(x, y.p);
|
|
80
|
-
bezierPieces_ = cullBezierPieces(bezierPieces_, x, r);
|
|
81
|
-
z = getClosestBoundaryPoint(bezierPieces_, x, y.curve, y.t);
|
|
82
|
-
if (z === undefined) {
|
|
83
|
-
if (typeof _debug_ !== 'undefined') {
|
|
84
|
-
const elems = _debug_.generated.elems;
|
|
85
|
-
const elem = isHoleClosing
|
|
86
|
-
? elems.twoProng_holeClosing
|
|
87
|
-
: elems.twoProng_regular;
|
|
88
|
-
const elemStr = isHoleClosing
|
|
89
|
-
? 'hole-closing: ' + elem.length
|
|
90
|
-
: 'regular: ' + elem.length;
|
|
91
|
-
console.log('failed: no closest point - ' + elemStr);
|
|
92
|
-
}
|
|
93
|
-
failed = true;
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
if (typeof _debug_ !== 'undefined') {
|
|
97
|
-
xs.push({ x, y, z: z.pos, t: y.t });
|
|
98
|
-
}
|
|
99
|
-
/** squared distance between anti-pode boundary point and circle center */
|
|
100
|
-
const d = squaredDistanceBetween(x, z.pos.p);
|
|
101
|
-
//if (i === 1 && d*oneProngTolerance >= r) {
|
|
102
|
-
if (i === 1 && r < d + oneProngTolerance) {
|
|
103
|
-
// It is a 1-prong.
|
|
104
|
-
add1Prong(Math.sqrt(maxOsculatingCircleRadiusSquared), cpTrees, y);
|
|
105
|
-
return undefined;
|
|
106
|
-
}
|
|
107
|
-
// TODO - squaredSeperationTolerance should in future be replaced with
|
|
108
|
-
// a relative error, i.e. distance between y (or z) / length(y (or z)).
|
|
109
|
-
if (!isHoleClosing && squaredDistanceBetween(y.p, z.pos.p) <= squaredSeperationTolerance) {
|
|
110
|
-
if (typeof _debug_ !== 'undefined') {
|
|
111
|
-
/*
|
|
112
|
-
let elems = _debug_.generated.elems;
|
|
113
|
-
let elem = isHoleClosing
|
|
114
|
-
? elems.twoProng_holeClosing
|
|
115
|
-
: elems.twoProng_regular
|
|
116
|
-
let elemStr = isHoleClosing
|
|
117
|
-
? 'hole-closing: ' + elem.length
|
|
118
|
-
: 'regular: ' + elem.length;
|
|
119
|
-
console.log(
|
|
120
|
-
'failed: two-prong radius too small - ' + elemStr
|
|
121
|
-
);
|
|
122
|
-
*/
|
|
123
|
-
}
|
|
124
|
-
failed = true;
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
// TODO - Accuracy optimization: tolerance should not be between x and
|
|
128
|
-
// nextX, but rather (distance from x to y) - (distance from x to z)
|
|
129
|
-
// Find the point on the line connecting y with x that is
|
|
130
|
-
// equidistant from y and z. This will be our next x.
|
|
131
|
-
const nextX = findEquidistantPointOnLine(x, y.p, z.pos.p);
|
|
132
|
-
const squaredError = squaredDistanceBetween(x, nextX);
|
|
133
|
-
x = nextX;
|
|
134
|
-
if (squaredError < squaredErrorTolerance) {
|
|
135
|
-
done++; // Do one more iteration
|
|
136
|
-
}
|
|
137
|
-
else if (i === MAX_ITERATIONS) {
|
|
138
|
-
// Convergence was too slow.
|
|
139
|
-
failed = true;
|
|
140
|
-
break; // We're done
|
|
141
|
-
}
|
|
142
|
-
} while (done < 1);
|
|
143
|
-
// TODO - Optimization: only do this if second closest point is within the
|
|
144
|
-
// tolerance which can be checked in getClosestBoundaryPoint algorithm
|
|
145
|
-
let zs = [];
|
|
146
|
-
if (!failed) {
|
|
147
|
-
zs = getCloseBoundaryPoints(bezierPieces_, x, y, distanceBetween(x, z.pos.p));
|
|
148
|
-
if (!zs.length) {
|
|
149
|
-
// TODO - Numerical issue - fix
|
|
150
|
-
zs.push(z);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
let circle;
|
|
154
|
-
if (z !== undefined) {
|
|
155
|
-
circle = { center: x, radius: distanceBetween(x, z.pos.p) };
|
|
156
|
-
}
|
|
157
|
-
if (typeof _debug_ !== 'undefined' && !failed) {
|
|
158
|
-
xs.push({ x, y, z: z.pos, t: y.t });
|
|
159
|
-
addDebugInfo(bezierPieces, failed, y, circle, z.pos, δ, xs, isHoleClosing);
|
|
160
|
-
}
|
|
161
|
-
return failed ? undefined : { circle, zs };
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* @hidden
|
|
165
|
-
* Reduces the circle radius initially as an optimization step.
|
|
166
|
-
*/
|
|
167
|
-
function reduceRadius(extreme, bezierPieces, p, x) {
|
|
168
|
-
const TOLERANCE = extreme * 1e-3;
|
|
169
|
-
let prevP = undefined;
|
|
170
|
-
let minRadius = Number.POSITIVE_INFINITY;
|
|
171
|
-
for (let i = 0; i < bezierPieces.length; i++) {
|
|
172
|
-
const bezierPiece = bezierPieces[i];
|
|
173
|
-
const ps = bezierPiece.curve.ps;
|
|
174
|
-
const p1 = evalDeCasteljau(ps, bezierPiece.ts[0]);
|
|
175
|
-
let r1 = Number.POSITIVE_INFINITY;
|
|
176
|
-
// Prevent evaluating the same points twice
|
|
177
|
-
if (!prevP || prevP[0] !== p1[0] || prevP[1] !== p1[1]) {
|
|
178
|
-
const cc1 = getCircleCenterFrom2PointsAndNormal(extreme, p, x, p1);
|
|
179
|
-
if (cc1) {
|
|
180
|
-
r1 = squaredDistanceBetween(p, cc1);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
let r2 = Number.POSITIVE_INFINITY;
|
|
184
|
-
const p2 = evalDeCasteljau(ps, bezierPiece.ts[1]);
|
|
185
|
-
const cc2 = getCircleCenterFrom2PointsAndNormal(extreme, p, x, p2);
|
|
186
|
-
if (cc2) {
|
|
187
|
-
r2 = squaredDistanceBetween(p, cc2);
|
|
188
|
-
}
|
|
189
|
-
prevP = p2;
|
|
190
|
-
const d = Math.min(r1, r2);
|
|
191
|
-
if (d < minRadius) {
|
|
192
|
-
minRadius = d;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
// The extra bit is to account for floating point precision.
|
|
196
|
-
// TODO - base delta on theory
|
|
197
|
-
return minRadius + TOLERANCE;
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* @hidden
|
|
201
|
-
* @param p A point on the circle with normal pointing to x towards the center
|
|
202
|
-
* of the circle.
|
|
203
|
-
* @param x
|
|
204
|
-
* @param p1 Another point on the circle.
|
|
205
|
-
*/
|
|
206
|
-
function getCircleCenterFrom2PointsAndNormal(extreme, p, x, p1) {
|
|
207
|
-
// TODO - remove delta
|
|
208
|
-
const TOLERANCE = (1e-4 * extreme) ** 2;
|
|
209
|
-
// Ignore if p and p1 are too close together
|
|
210
|
-
if (squaredDistanceBetween(p, p1) < TOLERANCE) {
|
|
211
|
-
return undefined;
|
|
212
|
-
}
|
|
213
|
-
/** The perpindicular bisector between the two given points on the circle */
|
|
214
|
-
const pb = [
|
|
215
|
-
(p[0] + p1[0]) / 2,
|
|
216
|
-
(p[1] + p1[1]) / 2,
|
|
217
|
-
];
|
|
218
|
-
const tan = [p1[0] - p[0], p1[1] - p[1]];
|
|
219
|
-
const norm = [-tan[1], tan[0]]; // Rotate by 90 degrees
|
|
220
|
-
const pb2 = [pb[0] + norm[0], pb[1] + norm[1]];
|
|
221
|
-
const res = lineLineIntersection([p, x], [pb, pb2]);
|
|
222
|
-
if (!res) {
|
|
223
|
-
return undefined;
|
|
224
|
-
}
|
|
225
|
-
const resO = [res[0] - p[0], res[1] - p[1]];
|
|
226
|
-
const xO = [x[0] - p[0], x[1] - p[1]];
|
|
227
|
-
if (dot(resO, xO) < 0) {
|
|
228
|
-
return undefined;
|
|
229
|
-
}
|
|
230
|
-
return res;
|
|
231
|
-
}
|
|
232
|
-
export { find2Prong };
|
|
1
|
+
import { lineLineIntersection, distanceBetween, squaredDistanceBetween, interpolate, dot } from 'flo-vector2d';
|
|
2
|
+
import { evalDeCasteljau as evalDeCasteljau_ } from 'flo-bezier3';
|
|
3
|
+
import { getClosestBoundaryPoint } from '../../closest-boundary-point/get-closest-boundary-point.js';
|
|
4
|
+
import { getOsculatingCircle } from '../../../point-on-shape.js';
|
|
5
|
+
import { add1Prong } from '../add-1-prong.js';
|
|
6
|
+
import { addDebugInfo } from './add-debug-info.js';
|
|
7
|
+
import { cullBezierPieces } from './cull-bezier-pieces.js';
|
|
8
|
+
import { findEquidistantPointOnLine } from './find-equidistant-point-on-line.js';
|
|
9
|
+
import { getInitialBezierPieces } from './get-initial-bezier-pieces.js';
|
|
10
|
+
import { getCloseBoundaryPoints } from '../../closest-boundary-point/get-close-boundary-points.js';
|
|
11
|
+
const evalDeCasteljau = evalDeCasteljau_;
|
|
12
|
+
/**
|
|
13
|
+
* @hidden
|
|
14
|
+
* Adds a 2-prong to the MAT. The first point on the shape boundary is given and
|
|
15
|
+
* the second one is found by the algorithm.
|
|
16
|
+
*
|
|
17
|
+
* A 2-prong is defined as a MAT circle that touches the shape at exactly 2
|
|
18
|
+
* points.
|
|
19
|
+
*
|
|
20
|
+
* Before any 2-prongs are added the entire shape is our δΩ (1-prongs do not
|
|
21
|
+
* reduce the boundary).
|
|
22
|
+
*
|
|
23
|
+
* As per the paper by Choi, Choi, Moon and Wee:
|
|
24
|
+
* "The starting point of this algorithm is a choice of a circle Br(x)
|
|
25
|
+
* centered at an interior point x which contains two boundary portions c and
|
|
26
|
+
* d of dΩ as in Fig. 19."
|
|
27
|
+
* In fact, we (and they) start by fixing one point on the boundary beforehand.
|
|
28
|
+
* @param loops A shape represented by path loops
|
|
29
|
+
* @param extreme The extreme coordinate value of the shape
|
|
30
|
+
* @param squaredDiagonalLength The squared diagonal length of the shape
|
|
31
|
+
* bounding box.
|
|
32
|
+
* @param y The source point of the 2-prong to be found
|
|
33
|
+
* @param isHoleClosing True if this is a hole-closing two-prong, false otherwise
|
|
34
|
+
* @param k The loop array index
|
|
35
|
+
*/
|
|
36
|
+
function find2Prong(loops, extreme, squaredDiagonalLength, cpTrees, y, isHoleClosing, k) {
|
|
37
|
+
const MAX_ITERATIONS = 25;
|
|
38
|
+
const squaredSeperationTolerance = (1e-6 * extreme) ** 2;
|
|
39
|
+
// TODO - base deltas on theory or remove
|
|
40
|
+
const oneProngTolerance = (1e-4) ** 2;
|
|
41
|
+
const squaredErrorTolerance = 1e-2 * squaredSeperationTolerance;
|
|
42
|
+
const maxOsculatingCircleRadiusSquared = squaredDiagonalLength;
|
|
43
|
+
// The boundary piece that should contain the other point of
|
|
44
|
+
// the 2-prong circle. (Defined by start and end points).
|
|
45
|
+
const { bezierPieces, δ } = getInitialBezierPieces(isHoleClosing, k, loops, cpTrees, y);
|
|
46
|
+
//console.log(bezierPieces.length)
|
|
47
|
+
/** The center of the two-prong (successively refined) */
|
|
48
|
+
let x;
|
|
49
|
+
let p;
|
|
50
|
+
let r;
|
|
51
|
+
if (isHoleClosing) {
|
|
52
|
+
p = [y.p[0], y.p[1]];
|
|
53
|
+
x = [p[0], p[1] - Math.sqrt(maxOsculatingCircleRadiusSquared)];
|
|
54
|
+
r = maxOsculatingCircleRadiusSquared;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
p = y.p;
|
|
58
|
+
//x = PointOnShape.getOsculatingCircle(maxOsculatingCircleRadiusSquared, y).center;
|
|
59
|
+
x = getOsculatingCircle(maxOsculatingCircleRadiusSquared, y).center;
|
|
60
|
+
r = squaredDistanceBetween(p, x);
|
|
61
|
+
}
|
|
62
|
+
// The lines below is an optimization.
|
|
63
|
+
const r_ = reduceRadius(extreme, bezierPieces, p, x);
|
|
64
|
+
if (r > r_) {
|
|
65
|
+
x = interpolate(p, x, Math.sqrt(r_ / r));
|
|
66
|
+
}
|
|
67
|
+
/** Trace the convergence (for debugging). */
|
|
68
|
+
const xs = [];
|
|
69
|
+
/** The antipode of the two-prong (successively refined) */
|
|
70
|
+
let z;
|
|
71
|
+
let i = 0;
|
|
72
|
+
let done = 0;
|
|
73
|
+
let failed = false; // The failed flag is set if a 2-prong cannot be found.
|
|
74
|
+
let bezierPieces_ = bezierPieces;
|
|
75
|
+
// ---> for (let b of bezierPieces) { d.fs.draw.bezierPiece(document.getElementsByTagName('g')[0], b.curve.ps, b.ts, 'nofill thin10 red', 100); }
|
|
76
|
+
do {
|
|
77
|
+
i++;
|
|
78
|
+
/** squared distance between source boundary point and circle center */
|
|
79
|
+
const r = squaredDistanceBetween(x, y.p);
|
|
80
|
+
bezierPieces_ = cullBezierPieces(bezierPieces_, x, r);
|
|
81
|
+
z = getClosestBoundaryPoint(bezierPieces_, x, y.curve, y.t);
|
|
82
|
+
if (z === undefined) {
|
|
83
|
+
if (typeof _debug_ !== 'undefined') {
|
|
84
|
+
const elems = _debug_.generated.elems;
|
|
85
|
+
const elem = isHoleClosing
|
|
86
|
+
? elems.twoProng_holeClosing
|
|
87
|
+
: elems.twoProng_regular;
|
|
88
|
+
const elemStr = isHoleClosing
|
|
89
|
+
? 'hole-closing: ' + elem.length
|
|
90
|
+
: 'regular: ' + elem.length;
|
|
91
|
+
console.log('failed: no closest point - ' + elemStr);
|
|
92
|
+
}
|
|
93
|
+
failed = true;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
if (typeof _debug_ !== 'undefined') {
|
|
97
|
+
xs.push({ x, y, z: z.pos, t: y.t });
|
|
98
|
+
}
|
|
99
|
+
/** squared distance between anti-pode boundary point and circle center */
|
|
100
|
+
const d = squaredDistanceBetween(x, z.pos.p);
|
|
101
|
+
//if (i === 1 && d*oneProngTolerance >= r) {
|
|
102
|
+
if (i === 1 && r < d + oneProngTolerance) {
|
|
103
|
+
// It is a 1-prong.
|
|
104
|
+
add1Prong(Math.sqrt(maxOsculatingCircleRadiusSquared), cpTrees, y);
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
// TODO - squaredSeperationTolerance should in future be replaced with
|
|
108
|
+
// a relative error, i.e. distance between y (or z) / length(y (or z)).
|
|
109
|
+
if (!isHoleClosing && squaredDistanceBetween(y.p, z.pos.p) <= squaredSeperationTolerance) {
|
|
110
|
+
if (typeof _debug_ !== 'undefined') {
|
|
111
|
+
/*
|
|
112
|
+
let elems = _debug_.generated.elems;
|
|
113
|
+
let elem = isHoleClosing
|
|
114
|
+
? elems.twoProng_holeClosing
|
|
115
|
+
: elems.twoProng_regular
|
|
116
|
+
let elemStr = isHoleClosing
|
|
117
|
+
? 'hole-closing: ' + elem.length
|
|
118
|
+
: 'regular: ' + elem.length;
|
|
119
|
+
console.log(
|
|
120
|
+
'failed: two-prong radius too small - ' + elemStr
|
|
121
|
+
);
|
|
122
|
+
*/
|
|
123
|
+
}
|
|
124
|
+
failed = true;
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
// TODO - Accuracy optimization: tolerance should not be between x and
|
|
128
|
+
// nextX, but rather (distance from x to y) - (distance from x to z)
|
|
129
|
+
// Find the point on the line connecting y with x that is
|
|
130
|
+
// equidistant from y and z. This will be our next x.
|
|
131
|
+
const nextX = findEquidistantPointOnLine(x, y.p, z.pos.p);
|
|
132
|
+
const squaredError = squaredDistanceBetween(x, nextX);
|
|
133
|
+
x = nextX;
|
|
134
|
+
if (squaredError < squaredErrorTolerance) {
|
|
135
|
+
done++; // Do one more iteration
|
|
136
|
+
}
|
|
137
|
+
else if (i === MAX_ITERATIONS) {
|
|
138
|
+
// Convergence was too slow.
|
|
139
|
+
failed = true;
|
|
140
|
+
break; // We're done
|
|
141
|
+
}
|
|
142
|
+
} while (done < 1);
|
|
143
|
+
// TODO - Optimization: only do this if second closest point is within the
|
|
144
|
+
// tolerance which can be checked in getClosestBoundaryPoint algorithm
|
|
145
|
+
let zs = [];
|
|
146
|
+
if (!failed) {
|
|
147
|
+
zs = getCloseBoundaryPoints(bezierPieces_, x, y, distanceBetween(x, z.pos.p));
|
|
148
|
+
if (!zs.length) {
|
|
149
|
+
// TODO - Numerical issue - fix
|
|
150
|
+
zs.push(z);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
let circle;
|
|
154
|
+
if (z !== undefined) {
|
|
155
|
+
circle = { center: x, radius: distanceBetween(x, z.pos.p) };
|
|
156
|
+
}
|
|
157
|
+
if (typeof _debug_ !== 'undefined' && !failed) {
|
|
158
|
+
xs.push({ x, y, z: z.pos, t: y.t });
|
|
159
|
+
addDebugInfo(bezierPieces, failed, y, circle, z.pos, δ, xs, isHoleClosing);
|
|
160
|
+
}
|
|
161
|
+
return failed ? undefined : { circle, zs };
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* @hidden
|
|
165
|
+
* Reduces the circle radius initially as an optimization step.
|
|
166
|
+
*/
|
|
167
|
+
function reduceRadius(extreme, bezierPieces, p, x) {
|
|
168
|
+
const TOLERANCE = extreme * 1e-3;
|
|
169
|
+
let prevP = undefined;
|
|
170
|
+
let minRadius = Number.POSITIVE_INFINITY;
|
|
171
|
+
for (let i = 0; i < bezierPieces.length; i++) {
|
|
172
|
+
const bezierPiece = bezierPieces[i];
|
|
173
|
+
const ps = bezierPiece.curve.ps;
|
|
174
|
+
const p1 = evalDeCasteljau(ps, bezierPiece.ts[0]);
|
|
175
|
+
let r1 = Number.POSITIVE_INFINITY;
|
|
176
|
+
// Prevent evaluating the same points twice
|
|
177
|
+
if (!prevP || prevP[0] !== p1[0] || prevP[1] !== p1[1]) {
|
|
178
|
+
const cc1 = getCircleCenterFrom2PointsAndNormal(extreme, p, x, p1);
|
|
179
|
+
if (cc1) {
|
|
180
|
+
r1 = squaredDistanceBetween(p, cc1);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
let r2 = Number.POSITIVE_INFINITY;
|
|
184
|
+
const p2 = evalDeCasteljau(ps, bezierPiece.ts[1]);
|
|
185
|
+
const cc2 = getCircleCenterFrom2PointsAndNormal(extreme, p, x, p2);
|
|
186
|
+
if (cc2) {
|
|
187
|
+
r2 = squaredDistanceBetween(p, cc2);
|
|
188
|
+
}
|
|
189
|
+
prevP = p2;
|
|
190
|
+
const d = Math.min(r1, r2);
|
|
191
|
+
if (d < minRadius) {
|
|
192
|
+
minRadius = d;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// The extra bit is to account for floating point precision.
|
|
196
|
+
// TODO - base delta on theory
|
|
197
|
+
return minRadius + TOLERANCE;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* @hidden
|
|
201
|
+
* @param p A point on the circle with normal pointing to x towards the center
|
|
202
|
+
* of the circle.
|
|
203
|
+
* @param x
|
|
204
|
+
* @param p1 Another point on the circle.
|
|
205
|
+
*/
|
|
206
|
+
function getCircleCenterFrom2PointsAndNormal(extreme, p, x, p1) {
|
|
207
|
+
// TODO - remove delta
|
|
208
|
+
const TOLERANCE = (1e-4 * extreme) ** 2;
|
|
209
|
+
// Ignore if p and p1 are too close together
|
|
210
|
+
if (squaredDistanceBetween(p, p1) < TOLERANCE) {
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
213
|
+
/** The perpindicular bisector between the two given points on the circle */
|
|
214
|
+
const pb = [
|
|
215
|
+
(p[0] + p1[0]) / 2,
|
|
216
|
+
(p[1] + p1[1]) / 2,
|
|
217
|
+
];
|
|
218
|
+
const tan = [p1[0] - p[0], p1[1] - p[1]];
|
|
219
|
+
const norm = [-tan[1], tan[0]]; // Rotate by 90 degrees
|
|
220
|
+
const pb2 = [pb[0] + norm[0], pb[1] + norm[1]];
|
|
221
|
+
const res = lineLineIntersection([p, x], [pb, pb2]);
|
|
222
|
+
if (!res) {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
const resO = [res[0] - p[0], res[1] - p[1]];
|
|
226
|
+
const xO = [x[0] - p[0], x[1] - p[1]];
|
|
227
|
+
if (dot(resO, xO) < 0) {
|
|
228
|
+
return undefined;
|
|
229
|
+
}
|
|
230
|
+
return res;
|
|
231
|
+
}
|
|
232
|
+
export { find2Prong };
|
|
233
233
|
//# sourceMappingURL=find-2-prong.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @hidden
|
|
3
|
-
* @param x
|
|
4
|
-
* @param y
|
|
5
|
-
* @param z
|
|
6
|
-
* @returns The point on the line from y to x that is equidistant from y and z.
|
|
7
|
-
*/
|
|
8
|
-
declare function findEquidistantPointOnLine(x: number[], y: number[], z: number[]): number[];
|
|
9
|
-
export { findEquidistantPointOnLine };
|
|
1
|
+
/**
|
|
2
|
+
* @hidden
|
|
3
|
+
* @param x
|
|
4
|
+
* @param y
|
|
5
|
+
* @param z
|
|
6
|
+
* @returns The point on the line from y to x that is equidistant from y and z.
|
|
7
|
+
*/
|
|
8
|
+
declare function findEquidistantPointOnLine(x: number[], y: number[], z: number[]): number[];
|
|
9
|
+
export { findEquidistantPointOnLine };
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @hidden
|
|
3
|
-
* @param x
|
|
4
|
-
* @param y
|
|
5
|
-
* @param z
|
|
6
|
-
* @returns The point on the line from y to x that is equidistant from y and z.
|
|
7
|
-
*/
|
|
8
|
-
function findEquidistantPointOnLine(x, y, z) {
|
|
9
|
-
// Some basic algebra (not shown) finds the required point.
|
|
10
|
-
// Swap axes if x and y are more aligned to y-axis than to x-axis.
|
|
11
|
-
const swapAxes = Math.abs((x[1] - y[1]) / (x[0] - y[0])) > 1;
|
|
12
|
-
// Cache
|
|
13
|
-
let x1, x2, y1, y2, z1, z2;
|
|
14
|
-
if (swapAxes) {
|
|
15
|
-
x1 = x[1];
|
|
16
|
-
x2 = x[0];
|
|
17
|
-
y1 = y[1];
|
|
18
|
-
y2 = y[0];
|
|
19
|
-
z1 = z[1];
|
|
20
|
-
z2 = z[0];
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
x1 = x[0];
|
|
24
|
-
x2 = x[1];
|
|
25
|
-
y1 = y[0];
|
|
26
|
-
y2 = y[1];
|
|
27
|
-
z1 = z[0];
|
|
28
|
-
z2 = z[1];
|
|
29
|
-
}
|
|
30
|
-
// a <= 1 (due to swapped axes)
|
|
31
|
-
const a = (x2 - y2) / (x1 - y1);
|
|
32
|
-
const b = y2 - a * y1;
|
|
33
|
-
const c = (y1 * y1 + y2 * y2 - z1 * z1 - z2 * z2) + 2 * b * (z2 - y2);
|
|
34
|
-
const d = y1 - z1 + a * (y2 - z2);
|
|
35
|
-
const t1 = c / (2 * d);
|
|
36
|
-
const t2 = a * t1 + b;
|
|
37
|
-
return swapAxes ? [t2, t1] : [t1, t2];
|
|
38
|
-
}
|
|
39
|
-
export { findEquidistantPointOnLine };
|
|
1
|
+
/**
|
|
2
|
+
* @hidden
|
|
3
|
+
* @param x
|
|
4
|
+
* @param y
|
|
5
|
+
* @param z
|
|
6
|
+
* @returns The point on the line from y to x that is equidistant from y and z.
|
|
7
|
+
*/
|
|
8
|
+
function findEquidistantPointOnLine(x, y, z) {
|
|
9
|
+
// Some basic algebra (not shown) finds the required point.
|
|
10
|
+
// Swap axes if x and y are more aligned to y-axis than to x-axis.
|
|
11
|
+
const swapAxes = Math.abs((x[1] - y[1]) / (x[0] - y[0])) > 1;
|
|
12
|
+
// Cache
|
|
13
|
+
let x1, x2, y1, y2, z1, z2;
|
|
14
|
+
if (swapAxes) {
|
|
15
|
+
x1 = x[1];
|
|
16
|
+
x2 = x[0];
|
|
17
|
+
y1 = y[1];
|
|
18
|
+
y2 = y[0];
|
|
19
|
+
z1 = z[1];
|
|
20
|
+
z2 = z[0];
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
x1 = x[0];
|
|
24
|
+
x2 = x[1];
|
|
25
|
+
y1 = y[0];
|
|
26
|
+
y2 = y[1];
|
|
27
|
+
z1 = z[0];
|
|
28
|
+
z2 = z[1];
|
|
29
|
+
}
|
|
30
|
+
// a <= 1 (due to swapped axes)
|
|
31
|
+
const a = (x2 - y2) / (x1 - y1);
|
|
32
|
+
const b = y2 - a * y1;
|
|
33
|
+
const c = (y1 * y1 + y2 * y2 - z1 * z1 - z2 * z2) + 2 * b * (z2 - y2);
|
|
34
|
+
const d = y1 - z1 + a * (y2 - z2);
|
|
35
|
+
const t1 = c / (2 * d);
|
|
36
|
+
const t2 = a * t1 + b;
|
|
37
|
+
return swapAxes ? [t2, t1] : [t1, t2];
|
|
38
|
+
}
|
|
39
|
+
export { findEquidistantPointOnLine };
|
|
40
40
|
//# sourceMappingURL=find-equidistant-point-on-line.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { LlRbTree } from 'flo-ll-rb-tree';
|
|
2
|
-
import { BezierPiece } from '../../bezier-piece.js';
|
|
3
|
-
import { Loop } from '../../../loop.js';
|
|
4
|
-
import { CpNode } from '../../../cp-node.js';
|
|
5
|
-
import { IPointOnShape } from '../../../point-on-shape.js';
|
|
6
|
-
/** @hidden */
|
|
7
|
-
declare function getInitialBezierPieces(isHoleClosing: boolean, k: number, loops: Loop[], cpTrees: Map<Loop, LlRbTree<CpNode>>, y: IPointOnShape): {
|
|
8
|
-
bezierPieces: BezierPiece[];
|
|
9
|
-
δ: CpNode[];
|
|
10
|
-
};
|
|
11
|
-
export { getInitialBezierPieces };
|
|
1
|
+
import { LlRbTree } from 'flo-ll-rb-tree';
|
|
2
|
+
import { BezierPiece } from '../../bezier-piece.js';
|
|
3
|
+
import { Loop } from '../../../loop.js';
|
|
4
|
+
import { CpNode } from '../../../cp-node.js';
|
|
5
|
+
import { IPointOnShape } from '../../../point-on-shape.js';
|
|
6
|
+
/** @hidden */
|
|
7
|
+
declare function getInitialBezierPieces(isHoleClosing: boolean, k: number, loops: Loop[], cpTrees: Map<Loop, LlRbTree<CpNode>>, y: IPointOnShape): {
|
|
8
|
+
bezierPieces: BezierPiece[];
|
|
9
|
+
δ: CpNode[];
|
|
10
|
+
};
|
|
11
|
+
export { getInitialBezierPieces };
|