flo-mat 2.0.2 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/browser/index.js +8230 -8229
  2. package/browser/index.min.js +1 -1
  3. package/node/circle.d.ts +20 -20
  4. package/node/circle.js +31 -31
  5. package/node/compare-curvatures-at-interface.d.ts +19 -19
  6. package/node/compare-curvatures-at-interface.js +124 -124
  7. package/node/contact-point.d.ts +26 -26
  8. package/node/contact-point.js +25 -25
  9. package/node/cp-node/clone.d.ts +8 -8
  10. package/node/cp-node/clone.js +31 -31
  11. package/node/cp-node/remove.d.ts +9 -9
  12. package/node/cp-node/remove.js +19 -19
  13. package/node/cp-node.d.ts +202 -202
  14. package/node/cp-node.js +320 -320
  15. package/node/curve.d.ts +46 -46
  16. package/node/curve.js +88 -88
  17. package/node/debug/cp-node-for-debugging.d.ts +11 -11
  18. package/node/debug/cp-node-for-debugging.js +1 -1
  19. package/node/debug/debug-elem-types.d.ts +32 -32
  20. package/node/debug/debug-elem-types.js +1 -1
  21. package/node/debug/debug.d.ts +50 -50
  22. package/node/debug/debug.js +75 -75
  23. package/node/debug/functions/draw-elem/bounding-hull.d.ts +3 -3
  24. package/node/debug/functions/draw-elem/bounding-hull.js +7 -7
  25. package/node/debug/functions/draw-elem/branch.d.ts +4 -4
  26. package/node/debug/functions/draw-elem/branch.js +22 -22
  27. package/node/debug/functions/draw-elem/culls.d.ts +4 -4
  28. package/node/debug/functions/draw-elem/culls.js +21 -21
  29. package/node/debug/functions/draw-elem/draw-circle-percent.d.ts +3 -3
  30. package/node/debug/functions/draw-elem/draw-circle-percent.js +12 -12
  31. package/node/debug/functions/draw-elem/draw-elem.d.ts +8 -8
  32. package/node/debug/functions/draw-elem/draw-elem.js +45 -45
  33. package/node/debug/functions/draw-elem/dull-corner.d.ts +4 -4
  34. package/node/debug/functions/draw-elem/dull-corner.js +10 -10
  35. package/node/debug/functions/draw-elem/leaves.d.ts +4 -4
  36. package/node/debug/functions/draw-elem/leaves.js +12 -12
  37. package/node/debug/functions/draw-elem/loop.d.ts +4 -4
  38. package/node/debug/functions/draw-elem/loop.js +11 -11
  39. package/node/debug/functions/draw-elem/loops.d.ts +4 -4
  40. package/node/debug/functions/draw-elem/loops.js +6 -6
  41. package/node/debug/functions/draw-elem/loose-bounding-box.d.ts +3 -3
  42. package/node/debug/functions/draw-elem/loose-bounding-box.js +9 -9
  43. package/node/debug/functions/draw-elem/mat.d.ts +4 -4
  44. package/node/debug/functions/draw-elem/mat.js +30 -30
  45. package/node/debug/functions/draw-elem/max-vertex.d.ts +4 -4
  46. package/node/debug/functions/draw-elem/max-vertex.js +8 -8
  47. package/node/debug/functions/draw-elem/min-y.d.ts +4 -4
  48. package/node/debug/functions/draw-elem/min-y.js +13 -13
  49. package/node/debug/functions/draw-elem/one-prong-at-dull-corner.d.ts +4 -4
  50. package/node/debug/functions/draw-elem/one-prong-at-dull-corner.js +12 -12
  51. package/node/debug/functions/draw-elem/one-prong.d.ts +4 -4
  52. package/node/debug/functions/draw-elem/one-prong.js +16 -16
  53. package/node/debug/functions/draw-elem/sharp-corner.d.ts +4 -4
  54. package/node/debug/functions/draw-elem/sharp-corner.js +9 -9
  55. package/node/debug/functions/draw-elem/three-prong.d.ts +4 -4
  56. package/node/debug/functions/draw-elem/three-prong.js +16 -16
  57. package/node/debug/functions/draw-elem/tight-bounding-box.d.ts +3 -3
  58. package/node/debug/functions/draw-elem/tight-bounding-box.js +7 -7
  59. package/node/debug/functions/draw-elem/two-prong.d.ts +4 -4
  60. package/node/debug/functions/draw-elem/two-prong.js +36 -36
  61. package/node/debug/functions/draw-elem/vertex.d.ts +4 -4
  62. package/node/debug/functions/draw-elem/vertex.js +27 -27
  63. package/node/debug/functions/general.d.ts +48 -48
  64. package/node/debug/functions/general.js +52 -52
  65. package/node/debug/functions/three-prong.d.ts +11 -11
  66. package/node/debug/functions/three-prong.js +184 -184
  67. package/node/debug/functions/two-prong.d.ts +13 -13
  68. package/node/debug/functions/two-prong.js +117 -117
  69. package/node/debug/three-prong-for-debugging.d.ts +31 -31
  70. package/node/debug/three-prong-for-debugging.js +20 -20
  71. package/node/debug/two-prong-for-debugging.d.ts +26 -26
  72. package/node/debug/two-prong-for-debugging.js +1 -1
  73. package/node/find-mats.d.ts +26 -26
  74. package/node/find-mats.js +122 -122
  75. package/node/get-boundary-bezier-parts-to-next.d.ts +9 -9
  76. package/node/get-boundary-bezier-parts-to-next.js +42 -42
  77. package/node/get-boundary-beziers-to-next.d.ts +8 -8
  78. package/node/get-boundary-beziers-to-next.js +44 -44
  79. package/node/get-bounding-box-.d.ts +2 -2
  80. package/node/get-bounding-box-.js +4 -4
  81. package/node/get-branches.d.ts +12 -12
  82. package/node/get-branches.js +68 -68
  83. package/node/get-curve/get-curve-between.d.ts +9 -9
  84. package/node/get-curve/get-curve-between.js +56 -56
  85. package/node/get-curve/get-edge-direction.d.ts +9 -9
  86. package/node/get-curve/get-edge-direction.js +53 -53
  87. package/node/get-curve-to-next.d.ts +9 -9
  88. package/node/get-curve-to-next.js +11 -11
  89. package/node/get-interface-ccw.d.ts +24 -24
  90. package/node/get-interface-ccw.js +97 -97
  91. package/node/index.d.ts +36 -36
  92. package/node/index.js +32 -32
  93. package/node/loop/get-max-coordinate.d.ts +10 -10
  94. package/node/loop/get-max-coordinate.js +43 -43
  95. package/node/loop.d.ts +16 -16
  96. package/node/loop.js +34 -34
  97. package/node/mat/add-to-cp-graph.d.ts +16 -16
  98. package/node/mat/add-to-cp-graph.js +30 -30
  99. package/node/mat/bezier-piece.d.ts +12 -12
  100. package/node/mat/bezier-piece.js +1 -1
  101. package/node/mat/closest-boundary-point/closest-points-on-curve.d.ts +14 -14
  102. package/node/mat/closest-boundary-point/closest-points-on-curve.js +72 -72
  103. package/node/mat/closest-boundary-point/cull-bezier-pieces.d.ts +9 -9
  104. package/node/mat/closest-boundary-point/cull-bezier-pieces.js +19 -19
  105. package/node/mat/closest-boundary-point/cull-by-loose-bounding-box.d.ts +11 -11
  106. package/node/mat/closest-boundary-point/cull-by-loose-bounding-box.js +24 -24
  107. package/node/mat/closest-boundary-point/cull-by-tight-boundary-box.d.ts +11 -11
  108. package/node/mat/closest-boundary-point/cull-by-tight-boundary-box.js +26 -26
  109. package/node/mat/closest-boundary-point/get-best-distance-squared.d.ts +8 -8
  110. package/node/mat/closest-boundary-point/get-best-distance-squared.js +24 -24
  111. package/node/mat/closest-boundary-point/get-close-boundary-points.d.ts +17 -17
  112. package/node/mat/closest-boundary-point/get-close-boundary-points.js +80 -80
  113. package/node/mat/closest-boundary-point/get-closest-boundary-point.d.ts +18 -18
  114. package/node/mat/closest-boundary-point/get-closest-boundary-point.js +40 -40
  115. package/node/mat/corner.d.ts +37 -37
  116. package/node/mat/corner.js +1 -1
  117. package/node/mat/create-new-cp-tree.d.ts +9 -9
  118. package/node/mat/create-new-cp-tree.js +23 -23
  119. package/node/mat/elem-type-two-prong.d.ts +3 -3
  120. package/node/mat/elem-type-two-prong.js +1 -1
  121. package/node/mat/find-mat/add-1-prong.d.ts +12 -12
  122. package/node/mat/find-mat/add-1-prong.js +42 -42
  123. package/node/mat/find-mat/add-2-prong.d.ts +21 -21
  124. package/node/mat/find-mat/add-2-prong.js +192 -192
  125. package/node/mat/find-mat/add-3-prong.d.ts +19 -19
  126. package/node/mat/find-mat/add-3-prong.js +54 -54
  127. package/node/mat/find-mat/add-debug-info.d.ts +9 -9
  128. package/node/mat/find-mat/add-debug-info.js +67 -67
  129. package/node/mat/find-mat/create-get-interesting-points-on-loop.d.ts +11 -11
  130. package/node/mat/find-mat/create-get-interesting-points-on-loop.js +51 -51
  131. package/node/mat/find-mat/create-initial-cp-graph.d.ts +12 -12
  132. package/node/mat/find-mat/create-initial-cp-graph.js +40 -40
  133. package/node/mat/find-mat/find-2-prong/add-debug-info.d.ts +8 -8
  134. package/node/mat/find-mat/find-2-prong/add-debug-info.js +21 -21
  135. package/node/mat/find-mat/find-2-prong/cull-bezier-pieces.d.ts +11 -11
  136. package/node/mat/find-mat/find-2-prong/cull-bezier-pieces.js +29 -29
  137. package/node/mat/find-mat/find-2-prong/find-2-prong.d.ts +37 -37
  138. package/node/mat/find-mat/find-2-prong/find-2-prong.js +232 -232
  139. package/node/mat/find-mat/find-2-prong/find-equidistant-point-on-line.d.ts +9 -9
  140. package/node/mat/find-mat/find-2-prong/find-equidistant-point-on-line.js +39 -39
  141. package/node/mat/find-mat/find-2-prong/get-initial-bezier-pieces.d.ts +11 -11
  142. package/node/mat/find-mat/find-2-prong/get-initial-bezier-pieces.js +37 -37
  143. package/node/mat/find-mat/find-2-prong/x-for-debugging.d.ts +9 -9
  144. package/node/mat/find-mat/find-2-prong/x-for-debugging.js +1 -1
  145. package/node/mat/find-mat/find-3-prong/calc-better-x.d.ts +19 -19
  146. package/node/mat/find-mat/find-3-prong/calc-better-x.js +36 -36
  147. package/node/mat/find-mat/find-3-prong/calc-initial-3-prong-center.d.ts +13 -13
  148. package/node/mat/find-mat/find-3-prong/calc-initial-3-prong-center.js +25 -25
  149. package/node/mat/find-mat/find-3-prong/find-3-prong-for-delta3s.d.ts +22 -22
  150. package/node/mat/find-mat/find-3-prong/find-3-prong-for-delta3s.js +159 -159
  151. package/node/mat/find-mat/find-3-prong/find-3-prong.d.ts +16 -16
  152. package/node/mat/find-mat/find-3-prong/find-3-prong.js +76 -76
  153. package/node/mat/find-mat/find-3-prong/get-closest-points.d.ts +9 -9
  154. package/node/mat/find-mat/find-3-prong/get-closest-points.js +16 -16
  155. package/node/mat/find-mat/find-and-add-2-prongs-on-all-paths.d.ts +15 -15
  156. package/node/mat/find-mat/find-and-add-2-prongs-on-all-paths.js +20 -20
  157. package/node/mat/find-mat/find-and-add-2-prongs.d.ts +16 -16
  158. package/node/mat/find-mat/find-and-add-2-prongs.js +73 -73
  159. package/node/mat/find-mat/find-and-add-3-prongs.d.ts +13 -13
  160. package/node/mat/find-mat/find-and-add-3-prongs.js +146 -146
  161. package/node/mat/find-mat/find-and-add-hole-closing-2-prongs.d.ts +14 -14
  162. package/node/mat/find-mat/find-and-add-hole-closing-2-prongs.js +33 -33
  163. package/node/mat/find-mat/get-potential-2-prongs.d.ts +4 -4
  164. package/node/mat/find-mat/get-potential-2-prongs.js +16 -16
  165. package/node/mat/find-mat/get-sharp-corners.d.ts +4 -4
  166. package/node/mat/find-mat/get-sharp-corners.js +17 -17
  167. package/node/mat/geometry/get-closest-square-distance-to-rect.d.ts +5 -5
  168. package/node/mat/geometry/get-closest-square-distance-to-rect.js +49 -49
  169. package/node/mat/geometry/get-closest-squared-distance-to-rotated-rect.d.ts +5 -5
  170. package/node/mat/geometry/get-closest-squared-distance-to-rotated-rect.js +15 -15
  171. package/node/mat/get-boundary-piece-beziers.d.ts +11 -11
  172. package/node/mat/get-boundary-piece-beziers.js +58 -58
  173. package/node/mat/get-contact-circles-at-interface.d.ts +8 -8
  174. package/node/mat/get-contact-circles-at-interface.js +20 -20
  175. package/node/mat/get-largest-vertex.d.ts +4 -4
  176. package/node/mat/get-largest-vertex.js +9 -9
  177. package/node/mat/get-leaves.d.ts +4 -4
  178. package/node/mat/get-leaves.js +12 -12
  179. package/node/mat/get-neighboring-cps.d.ts +14 -14
  180. package/node/mat/get-neighboring-cps.js +30 -30
  181. package/node/mat/get-two-prong-type.d.ts +5 -5
  182. package/node/mat/get-two-prong-type.js +8 -8
  183. package/node/mat/is-another-cp-closeby.d.ts +20 -20
  184. package/node/mat/is-another-cp-closeby.js +55 -55
  185. package/node/mat/simplify-mat-map-only.d.ts +23 -23
  186. package/node/mat/simplify-mat-map-only.js +80 -80
  187. package/node/mat/to-scale-axis/add-debug-info.d.ts +7 -7
  188. package/node/mat/to-scale-axis/add-debug-info.js +13 -13
  189. package/node/mat/to-scale-axis/cull-non-cycles.d.ts +9 -9
  190. package/node/mat/to-scale-axis/cull-non-cycles.js +51 -51
  191. package/node/mat/to-scale-axis/cull.d.ts +12 -12
  192. package/node/mat/to-scale-axis/cull.js +132 -132
  193. package/node/mat/trim-mat.d.ts +8 -8
  194. package/node/mat/trim-mat.js +16 -16
  195. package/node/mat.d.ts +22 -22
  196. package/node/mat.js +1 -1
  197. package/node/point-on-shape.d.ts +73 -73
  198. package/node/point-on-shape.js +167 -167
  199. package/node/simplify-mat.d.ts +16 -16
  200. package/node/simplify-mat.js +71 -71
  201. package/node/svg/get-loop-bounds.d.ts +12 -12
  202. package/node/svg/get-loop-bounds.js +80 -80
  203. package/node/svg/get-min-y-pos.d.ts +8 -8
  204. package/node/svg/get-min-y-pos.js +9 -9
  205. package/node/svg/get-shape-bounds.d.ts +9 -9
  206. package/node/svg/get-shape-bounds.js +35 -35
  207. package/node/sweep-line/sweep-line.d.ts +18 -18
  208. package/node/sweep-line/sweep-line.js +72 -72
  209. package/node/to-scale-axis.d.ts +16 -16
  210. package/node/to-scale-axis.js +74 -74
  211. package/node/traverse-edges.d.ts +10 -10
  212. package/node/traverse-edges.js +21 -21
  213. package/node/traverse-vertices.d.ts +12 -12
  214. package/node/traverse-vertices.js +27 -27
  215. package/package.json +11 -11
  216. package/tsconfig.json +0 -1
