flo-mat 3.0.11 → 3.0.13
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 +213 -78
- 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/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/find-2-prong/find-2-prong.d.ts +1 -0
- package/node/find-2-prong/find-2-prong.js +2 -1
- package/node/find-2-prong/find-2-prong.js.map +1 -1
- package/node/find-mat/mat-options.js +1 -1
- package/node/find-mat/mat-options.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 +3 -3
- package/src/cp-node/cp-node-fs.ts +4 -4
- package/src/cp-node/cp-node.ts +8 -10
- 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 +4 -0
- 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/find-2-prong/find-2-prong.ts +4 -3
- package/src/find-mat/mat-options.ts +1 -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
|
@@ -2,6 +2,12 @@ import type { CpNode } from "../cp-node.js";
|
|
|
2
2
|
import { compareCps } from "../../contact-point/contact-point.js";
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Primarily for internal use.
|
|
7
|
+
*
|
|
8
|
+
* Compares the order of two `CpNode`s. The order is cyclic and depends
|
|
9
|
+
* on a `CpNode`'s relative position along the shape boundary.
|
|
10
|
+
*/
|
|
5
11
|
function cpNodeComparator(
|
|
6
12
|
a: CpNode,
|
|
7
13
|
b: CpNode) {
|
|
@@ -2,10 +2,10 @@ import type { CpNode } from "../cp-node.js";
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* @param
|
|
8
|
-
*
|
|
5
|
+
* Return this (except if exclThis is truthy) and the the other CpNodes
|
|
6
|
+
* around the maximal disk vertex circle in an anti-clockwise order.
|
|
7
|
+
* @param exclThis If true the returned array does not include this
|
|
8
|
+
* `CpNode`.
|
|
9
9
|
*/
|
|
10
10
|
function getAllOnCircle(
|
|
11
11
|
cpNode: CpNode,
|
|
@@ -4,13 +4,14 @@ import type { Curve } from '../../curve/curve.js';
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Returns the
|
|
8
|
-
*
|
|
7
|
+
* Returns the ordered `BezierPiece`s from this `CpNode` to the next `CpNode`
|
|
8
|
+
* on the boundary.
|
|
9
9
|
*
|
|
10
|
-
* * returns `
|
|
11
|
-
*
|
|
10
|
+
* * returns `[]` if (and only if) the next `CpNode` is on a different loop;
|
|
11
|
+
* this differs from "returns `[]` if (and only if) the next `CpNode` is a
|
|
12
|
+
* hole-closer" as half of hole-closers are on the same loop.
|
|
12
13
|
*
|
|
13
|
-
* @param cpNode
|
|
14
|
+
* @param cpNode
|
|
14
15
|
*/
|
|
15
16
|
function getBoundaryBezierPartsToNext(
|
|
16
17
|
cpNode: CpNode): BezierPiece[] {
|
|
@@ -4,14 +4,10 @@ import { getBoundaryBezierPartsToNext } from './get-boundary-bezier-parts-to-nex
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// * as this is a hole-closer and there are no boundary beziers between them.
|
|
12
|
-
// *
|
|
13
|
-
// * @param cpNode
|
|
14
|
-
// */
|
|
7
|
+
* Returns the ordered bezier curves from this `CpNode` to the next `CpNode`
|
|
8
|
+
* on the boundary.
|
|
9
|
+
* @param cpNode
|
|
10
|
+
*/
|
|
15
11
|
function getBoundaryBeziersToNext(
|
|
16
12
|
cpNode: CpNode): number[][][] {
|
|
17
13
|
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { CpNode } from "../cp-node.js";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Returns the children of this `CpNode` when seen as a MAT edge. Only
|
|
6
|
+
* children in a 'forward' direction are returned. These include all edges
|
|
7
|
+
* except the 'backward' edge given by `prevOnCircle`, even terminating
|
|
8
|
+
* edges.
|
|
9
|
+
*/
|
|
4
10
|
function getChildren(cpNode: CpNode) {
|
|
5
11
|
const children: CpNode[] = [];
|
|
6
12
|
|
|
@@ -7,6 +7,12 @@ import { isPosSharpCorner } from '../../point-on-shape/is-pos-sharp-corner.js';
|
|
|
7
7
|
import { Curve } from '../../curve/curve.js';
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* @internal
|
|
12
|
+
* Returns a line segment of unit length starting in the given Vertex center and
|
|
13
|
+
* pointing in the direction of the medial axis (viewed as a rooted tree).
|
|
14
|
+
* @param cpNode
|
|
15
|
+
*/
|
|
10
16
|
function getEdgeDirection(cpNode: CpNode) {
|
|
11
17
|
const circleCenter = cpNode.cp.circle.center;
|
|
12
18
|
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { CpNode } from "../cp-node.js";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Returns the first `CpNode` (from this one by successively applying
|
|
6
|
+
* .nextOnCircle) that exits the circle.
|
|
7
|
+
*/
|
|
4
8
|
function getFirstExit(cpNode: CpNode) {
|
|
5
9
|
// const startNode = this as CpNode;
|
|
6
10
|
const startNode = cpNode;
|
|
@@ -12,6 +12,12 @@ const TOLERANCE_ADD_2PRONG = 0.01;
|
|
|
12
12
|
const TOLERANCE_USE_LINE = 0.0001; // else cubic
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Returns the bezier curve from the maximal disk of one `CpNode` to another
|
|
17
|
+
* `CpNode`'s maximal disk.
|
|
18
|
+
* @param cpNodeFrom
|
|
19
|
+
* @param cpNodeTo
|
|
20
|
+
*/
|
|
15
21
|
function getMatCurveBetween(
|
|
16
22
|
cpNodeFrom: CpNode,
|
|
17
23
|
cpNodeTo: CpNode): number[][] {
|
|
@@ -3,6 +3,12 @@ import { CpNode } from '../cp-node.js';
|
|
|
3
3
|
import { getMatCurveBetween } from './get-mat-curve-between.js';
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Returns the bezier curve from the maximal disk of the given `CpNode` to the
|
|
8
|
+
* next `CpNode`'s maximal disk and thus directly represents a piece of the
|
|
9
|
+
* medial axis.
|
|
10
|
+
* @param cpNode
|
|
11
|
+
*/
|
|
6
12
|
function getMatCurveToNext(cpNode: CpNode) {
|
|
7
13
|
return getMatCurveBetween(cpNode, cpNode.next);
|
|
8
14
|
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { CpNode } from "../cp-node.js";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Returns the number of contact points on the maximal disk circle implied
|
|
6
|
+
* by this `CpNode`.
|
|
7
|
+
*
|
|
8
|
+
* Note, however, that even one-prongs and sharp corners will return 2 (see
|
|
9
|
+
* `isTerminating` for more details); if this is not desired use
|
|
10
|
+
* `getRealProngCount` instead which will return 1 in these cases.
|
|
11
|
+
*/
|
|
4
12
|
function getProngCount(cpNode: CpNode) {
|
|
5
13
|
const startCpNode = cpNode;
|
|
6
14
|
let cpNode_ = startCpNode;
|
|
@@ -3,6 +3,12 @@ import { getAllOnCircle } from "./get-all-on-circle.js";
|
|
|
3
3
|
import { isTerminating } from "./is-terminating.js";
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Returns the number of contact points (up to planar coordinates) on the
|
|
8
|
+
* maximal disk circle implied by this `CpNode`.
|
|
9
|
+
*
|
|
10
|
+
* See also `getProngCount`.
|
|
11
|
+
*/
|
|
6
12
|
function getRealProngCount(cpNode: CpNode) {
|
|
7
13
|
const nonTerminatingCpNodes = getAllOnCircle(cpNode)
|
|
8
14
|
.filter(cpNode => !isTerminating(cpNode));
|
|
@@ -2,6 +2,14 @@ import { CpNode } from "../cp-node.js";
|
|
|
2
2
|
import { isTerminating } from "./is-terminating.js";
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Similar to `getChildren` but returns the child nodes of the tree when
|
|
7
|
+
* `CpNode` is seen as a MAT vertex point (as opposed to edge). In this
|
|
8
|
+
* way the dual graph of the tree can easily be traversed - see e.g.
|
|
9
|
+
* `traverseVertices`. Generally, however, traversing the edges is
|
|
10
|
+
* preferred as it returns the entire Medial Axis (by utilizing
|
|
11
|
+
* `getMatCurveToNext` on each returned edge).
|
|
12
|
+
*/
|
|
5
13
|
function getVertexForwardChildren(cpNode: CpNode) {
|
|
6
14
|
const children: CpNode[] = [];
|
|
7
15
|
|
|
@@ -4,11 +4,8 @@ import { isTerminating } from "./is-terminating.js";
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* `false` otherwise.
|
|
10
|
-
*
|
|
11
|
-
* @param cpNode
|
|
7
|
+
* Like isTerminating() but only returns true if all cpNodes on the circle
|
|
8
|
+
* (except this.prevOnCircle) is terminating.
|
|
12
9
|
*/
|
|
13
10
|
function isFullyTerminating(cpNode: CpNode) {
|
|
14
11
|
const otherOnCircle = getAllOnCircle(cpNode.prevOnCircle, true);
|
|
@@ -2,6 +2,12 @@ import { CpNode } from "../cp-node.js";
|
|
|
2
2
|
import { getAllOnCircle } from "./get-all-on-circle.js";
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Returns true if the 2 given `CpNode`s are on the same maximal disk
|
|
7
|
+
* circle.
|
|
8
|
+
* @param cpNode1 A `CpNode`.
|
|
9
|
+
* @param cpNode2 Another `CpNode`
|
|
10
|
+
*/
|
|
5
11
|
function isOnSameCircle(
|
|
6
12
|
cpNode1: CpNode,
|
|
7
13
|
cpNode2: CpNode) {
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { CpNode } from "../cp-node.js";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Returns true if this `CpNode`'s maximal disk has only one contact point
|
|
6
|
+
* on the shape boundary (up to planar coordinates). These includes sharp
|
|
7
|
+
* corners.
|
|
8
|
+
*
|
|
9
|
+
* Note, however, that two `CpNode`s are stored for each such point to
|
|
10
|
+
* preserve symmetry - see `isTerminating` for more details.
|
|
11
|
+
*/
|
|
4
12
|
// TODO2 - remove - or replace with `getRealProngCount === 1`
|
|
5
13
|
function isOneProng(cpNode: CpNode) {
|
|
6
14
|
const cp1 = cpNode;
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
+
import type { CpNode } from "../cp-node.js";
|
|
1
2
|
import { LlRbTree } from "flo-ll-rb-tree";
|
|
2
3
|
import { compareCps, ContactPoint } from "../../contact-point/contact-point.js";
|
|
3
|
-
import { CpNode } from "../cp-node.js";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
function isOrderCorrect(
|
|
7
|
-
// isHoleClosing: boolean,
|
|
8
7
|
cpTree: LlRbTree<CpNode>,
|
|
9
8
|
cp: ContactPoint,
|
|
10
9
|
next: CpNode): boolean {
|
|
11
10
|
|
|
12
|
-
// if (isHoleClosing) { return true; }
|
|
13
|
-
|
|
14
11
|
// TODO2
|
|
15
12
|
const c = compareCps(cp,next.cp);
|
|
16
13
|
if (c < 0) { return true; }
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { CpNode } from "../cp-node.js";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Returns true if this `CpNode` represents a sharp corner, i.e. the
|
|
6
|
+
* limiting case of a two-prong having zero radius.
|
|
7
|
+
*
|
|
8
|
+
* Note that two `CpNode`s are stored for each sharp corner, one being
|
|
9
|
+
* terminating and one not. See `isTerminating` for more details.
|
|
10
|
+
*/
|
|
4
11
|
function isSharp(cpNode: CpNode) {
|
|
5
12
|
return cpNode.cp.circle.radius === 0;
|
|
6
13
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CpNode } from "../cp-node.js";
|
|
1
|
+
import type { CpNode } from "../cp-node.js";
|
|
2
2
|
import { getRealProngCount } from "./get-real-prong-count.js";
|
|
3
3
|
|
|
4
4
|
|
|
@@ -7,8 +7,7 @@ function isSpecial(
|
|
|
7
7
|
|
|
8
8
|
return (
|
|
9
9
|
(getRealProngCount(cpNode) !== 2) &&
|
|
10
|
-
!cpNode.isHoleClosing
|
|
11
|
-
// !cpNode.isHoleClosing && cpNode.cp.circle.radius !== 0 // TODO2
|
|
10
|
+
!cpNode.isHoleClosing
|
|
12
11
|
)
|
|
13
12
|
}
|
|
14
13
|
|
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
import type { CpNode } from "../cp-node.js";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Returns `true` if this `CpNode` is terminating, i.e. implies a leaf MAT
|
|
6
|
+
* vertex.
|
|
7
|
+
*
|
|
8
|
+
* The following are some instances where this is the case:
|
|
9
|
+
*
|
|
10
|
+
* * Sharp corners.
|
|
11
|
+
*
|
|
12
|
+
* * Half of Hole-closers, i.e. `CpNode`s whose next `CpNode` is on a different
|
|
13
|
+
* loop
|
|
14
|
+
*
|
|
15
|
+
* * Maximal disks with a single contact point.
|
|
16
|
+
* Note, however, that even in these cases there are two contact points stored
|
|
17
|
+
* (sitting 'on top' of each other) for the maximal disk. It can be seen as a
|
|
18
|
+
* limiting case of a two-prong where the distance between two of the contact
|
|
19
|
+
* points tend to zero. One point (represented by a `CpNode` of course) will
|
|
20
|
+
* be terminating with the other point being its `next`, whereas the other
|
|
21
|
+
* point will *not* be terminating and 'points' back into the shape.
|
|
22
|
+
*
|
|
23
|
+
* * Some 3-prongs may also become terminating if the Scale Axis Transform is
|
|
24
|
+
* applied to the shape.
|
|
25
|
+
*/
|
|
4
26
|
function isTerminating(cpNode: CpNode) {
|
|
5
27
|
return cpNode === cpNode.next.prevOnCircle;
|
|
6
28
|
}
|
|
@@ -2,6 +2,15 @@ import { CpNode } from "../cp-node.js";
|
|
|
2
2
|
import { isTerminating } from "./is-terminating.js";
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* @internal
|
|
7
|
+
*
|
|
8
|
+
* Traverses the shape from the given `CpNode` going around the shortest path
|
|
9
|
+
* so that only a piece of the shape is traversed and returns the visited
|
|
10
|
+
* `CpNode`s (starting from the given `CpNode`).
|
|
11
|
+
*
|
|
12
|
+
* @param cpStart The `CpNode` from where to start the traversal.
|
|
13
|
+
*/
|
|
5
14
|
function traverseCp(
|
|
6
15
|
cpStart: CpNode) {
|
|
7
16
|
|
|
@@ -3,6 +3,13 @@ import { isTerminating } from './is-terminating.js';
|
|
|
3
3
|
import { getAllOnLoop } from './get-all-on-loop.js';
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Traverses all edges (depth first) of the given MAT tree starting at the given
|
|
8
|
+
* vertex (represented by a `CpNode`).
|
|
9
|
+
* @param cpNode Any `CpNode` representing the start vertex.
|
|
10
|
+
* @param traverseEdgesCallback A callback function for each CpNode representing the vertex at the
|
|
11
|
+
* start of an edge.
|
|
12
|
+
*/
|
|
6
13
|
function traverseEdges(
|
|
7
14
|
cpNode: CpNode,
|
|
8
15
|
traverseEdgesCallback: (cpNode: CpNode) => void) {
|
|
@@ -5,6 +5,15 @@ import { isTerminating } from './is-terminating.js';
|
|
|
5
5
|
import { getVertexForwardChildren } from './get-vertex-forward-children.js';
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Traverses the MAT tree and calls the given callback function for each vertex
|
|
10
|
+
* (represented by a `CpNode`) on the MAT.
|
|
11
|
+
*
|
|
12
|
+
* It is usually preferable to use `traverseEdges` as it allows for the
|
|
13
|
+
* traversal of all the smooth curves representing the MAT.
|
|
14
|
+
* @param cpNode Any `CpNode` representing the start vertex.
|
|
15
|
+
* @param traverseVerticesCallback A callback function taking a single `CpNode` as parameter.
|
|
16
|
+
*/
|
|
8
17
|
function traverseVertices(
|
|
9
18
|
cpStart: CpNode,
|
|
10
19
|
traverseVerticesCallback: (cpNode: CpNode) => void) {
|
|
@@ -70,7 +70,6 @@ function add2Prong(
|
|
|
70
70
|
|
|
71
71
|
function closeHole(
|
|
72
72
|
meta: MatMeta,
|
|
73
|
-
// cpTrees: Map<Loop, LlRbTree<CpNode>>,
|
|
74
73
|
cpNodes: CpNode[]) {
|
|
75
74
|
|
|
76
75
|
const { cpTrees } = meta;
|
|
@@ -88,6 +87,8 @@ function closeHole(
|
|
|
88
87
|
cpNodeB,
|
|
89
88
|
meta.lastInsertId
|
|
90
89
|
)!;
|
|
90
|
+
cpNodeB2.holeCloserTwin = cpNodeB;
|
|
91
|
+
cpNodeB.holeCloserTwin = cpNodeB2;
|
|
91
92
|
|
|
92
93
|
const cpNodeB1 = insertCpNode(
|
|
93
94
|
true,
|
|
@@ -97,6 +98,8 @@ function closeHole(
|
|
|
97
98
|
cpNodeA.prev,
|
|
98
99
|
meta.lastInsertId
|
|
99
100
|
)!;
|
|
101
|
+
cpNodeB1.holeCloserTwin = cpNodeA;
|
|
102
|
+
cpNodeA.holeCloserTwin = cpNodeB1;
|
|
100
103
|
|
|
101
104
|
// Connect graph
|
|
102
105
|
cpNodeB1.prevOnCircle = cpNodeB2;
|
|
@@ -31,7 +31,8 @@ const { ceil, log2, max, sqrt, abs, sin, cos } = Math;
|
|
|
31
31
|
* "The starting point of this algorithm is a choice of a circle Br(x)
|
|
32
32
|
* centered at an interior point x which contains two boundary portions c and
|
|
33
33
|
* d of dΩ as in Fig. 19."
|
|
34
|
-
* In fact, we (and they) start by fixing one point on the boundary beforehand.
|
|
34
|
+
* In fact, we (and they) start by fixing one point on the boundary beforehand.
|
|
35
|
+
*
|
|
35
36
|
* @param loops A shape represented by path loops
|
|
36
37
|
* @param maxCoordinate The extreme coordinate value of the shape
|
|
37
38
|
* @param squaredDiagonalLength The squared diagonal length of the shape
|
|
@@ -45,7 +46,7 @@ function find2Prong(
|
|
|
45
46
|
isHoleClosing: boolean,
|
|
46
47
|
for1Prong: boolean,
|
|
47
48
|
angle: number,
|
|
48
|
-
y: PointOnShape): { circle: Circle,
|
|
49
|
+
y: PointOnShape): { circle: Circle, zs: PointOnShape[] } | undefined {
|
|
49
50
|
|
|
50
51
|
const { loops, maxCoordinate, squaredDiagonalLength } = meta;
|
|
51
52
|
|
|
@@ -145,7 +146,7 @@ function find2Prong(
|
|
|
145
146
|
}
|
|
146
147
|
}
|
|
147
148
|
|
|
148
|
-
// Find the point on the line connecting y with x that is
|
|
149
|
+
// Find the point on the line connecting y with x that is
|
|
149
150
|
// equidistant from y and z. This will be our next x.
|
|
150
151
|
const nextX = findEquidistantPointOnLineDd(x, y.p, z.p);
|
|
151
152
|
const error = abs(sqrt(xy) - sqrt(xz));
|
|
@@ -127,7 +127,7 @@ const matOptionRanges: Partial<{ [K in keyof MatOptions]: MatOptionMeta }> = {
|
|
|
127
127
|
range: [1, Number.POSITIVE_INFINITY],
|
|
128
128
|
},
|
|
129
129
|
simplifyTolerance: {
|
|
130
|
-
range: [2**-
|
|
130
|
+
range: [2**-20,2**20],
|
|
131
131
|
scaleByMaxCoordinate: true
|
|
132
132
|
},
|
|
133
133
|
minBezLength: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CpNode } from "../cp-node/cp-node.js";
|
|
1
|
+
import type { CpNode } from "../cp-node/cp-node.js";
|
|
2
2
|
import { getAllOnCircle } from "../cp-node/fs/get-all-on-circle.js";
|
|
3
3
|
import { getMatDistanceToNext$ } from "../cp-node/fs/get-distance-to-next.js";
|
|
4
4
|
import { isOnSameCircle } from "../cp-node/fs/is-on-same-circle.js";
|
|
@@ -36,7 +36,7 @@ function getGraph(
|
|
|
36
36
|
}
|
|
37
37
|
if (child.isHoleClosing) {
|
|
38
38
|
// Hole closer found - don't go around loop
|
|
39
|
-
child =
|
|
39
|
+
child = getHoleCloserNext(pairs, child);
|
|
40
40
|
continue;
|
|
41
41
|
}
|
|
42
42
|
if (isVertexSpecial(child)) {
|
|
@@ -62,7 +62,7 @@ function getGraph(
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
function
|
|
65
|
+
function getHoleCloserNext(
|
|
66
66
|
pairs: Map<CpNode,CpNode>,
|
|
67
67
|
holeCloser: CpNode) {
|
|
68
68
|
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import { CpNode } from "../cp-node/cp-node.js";
|
|
1
|
+
import type { CpNode } from "../cp-node/cp-node.js";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param holeClosers
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
// TODO - this function is currently O(n^2) but could be made O(n).
|
|
10
|
+
// TODO - only `pointOnShape.p` is checked but `pointOnShape.t` should also be checked
|
|
11
|
+
// or better yet, `CpNode.cp.order` and `CpNode.cp.order2`, etc.
|
|
4
12
|
function getHoleCloserPairs(
|
|
5
13
|
holeClosers: CpNode[]): Map<CpNode,CpNode> {
|
|
6
14
|
|
|
@@ -22,10 +22,9 @@ function addToCpTree(
|
|
|
22
22
|
isHoleClosing: boolean,
|
|
23
23
|
circle: Circle,
|
|
24
24
|
orders: number[],
|
|
25
|
-
// cpTrees: Map<Loop,LlRbTree<CpNode>>,
|
|
26
25
|
meta: MatMeta,
|
|
27
26
|
poss: PointOnShape[],
|
|
28
|
-
neighbors
|
|
27
|
+
neighbors?: CpNode[]): { anyFailed: boolean, cpNodes: (CpNode | undefined) [] } {
|
|
29
28
|
|
|
30
29
|
const { cpTrees } = meta;
|
|
31
30
|
|
|
@@ -7,6 +7,11 @@ import { getProngCount } from '../cp-node/fs/get-prong-count.js';
|
|
|
7
7
|
import { removeCpNode } from '../cp-node/fs/remove-cp-node.js';
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Removes a cpNode from the MAT.
|
|
12
|
+
* @param cpTree The tree graph holding the `CpNodes` of the MAT.
|
|
13
|
+
* @param cpNode The `CpNode` to remove.
|
|
14
|
+
*/
|
|
10
15
|
function removeVertex(
|
|
11
16
|
cpNode: CpNode,
|
|
12
17
|
meta: MatMeta): void {
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// import { ContactPoint } from '../../contact-point/contact-point.js';
|
|
2
|
-
// import { CpNode } from '../cp-node.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// function createCpNode(
|
|
6
|
-
// cp: ContactPoint,
|
|
7
|
-
// isHoleClosing : boolean,
|
|
8
|
-
// isIntersection : boolean,
|
|
9
|
-
// prev : CpNode = undefined!,
|
|
10
|
-
// next : CpNode = undefined!,
|
|
11
|
-
// prevOnCircle : CpNode = undefined!,
|
|
12
|
-
// nextOnCircle : CpNode = undefined!): CpNode {
|
|
13
|
-
|
|
14
|
-
// return {
|
|
15
|
-
// cp, isHoleClosing, isIntersection,
|
|
16
|
-
// prev, next, prevOnCircle, nextOnCircle
|
|
17
|
-
// }
|
|
18
|
-
// }
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// export { createCpNode }
|