flo-mat 3.0.9 → 3.0.10
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 +193 -190
- package/browser/index.min.js +1 -1
- package/node/closest-boundary-point/cull-bezier-pieces.d.ts +5 -4
- package/node/closest-boundary-point/cull-bezier-pieces.js +9 -8
- package/node/closest-boundary-point/cull-bezier-pieces.js.map +1 -1
- package/node/closest-boundary-point/cull-by-loose-bounding-box.d.ts +2 -2
- package/node/closest-boundary-point/cull-by-loose-bounding-box.js +8 -8
- package/node/closest-boundary-point/cull-by-loose-bounding-box.js.map +1 -1
- package/node/closest-boundary-point/cull-by-tight-boundary-box.d.ts +2 -2
- package/node/closest-boundary-point/cull-by-tight-boundary-box.js +8 -8
- package/node/closest-boundary-point/cull-by-tight-boundary-box.js.map +1 -1
- package/node/closest-boundary-point/get-best-distance-squared.d.ts +1 -1
- package/node/closest-boundary-point/get-best-distance-squared.js +6 -6
- package/node/closest-boundary-point/get-best-distance-squared.js.map +1 -1
- package/node/closest-boundary-point/get-close-boundary-points-certified.d.ts +2 -2
- package/node/closest-boundary-point/get-close-boundary-points-certified.js +7 -7
- package/node/closest-boundary-point/get-close-boundary-points-certified.js.map +1 -1
- package/node/cp-node/fs/get-boundary-bezier-parts-to-next.d.ts +1 -1
- package/node/cp-node/fs/get-boundary-bezier-parts-to-next.js +11 -16
- package/node/cp-node/fs/get-boundary-bezier-parts-to-next.js.map +1 -1
- package/node/cp-node/fs/get-boundary-beziers-between.js +4 -6
- package/node/cp-node/fs/get-boundary-beziers-between.js.map +1 -1
- package/node/cp-node/fs/get-boundary-beziers-to-next.d.ts +10 -1
- package/node/cp-node/fs/get-boundary-beziers-to-next.js +70 -35
- package/node/cp-node/fs/get-boundary-beziers-to-next.js.map +1 -1
- package/node/cp-node/fs/get-salience.js +2 -2
- package/node/cp-node/fs/get-salience.js.map +1 -1
- package/node/cp-node/fs/get-speed.js +0 -1
- package/node/cp-node/fs/get-speed.js.map +1 -1
- package/node/find-2-prong/cull-bezier-pieces.d.ts +4 -4
- package/node/find-2-prong/cull-bezier-pieces.js +9 -9
- package/node/find-2-prong/cull-bezier-pieces.js.map +1 -1
- package/node/find-2-prong/find-2-prong.js +8 -8
- package/node/find-2-prong/find-2-prong.js.map +1 -1
- package/node/find-2-prong/get-initial-bezier-pieces.d.ts +2 -2
- package/node/find-2-prong/get-initial-bezier-pieces.js +2 -2
- package/node/find-2-prong/get-initial-bezier-pieces.js.map +1 -1
- package/node/find-2-prong/reduce-radius.d.ts +1 -1
- package/node/find-2-prong/reduce-radius.js +5 -5
- package/node/find-2-prong/reduce-radius.js.map +1 -1
- package/node/find-3-prong.ts/calc-better-x.d.ts +2 -2
- package/node/find-3-prong.ts/calc-better-x.js +3 -3
- package/node/find-3-prong.ts/calc-better-x.js.map +1 -1
- package/node/find-3-prong.ts/calc-initial-3-prong-center.d.ts +2 -2
- package/node/find-3-prong.ts/calc-initial-3-prong-center.js +3 -3
- package/node/find-3-prong.ts/calc-initial-3-prong-center.js.map +1 -1
- package/node/find-3-prong.ts/find-3-prong-for-delta3s.d.ts +2 -2
- package/node/find-3-prong.ts/find-3-prong-for-delta3s.js +16 -16
- package/node/find-3-prong.ts/find-3-prong-for-delta3s.js.map +1 -1
- package/node/find-3-prong.ts/find-3-prong.js +2 -2
- package/node/find-3-prong.ts/find-3-prong.js.map +1 -1
- package/node/find-3-prong.ts/get-closest-points.d.ts +2 -2
- package/node/find-3-prong.ts/get-closest-points.js +4 -4
- package/node/find-3-prong.ts/get-closest-points.js.map +1 -1
- package/node/mat/get-boundary-piece-beziers.js +7 -7
- package/node/mat/get-boundary-piece-beziers.js.map +1 -1
- package/node/sat/cull.d.ts +7 -5
- package/node/sat/cull.js +7 -4
- package/node/sat/cull.js.map +1 -1
- package/node/sat/to-scale-axis.d.ts +3 -2
- package/node/sat/to-scale-axis.js +3 -2
- package/node/sat/to-scale-axis.js.map +1 -1
- package/package.json +5 -5
- package/src/closest-boundary-point/cull-bezier-pieces.ts +12 -11
- package/src/closest-boundary-point/cull-by-loose-bounding-box.ts +8 -8
- package/src/closest-boundary-point/cull-by-tight-boundary-box.ts +8 -8
- package/src/closest-boundary-point/get-best-distance-squared.ts +6 -6
- package/src/closest-boundary-point/get-close-boundary-points-certified.ts +8 -8
- package/src/cp-node/fs/get-boundary-bezier-parts-to-next.ts +12 -18
- package/src/cp-node/fs/get-boundary-beziers-between.ts +6 -7
- package/src/cp-node/fs/get-boundary-beziers-to-next.ts +79 -53
- package/src/cp-node/fs/get-salience.ts +2 -2
- package/src/cp-node/fs/get-speed.ts +1 -6
- package/src/curve/curve.ts +5 -5
- package/src/debug/functions/draw-elem/two-prong.ts +40 -40
- package/src/debug/functions/two-prong.ts +195 -195
- package/src/debug/two-prong-for-debugging.ts +26 -26
- package/src/find-2-prong/add-debug-info.ts +38 -38
- package/src/find-2-prong/cull-bezier-pieces.ts +10 -10
- package/src/find-2-prong/find-2-prong.ts +8 -8
- package/src/find-2-prong/get-initial-bezier-pieces.ts +2 -2
- package/src/find-2-prong/reduce-radius.ts +5 -5
- package/src/find-3-prong.ts/calc-better-x.ts +3 -3
- package/src/find-3-prong.ts/calc-initial-3-prong-center.ts +3 -3
- package/src/find-3-prong.ts/find-3-prong-for-delta3s.ts +16 -16
- package/src/find-3-prong.ts/find-3-prong.ts +2 -2
- package/src/find-3-prong.ts/get-closest-points.ts +4 -4
- package/src/find-mat/add-2-prongs-by-error.ts +7 -7
- package/src/index.ts +1 -1
- package/src/mat/get-boundary-piece-beziers.ts +7 -7
- package/src/mat/get-two-prong-type.ts +8 -8
- package/src/sat/cull.ts +10 -7
- package/src/sat/to-scale-axis.ts +18 -17
- package/src/utils/bezier-piece-to-bezier.ts +7 -7
- package/node/cp-node/fs/cp-nodes-to-boundary-beziers.d.ts +0 -3
- package/node/cp-node/fs/cp-nodes-to-boundary-beziers.js +0 -6
- package/node/cp-node/fs/cp-nodes-to-boundary-beziers.js.map +0 -1
- package/src/closest-boundary-point/get-closest-boundary-point-certified.ts +0 -70
- package/src/cp-node/fs/cp-nodes-to-boundary-beziers.ts +0 -10
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "flo-mat",
|
|
3
3
|
"sideEffects": false,
|
|
4
4
|
"description": "Medial / Scale Axis Transform (MAT/SAT) Library.",
|
|
5
|
-
"version": "3.0.
|
|
5
|
+
"version": "3.0.10",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Floris Steenkamp"
|
|
8
8
|
},
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"big-float-ts": "^4.0.2",
|
|
35
35
|
"double-double": "^3.0.4",
|
|
36
|
-
"flo-bezier3": "^6.0.
|
|
36
|
+
"flo-bezier3": "^6.0.8",
|
|
37
37
|
"flo-boolean": "^5.0.3",
|
|
38
38
|
"flo-draw": "^2.0.5",
|
|
39
39
|
"flo-gauss-quadrature": "^2.1.4",
|
|
@@ -47,19 +47,19 @@
|
|
|
47
47
|
"@swc/core": "^1.15.33",
|
|
48
48
|
"@swc/jest": "^0.2.39",
|
|
49
49
|
"@types/jest": "^30.0.0",
|
|
50
|
-
"@types/node": "^25.9.
|
|
50
|
+
"@types/node": "^25.9.1",
|
|
51
51
|
"jest": "^30.4.2",
|
|
52
52
|
"jest-ts-webcompat-resolver": "^1.0.1",
|
|
53
53
|
"c8": "^11.0.0",
|
|
54
54
|
"chai": "^6.2.2",
|
|
55
55
|
"circular-dependency-plugin": "^5.2.2",
|
|
56
|
-
"mocha": "^11.7.
|
|
56
|
+
"mocha": "^11.7.6",
|
|
57
57
|
"rimraf": "^6.1.3",
|
|
58
58
|
"source-map-support": "^0.5.21",
|
|
59
59
|
"ts-loader": "^9.5.7",
|
|
60
60
|
"ts-node": "^10.9.2",
|
|
61
61
|
"typescript": "^6.0.3",
|
|
62
|
-
"webpack": "^5.
|
|
62
|
+
"webpack": "^5.107.1",
|
|
63
63
|
"webpack-cli": "^7.0.2"
|
|
64
64
|
},
|
|
65
65
|
"scripts": {
|
|
@@ -5,31 +5,32 @@ import { cullByTightBoundingBox } from './cull-by-tight-boundary-box.js';
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* @
|
|
9
|
-
* @param bezierPieces
|
|
8
|
+
* @param curvePieces
|
|
10
9
|
* @param p
|
|
11
10
|
* @param extreme
|
|
11
|
+
*
|
|
12
|
+
* @internal
|
|
12
13
|
*/
|
|
13
|
-
function
|
|
14
|
-
|
|
14
|
+
function cullCurvePieces1(
|
|
15
|
+
curvePieces: CurvePiece[],
|
|
15
16
|
p: number[]) {
|
|
16
17
|
|
|
17
18
|
const bestSquaredDistance = getBestDistanceSquared(
|
|
18
|
-
|
|
19
|
+
curvePieces, p
|
|
19
20
|
);
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
curvePieces = cullByLooseBoundingBox(
|
|
22
|
+
curvePieces, p,
|
|
22
23
|
bestSquaredDistance
|
|
23
24
|
);
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
curvePieces = cullByTightBoundingBox(
|
|
27
|
+
curvePieces, p,
|
|
27
28
|
bestSquaredDistance
|
|
28
29
|
);
|
|
29
30
|
|
|
30
31
|
|
|
31
|
-
return
|
|
32
|
+
return curvePieces;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
|
|
35
|
-
export {
|
|
36
|
+
export { cullCurvePieces1 }
|
|
@@ -8,20 +8,20 @@ import { getBoundingBox$ } from '../geometry/get-bounding-box-.js';
|
|
|
8
8
|
* @internal
|
|
9
9
|
* When checking distances, ignore all those with closest possible distance
|
|
10
10
|
* further than 'bestSquaredDistance', i.e. cull them.
|
|
11
|
-
* @param
|
|
11
|
+
* @param curvePieces
|
|
12
12
|
* @param p
|
|
13
13
|
* @param dSquared
|
|
14
14
|
*/
|
|
15
15
|
function cullByLooseBoundingBox(
|
|
16
|
-
|
|
16
|
+
curvePieces: CurvePiece[],
|
|
17
17
|
p: number[],
|
|
18
18
|
dSquared: number) {
|
|
19
19
|
|
|
20
|
-
const
|
|
20
|
+
const candidateCurvePieces = [];
|
|
21
21
|
|
|
22
|
-
for (let i=0; i<
|
|
23
|
-
const
|
|
24
|
-
const ps =
|
|
22
|
+
for (let i=0; i<curvePieces.length; i++) {
|
|
23
|
+
const curvePiece = curvePieces[i];
|
|
24
|
+
const ps = curvePiece.curve.ps;
|
|
25
25
|
|
|
26
26
|
const boundingBox = getBoundingBox$(ps);
|
|
27
27
|
|
|
@@ -30,11 +30,11 @@ function cullByLooseBoundingBox(
|
|
|
30
30
|
p
|
|
31
31
|
);
|
|
32
32
|
if (d <= dSquared) {
|
|
33
|
-
|
|
33
|
+
candidateCurvePieces.push(curvePiece);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
return
|
|
37
|
+
return candidateCurvePieces;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
|
|
@@ -11,20 +11,20 @@ const getBoundingBoxTight_ = memoize(getBoundingBoxTight);
|
|
|
11
11
|
* @internal
|
|
12
12
|
* When checking distances, ignore all those with closest possible distance
|
|
13
13
|
* further than 'bestSquaredDistance', i.e. cull them.
|
|
14
|
-
* @param
|
|
14
|
+
* @param curvePieces
|
|
15
15
|
* @param p
|
|
16
16
|
* @param bestSquaredDistance
|
|
17
17
|
*/
|
|
18
18
|
function cullByTightBoundingBox(
|
|
19
|
-
|
|
19
|
+
curvePieces: CurvePiece[],
|
|
20
20
|
p: number[],
|
|
21
21
|
bestSquaredDistance: number) {
|
|
22
22
|
|
|
23
|
-
const
|
|
23
|
+
const candidateCurvePieces = [];
|
|
24
24
|
|
|
25
|
-
for (let i=0; i<
|
|
26
|
-
const
|
|
27
|
-
const ps =
|
|
25
|
+
for (let i=0; i<curvePieces.length; i++) {
|
|
26
|
+
const curvePiece = curvePieces[i];
|
|
27
|
+
const ps = curvePiece.curve.ps;
|
|
28
28
|
|
|
29
29
|
const tightBoundingBox = getBoundingBoxTight_(ps);
|
|
30
30
|
const d = getClosestSquaredDistanceToRotatedRect(
|
|
@@ -32,11 +32,11 @@ function cullByTightBoundingBox(
|
|
|
32
32
|
p
|
|
33
33
|
);
|
|
34
34
|
if (d <= bestSquaredDistance) {
|
|
35
|
-
|
|
35
|
+
candidateCurvePieces.push(curvePiece);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
return
|
|
39
|
+
return candidateCurvePieces;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
|
|
@@ -9,17 +9,17 @@ import { CurvePiece } from "../mat/curve-piece.js";
|
|
|
9
9
|
* this distance away.
|
|
10
10
|
*/
|
|
11
11
|
function getBestDistanceSquared(
|
|
12
|
-
|
|
12
|
+
curvePieces: CurvePiece[],
|
|
13
13
|
p: number[]) {
|
|
14
14
|
|
|
15
15
|
let bestSquaredDistance = Number.POSITIVE_INFINITY;
|
|
16
|
-
for (let i=0; i<
|
|
17
|
-
const
|
|
16
|
+
for (let i=0; i<curvePieces.length; i++) {
|
|
17
|
+
const curvePiece = curvePieces[i];
|
|
18
18
|
|
|
19
|
-
const ps =
|
|
19
|
+
const ps = curvePiece.curve.ps;
|
|
20
20
|
|
|
21
|
-
const p1 = evalDeCasteljau(ps,
|
|
22
|
-
const p2 = evalDeCasteljau(ps,
|
|
21
|
+
const p1 = evalDeCasteljau(ps, curvePiece.ts[0]);
|
|
22
|
+
const p2 = evalDeCasteljau(ps, curvePiece.ts[1]);
|
|
23
23
|
|
|
24
24
|
const d = Math.min(
|
|
25
25
|
squaredDistanceBetween(p, p1),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CurvePiece } from '../mat/curve-piece.js';
|
|
2
2
|
import { getPotentialClosestPointsOnCurveCertified } from './get-potential-closest-points-on-curve-certified.js';
|
|
3
|
-
import {
|
|
3
|
+
import { cullCurvePieces1 } from './cull-bezier-pieces.js';
|
|
4
4
|
import { Curve } from '../curve/curve.js';
|
|
5
5
|
import { FootAndEndpointInfo } from './foot-and-endpoint-info.js';
|
|
6
6
|
import { PointOnShape } from '../point-on-shape/point-on-shape.js';
|
|
@@ -13,7 +13,7 @@ import { createPos } from '../point-on-shape/create-pos.js';
|
|
|
13
13
|
* bezier pieces, including the beziers actually checked after culling.
|
|
14
14
|
*
|
|
15
15
|
* @param pow
|
|
16
|
-
* @param
|
|
16
|
+
* @param curvePieces
|
|
17
17
|
* @param x
|
|
18
18
|
* @param touchedCurve
|
|
19
19
|
* @param t
|
|
@@ -22,24 +22,24 @@ import { createPos } from '../point-on-shape/create-pos.js';
|
|
|
22
22
|
*/
|
|
23
23
|
function getCloseBoundaryPointsCertified(
|
|
24
24
|
pow: number,
|
|
25
|
-
|
|
25
|
+
curvePieces: CurvePiece[],
|
|
26
26
|
x: number[],
|
|
27
27
|
touchedCurve: Curve | undefined = undefined,
|
|
28
28
|
t: number | undefined = undefined,
|
|
29
29
|
for1Prong = false,
|
|
30
30
|
angle = 0): PointOnShape[] {
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
curvePieces = cullCurvePieces1(curvePieces, x);
|
|
33
33
|
|
|
34
34
|
const pInfoss: FootAndEndpointInfo[] = [];
|
|
35
|
-
for (let i=0; i<
|
|
36
|
-
const
|
|
35
|
+
for (let i=0; i<curvePieces.length; i++) {
|
|
36
|
+
const curvePiece = curvePieces[i];
|
|
37
37
|
|
|
38
38
|
const pInfos = getPotentialClosestPointsOnCurveCertified(
|
|
39
39
|
pow,
|
|
40
|
-
|
|
40
|
+
curvePiece.curve,
|
|
41
41
|
x,
|
|
42
|
-
|
|
42
|
+
curvePiece.ts,
|
|
43
43
|
touchedCurve,
|
|
44
44
|
t,
|
|
45
45
|
for1Prong,
|
|
@@ -13,7 +13,7 @@ import type { Curve } from '../../curve/curve.js';
|
|
|
13
13
|
* @param cpNode
|
|
14
14
|
*/
|
|
15
15
|
function getBoundaryBezierPartsToNext(
|
|
16
|
-
cpNode: CpNode): BezierPiece[]
|
|
16
|
+
cpNode: CpNode): BezierPiece[] {
|
|
17
17
|
|
|
18
18
|
const cpThis = cpNode;
|
|
19
19
|
const cpNext = cpNode.next;
|
|
@@ -27,27 +27,22 @@ function getBoundaryBezierPartsToNext(
|
|
|
27
27
|
if (curveThis.loop !== curveNext.loop) {
|
|
28
28
|
// It is a hole-closer going over to the other loop - a kind of terminal
|
|
29
29
|
// CpNode.
|
|
30
|
-
return undefined;
|
|
30
|
+
// return undefined;
|
|
31
|
+
return [];
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
const bezierPieces: BezierPiece[] = [];
|
|
34
35
|
|
|
35
36
|
if (curveNext === curveThis) {
|
|
36
37
|
bezierPieces.push(
|
|
37
|
-
{
|
|
38
|
-
ps: posThis.curve.ps,
|
|
39
|
-
ts: [posThis.t, posNext.t]
|
|
40
|
-
}
|
|
38
|
+
{ ps: posThis.curve.ps, ts: [posThis.t, posNext.t] }
|
|
41
39
|
);
|
|
42
40
|
} else {
|
|
43
41
|
bezierPieces.push(
|
|
44
|
-
{
|
|
45
|
-
ps: posThis.curve.ps,
|
|
46
|
-
ts: [posThis.t, 1]
|
|
47
|
-
}
|
|
42
|
+
{ ps: posThis.curve.ps, ts: [posThis.t, 1] }
|
|
48
43
|
);
|
|
49
44
|
|
|
50
|
-
|
|
45
|
+
addSkippedBezierPiecess(
|
|
51
46
|
bezierPieces,
|
|
52
47
|
posThis.curve,
|
|
53
48
|
posNext.curve,
|
|
@@ -60,10 +55,10 @@ function getBoundaryBezierPartsToNext(
|
|
|
60
55
|
|
|
61
56
|
|
|
62
57
|
/**
|
|
63
|
-
* @internal
|
|
64
58
|
* Adds pieces of skipped beziers.
|
|
59
|
+
* @internal
|
|
65
60
|
*/
|
|
66
|
-
function
|
|
61
|
+
function addSkippedBezierPiecess(
|
|
67
62
|
bezierPieces: BezierPiece[],
|
|
68
63
|
curveStart: Curve,
|
|
69
64
|
curveEnd: Curve,
|
|
@@ -72,11 +67,10 @@ function addSkippedBeziers(
|
|
|
72
67
|
let curveThis = curveStart;
|
|
73
68
|
do {
|
|
74
69
|
curveThis = curveThis.next;
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
bezierPieces.push(bezierPart);
|
|
70
|
+
const tEnd = curveThis === curveEnd ? t1 : 1;
|
|
71
|
+
bezierPieces.push({
|
|
72
|
+
ps: curveThis.ps, ts: [0, tEnd]
|
|
73
|
+
});
|
|
80
74
|
} while (curveThis !== curveEnd);
|
|
81
75
|
}
|
|
82
76
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { BezierPiece } from "flo-bezier3";
|
|
2
1
|
import type { CpNode } from "../cp-node.js";
|
|
3
|
-
import { cpNodesToBoundaryBeziers } from "./cp-nodes-to-boundary-beziers.js";
|
|
4
2
|
import { getAllBetween } from "./get-all-between.js";
|
|
3
|
+
import { getBoundaryBeziersToNext } from "./get-boundary-beziers-to-next.js";
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -23,12 +22,12 @@ function getBoundaryBeziersBetween(
|
|
|
23
22
|
hasHoleCloser: boolean
|
|
24
23
|
} {
|
|
25
24
|
|
|
26
|
-
const
|
|
25
|
+
const { cpNodes, hasHoleCloser } =
|
|
26
|
+
getAllBetween(cpNode1,cpNode2,inclAllIfEqual);
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
28
|
+
const pss = cpNodes.flatMap(getBoundaryBeziersToNext);
|
|
29
|
+
|
|
30
|
+
return { pss, hasHoleCloser }
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
|
|
@@ -1,70 +1,96 @@
|
|
|
1
|
+
import type { CpNode } from '../cp-node.js';
|
|
1
2
|
import { fromTo } from 'flo-bezier3';
|
|
2
|
-
import {
|
|
3
|
-
import { Curve } from '../../curve/curve.js';
|
|
3
|
+
import { getBoundaryBezierPartsToNext } from './get-boundary-bezier-parts-to-next.js';
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
// * Returns the boundary beziers between this `CpNode` and the next
|
|
8
|
+
// * one.
|
|
9
|
+
// *
|
|
10
|
+
// * * returns `[]` if the next `CpNode` is on a different loop,
|
|
11
|
+
// * as this is a hole-closer and there are no boundary beziers between them.
|
|
12
|
+
// *
|
|
13
|
+
// * @param cpNode
|
|
14
|
+
// */
|
|
6
15
|
function getBoundaryBeziersToNext(
|
|
7
16
|
cpNode: CpNode): number[][][] {
|
|
8
17
|
|
|
9
|
-
|
|
10
|
-
|
|
18
|
+
return getBoundaryBezierPartsToNext(cpNode).map(
|
|
19
|
+
bp => fromTo(bp.ps, bp.ts[0], bp.ts[1])
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
// /**
|
|
25
|
+
// * Returns the boundary beziers between this `CpNode` and the next
|
|
26
|
+
// * one.
|
|
27
|
+
// *
|
|
28
|
+
// * * returns `[]` if the next `CpNode` is on a different loop,
|
|
29
|
+
// * as this is a hole-closer and there are no boundary beziers between them.
|
|
30
|
+
// *
|
|
31
|
+
// * @param cpNode
|
|
32
|
+
// */
|
|
33
|
+
// function getBoundaryBeziersToNext(
|
|
34
|
+
// cpNode: CpNode): number[][][] {
|
|
35
|
+
|
|
36
|
+
// const cpThis = cpNode;
|
|
37
|
+
// const cpNext = cpNode.next;
|
|
11
38
|
|
|
12
|
-
|
|
13
|
-
|
|
39
|
+
// const posThis = cpThis.cp.pointOnShape;
|
|
40
|
+
// const posNext = cpNext.cp.pointOnShape;
|
|
14
41
|
|
|
15
|
-
|
|
16
|
-
|
|
42
|
+
// const curveThis = posThis.curve;
|
|
43
|
+
// const curveNext = posNext.curve;
|
|
17
44
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
45
|
+
// if (curveThis.loop !== curveNext.loop) {
|
|
46
|
+
// // It is a hole-closer going over to the other loop - a kind of terminal
|
|
47
|
+
// // CpNode.
|
|
48
|
+
// // return undefined!;
|
|
49
|
+
// return [];
|
|
50
|
+
// }
|
|
24
51
|
|
|
25
|
-
|
|
52
|
+
// const beziers: number[][][] = [];
|
|
26
53
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
54
|
+
// if (curveNext === curveThis) {
|
|
55
|
+
// beziers.push(
|
|
56
|
+
// fromTo(posThis.curve.ps, posThis.t, posNext.t)
|
|
57
|
+
// );
|
|
58
|
+
// } else {
|
|
59
|
+
// beziers.push(
|
|
60
|
+
// fromTo(posThis.curve.ps, posThis.t, 1)
|
|
61
|
+
// );
|
|
35
62
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return beziers;
|
|
45
|
-
}
|
|
63
|
+
// addSkippedBeziers(
|
|
64
|
+
// beziers,
|
|
65
|
+
// posThis.curve,
|
|
66
|
+
// posNext.curve,
|
|
67
|
+
// posNext.t
|
|
68
|
+
// );
|
|
69
|
+
// }
|
|
46
70
|
|
|
71
|
+
// return beziers;
|
|
72
|
+
// }
|
|
47
73
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
74
|
+
|
|
75
|
+
// /**
|
|
76
|
+
// * Adds pieces of skipped beziers.
|
|
77
|
+
// * @internal
|
|
78
|
+
// */
|
|
79
|
+
// function addSkippedBeziers(
|
|
80
|
+
// beziers: number[][][],
|
|
81
|
+
// curveStart: Curve,
|
|
82
|
+
// curveEnd: Curve,
|
|
83
|
+
// t1: number) {
|
|
84
|
+
|
|
85
|
+
// let curveThis = curveStart;
|
|
86
|
+
// do {
|
|
87
|
+
// curveThis = curveThis.next;
|
|
88
|
+
// const tEnd = curveThis === curveEnd ? t1 : 1;
|
|
89
|
+
// beziers.push(
|
|
90
|
+
// fromTo(curveThis.ps, 0, tEnd)
|
|
91
|
+
// );
|
|
92
|
+
// } while (curveThis !== curveEnd);
|
|
93
|
+
// }
|
|
68
94
|
|
|
69
95
|
|
|
70
96
|
export { getBoundaryBeziersToNext }
|
|
@@ -17,9 +17,9 @@ function getSalience(cpNode: CpNode) {
|
|
|
17
17
|
|
|
18
18
|
const d = distanceBetween(bp1, bp2);
|
|
19
19
|
|
|
20
|
-
const { pss
|
|
20
|
+
const { pss, hasHoleCloser } = getBoundaryBeziersBetween(cpNode1, cpNode2);
|
|
21
21
|
|
|
22
|
-
const s = sum(
|
|
22
|
+
const s = sum(pss.map(ps => totalLength(ps)));
|
|
23
23
|
|
|
24
24
|
return hasHoleCloser ? Number.POSITIVE_INFINITY : s/d;
|
|
25
25
|
}
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { totalAbsoluteCurvature, totalLength } from "flo-bezier3";
|
|
2
2
|
import { memoize } from "flo-memoize";
|
|
3
|
-
import { sum } from "../../utils/sum.js";
|
|
4
3
|
import { CpNode } from "../cp-node.js";
|
|
5
|
-
import { getBoundaryBeziersToNext } from "./get-boundary-beziers-to-next.js";
|
|
6
4
|
import { getMatCurveToNext } from "./get-mat-curve-to-next.js";
|
|
7
5
|
import { getRealProngCount } from "./get-real-prong-count.js";
|
|
8
6
|
|
|
9
|
-
const { min, abs } = Math;
|
|
10
|
-
|
|
11
|
-
|
|
12
7
|
const getSpeed$ = memoize(getSpeed);
|
|
13
8
|
|
|
14
9
|
|
package/src/curve/curve.ts
CHANGED
|
@@ -9,28 +9,28 @@ interface Curve {
|
|
|
9
9
|
* The closed loop of bezier curves representing the shape
|
|
10
10
|
* boundary this curve belongs to.
|
|
11
11
|
*/
|
|
12
|
-
loop
|
|
12
|
+
loop: Loop;
|
|
13
13
|
/**
|
|
14
14
|
* The bezier control points.
|
|
15
15
|
*/
|
|
16
|
-
ps
|
|
16
|
+
ps: number[][];
|
|
17
17
|
/**
|
|
18
18
|
* The previous curve (when going in a negative direction around
|
|
19
19
|
* the shape boundary, i.e. clockwise for the outer shape and anti-clockwise
|
|
20
20
|
* for the holes (if any))
|
|
21
21
|
*/
|
|
22
|
-
prev
|
|
22
|
+
prev: Curve;
|
|
23
23
|
/**
|
|
24
24
|
* The next curve (when going in a positive direction around
|
|
25
25
|
* the shape boundary, i.e. anti-clockwise for the outer shape and clockwise
|
|
26
26
|
* for the holes (if any))
|
|
27
27
|
*/
|
|
28
|
-
next
|
|
28
|
+
next: Curve;
|
|
29
29
|
/**
|
|
30
30
|
* The curve's ordered index in the loop. This imposes a cycling
|
|
31
31
|
* ordering of the curves in the loop
|
|
32
32
|
*/
|
|
33
|
-
idx
|
|
33
|
+
idx: number;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
|
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
import { drawFs } from 'flo-draw';
|
|
2
|
-
import { TwoProngForDebugging } from '../../two-prong-for-debugging.js';
|
|
3
|
-
import { getTwoProngType } from '../../../mat/get-two-prong-type.js';
|
|
1
|
+
// import { drawFs } from 'flo-draw';
|
|
2
|
+
// import { TwoProngForDebugging } from '../../two-prong-for-debugging.js';
|
|
3
|
+
// import { getTwoProngType } from '../../../mat/get-two-prong-type.js';
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
/** @internal */
|
|
7
|
-
function twoProng(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
// /** @internal */
|
|
7
|
+
// function twoProng(
|
|
8
|
+
// g: SVGGElement,
|
|
9
|
+
// twoProng: TwoProngForDebugging,
|
|
10
|
+
// classes?: string,
|
|
11
|
+
// delay = 0,
|
|
12
|
+
// scaleFactor = 1) {
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
// let $failedDot : SVGElement[] = [];
|
|
15
|
+
// let $center : SVGElement[] = [];
|
|
16
|
+
// let $circle : SVGElement[] = [];
|
|
17
|
+
// let $cp1 : SVGElement[] = [];
|
|
18
|
+
// let $cp2 : SVGElement[] = [];
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
// let color;
|
|
21
|
+
// let thin;
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
// switch (getTwoProngType(twoProng)) {
|
|
24
|
+
// case 'twoProng_regular': {
|
|
25
|
+
// color = 'red ';
|
|
26
|
+
// thin = '2';
|
|
27
|
+
// break;
|
|
28
|
+
// }
|
|
29
|
+
// case 'twoProng_holeClosing': {
|
|
30
|
+
// color = 'cyan ';
|
|
31
|
+
// thin = '10';
|
|
32
|
+
// break;
|
|
33
|
+
// }
|
|
34
|
+
// }
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
// if (twoProng.failed) {
|
|
38
|
+
// $failedDot = drawFs.dot(g, twoProng.pos.p, 1*scaleFactor, 'black', delay);
|
|
39
|
+
// } else if (!twoProng.failed) {
|
|
40
|
+
// $center = drawFs.dot (g, twoProng.circle.center, 0.01*scaleFactor, 'yellow', delay);
|
|
41
|
+
// $circle = drawFs.circle(g, twoProng.circle, color + 'thin' + thin + ' nofill', delay);
|
|
42
|
+
// $cp1 = drawFs.dot (g, twoProng.pos.p, 0.0175*scaleFactor, color, delay);
|
|
43
|
+
// $cp2 = drawFs.dot (g, twoProng.z, 0.035*scaleFactor, color, delay);
|
|
44
|
+
// }
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
}
|
|
46
|
+
// return [...$failedDot, ...$center, ...$circle, ...$cp1, ...$cp2];
|
|
47
|
+
// }
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
export { twoProng }
|
|
50
|
+
// export { twoProng }
|