package/node/cp-node.js CHANGED
@@ -1,321 +1,321 @@
1
- import { compareCps } from './contact-point.js';
2
- import { removeCpNode } from './cp-node/remove.js';
3
- import { getCurveToNext } from './get-curve-to-next.js';
4
- /**
5
- * The primary class of the library.
6
- *
7
- * Since the MAT is a full representation of the shape boundary an instance of
8
- * this class contains both the information of a boundary point and a medial
9
- * axis point (and edge to the next point(s)). It also contains edges to other
10
- * [[CpNode]]s which allows for traversal of the MAT and thus implictly
11
- * represents the entire MAT.
12
- *
13
- * To get the maximal disk circle (of which the center is on the medial axis)
14
- * use [[cp]].circle.
15
- *
16
- * To get the boundary point, use [[cp]].pointOnShape.
17
- *
18
- * The edge [[next]] (resp. [[prev]]) allows one to move anti-clockwise (resp.
19
- * clockwise) on the shape boundary to the next [[CpNode]]. This also imposes a
20
- * direction of traversal of the MAT edges and vertices.
21
- *
22
- * The edge [[nextOnCircle]] (resp. [[prevOnCircle]]) allows one to go
23
- * anti-clockwise (resp. clockwise) around the maximal disks implied by
24
- * the CpNode to the next maximal disk contact point. This is equivalent to
25
- * following other branches on the MAT.
26
- *
27
- * Call [[getCurveBetween]](cpNodeFrom, cpNodeTo) or getCurveToNext(cpNode)
28
- * (replacing the older CpNode.[[matCurveToNextVertex]]) to get a bezier curve
29
- * from the maximal disk of this [[CpNode]] to the next [[CpNode]]'s
30
- * maximal disk and thus directly representing a piece of the medial axis.
31
- *
32
- * The function, [[getChildren]], returns the children of this [[CpNode]] when
33
- * seen as a MAT edge. Only children in a 'forward' direction are returned. These
34
- * include all edges except the 'backward' edge given by [[prevOnCircle]]. For
35
- * [[CpNode]]s having a maximal disk with 2 contact points (a 2-prong, the usual
36
- * case) the children will be the single edge [[next]]. For a 3-prong this will
37
- * be the edges [[next]] and [[nextOnCircle]], etc. [[getChildren]] allows one to
38
- * easily traverse the MAT tree - see e.g. the implementation of [[traverseEdges]].
39
- *
40
- * The getter, [[vertexChildren]], is similar to [[getChildren]] but returns the
41
- * child nodes of the tree when [[CpNode]] is seen as a MAT vertex point (as
42
- * opposed to edge). In this way the dual graph of the tree can easily be
43
- * traversed - see e.g. [[traverseVertices]]. Generally, however, traversing the
44
- * edges is preferred as it returns the entire Medial Axis (by utilizing
45
- * [[getCurveToNext]] on each returned edge).
46
- *
47
- * It may be worth mentioning that by traversing from the CpNode by following
48
- * [[next]] repeatedly until one is back at the same CpNode allows one
49
- * to 'go around' the shape boundary and at the same time traverse the MAT twice
50
- * in opposite directions.
51
- */
52
- class CpNode {
53
- /**
54
- * Primarily for internal use.
55
- * @param cp The shape boundary contact point, i.e. a [[CpNode]] without its
56
- * edges.
57
- * @param isHoleClosing If true, this [[CpNode]] belongs to a hole-closing
58
- * maximal disk.
59
- * @param isIntersection true if this cpNode is at a shape boundary
60
- * intersection point, false otherwise
61
- * @param prev The previous (going clockwise around the boundary) contact
62
- * point ([[CpNode]]).
63
- * @param next The next (going anti-clockwise around the boundary) contact
64
- * point ([[CpNode]]).
65
- * @param prevOnCircle The previous [[CpNode]] (going clockwise around
66
- * the inscribed circle defined by the maximal disk).
67
- * @param nextOnCircle The next [[CpNode]] (going anti-clockwise around
68
- * the inscribed circle defined by the maximal disk).
69
- */
70
- constructor(cp, isHoleClosing, isIntersection, prev = undefined, next = undefined, prevOnCircle = undefined, nextOnCircle = undefined) {
71
- this.cp = cp;
72
- this.isHoleClosing = isHoleClosing;
73
- this.isIntersection = isIntersection;
74
- this.prev = prev;
75
- this.next = next;
76
- this.prevOnCircle = prevOnCircle;
77
- this.nextOnCircle = nextOnCircle;
78
- }
79
- /**
80
- * Returns the bezier curve from the maximal disk of this [[CpNode]] to the
81
- * next [[CpNode]]'s maximal disk and thus directly represents a piece of the
82
- * medial axis.
83
- * @deprecated Use [[getCurveToNext]] instead
84
- * @param cpNode
85
- */
86
- get matCurveToNextVertex() {
87
- return getCurveToNext(this);
88
- }
89
- /**
90
- * Returns the children of this [[CpNode]] when seen as a MAT edge. Only
91
- * children in a 'forward' direction are returned. These include all edges
92
- * except the 'backward' edge given by [[prevOnCircle]], even terminating
93
- * edges.
94
- */
95
- getChildren() {
96
- const children = [];
97
- const cp = this.next;
98
- let cp_ = cp;
99
- do {
100
- children.push(cp_);
101
- cp_ = cp_.nextOnCircle;
102
- } while (cp_.nextOnCircle !== cp);
103
- return children;
104
- }
105
- /**
106
- * Similar to [[getChildren]] but returns the child nodes of the tree when
107
- * [[CpNode]] is seen as a MAT vertex point (as opposed to edge). In this
108
- * way the dual graph of the tree can easily be traversed - see e.g.
109
- * [[traverseVertices]]. Generally, however, traversing the edges is
110
- * preferred as it returns the entire Medial Axis (by utilizing
111
- * [[getCurveToNext]] on each returned edge).
112
- */
113
- get vertexChildren() {
114
- if (this.isTerminating()) {
115
- return [];
116
- }
117
- const cp = this;
118
- const children = [];
119
- let cp_ = cp;
120
- while (cp_ !== cp.prevOnCircle) {
121
- if (!cp_.isTerminating()) {
122
- children.push(cp_.next);
123
- }
124
- cp_ = cp_.nextOnCircle;
125
- }
126
- return children;
127
- }
128
- /**
129
- * Returns all [[CpNode]]s on the MAT that this [[CpNode]] is part of
130
- * starting from the current one and going anti-clockwise around the shape.
131
- */
132
- getAllOnLoop() {
133
- const cpStart = this;
134
- const cps = [cpStart];
135
- let cp = this.next;
136
- while (cp !== cpStart) {
137
- cps.push(cp);
138
- cp = cp.next;
139
- }
140
- return cps;
141
- }
142
- /**
143
- * Primarily for internal use.
144
- *
145
- * Insert a [[CpNode]] into the MAT tree graph after the specified point
146
- * and returns the freshly inserted [[CpNode]].
147
- * @param isHoleClosing True if this is a hole closing contact point.
148
- * @param isIntersection True if this is a contact point at a shape boundary
149
- * intersection point.
150
- * @param cpTree The tree graph holding the [[CpNodes]] of the MAT.
151
- * @param cp [[ContactPoint]] defining the [[CpNode]].
152
- * @param prev_ Inserts the new [[CpNode]] right after this item if the
153
- * loop is not empty, else insert the new [[CpNode]] as the only item in the
154
- * loop.
155
- */
156
- static insert(isHoleClosing, isIntersection, cpTree, cp, prev_) {
157
- const cpNode = new CpNode(cp, isHoleClosing, isIntersection);
158
- if (typeof _debug_ !== 'undefined') {
159
- _debug_.generated.elems.cpNode.push({
160
- generated: _debug_.generated,
161
- cpNode
162
- });
163
- }
164
- let prev;
165
- let next;
166
- if (!prev_) {
167
- prev = cpNode;
168
- next = cpNode;
169
- }
170
- else {
171
- prev = prev_;
172
- next = prev.next;
173
- }
174
- next.prev = cpNode;
175
- prev.next = cpNode;
176
- cpNode.prev = prev;
177
- cpNode.next = next;
178
- cpTree.insert(cpNode);
179
- return cpNode;
180
- }
181
- /**
182
- * Return this (except if exclThis is truthy) and the the other CpNodes
183
- * around the maximal disk vertex circle in an anti-clockwise order.
184
- * @param exclThis If true the returned array does not include this
185
- * [[CpNode]].
186
- */
187
- getCpNodesOnCircle(exclThis = false) {
188
- const startCp = this;
189
- let cp = startCp;
190
- const cps = [];
191
- do {
192
- if (exclThis) {
193
- exclThis = false;
194
- }
195
- else {
196
- cps.push(cp);
197
- }
198
- cp = cp.nextOnCircle;
199
- } while (cp !== startCp);
200
- return cps;
201
- }
202
- /**
203
- * Returns true if the 2 given [[CpNode]]s are on the same maximal disk
204
- * circle.
205
- * @param cpNode1 A [[CpNode]].
206
- * @param cpNode2 Another [[CpNode]]
207
- */
208
- static isOnSameCircle(cpNode1, cpNode2) {
209
- const cpNodes = cpNode1.getCpNodesOnCircle(true);
210
- return cpNodes.indexOf(cpNode2) >= 0;
211
- }
212
- /**
213
- * Returns true if this [[CpNode]] is terminating, i.e. implies a leaf MAT
214
- * vertex.
215
- *
216
- * This is always the case for sharp corners and maximal disks with
217
- * a single contact point. Note, however, that even in these cases there are
218
- * two contact points stored (sitting 'on top' of each other) for the
219
- * maximal disk. It can be seen as a limiting case of a two-prong where the
220
- * distance between two of the contact points tend to zero. One point
221
- * (represented by a [[CpNode]] of course) will be terminating with the
222
- * other point being its [[next]], whereas the other point will *not* be
223
- * terminating and 'points' back into the shape.
224
- */
225
- isTerminating() {
226
- return this === this.next.prevOnCircle;
227
- }
228
- /**
229
- * Like isTerminating() but only returns true if all cpNodes on the circle
230
- * (except this.prevOnCircle) is terminating.
231
- */
232
- isFullyTerminating() {
233
- const otherOnCircle = this.prevOnCircle.getCpNodesOnCircle(true);
234
- const isFullyTerminating = otherOnCircle.every(cpNode => cpNode.isTerminating());
235
- return isFullyTerminating;
236
- }
237
- /**
238
- * Returns the first [[CpNode]] (from this one by successively applying
239
- * .nextOnCircle) that exits the circle.
240
- */
241
- getFirstExit() {
242
- const startNode = this;
243
- let cpNode = startNode;
244
- while (cpNode.next === cpNode.prevOnCircle) {
245
- cpNode = cpNode.next;
246
- if (cpNode === startNode) {
247
- // The very special case the MAT is a single point.
248
- return undefined;
249
- }
250
- }
251
- return cpNode;
252
- }
253
- /**
254
- * Returns true if this [[CpNode]] represents a sharp corner, i.e. the
255
- * limiting case of a two-prong having zero radius.
256
- *
257
- * Note that two [[CpNode]]s are stored for each sharp corner, one being
258
- * terminating and one not. See [[isTerminating]] for more details.
259
- */
260
- isSharp() {
261
- return this.cp.circle.radius === 0;
262
- }
263
- /**
264
- * Returns true if this [[CpNode]]'s maximal disk has only one contact point
265
- * on the shape boundary (up to planar coordinates). These includes sharp
266
- * corners.
267
- *
268
- * Note, however, that two [[CpNode]]s are stored for each such point to
269
- * preserve symmetry - see [[isTerminating]] for more details.
270
- */
271
- isOneProng() {
272
- const cp1 = this;
273
- if (cp1.cp.circle.radius === 0) {
274
- return true;
275
- }
276
- const cp2 = cp1.nextOnCircle;
277
- const p1 = cp1.cp.pointOnShape.p;
278
- const p2 = cp2.cp.pointOnShape.p;
279
- return (p1[0] === p2[0] && p1[1] === p2[1]);
280
- }
281
- /**
282
- * Returns the number of contact points on the maximal disk circle implied
283
- * by this [[CpNode]].
284
- *
285
- * Note, however, that even one-prongs and sharp corners will return 2 (see
286
- * [[isTerminating]] for more details); if this is not desired use
287
- * [[getRealProngCount]] instead which will return 1 in these cases.
288
- */
289
- getProngCount() {
290
- const startCp = this;
291
- let cp = startCp;
292
- let i = 0;
293
- do {
294
- i++;
295
- cp = cp.nextOnCircle;
296
- } while (cp !== startCp);
297
- return i;
298
- }
299
- /**
300
- * Returns the number of contact points (up to planar coordinates) on the
301
- * maximal disk circle implied by this [[CpNode]].
302
- *
303
- * See also [[getProngCount]].
304
- */
305
- getRealProngCount() {
306
- if (this.isOneProng()) {
307
- return 1;
308
- }
309
- return this.getProngCount();
310
- }
311
- }
312
- /**
313
- * Primarily for internal use.
314
- *
315
- * Compares the order of two [[CpNode]]s. The order is cyclic and depends
316
- * on a [[CpNode]]'s relative position along the shape boundary.
317
- */
318
- CpNode.comparator = (a, b) => compareCps(a.cp, b.cp);
319
- CpNode.remove = removeCpNode;
320
- export { CpNode };
1
+ import { compareCps } from './contact-point.js';
2
+ import { removeCpNode } from './cp-node/remove.js';
3
+ import { getCurveToNext } from './get-curve-to-next.js';
4
+ /**
5
+ * The primary class of the library.
6
+ *
7
+ * Since the MAT is a full representation of the shape boundary an instance of
8
+ * this class contains both the information of a boundary point and a medial
9
+ * axis point (and edge to the next point(s)). It also contains edges to other
10
+ * [[CpNode]]s which allows for traversal of the MAT and thus implictly
11
+ * represents the entire MAT.
12
+ *
13
+ * To get the maximal disk circle (of which the center is on the medial axis)
14
+ * use [[cp]].circle.
15
+ *
16
+ * To get the boundary point, use [[cp]].pointOnShape.
17
+ *
18
+ * The edge [[next]] (resp. [[prev]]) allows one to move anti-clockwise (resp.
19
+ * clockwise) on the shape boundary to the next [[CpNode]]. This also imposes a
20
+ * direction of traversal of the MAT edges and vertices.
21
+ *
22
+ * The edge [[nextOnCircle]] (resp. [[prevOnCircle]]) allows one to go
23
+ * anti-clockwise (resp. clockwise) around the maximal disks implied by
24
+ * the CpNode to the next maximal disk contact point. This is equivalent to
25
+ * following other branches on the MAT.
26
+ *
27
+ * Call [[getCurveBetween]](cpNodeFrom, cpNodeTo) or getCurveToNext(cpNode)
28
+ * (replacing the older CpNode.[[matCurveToNextVertex]]) to get a bezier curve
29
+ * from the maximal disk of this [[CpNode]] to the next [[CpNode]]'s
30
+ * maximal disk and thus directly representing a piece of the medial axis.
31
+ *
32
+ * The function, [[getChildren]], returns the children of this [[CpNode]] when
33
+ * seen as a MAT edge. Only children in a 'forward' direction are returned. These
34
+ * include all edges except the 'backward' edge given by [[prevOnCircle]]. For
35
+ * [[CpNode]]s having a maximal disk with 2 contact points (a 2-prong, the usual
36
+ * case) the children will be the single edge [[next]]. For a 3-prong this will
37
+ * be the edges [[next]] and [[nextOnCircle]], etc. [[getChildren]] allows one to
38
+ * easily traverse the MAT tree - see e.g. the implementation of [[traverseEdges]].
39
+ *
40
+ * The getter, [[vertexChildren]], is similar to [[getChildren]] but returns the
41
+ * child nodes of the tree when [[CpNode]] is seen as a MAT vertex point (as
42
+ * opposed to edge). In this way the dual graph of the tree can easily be
43
+ * traversed - see e.g. [[traverseVertices]]. Generally, however, traversing the
44
+ * edges is preferred as it returns the entire Medial Axis (by utilizing
45
+ * [[getCurveToNext]] on each returned edge).
46
+ *
47
+ * It may be worth mentioning that by traversing from the CpNode by following
48
+ * [[next]] repeatedly until one is back at the same CpNode allows one
49
+ * to 'go around' the shape boundary and at the same time traverse the MAT twice
50
+ * in opposite directions.
51
+ */
52
+ class CpNode {
53
+ /**
54
+ * Primarily for internal use.
55
+ * @param cp The shape boundary contact point, i.e. a [[CpNode]] without its
56
+ * edges.
57
+ * @param isHoleClosing If true, this [[CpNode]] belongs to a hole-closing
58
+ * maximal disk.
59
+ * @param isIntersection true if this cpNode is at a shape boundary
60
+ * intersection point, false otherwise
61
+ * @param prev The previous (going clockwise around the boundary) contact
62
+ * point ([[CpNode]]).
63
+ * @param next The next (going anti-clockwise around the boundary) contact
64
+ * point ([[CpNode]]).
65
+ * @param prevOnCircle The previous [[CpNode]] (going clockwise around
66
+ * the inscribed circle defined by the maximal disk).
67
+ * @param nextOnCircle The next [[CpNode]] (going anti-clockwise around
68
+ * the inscribed circle defined by the maximal disk).
69
+ */
70
+ constructor(cp, isHoleClosing, isIntersection, prev = undefined, next = undefined, prevOnCircle = undefined, nextOnCircle = undefined) {
71
+ this.cp = cp;
72
+ this.isHoleClosing = isHoleClosing;
73
+ this.isIntersection = isIntersection;
74
+ this.prev = prev;
75
+ this.next = next;
76
+ this.prevOnCircle = prevOnCircle;
77
+ this.nextOnCircle = nextOnCircle;
78
+ }
79
+ /**
80
+ * Returns the bezier curve from the maximal disk of this [[CpNode]] to the
81
+ * next [[CpNode]]'s maximal disk and thus directly represents a piece of the
82
+ * medial axis.
83
+ * @deprecated Use [[getCurveToNext]] instead
84
+ * @param cpNode
85
+ */
86
+ get matCurveToNextVertex() {
87
+ return getCurveToNext(this);
88
+ }
89
+ /**
90
+ * Returns the children of this [[CpNode]] when seen as a MAT edge. Only
91
+ * children in a 'forward' direction are returned. These include all edges
92
+ * except the 'backward' edge given by [[prevOnCircle]], even terminating
93
+ * edges.
94
+ */
95
+ getChildren() {
96
+ const children = [];
97
+ const cp = this.next;
98
+ let cp_ = cp;
99
+ do {
100
+ children.push(cp_);
101
+ cp_ = cp_.nextOnCircle;
102
+ } while (cp_.nextOnCircle !== cp);
103
+ return children;
104
+ }
105
+ /**
106
+ * Similar to [[getChildren]] but returns the child nodes of the tree when
107
+ * [[CpNode]] is seen as a MAT vertex point (as opposed to edge). In this
108
+ * way the dual graph of the tree can easily be traversed - see e.g.
109
+ * [[traverseVertices]]. Generally, however, traversing the edges is
110
+ * preferred as it returns the entire Medial Axis (by utilizing
111
+ * [[getCurveToNext]] on each returned edge).
112
+ */
113
+ get vertexChildren() {
114
+ if (this.isTerminating()) {
115
+ return [];
116
+ }
117
+ const cp = this;
118
+ const children = [];
119
+ let cp_ = cp;
120
+ while (cp_ !== cp.prevOnCircle) {
121
+ if (!cp_.isTerminating()) {
122
+ children.push(cp_.next);
123
+ }
124
+ cp_ = cp_.nextOnCircle;
125
+ }
126
+ return children;
127
+ }
128
+ /**
129
+ * Returns all [[CpNode]]s on the MAT that this [[CpNode]] is part of
130
+ * starting from the current one and going anti-clockwise around the shape.
131
+ */
132
+ getAllOnLoop() {
133
+ const cpStart = this;
134
+ const cps = [cpStart];
135
+ let cp = this.next;
136
+ while (cp !== cpStart) {
137
+ cps.push(cp);
138
+ cp = cp.next;
139
+ }
140
+ return cps;
141
+ }
142
+ /**
143
+ * Primarily for internal use.
144
+ *
145
+ * Insert a [[CpNode]] into the MAT tree graph after the specified point
146
+ * and returns the freshly inserted [[CpNode]].
147
+ * @param isHoleClosing True if this is a hole closing contact point.
148
+ * @param isIntersection True if this is a contact point at a shape boundary
149
+ * intersection point.
150
+ * @param cpTree The tree graph holding the [[CpNodes]] of the MAT.
151
+ * @param cp [[ContactPoint]] defining the [[CpNode]].
152
+ * @param prev_ Inserts the new [[CpNode]] right after this item if the
153
+ * loop is not empty, else insert the new [[CpNode]] as the only item in the
154
+ * loop.
155
+ */
156
+ static insert(isHoleClosing, isIntersection, cpTree, cp, prev_) {
157
+ const cpNode = new CpNode(cp, isHoleClosing, isIntersection);
158
+ if (typeof _debug_ !== 'undefined') {
159
+ _debug_.generated.elems.cpNode.push({
160
+ generated: _debug_.generated,
161
+ cpNode
162
+ });
163
+ }
164
+ let prev;
165
+ let next;
166
+ if (!prev_) {
167
+ prev = cpNode;
168
+ next = cpNode;
169
+ }
170
+ else {
171
+ prev = prev_;
172
+ next = prev.next;
173
+ }
174
+ next.prev = cpNode;
175
+ prev.next = cpNode;
176
+ cpNode.prev = prev;
177
+ cpNode.next = next;
178
+ cpTree.insert(cpNode);
179
+ return cpNode;
180
+ }
181
+ /**
182
+ * Return this (except if exclThis is truthy) and the the other CpNodes
183
+ * around the maximal disk vertex circle in an anti-clockwise order.
184
+ * @param exclThis If true the returned array does not include this
185
+ * [[CpNode]].
186
+ */
187
+ getCpNodesOnCircle(exclThis = false) {
188
+ const startCp = this;
189
+ let cp = startCp;
190
+ const cps = [];
191
+ do {
192
+ if (exclThis) {
193
+ exclThis = false;
194
+ }
195
+ else {
196
+ cps.push(cp);
197
+ }
198
+ cp = cp.nextOnCircle;
199
+ } while (cp !== startCp);
200
+ return cps;
201
+ }
202
+ /**
203
+ * Returns true if the 2 given [[CpNode]]s are on the same maximal disk
204
+ * circle.
205
+ * @param cpNode1 A [[CpNode]].
206
+ * @param cpNode2 Another [[CpNode]]
207
+ */
208
+ static isOnSameCircle(cpNode1, cpNode2) {
209
+ const cpNodes = cpNode1.getCpNodesOnCircle(true);
210
+ return cpNodes.indexOf(cpNode2) >= 0;
211
+ }
212
+ /**
213
+ * Returns true if this [[CpNode]] is terminating, i.e. implies a leaf MAT
214
+ * vertex.
215
+ *
216
+ * This is always the case for sharp corners and maximal disks with
217
+ * a single contact point. Note, however, that even in these cases there are
218
+ * two contact points stored (sitting 'on top' of each other) for the
219
+ * maximal disk. It can be seen as a limiting case of a two-prong where the
220
+ * distance between two of the contact points tend to zero. One point
221
+ * (represented by a [[CpNode]] of course) will be terminating with the
222
+ * other point being its [[next]], whereas the other point will *not* be
223
+ * terminating and 'points' back into the shape.
224
+ */
225
+ isTerminating() {
226
+ return this === this.next.prevOnCircle;
227
+ }
228
+ /**
229
+ * Like isTerminating() but only returns true if all cpNodes on the circle
230
+ * (except this.prevOnCircle) is terminating.
231
+ */
232
+ isFullyTerminating() {
233
+ const otherOnCircle = this.prevOnCircle.getCpNodesOnCircle(true);
234
+ const isFullyTerminating = otherOnCircle.every(cpNode => cpNode.isTerminating());
235
+ return isFullyTerminating;
236
+ }
237
+ /**
238
+ * Returns the first [[CpNode]] (from this one by successively applying
239
+ * .nextOnCircle) that exits the circle.
240
+ */
241
+ getFirstExit() {
242
+ const startNode = this;
243
+ let cpNode = startNode;
244
+ while (cpNode.next === cpNode.prevOnCircle) {
245
+ cpNode = cpNode.next;
246
+ if (cpNode === startNode) {
247
+ // The very special case the MAT is a single point.
248
+ return undefined;
249
+ }
250
+ }
251
+ return cpNode;
252
+ }
253
+ /**
254
+ * Returns true if this [[CpNode]] represents a sharp corner, i.e. the
255
+ * limiting case of a two-prong having zero radius.
256
+ *
257
+ * Note that two [[CpNode]]s are stored for each sharp corner, one being
258
+ * terminating and one not. See [[isTerminating]] for more details.
259
+ */
260
+ isSharp() {
261
+ return this.cp.circle.radius === 0;
262
+ }
263
+ /**
264
+ * Returns true if this [[CpNode]]'s maximal disk has only one contact point
265
+ * on the shape boundary (up to planar coordinates). These includes sharp
266
+ * corners.
267
+ *
268
+ * Note, however, that two [[CpNode]]s are stored for each such point to
269
+ * preserve symmetry - see [[isTerminating]] for more details.
270
+ */
271
+ isOneProng() {
272
+ const cp1 = this;
273
+ if (cp1.cp.circle.radius === 0) {
274
+ return true;
275
+ }
276
+ const cp2 = cp1.nextOnCircle;
277
+ const p1 = cp1.cp.pointOnShape.p;
278
+ const p2 = cp2.cp.pointOnShape.p;
279
+ return (p1[0] === p2[0] && p1[1] === p2[1]);
280
+ }
281
+ /**
282
+ * Returns the number of contact points on the maximal disk circle implied
283
+ * by this [[CpNode]].
284
+ *
285
+ * Note, however, that even one-prongs and sharp corners will return 2 (see
286
+ * [[isTerminating]] for more details); if this is not desired use
287
+ * [[getRealProngCount]] instead which will return 1 in these cases.
288
+ */
289
+ getProngCount() {
290
+ const startCp = this;
291
+ let cp = startCp;
292
+ let i = 0;
293
+ do {
294
+ i++;
295
+ cp = cp.nextOnCircle;
296
+ } while (cp !== startCp);
297
+ return i;
298
+ }
299
+ /**
300
+ * Returns the number of contact points (up to planar coordinates) on the
301
+ * maximal disk circle implied by this [[CpNode]].
302
+ *
303
+ * See also [[getProngCount]].
304
+ */
305
+ getRealProngCount() {
306
+ if (this.isOneProng()) {
307
+ return 1;
308
+ }
309
+ return this.getProngCount();
310
+ }
311
+ }
312
+ /**
313
+ * Primarily for internal use.
314
+ *
315
+ * Compares the order of two [[CpNode]]s. The order is cyclic and depends
316
+ * on a [[CpNode]]'s relative position along the shape boundary.
317
+ */
318
+ CpNode.comparator = (a, b) => compareCps(a.cp, b.cp);
319
+ CpNode.remove = removeCpNode;
320
+ export { CpNode };
321
321
  //# sourceMappingURL=cp-node.js.map