flo-mat 4.1.2 → 4.1.4
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__/find-2-prong/get-medial/dd-get-medial-point-coeffs-same-curve.spec.ts +1 -1
- package/__tests__/get-mats1.ts +23 -22
- package/__tests__/specific-cases/specific-cases.spec.ts +1 -14
- package/__tests__/specific-cases/test-svgs/achispado.svg +37 -24
- package/browser/index.js +408 -198
- package/browser/index.min.js +1 -1
- package/node/cp-node/fs/insert-cp-node.d.ts +12 -1
- package/node/cp-node/fs/insert-cp-node.js +21 -6
- package/node/cp-node/fs/insert-cp-node.js.map +1 -1
- package/node/cp-node/fs/is-order-correct.d.ts +9 -1
- package/node/cp-node/fs/is-order-correct.js +51 -10
- package/node/cp-node/fs/is-order-correct.js.map +1 -1
- package/node/cp-node/fs/remove-cp-node.js +1 -1
- package/node/cp-node/fs/remove-cp-node.js.map +1 -1
- package/node/cp-node/stringification/from-stringifyable.js +2 -1
- package/node/cp-node/stringification/from-stringifyable.js.map +1 -1
- package/node/cp-node/stringification/to-stringifyable.js +2 -2
- package/node/cp-node/stringification/to-stringifyable.js.map +1 -1
- package/node/debug/functions/check-ordering.d.ts +4 -0
- package/node/debug/functions/check-ordering.js +43 -0
- package/node/debug/functions/check-ordering.js.map +1 -0
- package/node/find-2-prong/add-2-prong.js +4 -2
- package/node/find-2-prong/add-2-prong.js.map +1 -1
- package/node/find-2-prong/find-and-add-2-prongs.js +1 -1
- package/node/find-2-prong/find-and-add-2-prongs.js.map +1 -1
- 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-3-prong/find-3-prong-for-delta3s.d.ts +1 -1
- package/node/find-3-prong/find-3-prong-for-delta3s.js.map +1 -1
- package/node/find-3-prong/find-3-prong.d.ts +1 -1
- package/node/find-3-prong/find-3-prong.js.map +1 -1
- package/node/find-3-prong/find-and-add-3-prong.js +1 -1
- package/node/find-3-prong/find-and-add-3-prong.js.map +1 -1
- package/node/find-3-prong/find-and-add-3-prongs-on-loop.d.ts +1 -1
- package/node/find-3-prong/find-and-add-3-prongs-on-loop.js +6 -2
- package/node/find-3-prong/find-and-add-3-prongs-on-loop.js.map +1 -1
- package/node/find-3-prong/three-prong-info.d.ts +1 -1
- package/node/find-mat/create-initial-cp-tree.js +2 -2
- package/node/find-mat/create-initial-cp-tree.js.map +1 -1
- package/node/find-mat/find-mat.js +2 -2
- package/node/find-mat/find-mat.js.map +1 -1
- package/node/find-mat/get-for-1-prongs-on-loop.js +3 -1
- package/node/find-mat/get-for-1-prongs-on-loop.js.map +1 -1
- package/node/mat/add-to-cp-tree.d.ts +4 -1
- package/node/mat/add-to-cp-tree.js +11 -4
- package/node/mat/add-to-cp-tree.js.map +1 -1
- package/node/mat/get-boundary-piece-beziers.d.ts +2 -2
- package/node/mat/get-boundary-piece-beziers.js +1 -1
- package/node/mat/get-boundary-piece-beziers.js.map +1 -1
- package/node/mat/get-closeby-cp-if-exist.js +2 -2
- package/node/mat/get-closeby-cp-if-exist.js.map +1 -1
- package/node/mat/{get-cp-node-to-left-or-same.d.ts → get-cp-node-neighbors.d.ts} +2 -2
- package/node/mat/get-cp-node-neighbors.js +31 -0
- package/node/mat/get-cp-node-neighbors.js.map +1 -0
- package/package.json +11 -11
- package/src/cp-node/fs/insert-cp-node.ts +22 -7
- package/src/cp-node/fs/is-order-correct copy.ts +60 -0
- package/src/cp-node/fs/is-order-correct.ts +61 -13
- package/src/cp-node/fs/remove-cp-node.ts +1 -1
- package/src/cp-node/stringification/from-stringifyable.ts +2 -1
- package/src/cp-node/stringification/to-stringifyable.ts +2 -2
- package/src/debug/functions/check-ordering.ts +44 -61
- package/src/find-2-prong/add-2-prong.ts +3 -1
- package/src/find-2-prong/find-and-add-2-prongs.ts +1 -1
- package/src/find-2-prong/get-initial-bezier-pieces.ts +2 -2
- package/src/find-3-prong/find-3-prong-for-delta3s.ts +14 -6
- package/src/find-3-prong/find-3-prong.ts +1 -1
- package/src/find-3-prong/find-and-add-3-prong.ts +1 -4
- package/src/find-3-prong/find-and-add-3-prongs-on-loop.ts +6 -3
- package/src/find-3-prong/three-prong-info.ts +1 -1
- package/src/find-mat/create-initial-cp-tree.ts +2 -2
- package/src/find-mat/find-mat.ts +3 -2
- package/src/find-mat/get-for-1-prongs-on-loop.ts +3 -1
- package/src/mat/add-to-cp-tree copy.ts +71 -0
- package/src/mat/add-to-cp-tree.ts +12 -4
- package/src/mat/get-boundary-piece-beziers.ts +2 -2
- package/src/mat/get-closeby-cp-if-exist.ts +2 -2
- package/src/mat/{get-cp-node-to-left-or-same.ts → get-cp-node-neighbors.ts} +12 -10
- package/node/mat/get-cp-node-to-left-or-same.js +0 -30
- package/node/mat/get-cp-node-to-left-or-same.js.map +0 -1
|
@@ -3,6 +3,9 @@ import type { PrePointOnShape } from '../point-on-shape/point-on-shape.js';
|
|
|
3
3
|
import type { CpNode } from '../cp-node/cp-node.js';
|
|
4
4
|
import type { MatMeta } from '../mat/mat-meta.js';
|
|
5
5
|
/**
|
|
6
|
+
* Insert the given `poss` into the `cpTree` (within `meta`) and returns the
|
|
7
|
+
* newly inserted `CpNode`s.
|
|
8
|
+
*
|
|
6
9
|
* @param circle
|
|
7
10
|
* @param orders
|
|
8
11
|
* @param cpTrees
|
|
@@ -11,7 +14,7 @@ import type { MatMeta } from '../mat/mat-meta.js';
|
|
|
11
14
|
*
|
|
12
15
|
* @internal
|
|
13
16
|
*/
|
|
14
|
-
declare function addToCpTree(insertIfOrderIsWrong: boolean, isHoleClosing: boolean, circle: Circle, orders: number[], meta: MatMeta, poss: PrePointOnShape[], neighbors?: CpNode[]): {
|
|
17
|
+
declare function addToCpTree(insertIfOrderIsWrong: boolean, isHoleClosing: boolean, circle: Circle, orders: number[], meta: MatMeta, poss: PrePointOnShape[], neighbors?: [CpNode, CpNode][]): {
|
|
15
18
|
anyFailed: boolean;
|
|
16
19
|
cpNodes: (CpNode | undefined)[];
|
|
17
20
|
};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getCpNodeNeighbors } from './get-cp-node-neighbors.js';
|
|
2
2
|
import { insertCpNode } from '../cp-node/fs/insert-cp-node.js';
|
|
3
3
|
import { joinSpokes } from '../add-n-prong.ts/join-spokes.js';
|
|
4
4
|
/**
|
|
5
|
+
* Insert the given `poss` into the `cpTree` (within `meta`) and returns the
|
|
6
|
+
* newly inserted `CpNode`s.
|
|
7
|
+
*
|
|
5
8
|
* @param circle
|
|
6
9
|
* @param orders
|
|
7
10
|
* @param cpTrees
|
|
@@ -17,10 +20,14 @@ function addToCpTree(insertIfOrderIsWrong, isHoleClosing, circle, orders, meta,
|
|
|
17
20
|
const order = orders[i];
|
|
18
21
|
const cpTree = cpTrees.get(ppos.curve.loop);
|
|
19
22
|
const pos = { ...ppos, circle, order, order2: 0 };
|
|
20
|
-
const
|
|
21
|
-
?
|
|
23
|
+
const r = neighbors === undefined
|
|
24
|
+
? getCpNodeNeighbors(cpTree, ppos, order, 0)
|
|
22
25
|
: neighbors[i];
|
|
23
|
-
const
|
|
26
|
+
const pred = r?.[0];
|
|
27
|
+
const succ = r?.[1];
|
|
28
|
+
const cpNode = insertCpNode(insertIfOrderIsWrong, isHoleClosing, false, cpTree, pos, pred,
|
|
29
|
+
// pred?.next,
|
|
30
|
+
succ, meta.lastInsertId);
|
|
24
31
|
if (cpNode === undefined) {
|
|
25
32
|
anyFailed = true;
|
|
26
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-to-cp-tree.js","sourceRoot":"","sources":["../../src/mat/add-to-cp-tree.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"add-to-cp-tree.js","sourceRoot":"","sources":["../../src/mat/add-to-cp-tree.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAG9D;;;;;;;;;;;GAWG;AACH,SAAS,WAAW,CACZ,oBAA6B,EAC7B,aAAsB,EACtB,MAAc,EACd,MAAgB,EAChB,IAAa,EACb,IAAuB,EACvB,SAA6B;IAEjC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAEzB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAC,CAAC,EAAE,EAAE;QAChC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC;QAC7C,MAAM,GAAG,GAAiB,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAEhE,MAAM,CAAC,GAAG,SAAS,KAAK,SAAS;YAC7B,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5C,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAEnB,MAAM,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAEpB,MAAM,MAAM,GAAG,YAAY,CACvB,oBAAoB,EACpB,aAAa,EACb,KAAK,EACL,MAAM,EACN,GAAG,EACH,IAAI;QACJ,cAAc;QACd,IAAI,EACJ,IAAI,CAAC,YAAY,CACpB,CAAC;QAEF,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAAC,SAAS,GAAG,IAAI,CAAC;QAAC,CAAC;QAE/C,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,UAAU,CAAC,MAAM,EAAE,OAAmB,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAClC,CAAC;AAGD,OAAO,EAAE,WAAW,EAAE,CAAA"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { CpNode } from '../cp-node/cp-node.js';
|
|
2
2
|
import type { CurvePiece } from './curve-piece.js';
|
|
3
3
|
/**
|
|
4
|
-
* Returns the ordered bezier pieces between
|
|
4
|
+
* Returns the ordered bezier pieces between the two given `CpNode`s.
|
|
5
5
|
*
|
|
6
6
|
* @param cpNodes - An ordered pair that represents the start and end points of
|
|
7
7
|
* the boundary piece
|
|
8
8
|
*
|
|
9
9
|
* @internal
|
|
10
10
|
*/
|
|
11
|
-
declare function getBoundaryPieceBeziers(cpNodes: CpNode
|
|
11
|
+
declare function getBoundaryPieceBeziers(cpNodes: [CpNode, CpNode]): CurvePiece[];
|
|
12
12
|
export { getBoundaryPieceBeziers };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { comparePoss } from '../point-on-shape/compare-poss.js';
|
|
2
2
|
/**
|
|
3
|
-
* Returns the ordered bezier pieces between
|
|
3
|
+
* Returns the ordered bezier pieces between the two given `CpNode`s.
|
|
4
4
|
*
|
|
5
5
|
* @param cpNodes - An ordered pair that represents the start and end points of
|
|
6
6
|
* the boundary piece
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-boundary-piece-beziers.js","sourceRoot":"","sources":["../../src/mat/get-boundary-piece-beziers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAGhE;;;;;;;GAOG;AACH,SAAS,uBAAuB,CACxB,
|
|
1
|
+
{"version":3,"file":"get-boundary-piece-beziers.js","sourceRoot":"","sources":["../../src/mat/get-boundary-piece-beziers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { distanceBetween, toUnitVector, fromTo, dot } from 'flo-vector2d';
|
|
2
|
-
import {
|
|
2
|
+
import { getCpNodeNeighbors } from './get-cp-node-neighbors.js';
|
|
3
3
|
/** @internal */
|
|
4
4
|
const DEGREES = 1;
|
|
5
5
|
const ANGLE_THRESHOLD = Math.cos(DEGREES * (Math.PI / 180));
|
|
@@ -19,7 +19,7 @@ function getCloseByCpIfExist(meta, pos, circle, order, order2, forProngCount) {
|
|
|
19
19
|
const DISTANCE_THRESHOLD = 2 ** (maxCoordPowerOf2 - 40); // approx. 1e-9 for 1024 x 1024 shapes
|
|
20
20
|
const DISTANCE_THRESHOLD_2 = 2 ** (maxCoordPowerOf2 - 46);
|
|
21
21
|
const cpTree = cpTrees.get(pos.curve.loop);
|
|
22
|
-
const cur =
|
|
22
|
+
const cur = getCpNodeNeighbors(cpTree, pos, order, order2)?.[0];
|
|
23
23
|
if (!cur) {
|
|
24
24
|
return undefined;
|
|
25
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-closeby-cp-if-exist.js","sourceRoot":"","sources":["../../src/mat/get-closeby-cp-if-exist.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"get-closeby-cp-if-exist.js","sourceRoot":"","sources":["../../src/mat/get-closeby-cp-if-exist.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGhE,gBAAgB;AAChB,MAAM,OAAO,GAAG,CAAC,CAAC;AAClB,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;AAG5D;;;;;;;;;;GAUG;AACH,SAAS,mBAAmB,CACpB,IAAa,EACb,GAAoB,EACpB,MAAc,EACd,KAAa,EACb,MAAc,EACd,aAAsB;IAE1B,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;IAE3C,MAAM,kBAAkB,GAAG,CAAC,IAAE,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC,CAAE,sCAAsC;IAC9F,MAAM,oBAAoB,GAAG,CAAC,IAAE,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC;IAExD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC;IAC5C,MAAM,GAAG,GAAG,kBAAkB,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAChE,IAAI,CAAC,GAAG,EAAE,CAAC;QAAC,OAAO,SAAS,CAAC;IAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAEhC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC;IACrB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC;QACjC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;QAClB,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,EAAC,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,kBAAkB,EAAE,CAAC;YACzB,SAAS;QACb,CAAC;QACD,iBAAiB;QAEjB,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACvE,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,EAAC,EAAE,CAAC,CAAC;QAE5B,IAAI,QAAQ,GAAG,eAAe;YAC1B,CAAC,CAAC,GAAG,oBAAoB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAEnD,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;gBACtB,4BAA4B;gBAC5B,kBAAkB;gBAClB,uCAAuC;gBACvC,qBAAqB;YACzB,CAAC;YACD,OAAO,MAAM,CAAC;QAClB,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACrB,CAAC;AAGD,OAAO,EAAE,mBAAmB,EAAE,CAAA"}
|
|
@@ -14,5 +14,5 @@ import { RbTree } from 'flo-ll-rb-tree';
|
|
|
14
14
|
* @param order
|
|
15
15
|
* @param order2
|
|
16
16
|
*/
|
|
17
|
-
declare function
|
|
18
|
-
export {
|
|
17
|
+
declare function getCpNodeNeighbors(cpTree: RbTree<CpNode>, pos: PrePointOnShape, order: number, order2: number): [CpNode, CpNode] | undefined;
|
|
18
|
+
export { getCpNodeNeighbors };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal
|
|
3
|
+
*
|
|
4
|
+
* Returns the predecessor `CpNode` in the `CpTree` or the same one if they fall
|
|
5
|
+
* on top of each other.
|
|
6
|
+
*
|
|
7
|
+
* * returns `undefined` if the tree is still empty
|
|
8
|
+
*
|
|
9
|
+
* @param cpTree
|
|
10
|
+
* @param pos
|
|
11
|
+
* @param order
|
|
12
|
+
* @param order2
|
|
13
|
+
*/
|
|
14
|
+
function getCpNodeNeighbors(cpTree, pos, order, order2) {
|
|
15
|
+
const pointOnShape = { ...pos, order, order2 };
|
|
16
|
+
const cps = cpTree.findBounds({ pointOnShape });
|
|
17
|
+
const [cp0, cp1] = cps;
|
|
18
|
+
if (cp0 === undefined && cp1 === undefined) {
|
|
19
|
+
// The tree is still empty
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
if (cp0 === undefined || cp1 === undefined) {
|
|
23
|
+
// Smaller than all OR larger than all
|
|
24
|
+
const minNode = cpTree.getMinNode()?.datum;
|
|
25
|
+
const maxNode = cpTree.getMaxNode()?.datum;
|
|
26
|
+
return [maxNode, minNode];
|
|
27
|
+
}
|
|
28
|
+
return [cp0.datum, cp1.datum];
|
|
29
|
+
}
|
|
30
|
+
export { getCpNodeNeighbors };
|
|
31
|
+
//# sourceMappingURL=get-cp-node-neighbors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-cp-node-neighbors.js","sourceRoot":"","sources":["../../src/mat/get-cp-node-neighbors.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,SAAS,kBAAkB,CACnB,MAAsB,EACtB,GAAoB,EACpB,KAAa,EACb,MAAc;IAElB,MAAM,YAAY,GAAG,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC/C,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,EAAE,YAAY,EAAY,CAAC,CAAC;IAC1D,MAAM,CAAC,GAAG,EAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAEtB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACzC,0BAA0B;QAC1B,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACzC,sCAAsC;QACtC,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,EAAE,KAAM,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,EAAE,KAAM,CAAC;QAE5C,OAAO,CAAC,OAAO,EAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAGD,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
|
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": "4.1.
|
|
5
|
+
"version": "4.1.4",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Floris Steenkamp"
|
|
8
8
|
},
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"big-float-ts": "^4.0.4",
|
|
35
35
|
"double-double": "^3.0.4",
|
|
36
|
-
"flo-bezier3": "^8.
|
|
36
|
+
"flo-bezier3": "^8.1.1",
|
|
37
37
|
"flo-boolean": "^6.0.2",
|
|
38
38
|
"flo-gauss-quadrature": "^2.1.4",
|
|
39
|
-
"flo-ll-rb-tree": "^1.0.
|
|
39
|
+
"flo-ll-rb-tree": "^1.0.4",
|
|
40
40
|
"flo-memoize": "^2.0.1",
|
|
41
41
|
"flo-poly": "^8.1.4",
|
|
42
42
|
"flo-vector2d": "^4.0.6"
|
|
@@ -44,20 +44,20 @@
|
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"squares-rng": "^2.0.4",
|
|
46
46
|
"@jest/globals": "^30.5.1",
|
|
47
|
-
"@swc/core": "^1.16.
|
|
47
|
+
"@swc/core": "^1.16.2",
|
|
48
48
|
"@swc/jest": "^0.2.39",
|
|
49
49
|
"@types/jest": "^30.0.0",
|
|
50
|
-
"
|
|
50
|
+
"jest": "^30.5.1",
|
|
51
|
+
"jest-ts-webcompat-resolver": "^1.0.1",
|
|
52
|
+
"ts-node": "^10.9.2",
|
|
53
|
+
"@types/node": "^26.6.0",
|
|
51
54
|
"c8": "^12.0.0",
|
|
52
55
|
"cheerio": "^1.2.0",
|
|
53
56
|
"circular-dependency-plugin": "^5.2.2",
|
|
54
|
-
"jest": "^30.5.1",
|
|
55
|
-
"jest-ts-webcompat-resolver": "^1.0.1",
|
|
56
57
|
"rimraf": "^6.1.3",
|
|
57
58
|
"ts-loader": "^9.6.2",
|
|
58
|
-
"ts-node": "^10.9.2",
|
|
59
59
|
"typescript": "^6.0.3",
|
|
60
|
-
"webpack": "^5.
|
|
60
|
+
"webpack": "^5.111.0",
|
|
61
61
|
"webpack-cli": "^7.2.3"
|
|
62
62
|
},
|
|
63
63
|
"scripts": {
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
"test-package": "npm pack"
|
|
69
69
|
},
|
|
70
70
|
"allowScripts": {
|
|
71
|
-
"@swc/core@1.16.1": true,
|
|
72
71
|
"unrs-resolver@1.12.2": true,
|
|
73
|
-
"@parcel/watcher@2.6.0": true
|
|
72
|
+
"@parcel/watcher@2.6.0": true,
|
|
73
|
+
"@swc/core@1.16.2": true
|
|
74
74
|
}
|
|
75
75
|
}
|
|
@@ -5,19 +5,34 @@ import { RbTree } from "flo-ll-rb-tree";
|
|
|
5
5
|
import { isOrderCorrect } from "./is-order-correct.js";
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param insertIfOrderWrong order cannot be checked for hole-closers since they're on different loops
|
|
11
|
+
* @param isHoleClosing
|
|
12
|
+
* @param isIntersection
|
|
13
|
+
* @param cpTree
|
|
14
|
+
* @param pos
|
|
15
|
+
* @param pred predecessor (to `pos`) on sampe loop (found via `cpTree`)
|
|
16
|
+
* @param succ successor (to `pos`) on sampe loop (found via `cpTree`)
|
|
17
|
+
* @param lastInsertId
|
|
18
|
+
*/
|
|
8
19
|
function insertCpNode(
|
|
9
20
|
insertIfOrderWrong: boolean,
|
|
10
21
|
isHoleClosing: boolean,
|
|
11
22
|
isIntersection: boolean,
|
|
12
23
|
cpTree: RbTree<CpNode>,
|
|
13
24
|
pos: PointOnShape,
|
|
14
|
-
|
|
25
|
+
pred: CpNode | undefined,
|
|
26
|
+
succ: CpNode | undefined,
|
|
15
27
|
lastInsertId: { id: number }): CpNode | undefined {
|
|
16
28
|
|
|
17
|
-
if (
|
|
18
|
-
!isOrderCorrect(cpTree, pos,
|
|
19
|
-
|
|
20
|
-
if (!
|
|
29
|
+
if (pred !== undefined && succ !== undefined) {
|
|
30
|
+
// !isOrderCorrect(cpTree, pos, pred.next, false)) {
|
|
31
|
+
const orderCorrect = isOrderCorrect(cpTree, pred, pos, succ, false);
|
|
32
|
+
// if (!orderCorrect) {
|
|
33
|
+
// console.log('aaaaa');
|
|
34
|
+
// }
|
|
35
|
+
if (!insertIfOrderWrong && !orderCorrect) {
|
|
21
36
|
return undefined;
|
|
22
37
|
}
|
|
23
38
|
}
|
|
@@ -34,8 +49,8 @@ function insertCpNode(
|
|
|
34
49
|
};
|
|
35
50
|
lastInsertId.id++;
|
|
36
51
|
|
|
37
|
-
const prev =
|
|
38
|
-
const next =
|
|
52
|
+
const prev = pred === undefined ? cpNode : pred;
|
|
53
|
+
const next = pred === undefined ? cpNode : prev.next;
|
|
39
54
|
|
|
40
55
|
(next as Mutable<CpNode>).prev = cpNode;
|
|
41
56
|
(prev as Mutable<CpNode>).next = cpNode;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { CpNode } from "../cp-node.js";
|
|
2
|
+
import { RbTree } from "flo-ll-rb-tree";
|
|
3
|
+
import { PointOnShape } from "../../point-on-shape/point-on-shape.js";
|
|
4
|
+
import { comparePoss } from "../../point-on-shape/compare-poss.js";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param cpTree
|
|
10
|
+
* @param pos
|
|
11
|
+
* @param succ
|
|
12
|
+
* @param alreadyInserted set to `true` if the given `pos` has already been
|
|
13
|
+
* inserted, `false` otherwise.
|
|
14
|
+
*/
|
|
15
|
+
function isOrderCorrect(
|
|
16
|
+
cpTree: RbTree<CpNode>,
|
|
17
|
+
pred: CpNode,
|
|
18
|
+
pos: PointOnShape,
|
|
19
|
+
succ: CpNode,
|
|
20
|
+
alreadyInserted: boolean): boolean {
|
|
21
|
+
|
|
22
|
+
if (cpTree.size <= (alreadyInserted ? 2 : 1)) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const c = comparePoss(pos, succ.pointOnShape);
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if (c < 0) { return true; }
|
|
30
|
+
if (c === 0) { return false; }
|
|
31
|
+
|
|
32
|
+
const minNode = cpTree.getMinNode()!.datum;
|
|
33
|
+
const maxNode = cpTree.getMaxNode()!.datum;
|
|
34
|
+
|
|
35
|
+
// larger than all -> crossing zero on loop
|
|
36
|
+
const largerThanAll = comparePoss(pos, maxNode.pointOnShape!) >= 0;
|
|
37
|
+
const r =
|
|
38
|
+
largerThanAll &&
|
|
39
|
+
minNode === succ;
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
// const r = (pos === max.pointOnShape) && (next === min);
|
|
43
|
+
|
|
44
|
+
if (!r) {
|
|
45
|
+
console.log(c);
|
|
46
|
+
console.log(cpTree.toArr().map(v => {
|
|
47
|
+
return {
|
|
48
|
+
curveIdx: v.pointOnShape.curve.idx,
|
|
49
|
+
t: v.pointOnShape.t,
|
|
50
|
+
order: v.pointOnShape.order,
|
|
51
|
+
order2: v.pointOnShape.order2
|
|
52
|
+
}
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return r;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
export { isOrderCorrect }
|
|
@@ -4,27 +4,75 @@ import { PointOnShape } from "../../point-on-shape/point-on-shape.js";
|
|
|
4
4
|
import { comparePoss } from "../../point-on-shape/compare-poss.js";
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param cpTree
|
|
10
|
+
* @param pos
|
|
11
|
+
* @param succ
|
|
12
|
+
* @param alreadyInserted set to `true` if the given `pos` has already been
|
|
13
|
+
* inserted, `false` otherwise.
|
|
14
|
+
*/
|
|
7
15
|
function isOrderCorrect(
|
|
8
16
|
cpTree: RbTree<CpNode>,
|
|
17
|
+
pred: CpNode,
|
|
9
18
|
pos: PointOnShape,
|
|
10
|
-
|
|
19
|
+
succ: CpNode,
|
|
20
|
+
alreadyInserted: boolean): boolean {
|
|
11
21
|
|
|
12
|
-
|
|
13
|
-
if (c < 0) { return true; }
|
|
14
|
-
if (c === 0) {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const minNode = cpTree.getMinNode();
|
|
19
|
-
if (minNode === undefined) { // if tree not empty
|
|
22
|
+
if (cpTree.size <= (alreadyInserted ? 2 : 1)) {
|
|
20
23
|
return true;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
const
|
|
24
|
-
const
|
|
26
|
+
const a = pred.pointOnShape;
|
|
27
|
+
const b = pos;
|
|
28
|
+
const c = succ.pointOnShape;
|
|
29
|
+
|
|
30
|
+
// Let a = pred, b = pos, and c = succ.
|
|
31
|
+
// For a cyclic order we need:
|
|
32
|
+
// `(a < b && b < c)` || `(b < c && c < a)` || `(c < a && a < b)`
|
|
33
|
+
// Let `X = a < b, Y = b < c, Z = c < a` then
|
|
34
|
+
// `(X && Y)` || `(Y && Z)` || `(Z && X)`
|
|
35
|
+
|
|
36
|
+
const _X = comparePoss(a, b);
|
|
37
|
+
if (_X === 0) { // two points must have different order
|
|
38
|
+
// console.log('aaa');
|
|
39
|
+
// throw 'a';
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const _Y = comparePoss(b, c);
|
|
43
|
+
if (_Y === 0) { // two points must have different order
|
|
44
|
+
// console.log('bbb');
|
|
45
|
+
// throw 'b';
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const _Z = comparePoss(c, a);
|
|
49
|
+
if (_Z === 0) {
|
|
50
|
+
// console.log('bbb');
|
|
51
|
+
// throw 'c';
|
|
52
|
+
return false;
|
|
53
|
+
} // impossible anyway at this point
|
|
54
|
+
|
|
55
|
+
// Now neither `_X` nor `_Y` nor `_Z` === `0`
|
|
56
|
+
const X = _X < 0;
|
|
57
|
+
const Y = _Y < 0;
|
|
58
|
+
const Z = _Z < 0;
|
|
59
|
+
|
|
60
|
+
// Cyclic order condition
|
|
61
|
+
if ((X && Y) || (Y && Z) || (Z && X)) { return true; }
|
|
62
|
+
|
|
63
|
+
// throw 'd';
|
|
64
|
+
|
|
65
|
+
// console.log(_X, _Y, _Z);
|
|
66
|
+
// console.log(cpTree.toArr().map(v => {
|
|
67
|
+
// return {
|
|
68
|
+
// curveIdx: v.pointOnShape.curve.idx,
|
|
69
|
+
// t: v.pointOnShape.t,
|
|
70
|
+
// order: v.pointOnShape.order,
|
|
71
|
+
// order2: v.pointOnShape.order2
|
|
72
|
+
// }
|
|
73
|
+
// }));
|
|
25
74
|
|
|
26
|
-
|
|
27
|
-
return (comparePoss(max.pointOnShape!, pos) < 0 && min === next);
|
|
75
|
+
return false;
|
|
28
76
|
}
|
|
29
77
|
|
|
30
78
|
|
|
@@ -10,6 +10,7 @@ function fromStringifyable(
|
|
|
10
10
|
|
|
11
11
|
const { cpNodes: _cpNodes, loops: _loops } = cpNodesStringifyable;
|
|
12
12
|
const loops = _loops.map(loopFromStringifyable);
|
|
13
|
+
const loopsByIdx = new Map(loops.map(loop => [loop.idx, loop]));
|
|
13
14
|
|
|
14
15
|
//--------------------------------------------------------------------------
|
|
15
16
|
// First pass: build all CpNode objects with proper `cp`.
|
|
@@ -20,7 +21,7 @@ function fromStringifyable(
|
|
|
20
21
|
const { circle, order, order2 } = pointOnShape;
|
|
21
22
|
const { curveIdx, loopIdx, p, pDd, t, isSource } = pointOnShape;
|
|
22
23
|
|
|
23
|
-
const curve =
|
|
24
|
+
const curve = loopsByIdx.get(loopIdx)!.curves[curveIdx];
|
|
24
25
|
|
|
25
26
|
const pointOnShape_: PointOnShape = {
|
|
26
27
|
circle,
|
|
@@ -35,8 +35,8 @@ function toStringifyable(
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
const posSimplified: PointOnShapeSimplified = {
|
|
38
|
-
curveIdx, loopIdx: loop.idx!, p, t, isSource,
|
|
39
|
-
circle, order, order2
|
|
38
|
+
curveIdx, loopIdx: loop.idx!, p, pDd, t, isSource,
|
|
39
|
+
circle, order, order2
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
cpNodes_.push({
|
|
@@ -4,7 +4,18 @@ import { CpNode } from "../../cp-node/cp-node.js";
|
|
|
4
4
|
import { getAllOnLoop } from "../../cp-node/fs/get-all-on-loop.js";
|
|
5
5
|
import { getProngCount } from "../../cp-node/fs/get-prong-count.js";
|
|
6
6
|
import { isOrderCorrect } from "../../cp-node/fs/is-order-correct.js";
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
interface Order {
|
|
10
|
+
prongCount: number;
|
|
11
|
+
cpNode: CpNode;
|
|
12
|
+
p: number[];
|
|
13
|
+
/** From highest to lowest significance */
|
|
14
|
+
curveIdx: number;
|
|
15
|
+
t: number;
|
|
16
|
+
order: number;
|
|
17
|
+
order2: number;
|
|
18
|
+
}
|
|
8
19
|
|
|
9
20
|
|
|
10
21
|
function checkOrdering(
|
|
@@ -16,81 +27,53 @@ function checkOrdering(
|
|
|
16
27
|
const cpNodes = getAllOnLoop(cpStart);
|
|
17
28
|
|
|
18
29
|
const wrongsPerLoop: Map<Loop,[Order,Order][]> = new Map();
|
|
19
|
-
for (const
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
// const loopB = posB.curve.loop;
|
|
32
|
-
// const cpTreeB = cpTrees.get(loopB)!;
|
|
33
|
-
|
|
30
|
+
for (const cpNode of cpNodes) {
|
|
31
|
+
const pos = cpNode.pointOnShape;
|
|
32
|
+
const loop = pos.curve.loop;
|
|
33
|
+
|
|
34
|
+
if (loop !== cpNode.prev.pointOnShape.curve.loop ||
|
|
35
|
+
loop !== cpNode.next.pointOnShape.curve.loop) {
|
|
36
|
+
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const cpTree = cpTrees.get(loop)!;
|
|
41
|
+
|
|
34
42
|
const orderCorrect = isOrderCorrect(
|
|
35
|
-
|
|
36
|
-
)
|
|
43
|
+
cpTree, cpNode.prev, cpNode.pointOnShape, cpNode.next, true
|
|
44
|
+
);
|
|
37
45
|
if (!orderCorrect) {
|
|
38
|
-
const A
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
curveIdx: idxA,
|
|
43
|
-
t: posA.t,
|
|
44
|
-
order: posA.order,
|
|
45
|
-
order2: posA.order2
|
|
46
|
-
}
|
|
47
|
-
const B: Order = {
|
|
48
|
-
prongCount: getProngCount(cpNodeB),
|
|
49
|
-
p: pB,
|
|
50
|
-
cpNode: cpNodeB,
|
|
51
|
-
curveIdx: idxB,
|
|
52
|
-
t: posB.t,
|
|
53
|
-
order: posB.order,
|
|
54
|
-
order2: posB.order2
|
|
55
|
-
}
|
|
56
|
-
const loopA = A.cpNode.pointOnShape.curve.loop;
|
|
57
|
-
let wrongs = wrongsPerLoop.get(loopA);
|
|
58
|
-
if (wrongs === undefined) {
|
|
59
|
-
wrongs = [];
|
|
60
|
-
wrongsPerLoop.set(loopA, wrongs);
|
|
61
|
-
}
|
|
46
|
+
const A = toOrder(cpNode);
|
|
47
|
+
const B = toOrder(cpNode.next);
|
|
48
|
+
|
|
49
|
+
let wrongs = wrongsPerLoop.getOrInsert(loop, []);
|
|
62
50
|
wrongs.push([A,B]);
|
|
63
51
|
}
|
|
64
52
|
}
|
|
65
53
|
|
|
66
54
|
for (const [loop,wrongs] of wrongsPerLoop) {
|
|
67
|
-
let maxOrder = -Infinity;
|
|
68
|
-
let max: Order | undefined = undefined;
|
|
69
55
|
for (const wrong of wrongs) {
|
|
70
56
|
const A = wrong[0];
|
|
71
57
|
const B = wrong[1];
|
|
72
|
-
const c = comparePoss(A.cpNode.pointOnShape, B.cpNode.pointOnShape);
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
// console.log(wrong[1]);
|
|
78
|
-
// console.log('---------');
|
|
58
|
+
// const c = comparePoss(A.cpNode.pointOnShape, B.cpNode.pointOnShape);
|
|
59
|
+
|
|
60
|
+
console.log(A);
|
|
61
|
+
console.log(B);
|
|
62
|
+
console.log('---------');
|
|
79
63
|
}
|
|
80
64
|
}
|
|
81
|
-
// }
|
|
82
65
|
}
|
|
83
66
|
|
|
84
67
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
order2
|
|
68
|
+
function toOrder(
|
|
69
|
+
cpNode: CpNode): Order {
|
|
70
|
+
|
|
71
|
+
const prongCount = getProngCount(cpNode);
|
|
72
|
+
const { pointOnShape } = cpNode;
|
|
73
|
+
const { p, t, order, order2, curve } = pointOnShape;
|
|
74
|
+
const curveIdx = curve.idx;
|
|
75
|
+
|
|
76
|
+
return { cpNode, prongCount, p, curveIdx, t, order, order2 };
|
|
94
77
|
}
|
|
95
78
|
|
|
96
79
|
|
|
@@ -90,6 +90,7 @@ function closeHole(
|
|
|
90
90
|
cpTrees.get(posAntipode.curve.loop)!,
|
|
91
91
|
{ ...posAntipode, order2: +1 },
|
|
92
92
|
cpNodeAntipode,
|
|
93
|
+
undefined, // unused
|
|
93
94
|
meta.lastInsertId
|
|
94
95
|
)! as Mutable<CpNode>;
|
|
95
96
|
cpNodeAntipodeTwin.holeCloserTwin = cpNodeAntipode;
|
|
@@ -100,8 +101,9 @@ function closeHole(
|
|
|
100
101
|
const cpNodeSourceTwin = insertCpNode(
|
|
101
102
|
true, true, false,
|
|
102
103
|
cpTrees.get(posSource.curve.loop)!,
|
|
103
|
-
{ ...
|
|
104
|
+
{ ...posSource!, order2: -1 },
|
|
104
105
|
cpNodeSource.prev,
|
|
106
|
+
undefined, // unused
|
|
105
107
|
meta.lastInsertId
|
|
106
108
|
)! as Mutable<CpNode>;
|
|
107
109
|
cpNodeSourceTwin.holeCloserTwin = cpNodeSource;
|
|
@@ -37,7 +37,7 @@ function findAndAdd2Prongs(
|
|
|
37
37
|
for (let i=0; i<for2Prongs.length; i++) {
|
|
38
38
|
const pos = for2Prongs[i];
|
|
39
39
|
|
|
40
|
-
const angles = getValidAngles(angleIncrement_, pos);
|
|
40
|
+
const angles = for1Prong ? [0] : getValidAngles(angleIncrement_, pos);
|
|
41
41
|
|
|
42
42
|
for (const angle of angles) {
|
|
43
43
|
const twoProngInfo = find2Prong_(
|