flo-mat 3.0.12 → 3.0.14
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 +188 -50
- package/browser/index.min.js +1 -1
- package/node/cp-node/cp-node-fs.d.ts +4 -4
- package/node/cp-node/cp-node-fs.js +4 -4
- package/node/cp-node/cp-node.d.ts +8 -10
- package/node/cp-node/fs/clone.d.ts +1 -1
- package/node/cp-node/fs/clone.js +14 -10
- package/node/cp-node/fs/clone.js.map +1 -1
- package/node/cp-node/fs/cp-node-comparator.d.ts +6 -0
- package/node/cp-node/fs/cp-node-comparator.js +6 -0
- package/node/cp-node/fs/cp-node-comparator.js.map +1 -1
- package/node/cp-node/fs/enhance-cp-node.d.ts +5 -2
- package/node/cp-node/fs/enhance-cp-node.js +4 -0
- package/node/cp-node/fs/enhance-cp-node.js.map +1 -1
- package/node/cp-node/fs/get-all-on-circle.d.ts +4 -4
- package/node/cp-node/fs/get-all-on-circle.js +4 -4
- package/node/cp-node/fs/get-all-on-loop.d.ts +4 -0
- package/node/cp-node/fs/get-all-on-loop.js +4 -0
- package/node/cp-node/fs/get-all-on-loop.js.map +1 -1
- package/node/cp-node/fs/get-boundary-bezier-parts-to-next.d.ts +5 -4
- package/node/cp-node/fs/get-boundary-bezier-parts-to-next.js +5 -4
- package/node/cp-node/fs/get-boundary-bezier-parts-to-next.js.map +1 -1
- package/node/cp-node/fs/get-boundary-beziers-to-next.d.ts +4 -8
- package/node/cp-node/fs/get-boundary-beziers-to-next.js +4 -8
- package/node/cp-node/fs/get-boundary-beziers-to-next.js.map +1 -1
- package/node/cp-node/fs/get-children.d.ts +6 -0
- package/node/cp-node/fs/get-children.js +6 -0
- package/node/cp-node/fs/get-children.js.map +1 -1
- package/node/cp-node/fs/get-edge-direction.d.ts +6 -0
- package/node/cp-node/fs/get-edge-direction.js +6 -0
- package/node/cp-node/fs/get-edge-direction.js.map +1 -1
- package/node/cp-node/fs/get-first-exit.d.ts +4 -0
- package/node/cp-node/fs/get-first-exit.js +4 -0
- package/node/cp-node/fs/get-first-exit.js.map +1 -1
- package/node/cp-node/fs/get-mat-curve-between.d.ts +6 -0
- package/node/cp-node/fs/get-mat-curve-between.js +6 -0
- package/node/cp-node/fs/get-mat-curve-between.js.map +1 -1
- package/node/cp-node/fs/get-mat-curve-to-next.d.ts +6 -0
- package/node/cp-node/fs/get-mat-curve-to-next.js +6 -0
- package/node/cp-node/fs/get-mat-curve-to-next.js.map +1 -1
- package/node/cp-node/fs/get-prong-count.d.ts +8 -0
- package/node/cp-node/fs/get-prong-count.js +8 -0
- package/node/cp-node/fs/get-prong-count.js.map +1 -1
- package/node/cp-node/fs/get-real-prong-count.d.ts +6 -0
- package/node/cp-node/fs/get-real-prong-count.js +6 -0
- package/node/cp-node/fs/get-real-prong-count.js.map +1 -1
- package/node/cp-node/fs/get-vertex-forward-children.d.ts +8 -0
- package/node/cp-node/fs/get-vertex-forward-children.js +8 -0
- package/node/cp-node/fs/get-vertex-forward-children.js.map +1 -1
- package/node/cp-node/fs/is-fully-terminating.d.ts +2 -5
- package/node/cp-node/fs/is-fully-terminating.js +2 -5
- package/node/cp-node/fs/is-fully-terminating.js.map +1 -1
- package/node/cp-node/fs/is-on-same-circle.d.ts +6 -0
- package/node/cp-node/fs/is-on-same-circle.js +6 -0
- package/node/cp-node/fs/is-on-same-circle.js.map +1 -1
- package/node/cp-node/fs/is-one-prong.d.ts +8 -0
- package/node/cp-node/fs/is-one-prong.js +8 -0
- package/node/cp-node/fs/is-one-prong.js.map +1 -1
- package/node/cp-node/fs/is-order-correct.d.ts +1 -1
- package/node/cp-node/fs/is-order-correct.js +1 -4
- package/node/cp-node/fs/is-order-correct.js.map +1 -1
- package/node/cp-node/fs/is-sharp.d.ts +7 -0
- package/node/cp-node/fs/is-sharp.js +7 -0
- package/node/cp-node/fs/is-sharp.js.map +1 -1
- package/node/cp-node/fs/is-special.d.ts +1 -1
- package/node/cp-node/fs/is-special.js +1 -3
- package/node/cp-node/fs/is-special.js.map +1 -1
- package/node/cp-node/fs/is-terminating.d.ts +22 -0
- package/node/cp-node/fs/is-terminating.js +22 -0
- package/node/cp-node/fs/is-terminating.js.map +1 -1
- package/node/cp-node/fs/traverse-cp.d.ts +9 -0
- package/node/cp-node/fs/traverse-cp.js +9 -0
- package/node/cp-node/fs/traverse-cp.js.map +1 -1
- package/node/cp-node/fs/traverse-edges.d.ts +7 -0
- package/node/cp-node/fs/traverse-edges.js +7 -0
- package/node/cp-node/fs/traverse-edges.js.map +1 -1
- package/node/cp-node/fs/traverse-vertices.d.ts +9 -0
- package/node/cp-node/fs/traverse-vertices.js +9 -0
- package/node/cp-node/fs/traverse-vertices.js.map +1 -1
- package/node/find-2-prong/add-2-prong.js +5 -3
- package/node/find-2-prong/add-2-prong.js.map +1 -1
- package/node/floyd-warshall/get-graph.d.ts +1 -1
- package/node/floyd-warshall/get-graph.js +2 -2
- package/node/floyd-warshall/get-graph.js.map +1 -1
- package/node/floyd-warshall/get-hole-closer-pairs.d.ts +6 -1
- package/node/floyd-warshall/get-hole-closer-pairs.js +8 -0
- package/node/floyd-warshall/get-hole-closer-pairs.js.map +1 -1
- package/node/mat/add-to-cp-tree.js +1 -3
- package/node/mat/add-to-cp-tree.js.map +1 -1
- package/node/vertex/remove-vertex.d.ts +5 -0
- package/node/vertex/remove-vertex.js +5 -0
- package/node/vertex/remove-vertex.js.map +1 -1
- package/package.json +1 -1
- package/src/cp-node/cp-node-fs.ts +4 -4
- package/src/cp-node/cp-node.ts +8 -10
- package/src/cp-node/fs/clone.ts +20 -14
- package/src/cp-node/fs/cp-node-comparator.ts +6 -0
- package/src/cp-node/fs/enhance-cp-node.ts +4 -0
- package/src/cp-node/fs/get-all-on-circle.ts +4 -4
- package/src/cp-node/fs/get-all-on-loop.ts +5 -1
- package/src/cp-node/fs/get-boundary-bezier-parts-to-next.ts +6 -5
- package/src/cp-node/fs/get-boundary-beziers-to-next.ts +4 -8
- package/src/cp-node/fs/get-children.ts +6 -0
- package/src/cp-node/fs/get-edge-direction.ts +6 -0
- package/src/cp-node/fs/get-first-exit.ts +4 -0
- package/src/cp-node/fs/get-mat-curve-between.ts +6 -0
- package/src/cp-node/fs/get-mat-curve-to-next.ts +6 -0
- package/src/cp-node/fs/get-prong-count.ts +8 -0
- package/src/cp-node/fs/get-real-prong-count.ts +6 -0
- package/src/cp-node/fs/get-vertex-forward-children.ts +8 -0
- package/src/cp-node/fs/is-fully-terminating.ts +2 -5
- package/src/cp-node/fs/is-on-same-circle.ts +6 -0
- package/src/cp-node/fs/is-one-prong.ts +8 -0
- package/src/cp-node/fs/is-order-correct.ts +1 -4
- package/src/cp-node/fs/is-sharp.ts +7 -0
- package/src/cp-node/fs/is-special.ts +2 -3
- package/src/cp-node/fs/is-terminating.ts +22 -0
- package/src/cp-node/fs/traverse-cp.ts +9 -0
- package/src/cp-node/fs/traverse-edges.ts +7 -0
- package/src/cp-node/fs/traverse-vertices.ts +9 -0
- package/src/find-2-prong/add-2-prong.ts +4 -1
- package/src/floyd-warshall/get-graph.ts +3 -3
- package/src/floyd-warshall/get-hole-closer-pairs.ts +9 -1
- package/src/mat/add-to-cp-tree.ts +1 -2
- package/src/vertex/remove-vertex.ts +5 -0
- package/src/cp-node/fs/create-cp-node.ts +0 -21
package/browser/index.js
CHANGED
|
@@ -893,6 +893,10 @@ function floydWarshall(graph) {
|
|
|
893
893
|
// floydWarshall(graph);//?
|
|
894
894
|
|
|
895
895
|
;// ./src/cp-node/fs/get-all-on-loop.ts
|
|
896
|
+
/**
|
|
897
|
+
* Returns all `CpNode`s on the MAT that this `CpNode` is part of
|
|
898
|
+
* starting from the current one and going anti-clockwise around the shape.
|
|
899
|
+
*/
|
|
896
900
|
function getAllOnLoop(cpNode) {
|
|
897
901
|
const cpStart = cpNode;
|
|
898
902
|
const cpNodes = [cpStart];
|
|
@@ -6246,6 +6250,12 @@ const isPosSharpCorner = memoize((pos) => {
|
|
|
6246
6250
|
|
|
6247
6251
|
|
|
6248
6252
|
|
|
6253
|
+
/**
|
|
6254
|
+
* @internal
|
|
6255
|
+
* Returns a line segment of unit length starting in the given Vertex center and
|
|
6256
|
+
* pointing in the direction of the medial axis (viewed as a rooted tree).
|
|
6257
|
+
* @param cpNode
|
|
6258
|
+
*/
|
|
6249
6259
|
function getEdgeDirection(cpNode) {
|
|
6250
6260
|
const circleCenter = cpNode.cp.circle.center;
|
|
6251
6261
|
const cp1 = cpNode;
|
|
@@ -6296,6 +6306,12 @@ function getEdgeDirection(cpNode) {
|
|
|
6296
6306
|
const TOLERANCE_ADD_2PRONG = 0.01;
|
|
6297
6307
|
/** @internal */
|
|
6298
6308
|
const TOLERANCE_USE_LINE = 0.0001; // else cubic
|
|
6309
|
+
/**
|
|
6310
|
+
* Returns the bezier curve from the maximal disk of one `CpNode` to another
|
|
6311
|
+
* `CpNode`'s maximal disk.
|
|
6312
|
+
* @param cpNodeFrom
|
|
6313
|
+
* @param cpNodeTo
|
|
6314
|
+
*/
|
|
6299
6315
|
function getMatCurveBetween(cpNodeFrom, cpNodeTo) {
|
|
6300
6316
|
const fromCc = cpNodeFrom.cp.circle.center;
|
|
6301
6317
|
const fromL = getEdgeDirection(cpNodeFrom);
|
|
@@ -6344,6 +6360,12 @@ function getMatCurveBetween(cpNodeFrom, cpNodeTo) {
|
|
|
6344
6360
|
;// ./src/cp-node/fs/get-mat-curve-to-next.ts
|
|
6345
6361
|
|
|
6346
6362
|
|
|
6363
|
+
/**
|
|
6364
|
+
* Returns the bezier curve from the maximal disk of the given `CpNode` to the
|
|
6365
|
+
* next `CpNode`'s maximal disk and thus directly represents a piece of the
|
|
6366
|
+
* medial axis.
|
|
6367
|
+
* @param cpNode
|
|
6368
|
+
*/
|
|
6347
6369
|
function getMatCurveToNext(cpNode) {
|
|
6348
6370
|
return getMatCurveBetween(cpNode, cpNode.next);
|
|
6349
6371
|
}
|
|
@@ -6352,10 +6374,10 @@ const getMatCurveToNext$ = memoize(getMatCurveToNext);
|
|
|
6352
6374
|
|
|
6353
6375
|
;// ./src/cp-node/fs/get-all-on-circle.ts
|
|
6354
6376
|
/**
|
|
6355
|
-
*
|
|
6356
|
-
*
|
|
6357
|
-
* @param
|
|
6358
|
-
*
|
|
6377
|
+
* Return this (except if exclThis is truthy) and the the other CpNodes
|
|
6378
|
+
* around the maximal disk vertex circle in an anti-clockwise order.
|
|
6379
|
+
* @param exclThis If true the returned array does not include this
|
|
6380
|
+
* `CpNode`.
|
|
6359
6381
|
*/
|
|
6360
6382
|
function getAllOnCircle(cpNode, exclThis = false) {
|
|
6361
6383
|
const startCpNode = cpNode;
|
|
@@ -6370,6 +6392,28 @@ function getAllOnCircle(cpNode, exclThis = false) {
|
|
|
6370
6392
|
|
|
6371
6393
|
|
|
6372
6394
|
;// ./src/cp-node/fs/is-terminating.ts
|
|
6395
|
+
/**
|
|
6396
|
+
* Returns `true` if this `CpNode` is terminating, i.e. implies a leaf MAT
|
|
6397
|
+
* vertex.
|
|
6398
|
+
*
|
|
6399
|
+
* The following are some instances where this is the case:
|
|
6400
|
+
*
|
|
6401
|
+
* * Sharp corners.
|
|
6402
|
+
*
|
|
6403
|
+
* * Half of Hole-closers, i.e. `CpNode`s whose next `CpNode` is on a different
|
|
6404
|
+
* loop
|
|
6405
|
+
*
|
|
6406
|
+
* * Maximal disks with a single contact point.
|
|
6407
|
+
* Note, however, that even in these cases there are two contact points stored
|
|
6408
|
+
* (sitting 'on top' of each other) for the maximal disk. It can be seen as a
|
|
6409
|
+
* limiting case of a two-prong where the distance between two of the contact
|
|
6410
|
+
* points tend to zero. One point (represented by a `CpNode` of course) will
|
|
6411
|
+
* be terminating with the other point being its `next`, whereas the other
|
|
6412
|
+
* point will *not* be terminating and 'points' back into the shape.
|
|
6413
|
+
*
|
|
6414
|
+
* * Some 3-prongs may also become terminating if the Scale Axis Transform is
|
|
6415
|
+
* applied to the shape.
|
|
6416
|
+
*/
|
|
6373
6417
|
function isTerminating(cpNode) {
|
|
6374
6418
|
return cpNode === cpNode.next.prevOnCircle;
|
|
6375
6419
|
}
|
|
@@ -6378,6 +6422,12 @@ function isTerminating(cpNode) {
|
|
|
6378
6422
|
;// ./src/cp-node/fs/get-real-prong-count.ts
|
|
6379
6423
|
|
|
6380
6424
|
|
|
6425
|
+
/**
|
|
6426
|
+
* Returns the number of contact points (up to planar coordinates) on the
|
|
6427
|
+
* maximal disk circle implied by this `CpNode`.
|
|
6428
|
+
*
|
|
6429
|
+
* See also `getProngCount`.
|
|
6430
|
+
*/
|
|
6381
6431
|
function getRealProngCount(cpNode) {
|
|
6382
6432
|
const nonTerminatingCpNodes = getAllOnCircle(cpNode)
|
|
6383
6433
|
.filter(cpNode => !isTerminating(cpNode));
|
|
@@ -6467,11 +6517,8 @@ function memoizePrimitive(f) {
|
|
|
6467
6517
|
|
|
6468
6518
|
|
|
6469
6519
|
/**
|
|
6470
|
-
*
|
|
6471
|
-
*
|
|
6472
|
-
* `false` otherwise.
|
|
6473
|
-
*
|
|
6474
|
-
* @param cpNode
|
|
6520
|
+
* Like isTerminating() but only returns true if all cpNodes on the circle
|
|
6521
|
+
* (except this.prevOnCircle) is terminating.
|
|
6475
6522
|
*/
|
|
6476
6523
|
function isFullyTerminating(cpNode) {
|
|
6477
6524
|
const otherOnCircle = getAllOnCircle(cpNode.prevOnCircle, true);
|
|
@@ -6573,6 +6620,14 @@ function getCpNodeOrdering(cpNode) {
|
|
|
6573
6620
|
|
|
6574
6621
|
|
|
6575
6622
|
;// ./src/cp-node/fs/get-prong-count.ts
|
|
6623
|
+
/**
|
|
6624
|
+
* Returns the number of contact points on the maximal disk circle implied
|
|
6625
|
+
* by this `CpNode`.
|
|
6626
|
+
*
|
|
6627
|
+
* Note, however, that even one-prongs and sharp corners will return 2 (see
|
|
6628
|
+
* `isTerminating` for more details); if this is not desired use
|
|
6629
|
+
* `getRealProngCount` instead which will return 1 in these cases.
|
|
6630
|
+
*/
|
|
6576
6631
|
function getProngCount(cpNode) {
|
|
6577
6632
|
const startCpNode = cpNode;
|
|
6578
6633
|
let cpNode_ = startCpNode;
|
|
@@ -6586,6 +6641,13 @@ function getProngCount(cpNode) {
|
|
|
6586
6641
|
|
|
6587
6642
|
|
|
6588
6643
|
;// ./src/cp-node/fs/is-sharp.ts
|
|
6644
|
+
/**
|
|
6645
|
+
* Returns true if this `CpNode` represents a sharp corner, i.e. the
|
|
6646
|
+
* limiting case of a two-prong having zero radius.
|
|
6647
|
+
*
|
|
6648
|
+
* Note that two `CpNode`s are stored for each sharp corner, one being
|
|
6649
|
+
* terminating and one not. See `isTerminating` for more details.
|
|
6650
|
+
*/
|
|
6589
6651
|
function isSharp(cpNode) {
|
|
6590
6652
|
return cpNode.cp.circle.radius === 0;
|
|
6591
6653
|
}
|
|
@@ -6598,6 +6660,10 @@ function isSharp(cpNode) {
|
|
|
6598
6660
|
|
|
6599
6661
|
|
|
6600
6662
|
|
|
6663
|
+
/**
|
|
6664
|
+
* For debugging
|
|
6665
|
+
* @param cpNode
|
|
6666
|
+
*/
|
|
6601
6667
|
function enhanceCpNode(cpNode) {
|
|
6602
6668
|
const cp = cpNode.cp;
|
|
6603
6669
|
const pos = cp.pointOnShape;
|
|
@@ -6621,6 +6687,15 @@ function enhanceCpNode(cpNode) {
|
|
|
6621
6687
|
|
|
6622
6688
|
;// ./src/cp-node/fs/traverse-cp.ts
|
|
6623
6689
|
|
|
6690
|
+
/**
|
|
6691
|
+
* @internal
|
|
6692
|
+
*
|
|
6693
|
+
* Traverses the shape from the given `CpNode` going around the shortest path
|
|
6694
|
+
* so that only a piece of the shape is traversed and returns the visited
|
|
6695
|
+
* `CpNode`s (starting from the given `CpNode`).
|
|
6696
|
+
*
|
|
6697
|
+
* @param cpStart The `CpNode` from where to start the traversal.
|
|
6698
|
+
*/
|
|
6624
6699
|
function traverseCp(cpStart) {
|
|
6625
6700
|
let cpNode = cpStart;
|
|
6626
6701
|
if (isTerminating(cpNode)) {
|
|
@@ -6641,6 +6716,13 @@ function traverseCp(cpStart) {
|
|
|
6641
6716
|
;// ./src/cp-node/fs/traverse-edges.ts
|
|
6642
6717
|
|
|
6643
6718
|
|
|
6719
|
+
/**
|
|
6720
|
+
* Traverses all edges (depth first) of the given MAT tree starting at the given
|
|
6721
|
+
* vertex (represented by a `CpNode`).
|
|
6722
|
+
* @param cpNode Any `CpNode` representing the start vertex.
|
|
6723
|
+
* @param traverseEdgesCallback A callback function for each CpNode representing the vertex at the
|
|
6724
|
+
* start of an edge.
|
|
6725
|
+
*/
|
|
6644
6726
|
function traverseEdges(cpNode, traverseEdgesCallback) {
|
|
6645
6727
|
const cpNodes = getAllOnLoop(cpNode);
|
|
6646
6728
|
const seen = new Set();
|
|
@@ -6655,6 +6737,14 @@ function traverseEdges(cpNode, traverseEdgesCallback) {
|
|
|
6655
6737
|
|
|
6656
6738
|
;// ./src/cp-node/fs/get-vertex-forward-children.ts
|
|
6657
6739
|
|
|
6740
|
+
/**
|
|
6741
|
+
* Similar to `getChildren` but returns the child nodes of the tree when
|
|
6742
|
+
* `CpNode` is seen as a MAT vertex point (as opposed to edge). In this
|
|
6743
|
+
* way the dual graph of the tree can easily be traversed - see e.g.
|
|
6744
|
+
* `traverseVertices`. Generally, however, traversing the edges is
|
|
6745
|
+
* preferred as it returns the entire Medial Axis (by utilizing
|
|
6746
|
+
* `getMatCurveToNext` on each returned edge).
|
|
6747
|
+
*/
|
|
6658
6748
|
function getVertexForwardChildren(cpNode) {
|
|
6659
6749
|
const children = [];
|
|
6660
6750
|
const cpStart = cpNode;
|
|
@@ -6673,6 +6763,15 @@ function getVertexForwardChildren(cpNode) {
|
|
|
6673
6763
|
|
|
6674
6764
|
|
|
6675
6765
|
|
|
6766
|
+
/**
|
|
6767
|
+
* Traverses the MAT tree and calls the given callback function for each vertex
|
|
6768
|
+
* (represented by a `CpNode`) on the MAT.
|
|
6769
|
+
*
|
|
6770
|
+
* It is usually preferable to use `traverseEdges` as it allows for the
|
|
6771
|
+
* traversal of all the smooth curves representing the MAT.
|
|
6772
|
+
* @param cpNode Any `CpNode` representing the start vertex.
|
|
6773
|
+
* @param traverseVerticesCallback A callback function taking a single `CpNode` as parameter.
|
|
6774
|
+
*/
|
|
6676
6775
|
function traverseVertices(cpStart, traverseVerticesCallback) {
|
|
6677
6776
|
traverseVerticesCallback(cpStart);
|
|
6678
6777
|
// Since the tree is unrooted we must iterate in all directions from the
|
|
@@ -6693,7 +6792,7 @@ function traverseVertices(cpStart, traverseVerticesCallback) {
|
|
|
6693
6792
|
|
|
6694
6793
|
;// ./src/cp-node/fs/clone.ts
|
|
6695
6794
|
/** @internal */
|
|
6696
|
-
const EDGES = ['prev', 'next', 'prevOnCircle', 'nextOnCircle'];
|
|
6795
|
+
const EDGES = ['prev', 'next', 'prevOnCircle', 'nextOnCircle', 'holeCloserTwin'];
|
|
6697
6796
|
/**
|
|
6698
6797
|
* Returns a deep clone of this `CpNode`. Can be used to copy the MAT
|
|
6699
6798
|
* since cloning a single `CpNode` necessarily implies cloning all
|
|
@@ -6703,32 +6802,36 @@ function clone(cpNode) {
|
|
|
6703
6802
|
// Don't change this function to be recursive, the call stack may
|
|
6704
6803
|
// overflow if there are too many CpNodes.
|
|
6705
6804
|
const nodeMap = new Map();
|
|
6706
|
-
const newCpNode =
|
|
6805
|
+
const newCpNode = cloneWithoutEdges(cpNode);
|
|
6707
6806
|
nodeMap.set(cpNode, newCpNode);
|
|
6708
6807
|
const cpStack = [{ cpNode, newCpNode }];
|
|
6709
6808
|
while (cpStack.length) {
|
|
6710
6809
|
const { cpNode, newCpNode } = cpStack.pop();
|
|
6711
6810
|
for (const edge of EDGES) {
|
|
6712
6811
|
const node = cpNode[edge];
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
newNode = cloneWithoutLinks(node);
|
|
6716
|
-
nodeMap.set(node, newNode);
|
|
6717
|
-
cpStack.push({ cpNode: node, newCpNode: newNode });
|
|
6812
|
+
if (node === undefined) {
|
|
6813
|
+
continue;
|
|
6718
6814
|
}
|
|
6719
|
-
|
|
6815
|
+
let node_ = nodeMap.get(node);
|
|
6816
|
+
if (!node_) {
|
|
6817
|
+
node_ = cloneWithoutEdges(node);
|
|
6818
|
+
nodeMap.set(node, node_);
|
|
6819
|
+
cpStack.push({ cpNode: node, newCpNode: node_ });
|
|
6820
|
+
}
|
|
6821
|
+
newCpNode[edge] = node_;
|
|
6720
6822
|
}
|
|
6721
6823
|
}
|
|
6722
6824
|
return newCpNode;
|
|
6723
6825
|
}
|
|
6724
|
-
function
|
|
6826
|
+
function cloneWithoutEdges(cpNode) {
|
|
6725
6827
|
const newNode = {
|
|
6726
6828
|
...cpNode,
|
|
6727
6829
|
...{
|
|
6728
6830
|
prev: undefined,
|
|
6729
6831
|
next: undefined,
|
|
6730
6832
|
prevOnCircle: undefined,
|
|
6731
|
-
nextOnCircle: undefined
|
|
6833
|
+
nextOnCircle: undefined,
|
|
6834
|
+
holeCloserTwin: undefined
|
|
6732
6835
|
}
|
|
6733
6836
|
};
|
|
6734
6837
|
return newNode;
|
|
@@ -6737,11 +6840,12 @@ function cloneWithoutLinks(cpNode) {
|
|
|
6737
6840
|
|
|
6738
6841
|
;// ./src/cp-node/fs/get-boundary-bezier-parts-to-next.ts
|
|
6739
6842
|
/**
|
|
6740
|
-
* Returns the
|
|
6741
|
-
*
|
|
6843
|
+
* Returns the ordered `BezierPiece`s from this `CpNode` to the next `CpNode`
|
|
6844
|
+
* on the boundary.
|
|
6742
6845
|
*
|
|
6743
|
-
* * returns `
|
|
6744
|
-
*
|
|
6846
|
+
* * returns `[]` if (and only if) the next `CpNode` is on a different loop;
|
|
6847
|
+
* this differs from "returns `[]` if (and only if) the next `CpNode` is a
|
|
6848
|
+
* hole-closer" as half of hole-closers are on the same loop.
|
|
6745
6849
|
*
|
|
6746
6850
|
* @param cpNode
|
|
6747
6851
|
*/
|
|
@@ -6788,14 +6892,10 @@ function addSkippedBezierPiecess(bezierPieces, curveStart, curveEnd, t1) {
|
|
|
6788
6892
|
|
|
6789
6893
|
|
|
6790
6894
|
/**
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
|
|
6795
|
-
// * as this is a hole-closer and there are no boundary beziers between them.
|
|
6796
|
-
// *
|
|
6797
|
-
// * @param cpNode
|
|
6798
|
-
// */
|
|
6895
|
+
* Returns the ordered bezier curves from this `CpNode` to the next `CpNode`
|
|
6896
|
+
* on the boundary.
|
|
6897
|
+
* @param cpNode
|
|
6898
|
+
*/
|
|
6799
6899
|
function getBoundaryBeziersToNext(cpNode) {
|
|
6800
6900
|
return getBoundaryBezierPartsToNext(cpNode).map(bp => fromTo(bp.ps, bp.ts[0], bp.ts[1]));
|
|
6801
6901
|
}
|
|
@@ -6877,6 +6977,11 @@ function removeCpNode(cpNode, meta) {
|
|
|
6877
6977
|
|
|
6878
6978
|
|
|
6879
6979
|
|
|
6980
|
+
/**
|
|
6981
|
+
* Removes a cpNode from the MAT.
|
|
6982
|
+
* @param cpTree The tree graph holding the `CpNodes` of the MAT.
|
|
6983
|
+
* @param cpNode The `CpNode` to remove.
|
|
6984
|
+
*/
|
|
6880
6985
|
function removeVertex(cpNode, meta) {
|
|
6881
6986
|
// cpTrees: Map<Loop, LlRbTree<CpNode>>): void {
|
|
6882
6987
|
const prongCount = getProngCount(cpNode);
|
|
@@ -6888,6 +6993,12 @@ function removeVertex(cpNode, meta) {
|
|
|
6888
6993
|
|
|
6889
6994
|
|
|
6890
6995
|
;// ./src/cp-node/fs/get-children.ts
|
|
6996
|
+
/**
|
|
6997
|
+
* Returns the children of this `CpNode` when seen as a MAT edge. Only
|
|
6998
|
+
* children in a 'forward' direction are returned. These include all edges
|
|
6999
|
+
* except the 'backward' edge given by `prevOnCircle`, even terminating
|
|
7000
|
+
* edges.
|
|
7001
|
+
*/
|
|
6891
7002
|
function getChildren(cpNode) {
|
|
6892
7003
|
const children = [];
|
|
6893
7004
|
const cp = cpNode.next;
|
|
@@ -6901,6 +7012,10 @@ function getChildren(cpNode) {
|
|
|
6901
7012
|
|
|
6902
7013
|
|
|
6903
7014
|
;// ./src/cp-node/fs/get-first-exit.ts
|
|
7015
|
+
/**
|
|
7016
|
+
* Returns the first `CpNode` (from this one by successively applying
|
|
7017
|
+
* .nextOnCircle) that exits the circle.
|
|
7018
|
+
*/
|
|
6904
7019
|
function getFirstExit(cpNode) {
|
|
6905
7020
|
// const startNode = this as CpNode;
|
|
6906
7021
|
const startNode = cpNode;
|
|
@@ -6918,6 +7033,12 @@ function getFirstExit(cpNode) {
|
|
|
6918
7033
|
|
|
6919
7034
|
;// ./src/cp-node/fs/is-on-same-circle.ts
|
|
6920
7035
|
|
|
7036
|
+
/**
|
|
7037
|
+
* Returns true if the 2 given `CpNode`s are on the same maximal disk
|
|
7038
|
+
* circle.
|
|
7039
|
+
* @param cpNode1 A `CpNode`.
|
|
7040
|
+
* @param cpNode2 Another `CpNode`
|
|
7041
|
+
*/
|
|
6921
7042
|
function isOnSameCircle(cpNode1, cpNode2) {
|
|
6922
7043
|
// const cpNodes = getAllOnCircle(cpNode1, true);
|
|
6923
7044
|
const cpNodes = getAllOnCircle(cpNode1);
|
|
@@ -6926,6 +7047,14 @@ function isOnSameCircle(cpNode1, cpNode2) {
|
|
|
6926
7047
|
|
|
6927
7048
|
|
|
6928
7049
|
;// ./src/cp-node/fs/is-one-prong.ts
|
|
7050
|
+
/**
|
|
7051
|
+
* Returns true if this `CpNode`'s maximal disk has only one contact point
|
|
7052
|
+
* on the shape boundary (up to planar coordinates). These includes sharp
|
|
7053
|
+
* corners.
|
|
7054
|
+
*
|
|
7055
|
+
* Note, however, that two `CpNode`s are stored for each such point to
|
|
7056
|
+
* preserve symmetry - see `isTerminating` for more details.
|
|
7057
|
+
*/
|
|
6929
7058
|
// TODO2 - remove - or replace with `getRealProngCount === 1`
|
|
6930
7059
|
function isOneProng(cpNode) {
|
|
6931
7060
|
const cp1 = cpNode;
|
|
@@ -7176,6 +7305,12 @@ function compareCps(a, b) {
|
|
|
7176
7305
|
|
|
7177
7306
|
;// ./src/cp-node/fs/cp-node-comparator.ts
|
|
7178
7307
|
|
|
7308
|
+
/**
|
|
7309
|
+
* Primarily for internal use.
|
|
7310
|
+
*
|
|
7311
|
+
* Compares the order of two `CpNode`s. The order is cyclic and depends
|
|
7312
|
+
* on a `CpNode`'s relative position along the shape boundary.
|
|
7313
|
+
*/
|
|
7179
7314
|
function cpNodeComparator(a, b) {
|
|
7180
7315
|
return compareCps(a.cp, b.cp);
|
|
7181
7316
|
}
|
|
@@ -7357,20 +7492,20 @@ const CpNodeFs = {
|
|
|
7357
7492
|
*/
|
|
7358
7493
|
clone: clone,
|
|
7359
7494
|
/**
|
|
7360
|
-
* Returns the ordered bezier curves from this CpNode to the next CpNode
|
|
7495
|
+
* Returns the ordered bezier curves from this `CpNode` to the next `CpNode`
|
|
7361
7496
|
* on the boundary.
|
|
7362
7497
|
* @param cpNode
|
|
7363
7498
|
*/
|
|
7364
7499
|
getBoundaryBezierPartsToNext: getBoundaryBezierPartsToNext,
|
|
7365
7500
|
/**
|
|
7366
|
-
* Returns the ordered bezier curves from this CpNode to the next CpNode
|
|
7501
|
+
* Returns the ordered bezier curves from this `CpNode` to the next `CpNode`
|
|
7367
7502
|
* on the boundary.
|
|
7368
7503
|
* @param cpNode
|
|
7369
7504
|
*/
|
|
7370
7505
|
getBoundaryBeziersToNext: getBoundaryBeziersToNext,
|
|
7371
7506
|
/**
|
|
7372
|
-
* Removes a
|
|
7373
|
-
* @param cpTree The tree graph holding the `
|
|
7507
|
+
* Removes a `CpNode` from the MAT.
|
|
7508
|
+
* @param cpTree The tree graph holding the `CpNode`s of the MAT.
|
|
7374
7509
|
* @param cpNode The `CpNode` to remove.
|
|
7375
7510
|
*/
|
|
7376
7511
|
removeVertex: removeVertex,
|
|
@@ -7413,9 +7548,7 @@ const CpNodeFs = {
|
|
|
7413
7548
|
|
|
7414
7549
|
function isSpecial(cpNode) {
|
|
7415
7550
|
return ((getRealProngCount(cpNode) !== 2) &&
|
|
7416
|
-
!cpNode.isHoleClosing
|
|
7417
|
-
// !cpNode.isHoleClosing && cpNode.cp.circle.radius !== 0 // TODO2
|
|
7418
|
-
);
|
|
7551
|
+
!cpNode.isHoleClosing);
|
|
7419
7552
|
}
|
|
7420
7553
|
|
|
7421
7554
|
|
|
@@ -26874,10 +27007,7 @@ function getCpNodeToLeftOrSame(cpTree, pos, order, order2) {
|
|
|
26874
27007
|
|
|
26875
27008
|
;// ./src/cp-node/fs/is-order-correct.ts
|
|
26876
27009
|
|
|
26877
|
-
function isOrderCorrect(
|
|
26878
|
-
// isHoleClosing: boolean,
|
|
26879
|
-
cpTree, cp, next) {
|
|
26880
|
-
// if (isHoleClosing) { return true; }
|
|
27010
|
+
function isOrderCorrect(cpTree, cp, next) {
|
|
26881
27011
|
// TODO2
|
|
26882
27012
|
const c = compareCps(cp, next.cp);
|
|
26883
27013
|
if (c < 0) {
|
|
@@ -26969,9 +27099,7 @@ function byAngle(circle) {
|
|
|
26969
27099
|
*
|
|
26970
27100
|
* @internal
|
|
26971
27101
|
*/
|
|
26972
|
-
function addToCpTree(insertIfOrderIsWrong, isHoleClosing, circle, orders,
|
|
26973
|
-
// cpTrees: Map<Loop,LlRbTree<CpNode>>,
|
|
26974
|
-
meta, poss, neighbors) {
|
|
27102
|
+
function addToCpTree(insertIfOrderIsWrong, isHoleClosing, circle, orders, meta, poss, neighbors) {
|
|
26975
27103
|
const { cpTrees } = meta;
|
|
26976
27104
|
let anyFailed = false;
|
|
26977
27105
|
const cpNodes = poss.map((pos, i) => {
|
|
@@ -28301,16 +28429,18 @@ function add2Prong(meta, circle, poss, isHoleClosing) {
|
|
|
28301
28429
|
}
|
|
28302
28430
|
return cpNodes[0]; // return the source `CpNode`
|
|
28303
28431
|
}
|
|
28304
|
-
function closeHole(meta,
|
|
28305
|
-
// cpTrees: Map<Loop, LlRbTree<CpNode>>,
|
|
28306
|
-
cpNodes) {
|
|
28432
|
+
function closeHole(meta, cpNodes) {
|
|
28307
28433
|
const { cpTrees } = meta;
|
|
28308
28434
|
const [cpNodeA, cpNodeB] = cpNodes;
|
|
28309
28435
|
// Duplicate ContactPoints
|
|
28310
28436
|
// const antipodeCpNode = cpNodeB[0];
|
|
28311
28437
|
const cpAntipode = cpNodeB.cp;
|
|
28312
28438
|
const cpNodeB2 = insertCpNode(true, true, false, cpTrees.get(cpAntipode.pointOnShape.curve.loop), { ...cpAntipode, order2: +1 }, cpNodeB, meta.lastInsertId);
|
|
28439
|
+
cpNodeB2.holeCloserTwin = cpNodeB;
|
|
28440
|
+
cpNodeB.holeCloserTwin = cpNodeB2;
|
|
28313
28441
|
const cpNodeB1 = insertCpNode(true, true, false, cpTrees.get(cpNodeA.cp.pointOnShape.curve.loop), { ...cpNodeA.cp, order2: -1 }, cpNodeA.prev, meta.lastInsertId);
|
|
28442
|
+
cpNodeB1.holeCloserTwin = cpNodeA;
|
|
28443
|
+
cpNodeA.holeCloserTwin = cpNodeB1;
|
|
28314
28444
|
// Connect graph
|
|
28315
28445
|
cpNodeB1.prevOnCircle = cpNodeB2;
|
|
28316
28446
|
cpNodeB1.nextOnCircle = cpNodeB2;
|
|
@@ -30637,6 +30767,14 @@ const getMatDistanceToNext$ = memoize(getMatDistanceToNext);
|
|
|
30637
30767
|
|
|
30638
30768
|
|
|
30639
30769
|
;// ./src/floyd-warshall/get-hole-closer-pairs.ts
|
|
30770
|
+
/**
|
|
30771
|
+
*
|
|
30772
|
+
* @param holeClosers
|
|
30773
|
+
* @returns
|
|
30774
|
+
*/
|
|
30775
|
+
// TODO - this function is currently O(n^2) but could be made O(n).
|
|
30776
|
+
// TODO - only `pointOnShape.p` is checked but `pointOnShape.t` should also be checked
|
|
30777
|
+
// or better yet, `CpNode.cp.order` and `CpNode.cp.order2`, etc.
|
|
30640
30778
|
function getHoleCloserPairs(holeClosers) {
|
|
30641
30779
|
const pairs = new Map();
|
|
30642
30780
|
for (let hcA of holeClosers) {
|
|
@@ -30685,7 +30823,7 @@ function getGraph(specialVertices, holeClosers) {
|
|
|
30685
30823
|
}
|
|
30686
30824
|
if (child.isHoleClosing) {
|
|
30687
30825
|
// Hole closer found - don't go around loop
|
|
30688
|
-
child =
|
|
30826
|
+
child = getHoleCloserNext(pairs, child);
|
|
30689
30827
|
continue;
|
|
30690
30828
|
}
|
|
30691
30829
|
if (isVertexSpecial(child)) {
|
|
@@ -30706,7 +30844,7 @@ function getGraph(specialVertices, holeClosers) {
|
|
|
30706
30844
|
}
|
|
30707
30845
|
return graph;
|
|
30708
30846
|
}
|
|
30709
|
-
function
|
|
30847
|
+
function getHoleCloserNext(pairs, holeCloser) {
|
|
30710
30848
|
return pairs.get(holeCloser).next;
|
|
30711
30849
|
}
|
|
30712
30850
|
|