@itwin/core-geometry 5.2.0-dev.7 → 5.3.0-dev.1

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 (438) hide show
  1. package/CHANGELOG.md +36 -1
  2. package/lib/cjs/Geometry.d.ts +30 -10
  3. package/lib/cjs/Geometry.d.ts.map +1 -1
  4. package/lib/cjs/Geometry.js +74 -10
  5. package/lib/cjs/Geometry.js.map +1 -1
  6. package/lib/cjs/bspline/AkimaCurve3d.d.ts +19 -6
  7. package/lib/cjs/bspline/AkimaCurve3d.d.ts.map +1 -1
  8. package/lib/cjs/bspline/AkimaCurve3d.js +21 -5
  9. package/lib/cjs/bspline/AkimaCurve3d.js.map +1 -1
  10. package/lib/cjs/bspline/BSplineCurve.d.ts +3 -3
  11. package/lib/cjs/bspline/BSplineCurve.d.ts.map +1 -1
  12. package/lib/cjs/bspline/BSplineCurve.js +6 -6
  13. package/lib/cjs/bspline/BSplineCurve.js.map +1 -1
  14. package/lib/cjs/bspline/BSplineCurveOps.d.ts.map +1 -1
  15. package/lib/cjs/bspline/BSplineCurveOps.js +1 -1
  16. package/lib/cjs/bspline/BSplineCurveOps.js.map +1 -1
  17. package/lib/cjs/bspline/BezierCurveBase.d.ts +2 -2
  18. package/lib/cjs/bspline/BezierCurveBase.d.ts.map +1 -1
  19. package/lib/cjs/bspline/BezierCurveBase.js +4 -6
  20. package/lib/cjs/bspline/BezierCurveBase.js.map +1 -1
  21. package/lib/cjs/bspline/InterpolationCurve3d.d.ts +27 -17
  22. package/lib/cjs/bspline/InterpolationCurve3d.d.ts.map +1 -1
  23. package/lib/cjs/bspline/InterpolationCurve3d.js +17 -7
  24. package/lib/cjs/bspline/InterpolationCurve3d.js.map +1 -1
  25. package/lib/cjs/clipping/ClipPlane.d.ts +19 -6
  26. package/lib/cjs/clipping/ClipPlane.d.ts.map +1 -1
  27. package/lib/cjs/clipping/ClipPlane.js +17 -2
  28. package/lib/cjs/clipping/ClipPlane.js.map +1 -1
  29. package/lib/cjs/clipping/ClipUtils.d.ts +14 -1
  30. package/lib/cjs/clipping/ClipUtils.d.ts.map +1 -1
  31. package/lib/cjs/clipping/ClipUtils.js +21 -3
  32. package/lib/cjs/clipping/ClipUtils.js.map +1 -1
  33. package/lib/cjs/clipping/ConvexClipPlaneSet.d.ts +14 -11
  34. package/lib/cjs/clipping/ConvexClipPlaneSet.d.ts.map +1 -1
  35. package/lib/cjs/clipping/ConvexClipPlaneSet.js +23 -16
  36. package/lib/cjs/clipping/ConvexClipPlaneSet.js.map +1 -1
  37. package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.d.ts +20 -3
  38. package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.d.ts.map +1 -1
  39. package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.js +22 -5
  40. package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.js.map +1 -1
  41. package/lib/cjs/curve/Arc3d.d.ts +27 -17
  42. package/lib/cjs/curve/Arc3d.d.ts.map +1 -1
  43. package/lib/cjs/curve/Arc3d.js +61 -35
  44. package/lib/cjs/curve/Arc3d.js.map +1 -1
  45. package/lib/cjs/curve/CurveCollection.d.ts +1 -0
  46. package/lib/cjs/curve/CurveCollection.d.ts.map +1 -1
  47. package/lib/cjs/curve/CurveCollection.js +1 -0
  48. package/lib/cjs/curve/CurveCollection.js.map +1 -1
  49. package/lib/cjs/curve/CurveLocationDetail.d.ts +8 -7
  50. package/lib/cjs/curve/CurveLocationDetail.d.ts.map +1 -1
  51. package/lib/cjs/curve/CurveLocationDetail.js.map +1 -1
  52. package/lib/cjs/curve/CurveOps.d.ts +51 -1
  53. package/lib/cjs/curve/CurveOps.d.ts.map +1 -1
  54. package/lib/cjs/curve/CurveOps.js +97 -3
  55. package/lib/cjs/curve/CurveOps.js.map +1 -1
  56. package/lib/cjs/curve/LineString3d.d.ts +4 -4
  57. package/lib/cjs/curve/LineString3d.d.ts.map +1 -1
  58. package/lib/cjs/curve/LineString3d.js +8 -8
  59. package/lib/cjs/curve/LineString3d.js.map +1 -1
  60. package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.js +3 -3
  61. package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
  62. package/lib/cjs/curve/Query/PlanarSubdivision.d.ts +6 -2
  63. package/lib/cjs/curve/Query/PlanarSubdivision.d.ts.map +1 -1
  64. package/lib/cjs/curve/Query/PlanarSubdivision.js +12 -7
  65. package/lib/cjs/curve/Query/PlanarSubdivision.js.map +1 -1
  66. package/lib/cjs/curve/RegionOps.d.ts +9 -4
  67. package/lib/cjs/curve/RegionOps.d.ts.map +1 -1
  68. package/lib/cjs/curve/RegionOps.js +10 -5
  69. package/lib/cjs/curve/RegionOps.js.map +1 -1
  70. package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -1
  71. package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js +2 -1
  72. package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
  73. package/lib/cjs/curve/internalContexts/MultiChainCollector.d.ts +4 -4
  74. package/lib/cjs/curve/internalContexts/MultiChainCollector.d.ts.map +1 -1
  75. package/lib/cjs/curve/internalContexts/MultiChainCollector.js +21 -18
  76. package/lib/cjs/curve/internalContexts/MultiChainCollector.js.map +1 -1
  77. package/lib/cjs/curve/internalContexts/PolygonOffsetContext.d.ts.map +1 -1
  78. package/lib/cjs/curve/internalContexts/PolygonOffsetContext.js +30 -50
  79. package/lib/cjs/curve/internalContexts/PolygonOffsetContext.js.map +1 -1
  80. package/lib/cjs/curve/spiral/DirectSpiral3d.d.ts +2 -2
  81. package/lib/cjs/curve/spiral/DirectSpiral3d.d.ts.map +1 -1
  82. package/lib/cjs/curve/spiral/DirectSpiral3d.js +6 -2
  83. package/lib/cjs/curve/spiral/DirectSpiral3d.js.map +1 -1
  84. package/lib/cjs/curve/spiral/IntegratedSpiral3d.d.ts +2 -2
  85. package/lib/cjs/curve/spiral/IntegratedSpiral3d.d.ts.map +1 -1
  86. package/lib/cjs/curve/spiral/IntegratedSpiral3d.js +6 -2
  87. package/lib/cjs/curve/spiral/IntegratedSpiral3d.js.map +1 -1
  88. package/lib/cjs/curve/spiral/TransitionSpiral3d.d.ts +5 -1
  89. package/lib/cjs/curve/spiral/TransitionSpiral3d.d.ts.map +1 -1
  90. package/lib/cjs/curve/spiral/TransitionSpiral3d.js +0 -3
  91. package/lib/cjs/curve/spiral/TransitionSpiral3d.js.map +1 -1
  92. package/lib/cjs/geometry3d/AngleSweep.d.ts +6 -2
  93. package/lib/cjs/geometry3d/AngleSweep.d.ts.map +1 -1
  94. package/lib/cjs/geometry3d/AngleSweep.js +12 -3
  95. package/lib/cjs/geometry3d/AngleSweep.js.map +1 -1
  96. package/lib/cjs/geometry3d/FrameBuilder.d.ts +2 -1
  97. package/lib/cjs/geometry3d/FrameBuilder.d.ts.map +1 -1
  98. package/lib/cjs/geometry3d/FrameBuilder.js +14 -18
  99. package/lib/cjs/geometry3d/FrameBuilder.js.map +1 -1
  100. package/lib/cjs/geometry3d/Matrix3d.d.ts +1 -1
  101. package/lib/cjs/geometry3d/Matrix3d.js +1 -1
  102. package/lib/cjs/geometry3d/Matrix3d.js.map +1 -1
  103. package/lib/cjs/geometry3d/Point2dVector2d.d.ts +18 -2
  104. package/lib/cjs/geometry3d/Point2dVector2d.d.ts.map +1 -1
  105. package/lib/cjs/geometry3d/Point2dVector2d.js +37 -4
  106. package/lib/cjs/geometry3d/Point2dVector2d.js.map +1 -1
  107. package/lib/cjs/geometry3d/Point3dVector3d.d.ts +1 -1
  108. package/lib/cjs/geometry3d/Point3dVector3d.d.ts.map +1 -1
  109. package/lib/cjs/geometry3d/Point3dVector3d.js +1 -0
  110. package/lib/cjs/geometry3d/Point3dVector3d.js.map +1 -1
  111. package/lib/cjs/geometry3d/PointStreaming.d.ts +8 -0
  112. package/lib/cjs/geometry3d/PointStreaming.d.ts.map +1 -1
  113. package/lib/cjs/geometry3d/PointStreaming.js +18 -2
  114. package/lib/cjs/geometry3d/PointStreaming.js.map +1 -1
  115. package/lib/cjs/geometry3d/PolygonOps.d.ts +18 -9
  116. package/lib/cjs/geometry3d/PolygonOps.d.ts.map +1 -1
  117. package/lib/cjs/geometry3d/PolygonOps.js +53 -26
  118. package/lib/cjs/geometry3d/PolygonOps.js.map +1 -1
  119. package/lib/cjs/geometry3d/PolylineCompressionByEdgeOffset.d.ts +8 -2
  120. package/lib/cjs/geometry3d/PolylineCompressionByEdgeOffset.d.ts.map +1 -1
  121. package/lib/cjs/geometry3d/PolylineCompressionByEdgeOffset.js +10 -4
  122. package/lib/cjs/geometry3d/PolylineCompressionByEdgeOffset.js.map +1 -1
  123. package/lib/cjs/geometry3d/PolylineOps.d.ts +14 -3
  124. package/lib/cjs/geometry3d/PolylineOps.d.ts.map +1 -1
  125. package/lib/cjs/geometry3d/PolylineOps.js +20 -4
  126. package/lib/cjs/geometry3d/PolylineOps.js.map +1 -1
  127. package/lib/cjs/geometry3d/Range.d.ts +34 -32
  128. package/lib/cjs/geometry3d/Range.d.ts.map +1 -1
  129. package/lib/cjs/geometry3d/Range.js +28 -21
  130. package/lib/cjs/geometry3d/Range.js.map +1 -1
  131. package/lib/cjs/geometry3d/Ray2d.d.ts +16 -6
  132. package/lib/cjs/geometry3d/Ray2d.d.ts.map +1 -1
  133. package/lib/cjs/geometry3d/Ray2d.js +28 -4
  134. package/lib/cjs/geometry3d/Ray2d.js.map +1 -1
  135. package/lib/cjs/geometry3d/Ray3d.d.ts.map +1 -1
  136. package/lib/cjs/geometry3d/Ray3d.js +3 -4
  137. package/lib/cjs/geometry3d/Ray3d.js.map +1 -1
  138. package/lib/cjs/geometry3d/Transform.d.ts +1 -1
  139. package/lib/cjs/geometry3d/Transform.js +1 -1
  140. package/lib/cjs/geometry3d/Transform.js.map +1 -1
  141. package/lib/cjs/geometry3d/XYZProps.d.ts +12 -1
  142. package/lib/cjs/geometry3d/XYZProps.d.ts.map +1 -1
  143. package/lib/cjs/geometry3d/XYZProps.js +17 -2
  144. package/lib/cjs/geometry3d/XYZProps.js.map +1 -1
  145. package/lib/cjs/geometry4d/Matrix4d.d.ts +16 -0
  146. package/lib/cjs/geometry4d/Matrix4d.d.ts.map +1 -1
  147. package/lib/cjs/geometry4d/Matrix4d.js +26 -0
  148. package/lib/cjs/geometry4d/Matrix4d.js.map +1 -1
  149. package/lib/cjs/numerics/BezierPolynomials.d.ts.map +1 -1
  150. package/lib/cjs/numerics/BezierPolynomials.js +5 -9
  151. package/lib/cjs/numerics/BezierPolynomials.js.map +1 -1
  152. package/lib/cjs/numerics/SmallSystem.d.ts +13 -7
  153. package/lib/cjs/numerics/SmallSystem.d.ts.map +1 -1
  154. package/lib/cjs/numerics/SmallSystem.js +13 -7
  155. package/lib/cjs/numerics/SmallSystem.js.map +1 -1
  156. package/lib/cjs/polyface/Polyface.d.ts +1 -3
  157. package/lib/cjs/polyface/Polyface.d.ts.map +1 -1
  158. package/lib/cjs/polyface/Polyface.js +2 -6
  159. package/lib/cjs/polyface/Polyface.js.map +1 -1
  160. package/lib/cjs/polyface/PolyfaceBuilder.d.ts +25 -6
  161. package/lib/cjs/polyface/PolyfaceBuilder.d.ts.map +1 -1
  162. package/lib/cjs/polyface/PolyfaceBuilder.js +59 -8
  163. package/lib/cjs/polyface/PolyfaceBuilder.js.map +1 -1
  164. package/lib/cjs/polyface/PolyfaceData.d.ts +2 -0
  165. package/lib/cjs/polyface/PolyfaceData.d.ts.map +1 -1
  166. package/lib/cjs/polyface/PolyfaceData.js +7 -3
  167. package/lib/cjs/polyface/PolyfaceData.js.map +1 -1
  168. package/lib/cjs/polyface/PolyfaceQuery.d.ts.map +1 -1
  169. package/lib/cjs/polyface/PolyfaceQuery.js +8 -10
  170. package/lib/cjs/polyface/PolyfaceQuery.js.map +1 -1
  171. package/lib/cjs/polyface/RangeTree/Point3dArrayRangeTreeContext.d.ts +8 -5
  172. package/lib/cjs/polyface/RangeTree/Point3dArrayRangeTreeContext.d.ts.map +1 -1
  173. package/lib/cjs/polyface/RangeTree/Point3dArrayRangeTreeContext.js +8 -4
  174. package/lib/cjs/polyface/RangeTree/Point3dArrayRangeTreeContext.js.map +1 -1
  175. package/lib/cjs/polyface/RangeTree/PolyfaceRangeTreeContext.d.ts +3 -3
  176. package/lib/cjs/polyface/RangeTree/PolyfaceRangeTreeContext.d.ts.map +1 -1
  177. package/lib/cjs/polyface/RangeTree/PolyfaceRangeTreeContext.js +1 -1
  178. package/lib/cjs/polyface/RangeTree/PolyfaceRangeTreeContext.js.map +1 -1
  179. package/lib/cjs/polyface/RangeTree/RangeTreeNode.d.ts +4 -2
  180. package/lib/cjs/polyface/RangeTree/RangeTreeNode.d.ts.map +1 -1
  181. package/lib/cjs/polyface/RangeTree/RangeTreeNode.js +9 -12
  182. package/lib/cjs/polyface/RangeTree/RangeTreeNode.js.map +1 -1
  183. package/lib/cjs/polyface/RangeTree/RangeTreeSearchHandlers.d.ts +8 -3
  184. package/lib/cjs/polyface/RangeTree/RangeTreeSearchHandlers.d.ts.map +1 -1
  185. package/lib/cjs/polyface/RangeTree/RangeTreeSearchHandlers.js +13 -6
  186. package/lib/cjs/polyface/RangeTree/RangeTreeSearchHandlers.js.map +1 -1
  187. package/lib/cjs/serialization/DeepCompare.js +1 -1
  188. package/lib/cjs/serialization/DeepCompare.js.map +1 -1
  189. package/lib/cjs/serialization/GeometrySamples.d.ts +2 -1
  190. package/lib/cjs/serialization/GeometrySamples.d.ts.map +1 -1
  191. package/lib/cjs/serialization/GeometrySamples.js +2 -1
  192. package/lib/cjs/serialization/GeometrySamples.js.map +1 -1
  193. package/lib/cjs/topology/Graph.d.ts +38 -12
  194. package/lib/cjs/topology/Graph.d.ts.map +1 -1
  195. package/lib/cjs/topology/Graph.js +91 -23
  196. package/lib/cjs/topology/Graph.js.map +1 -1
  197. package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.d.ts +5 -4
  198. package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.d.ts.map +1 -1
  199. package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.js +6 -5
  200. package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.js.map +1 -1
  201. package/lib/cjs/topology/HalfEdgeGraphSearch.d.ts +20 -11
  202. package/lib/cjs/topology/HalfEdgeGraphSearch.d.ts.map +1 -1
  203. package/lib/cjs/topology/HalfEdgeGraphSearch.js +43 -39
  204. package/lib/cjs/topology/HalfEdgeGraphSearch.js.map +1 -1
  205. package/lib/cjs/topology/Merging.d.ts +7 -4
  206. package/lib/cjs/topology/Merging.d.ts.map +1 -1
  207. package/lib/cjs/topology/Merging.js +16 -11
  208. package/lib/cjs/topology/Merging.js.map +1 -1
  209. package/lib/cjs/topology/Triangulation.d.ts +13 -11
  210. package/lib/cjs/topology/Triangulation.d.ts.map +1 -1
  211. package/lib/cjs/topology/Triangulation.js +40 -36
  212. package/lib/cjs/topology/Triangulation.js.map +1 -1
  213. package/lib/cjs/topology/Voronoi.d.ts +195 -0
  214. package/lib/cjs/topology/Voronoi.d.ts.map +1 -0
  215. package/lib/cjs/topology/Voronoi.js +700 -0
  216. package/lib/cjs/topology/Voronoi.js.map +1 -0
  217. package/lib/cjs/topology/XYParitySearchContext.d.ts +1 -1
  218. package/lib/cjs/topology/XYParitySearchContext.d.ts.map +1 -1
  219. package/lib/cjs/topology/XYParitySearchContext.js.map +1 -1
  220. package/lib/esm/Geometry.d.ts +30 -10
  221. package/lib/esm/Geometry.d.ts.map +1 -1
  222. package/lib/esm/Geometry.js +74 -10
  223. package/lib/esm/Geometry.js.map +1 -1
  224. package/lib/esm/bspline/AkimaCurve3d.d.ts +19 -6
  225. package/lib/esm/bspline/AkimaCurve3d.d.ts.map +1 -1
  226. package/lib/esm/bspline/AkimaCurve3d.js +21 -5
  227. package/lib/esm/bspline/AkimaCurve3d.js.map +1 -1
  228. package/lib/esm/bspline/BSplineCurve.d.ts +3 -3
  229. package/lib/esm/bspline/BSplineCurve.d.ts.map +1 -1
  230. package/lib/esm/bspline/BSplineCurve.js +6 -6
  231. package/lib/esm/bspline/BSplineCurve.js.map +1 -1
  232. package/lib/esm/bspline/BSplineCurveOps.d.ts.map +1 -1
  233. package/lib/esm/bspline/BSplineCurveOps.js +1 -1
  234. package/lib/esm/bspline/BSplineCurveOps.js.map +1 -1
  235. package/lib/esm/bspline/BezierCurveBase.d.ts +2 -2
  236. package/lib/esm/bspline/BezierCurveBase.d.ts.map +1 -1
  237. package/lib/esm/bspline/BezierCurveBase.js +4 -6
  238. package/lib/esm/bspline/BezierCurveBase.js.map +1 -1
  239. package/lib/esm/bspline/InterpolationCurve3d.d.ts +27 -17
  240. package/lib/esm/bspline/InterpolationCurve3d.d.ts.map +1 -1
  241. package/lib/esm/bspline/InterpolationCurve3d.js +17 -7
  242. package/lib/esm/bspline/InterpolationCurve3d.js.map +1 -1
  243. package/lib/esm/clipping/ClipPlane.d.ts +19 -6
  244. package/lib/esm/clipping/ClipPlane.d.ts.map +1 -1
  245. package/lib/esm/clipping/ClipPlane.js +17 -2
  246. package/lib/esm/clipping/ClipPlane.js.map +1 -1
  247. package/lib/esm/clipping/ClipUtils.d.ts +14 -1
  248. package/lib/esm/clipping/ClipUtils.d.ts.map +1 -1
  249. package/lib/esm/clipping/ClipUtils.js +21 -3
  250. package/lib/esm/clipping/ClipUtils.js.map +1 -1
  251. package/lib/esm/clipping/ConvexClipPlaneSet.d.ts +14 -11
  252. package/lib/esm/clipping/ConvexClipPlaneSet.d.ts.map +1 -1
  253. package/lib/esm/clipping/ConvexClipPlaneSet.js +23 -16
  254. package/lib/esm/clipping/ConvexClipPlaneSet.js.map +1 -1
  255. package/lib/esm/clipping/UnionOfConvexClipPlaneSets.d.ts +20 -3
  256. package/lib/esm/clipping/UnionOfConvexClipPlaneSets.d.ts.map +1 -1
  257. package/lib/esm/clipping/UnionOfConvexClipPlaneSets.js +22 -5
  258. package/lib/esm/clipping/UnionOfConvexClipPlaneSets.js.map +1 -1
  259. package/lib/esm/curve/Arc3d.d.ts +27 -17
  260. package/lib/esm/curve/Arc3d.d.ts.map +1 -1
  261. package/lib/esm/curve/Arc3d.js +61 -35
  262. package/lib/esm/curve/Arc3d.js.map +1 -1
  263. package/lib/esm/curve/CurveCollection.d.ts +1 -0
  264. package/lib/esm/curve/CurveCollection.d.ts.map +1 -1
  265. package/lib/esm/curve/CurveCollection.js +1 -0
  266. package/lib/esm/curve/CurveCollection.js.map +1 -1
  267. package/lib/esm/curve/CurveLocationDetail.d.ts +8 -7
  268. package/lib/esm/curve/CurveLocationDetail.d.ts.map +1 -1
  269. package/lib/esm/curve/CurveLocationDetail.js.map +1 -1
  270. package/lib/esm/curve/CurveOps.d.ts +51 -1
  271. package/lib/esm/curve/CurveOps.d.ts.map +1 -1
  272. package/lib/esm/curve/CurveOps.js +98 -4
  273. package/lib/esm/curve/CurveOps.js.map +1 -1
  274. package/lib/esm/curve/LineString3d.d.ts +4 -4
  275. package/lib/esm/curve/LineString3d.d.ts.map +1 -1
  276. package/lib/esm/curve/LineString3d.js +8 -8
  277. package/lib/esm/curve/LineString3d.js.map +1 -1
  278. package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.js +3 -3
  279. package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
  280. package/lib/esm/curve/Query/PlanarSubdivision.d.ts +6 -2
  281. package/lib/esm/curve/Query/PlanarSubdivision.d.ts.map +1 -1
  282. package/lib/esm/curve/Query/PlanarSubdivision.js +12 -7
  283. package/lib/esm/curve/Query/PlanarSubdivision.js.map +1 -1
  284. package/lib/esm/curve/RegionOps.d.ts +9 -4
  285. package/lib/esm/curve/RegionOps.d.ts.map +1 -1
  286. package/lib/esm/curve/RegionOps.js +10 -5
  287. package/lib/esm/curve/RegionOps.js.map +1 -1
  288. package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -1
  289. package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js +2 -1
  290. package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
  291. package/lib/esm/curve/internalContexts/MultiChainCollector.d.ts +4 -4
  292. package/lib/esm/curve/internalContexts/MultiChainCollector.d.ts.map +1 -1
  293. package/lib/esm/curve/internalContexts/MultiChainCollector.js +21 -18
  294. package/lib/esm/curve/internalContexts/MultiChainCollector.js.map +1 -1
  295. package/lib/esm/curve/internalContexts/PolygonOffsetContext.d.ts.map +1 -1
  296. package/lib/esm/curve/internalContexts/PolygonOffsetContext.js +30 -50
  297. package/lib/esm/curve/internalContexts/PolygonOffsetContext.js.map +1 -1
  298. package/lib/esm/curve/spiral/DirectSpiral3d.d.ts +2 -2
  299. package/lib/esm/curve/spiral/DirectSpiral3d.d.ts.map +1 -1
  300. package/lib/esm/curve/spiral/DirectSpiral3d.js +6 -2
  301. package/lib/esm/curve/spiral/DirectSpiral3d.js.map +1 -1
  302. package/lib/esm/curve/spiral/IntegratedSpiral3d.d.ts +2 -2
  303. package/lib/esm/curve/spiral/IntegratedSpiral3d.d.ts.map +1 -1
  304. package/lib/esm/curve/spiral/IntegratedSpiral3d.js +6 -2
  305. package/lib/esm/curve/spiral/IntegratedSpiral3d.js.map +1 -1
  306. package/lib/esm/curve/spiral/TransitionSpiral3d.d.ts +5 -1
  307. package/lib/esm/curve/spiral/TransitionSpiral3d.d.ts.map +1 -1
  308. package/lib/esm/curve/spiral/TransitionSpiral3d.js +0 -3
  309. package/lib/esm/curve/spiral/TransitionSpiral3d.js.map +1 -1
  310. package/lib/esm/geometry3d/AngleSweep.d.ts +6 -2
  311. package/lib/esm/geometry3d/AngleSweep.d.ts.map +1 -1
  312. package/lib/esm/geometry3d/AngleSweep.js +12 -3
  313. package/lib/esm/geometry3d/AngleSweep.js.map +1 -1
  314. package/lib/esm/geometry3d/FrameBuilder.d.ts +2 -1
  315. package/lib/esm/geometry3d/FrameBuilder.d.ts.map +1 -1
  316. package/lib/esm/geometry3d/FrameBuilder.js +14 -18
  317. package/lib/esm/geometry3d/FrameBuilder.js.map +1 -1
  318. package/lib/esm/geometry3d/Matrix3d.d.ts +1 -1
  319. package/lib/esm/geometry3d/Matrix3d.js +1 -1
  320. package/lib/esm/geometry3d/Matrix3d.js.map +1 -1
  321. package/lib/esm/geometry3d/Point2dVector2d.d.ts +18 -2
  322. package/lib/esm/geometry3d/Point2dVector2d.d.ts.map +1 -1
  323. package/lib/esm/geometry3d/Point2dVector2d.js +37 -4
  324. package/lib/esm/geometry3d/Point2dVector2d.js.map +1 -1
  325. package/lib/esm/geometry3d/Point3dVector3d.d.ts +1 -1
  326. package/lib/esm/geometry3d/Point3dVector3d.d.ts.map +1 -1
  327. package/lib/esm/geometry3d/Point3dVector3d.js +1 -0
  328. package/lib/esm/geometry3d/Point3dVector3d.js.map +1 -1
  329. package/lib/esm/geometry3d/PointStreaming.d.ts +8 -0
  330. package/lib/esm/geometry3d/PointStreaming.d.ts.map +1 -1
  331. package/lib/esm/geometry3d/PointStreaming.js +18 -2
  332. package/lib/esm/geometry3d/PointStreaming.js.map +1 -1
  333. package/lib/esm/geometry3d/PolygonOps.d.ts +18 -9
  334. package/lib/esm/geometry3d/PolygonOps.d.ts.map +1 -1
  335. package/lib/esm/geometry3d/PolygonOps.js +53 -26
  336. package/lib/esm/geometry3d/PolygonOps.js.map +1 -1
  337. package/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.d.ts +8 -2
  338. package/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.d.ts.map +1 -1
  339. package/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js +10 -4
  340. package/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js.map +1 -1
  341. package/lib/esm/geometry3d/PolylineOps.d.ts +14 -3
  342. package/lib/esm/geometry3d/PolylineOps.d.ts.map +1 -1
  343. package/lib/esm/geometry3d/PolylineOps.js +20 -4
  344. package/lib/esm/geometry3d/PolylineOps.js.map +1 -1
  345. package/lib/esm/geometry3d/Range.d.ts +34 -32
  346. package/lib/esm/geometry3d/Range.d.ts.map +1 -1
  347. package/lib/esm/geometry3d/Range.js +28 -21
  348. package/lib/esm/geometry3d/Range.js.map +1 -1
  349. package/lib/esm/geometry3d/Ray2d.d.ts +16 -6
  350. package/lib/esm/geometry3d/Ray2d.d.ts.map +1 -1
  351. package/lib/esm/geometry3d/Ray2d.js +28 -4
  352. package/lib/esm/geometry3d/Ray2d.js.map +1 -1
  353. package/lib/esm/geometry3d/Ray3d.d.ts.map +1 -1
  354. package/lib/esm/geometry3d/Ray3d.js +3 -4
  355. package/lib/esm/geometry3d/Ray3d.js.map +1 -1
  356. package/lib/esm/geometry3d/Transform.d.ts +1 -1
  357. package/lib/esm/geometry3d/Transform.js +1 -1
  358. package/lib/esm/geometry3d/Transform.js.map +1 -1
  359. package/lib/esm/geometry3d/XYZProps.d.ts +12 -1
  360. package/lib/esm/geometry3d/XYZProps.d.ts.map +1 -1
  361. package/lib/esm/geometry3d/XYZProps.js +16 -1
  362. package/lib/esm/geometry3d/XYZProps.js.map +1 -1
  363. package/lib/esm/geometry4d/Matrix4d.d.ts +16 -0
  364. package/lib/esm/geometry4d/Matrix4d.d.ts.map +1 -1
  365. package/lib/esm/geometry4d/Matrix4d.js +26 -0
  366. package/lib/esm/geometry4d/Matrix4d.js.map +1 -1
  367. package/lib/esm/numerics/BezierPolynomials.d.ts.map +1 -1
  368. package/lib/esm/numerics/BezierPolynomials.js +5 -9
  369. package/lib/esm/numerics/BezierPolynomials.js.map +1 -1
  370. package/lib/esm/numerics/SmallSystem.d.ts +13 -7
  371. package/lib/esm/numerics/SmallSystem.d.ts.map +1 -1
  372. package/lib/esm/numerics/SmallSystem.js +13 -7
  373. package/lib/esm/numerics/SmallSystem.js.map +1 -1
  374. package/lib/esm/polyface/Polyface.d.ts +1 -3
  375. package/lib/esm/polyface/Polyface.d.ts.map +1 -1
  376. package/lib/esm/polyface/Polyface.js +2 -6
  377. package/lib/esm/polyface/Polyface.js.map +1 -1
  378. package/lib/esm/polyface/PolyfaceBuilder.d.ts +25 -6
  379. package/lib/esm/polyface/PolyfaceBuilder.d.ts.map +1 -1
  380. package/lib/esm/polyface/PolyfaceBuilder.js +59 -8
  381. package/lib/esm/polyface/PolyfaceBuilder.js.map +1 -1
  382. package/lib/esm/polyface/PolyfaceData.d.ts +2 -0
  383. package/lib/esm/polyface/PolyfaceData.d.ts.map +1 -1
  384. package/lib/esm/polyface/PolyfaceData.js +7 -3
  385. package/lib/esm/polyface/PolyfaceData.js.map +1 -1
  386. package/lib/esm/polyface/PolyfaceQuery.d.ts.map +1 -1
  387. package/lib/esm/polyface/PolyfaceQuery.js +8 -10
  388. package/lib/esm/polyface/PolyfaceQuery.js.map +1 -1
  389. package/lib/esm/polyface/RangeTree/Point3dArrayRangeTreeContext.d.ts +8 -5
  390. package/lib/esm/polyface/RangeTree/Point3dArrayRangeTreeContext.d.ts.map +1 -1
  391. package/lib/esm/polyface/RangeTree/Point3dArrayRangeTreeContext.js +8 -4
  392. package/lib/esm/polyface/RangeTree/Point3dArrayRangeTreeContext.js.map +1 -1
  393. package/lib/esm/polyface/RangeTree/PolyfaceRangeTreeContext.d.ts +3 -3
  394. package/lib/esm/polyface/RangeTree/PolyfaceRangeTreeContext.d.ts.map +1 -1
  395. package/lib/esm/polyface/RangeTree/PolyfaceRangeTreeContext.js +1 -1
  396. package/lib/esm/polyface/RangeTree/PolyfaceRangeTreeContext.js.map +1 -1
  397. package/lib/esm/polyface/RangeTree/RangeTreeNode.d.ts +4 -2
  398. package/lib/esm/polyface/RangeTree/RangeTreeNode.d.ts.map +1 -1
  399. package/lib/esm/polyface/RangeTree/RangeTreeNode.js +9 -12
  400. package/lib/esm/polyface/RangeTree/RangeTreeNode.js.map +1 -1
  401. package/lib/esm/polyface/RangeTree/RangeTreeSearchHandlers.d.ts +8 -3
  402. package/lib/esm/polyface/RangeTree/RangeTreeSearchHandlers.d.ts.map +1 -1
  403. package/lib/esm/polyface/RangeTree/RangeTreeSearchHandlers.js +13 -6
  404. package/lib/esm/polyface/RangeTree/RangeTreeSearchHandlers.js.map +1 -1
  405. package/lib/esm/serialization/DeepCompare.js +1 -1
  406. package/lib/esm/serialization/DeepCompare.js.map +1 -1
  407. package/lib/esm/serialization/GeometrySamples.d.ts +2 -1
  408. package/lib/esm/serialization/GeometrySamples.d.ts.map +1 -1
  409. package/lib/esm/serialization/GeometrySamples.js +2 -1
  410. package/lib/esm/serialization/GeometrySamples.js.map +1 -1
  411. package/lib/esm/topology/Graph.d.ts +38 -12
  412. package/lib/esm/topology/Graph.d.ts.map +1 -1
  413. package/lib/esm/topology/Graph.js +92 -24
  414. package/lib/esm/topology/Graph.js.map +1 -1
  415. package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.d.ts +5 -4
  416. package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.d.ts.map +1 -1
  417. package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js +6 -5
  418. package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js.map +1 -1
  419. package/lib/esm/topology/HalfEdgeGraphSearch.d.ts +20 -11
  420. package/lib/esm/topology/HalfEdgeGraphSearch.d.ts.map +1 -1
  421. package/lib/esm/topology/HalfEdgeGraphSearch.js +43 -39
  422. package/lib/esm/topology/HalfEdgeGraphSearch.js.map +1 -1
  423. package/lib/esm/topology/Merging.d.ts +7 -4
  424. package/lib/esm/topology/Merging.d.ts.map +1 -1
  425. package/lib/esm/topology/Merging.js +17 -12
  426. package/lib/esm/topology/Merging.js.map +1 -1
  427. package/lib/esm/topology/Triangulation.d.ts +13 -11
  428. package/lib/esm/topology/Triangulation.d.ts.map +1 -1
  429. package/lib/esm/topology/Triangulation.js +40 -36
  430. package/lib/esm/topology/Triangulation.js.map +1 -1
  431. package/lib/esm/topology/Voronoi.d.ts +195 -0
  432. package/lib/esm/topology/Voronoi.d.ts.map +1 -0
  433. package/lib/esm/topology/Voronoi.js +696 -0
  434. package/lib/esm/topology/Voronoi.js.map +1 -0
  435. package/lib/esm/topology/XYParitySearchContext.d.ts +1 -1
  436. package/lib/esm/topology/XYParitySearchContext.d.ts.map +1 -1
  437. package/lib/esm/topology/XYParitySearchContext.js.map +1 -1
  438. package/package.json +3 -3
@@ -0,0 +1,696 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ /** @packageDocumentation
6
+ * @module Bspline
7
+ */
8
+ import { assert, Dictionary, DuplicatePolicy, SortedArray } from "@itwin/core-bentley";
9
+ import { ClipPlane } from "../clipping/ClipPlane";
10
+ import { ConvexClipPlaneSet } from "../clipping/ConvexClipPlaneSet";
11
+ import { UnionOfConvexClipPlaneSets } from "../clipping/UnionOfConvexClipPlaneSets";
12
+ import { Arc3d } from "../curve/Arc3d";
13
+ import { CurveCurve } from "../curve/CurveCurve";
14
+ import { CurveOps } from "../curve/CurveOps";
15
+ import { LineSegment3d } from "../curve/LineSegment3d";
16
+ import { LineString3d } from "../curve/LineString3d";
17
+ import { StrokeOptions } from "../curve/StrokeOptions";
18
+ import { Geometry } from "../Geometry";
19
+ import { Point2d, Vector2d } from "../geometry3d/Point2dVector2d";
20
+ import { Point3d } from "../geometry3d/Point3dVector3d";
21
+ import { PolylineOps } from "../geometry3d/PolylineOps";
22
+ import { Range2d } from "../geometry3d/Range";
23
+ import { Ray2d } from "../geometry3d/Ray2d";
24
+ import { Ray3d } from "../geometry3d/Ray3d";
25
+ import { XAndY } from "../geometry3d/XYZProps";
26
+ import { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from "./Graph";
27
+ import { HalfEdgeGraphSearch } from "./HalfEdgeGraphSearch";
28
+ import { HalfEdgeGraphMerge, HalfEdgeGraphOps } from "./Merging";
29
+ import { Triangulator } from "./Triangulation";
30
+ /**
31
+ * A class to represent a Voronoi diagram in the xy-plane.
32
+ * * A Voronoi diagram is a partitioning of the plane into regions of points closest to a given generating point or curve.
33
+ * * It is constructed from the circumcenters of its dual Delaunay triangulation.
34
+ * * Static construction methods take Delaunay, points, and CurveChain input.
35
+ * * More info can be found here: https://en.wikipedia.org/wiki/Voronoi_diagram and
36
+ * https://en.wikipedia.org/wiki/Delaunay_triangulation
37
+ * @internal
38
+ */
39
+ export class Voronoi {
40
+ _voronoiGraph;
41
+ _inputGraph;
42
+ _inputGraphIsTriangulation;
43
+ _inputGraphRange;
44
+ _idToIndexMap;
45
+ _circumcenterMap;
46
+ _circumcenterRange;
47
+ _isCurveBased;
48
+ _superFaceMask;
49
+ static _workXY0 = Point2d.createZero();
50
+ static _workXY1 = Point2d.createZero();
51
+ static _workRay = Ray2d.createZero();
52
+ static _workArc = Arc3d.createUnitCircle();
53
+ /** Construct an empty Voronoi graph and minimally validate input (use [[isValid]] to check). */
54
+ constructor(inputGraph, isColinear = false) {
55
+ this._voronoiGraph = new HalfEdgeGraph();
56
+ this._inputGraph = inputGraph;
57
+ this._inputGraphRange = HalfEdgeGraphOps.graphRangeXY(inputGraph);
58
+ this._idToIndexMap = inputGraph.constructIdToVertexIndexMap();
59
+ this._circumcenterMap = new Map();
60
+ this._inputGraphIsTriangulation = isColinear ? false : this.populateCircumcenters(this._circumcenterMap);
61
+ this._circumcenterRange = Range2d.createArray(Array.from(this._circumcenterMap.values()));
62
+ this._isCurveBased = false;
63
+ this._superFaceMask = HalfEdgeMask.NULL_MASK;
64
+ }
65
+ /**
66
+ * Accessor for the graph passed into the private constructor.
67
+ * * It is either a triangulation (assumed Delaunay) or a graph with no interior faces (assumed colinear path).
68
+ */
69
+ get getInputGraph() {
70
+ return this._inputGraph;
71
+ }
72
+ /** Accessor for the input graph's range */
73
+ get getInputGraphRange() {
74
+ return this._inputGraphRange;
75
+ }
76
+ /**
77
+ * Accessor for the Voronoi graph constructed from the input graph.
78
+ * * The Voronoi graph is typically constructed by static createFromXXX methods.
79
+ */
80
+ get getVoronoiGraph() {
81
+ return this._voronoiGraph;
82
+ }
83
+ /** Whether or not this instance represents a curve-based Voronoi diagram. */
84
+ get isCurveBased() {
85
+ return this._isCurveBased;
86
+ }
87
+ /** Accessor for the super face mask used for constructing a curve-based Voronoi diagram. */
88
+ get getSuperFaceMask() {
89
+ return this._superFaceMask;
90
+ }
91
+ /** Whether the constructor has created a minimally valid instance. */
92
+ get isValid() {
93
+ if (this._inputGraph.allHalfEdges.length < 2)
94
+ return false;
95
+ if (this._idToIndexMap.size === 0)
96
+ return false;
97
+ if (!this._inputGraphIsTriangulation)
98
+ return true;
99
+ return this._circumcenterMap.size > 0;
100
+ }
101
+ /** Add an edge to the graph and set its edgeTags. */
102
+ static addEdgeWithEdgeTags(graph, p0, p1, edgeTag0, edgeTag1) {
103
+ return graph.addEdgeXY(p0.x, p0.y, p1.x, p1.y, edgeTag0, edgeTag1);
104
+ }
105
+ /** Add an edge to the graph and set its faceTags. */
106
+ static addEdgeWithFaceTags(graph, p0, p1, faceTag0, faceTag1) {
107
+ return graph.addEdgeXY(p0.x, p0.y, p1.x, p1.y, undefined, undefined, faceTag0, faceTag1);
108
+ }
109
+ /** Return the smallest HalfEdge id in the face, or -1 if not a triangle. */
110
+ getTriangleId(face) {
111
+ if (face !== face.faceSuccessor.faceSuccessor.faceSuccessor)
112
+ return -1;
113
+ return Math.min(face.id, face.faceSuccessor.id, face.facePredecessor.id);
114
+ }
115
+ /**
116
+ * Populate a mapping from a triangle's id to its circumcircle.
117
+ * @returns whether the input graph is a triangulation.
118
+ */
119
+ populateCircumcenters(circumcenterMap) {
120
+ circumcenterMap.clear();
121
+ let isValid = true;
122
+ const p0 = Point3d.createZero();
123
+ const p1 = Point3d.createZero();
124
+ const p2 = Point3d.createZero();
125
+ this._inputGraph.announceFaceLoops((_g, face) => {
126
+ if (face.isMaskSet(HalfEdgeMask.EXTERIOR))
127
+ return true;
128
+ if (face.countEdgesAroundFace() !== 3)
129
+ return isValid = false;
130
+ face.getPoint3d(p0);
131
+ face.faceSuccessor.getPoint3d(p1);
132
+ face.facePredecessor.getPoint3d(p2);
133
+ p0.z = p1.z = p2.z = 0;
134
+ const circumcircle = Arc3d.createCircularStartMiddleEnd(p0, p1, p2, Voronoi._workArc);
135
+ if (circumcircle instanceof Arc3d) // ignore a degenerate triangle
136
+ circumcenterMap.set(this.getTriangleId(face), circumcircle.center); // getter clones center
137
+ return true;
138
+ });
139
+ if (!isValid)
140
+ circumcenterMap.clear();
141
+ return isValid;
142
+ }
143
+ /**
144
+ * Return a segment along the bisector of the given triangle edge with the following properties:
145
+ * * start point is the triangle's circumcenter
146
+ * * end point is on the Voronoi boundary
147
+ * * direction vector has positive dot product with the vector from triangle centroid to edge midpoint
148
+ * @returns bisector segment, or undefined if the triangle circumcenter lies outside the Voronoi boundary
149
+ */
150
+ getTriangleEdgeBisector(edge, circumcenter, box) {
151
+ const v0 = edge;
152
+ const v1 = edge.faceSuccessor;
153
+ const v2 = edge.facePredecessor;
154
+ const oneThird = 1.0 / 3.0;
155
+ const midPoint = Point2d.createAdd2ScaledXY(v0.x, v0.y, 0.5, v1.x, v1.y, 0.5);
156
+ const centroid = Point2d.createAdd3ScaledXY(v0.x, v0.y, oneThird, v1.x, v1.y, oneThird, v2.x, v2.y, oneThird);
157
+ const direction = Vector2d.createStartEnd(circumcenter, midPoint);
158
+ if (midPoint.dotVectorsToTargets(circumcenter, centroid) < 0)
159
+ direction.negate(direction); // ensure direction points away from triangle
160
+ const bisector = Ray2d.createOriginAndDirectionCapture(Point2d.createFrom(circumcenter), direction, Voronoi._workRay);
161
+ const fractions = box.intersect(bisector);
162
+ const haveTwoIntersections = undefined !== fractions && fractions.length === 2;
163
+ if (!haveTwoIntersections || (fractions[0] <= 0 && fractions[1] <= 0) || (fractions[0] >= 1 && fractions[1] >= 1))
164
+ return undefined; // bisector ray lies outside box
165
+ const start = bisector.fractionToPoint(Geometry.clamp(fractions[0], 0, 1), Voronoi._workXY0);
166
+ const end = bisector.fractionToPoint(fractions[1], Voronoi._workXY1);
167
+ return { start, end };
168
+ }
169
+ /** Add the edge of an unbounded Voronoi region that corresponds to a Delaunay boundary edge; clip it at the boundary. */
170
+ addVoronoiEdgeForDelaunayBoundaryEdge(edge, box) {
171
+ const triangleId = this.getTriangleId(edge);
172
+ if (triangleId < 0)
173
+ return false; // invalid graph (not a triangulation)
174
+ const circumcenter = this._circumcenterMap.get(triangleId);
175
+ if (!circumcenter)
176
+ return true; // skip Delaunay edge (degenerate boundary triangle)
177
+ const bisector = this.getTriangleEdgeBisector(edge, circumcenter, box);
178
+ if (!bisector)
179
+ return true; // skip Delaunay edge (bisector ray outside box)
180
+ const faceTag0 = this._idToIndexMap.get(edge.edgeMate.id);
181
+ const faceTag1 = this._idToIndexMap.get(edge.id);
182
+ Voronoi.addEdgeWithFaceTags(this._voronoiGraph, bisector.start, bisector.end, faceTag0, faceTag1);
183
+ return true;
184
+ }
185
+ /** Add the edge of a bounded Voronoi region that corresponds to a Delaunay interior edge. */
186
+ addVoronoiEdgeForDelaunayInteriorEdge(edge, box, distanceTol) {
187
+ const triangleId0 = this.getTriangleId(edge);
188
+ const triangleId1 = this.getTriangleId(edge.edgeMate);
189
+ if (triangleId0 < 0 || triangleId1 < 0)
190
+ return false; // invalid graph (not a triangulation)
191
+ const circumcenter0 = this._circumcenterMap.get(triangleId0);
192
+ const circumcenter1 = this._circumcenterMap.get(triangleId1);
193
+ if (!circumcenter0 && !circumcenter1)
194
+ return true; // skip Delaunay edge between degenerate triangles
195
+ if (!circumcenter0 || !circumcenter1) {
196
+ // only one triangle is degenerate; if it is a boundary triangle, treat the opposite edge as a boundary
197
+ if (!circumcenter0 && edge.findMaskAroundFace(HalfEdgeMask.BOUNDARY_EDGE))
198
+ return this.addVoronoiEdgeForDelaunayBoundaryEdge(edge.edgeMate, box);
199
+ if (!circumcenter1 && edge.edgeMate.findMaskAroundFace(HalfEdgeMask.BOUNDARY_EDGE))
200
+ return this.addVoronoiEdgeForDelaunayBoundaryEdge(edge, box);
201
+ return false; // invalid graph (interior degenerate triangle)
202
+ }
203
+ if (XAndY.almostEqual(circumcenter0, circumcenter1, distanceTol))
204
+ return true; // skip trivial Voronoi edge (it will collapse during clustering)
205
+ const segment = Ray2d.createOriginAndTarget(circumcenter0, circumcenter1, Voronoi._workRay);
206
+ const fractions = box.intersect(segment);
207
+ const haveTwoIntersections = undefined !== fractions && fractions.length === 2;
208
+ if (!haveTwoIntersections || (fractions[0] <= 0 && fractions[1] <= 0) || (fractions[0] >= 1 && fractions[1] >= 1))
209
+ return true; // skip Delaunay edge whose Voronoi segment is outside box
210
+ const pt0 = segment.fractionToPoint(Geometry.clamp(fractions[0], 0, 1), Voronoi._workXY0);
211
+ const pt1 = segment.fractionToPoint(Geometry.clamp(fractions[1], 0, 1), Voronoi._workXY1);
212
+ const faceTag0 = this._idToIndexMap.get(edge.edgeMate.id);
213
+ const faceTag1 = this._idToIndexMap.get(edge.id);
214
+ Voronoi.addEdgeWithFaceTags(this._voronoiGraph, pt0, pt1, faceTag0, faceTag1);
215
+ return true;
216
+ }
217
+ /** Mask the exterior face, and set missing interior face tags */
218
+ populateMasksAndFaceTags() {
219
+ this._voronoiGraph.announceFaceLoops((_g, face) => {
220
+ let faceTag;
221
+ let edge = face;
222
+ do { // look around the face for a faceTag
223
+ faceTag = edge.faceTag;
224
+ edge = edge.faceSuccessor;
225
+ } while (faceTag === undefined && edge !== face);
226
+ if (faceTag !== undefined) // ensure faceTag is set around the interior face
227
+ face.announceEdgesInFace((e) => e.faceTag = faceTag);
228
+ else // mask the edges of the exterior face
229
+ face.announceEdgesInFace((e) => { e.setMask(HalfEdgeMask.EXTERIOR); e.setMaskAroundEdge(HalfEdgeMask.BOUNDARY_EDGE); });
230
+ return true;
231
+ });
232
+ }
233
+ /**
234
+ * Construct a Voronoi instance from a Delaunay triangulation.
235
+ * * The Delaunay generating vertex `v` for a returned Voronoi region `R` is encoded thusly:
236
+ * * For each [[HalfEdge]] `e` in the face loop of `R`, `delaunayGraph.allHalfEdges[e.faceTag]` is a HalfEdge in the
237
+ * vertex loop of `v`.
238
+ * * The same `faceTag` is assigned to all HalfEdges in the face loop of `R`.
239
+ * * For best results:
240
+ * * The input triangulation should be Delaunay and have convex boundary.
241
+ * * Each HalfEdge in the exterior face loop of the input graph should have `HalfEdgeMask.BOUNDARY_EDGE` set on both edge mates.
242
+ * * Each HalfEdge in the exterior face loop of the input graph should have `HalfEdgeMask.EXTERIOR` set.
243
+ * * The input graph should not contain any pair of vertices closer than `distanceTol`.
244
+ * * The input graph should not contain any triangle altitude smaller than `distanceTol` (this is a degenerate triangle).
245
+ * @param delaunayGraph A HalfEdgeGraph representing a Delaunay triangulation. Z-coordinates are ignored.
246
+ * @param distanceTol Optional distance tolerance to use when comparing points; default is `Geometry.smallMetricDistance`.
247
+ * @param boundingBox Optional nominal xy-bounding box for the Voronoi diagram. Default uses the Delaunay circumcenter range so
248
+ * that interior Voronoi regions are maximal.
249
+ * @returns a new instance containing the Voronoi diagram derived from the input graph, or `undefined` if invalid input.
250
+ */
251
+ static createFromDelaunayGraph(delaunayGraph, distanceTol = Geometry.smallMetricDistance, boundingBox) {
252
+ const instance = new Voronoi(delaunayGraph);
253
+ if (!instance.isValid)
254
+ return undefined;
255
+ let isValidVoronoi = true;
256
+ const box = new VoronoiBoundary(instance._inputGraphRange, boundingBox ? boundingBox : instance._circumcenterRange);
257
+ // iterate Delaunay edges and add Voronoi edges:
258
+ // * for each boundary edge, add a bisector separating unbounded Voronoi cells
259
+ // * for each interior edge, add a segment joining the adjacent triangles' circumcenters
260
+ instance._inputGraph.announceEdges((_g, edge) => {
261
+ if (edge.isMaskSet(HalfEdgeMask.BOUNDARY_EDGE)) {
262
+ if (edge.isMaskSet(HalfEdgeMask.EXTERIOR))
263
+ edge = edge.edgeMate;
264
+ return isValidVoronoi = instance.addVoronoiEdgeForDelaunayBoundaryEdge(edge, box);
265
+ }
266
+ return isValidVoronoi = instance.addVoronoiEdgeForDelaunayInteriorEdge(edge, box, distanceTol);
267
+ });
268
+ if (!isValidVoronoi)
269
+ return undefined;
270
+ box.addEdgesToGraph(instance._voronoiGraph);
271
+ HalfEdgeGraphMerge.splitIntersectingEdges(instance._voronoiGraph, distanceTol);
272
+ HalfEdgeGraphMerge.clusterAndMergeXYTheta(instance._voronoiGraph, undefined, distanceTol);
273
+ instance.populateMasksAndFaceTags();
274
+ return instance;
275
+ }
276
+ /** Create a graph from ordered colinear points; optional Dictionary supplies edgeTag for the HalfEdges at each vertex. */
277
+ static createColinearXYGraph(points) {
278
+ const colinearGraph = new HalfEdgeGraph();
279
+ let indices;
280
+ if (!Array.isArray(points)) {
281
+ indices = Array.from(points.values());
282
+ points = Array.from(points.keys());
283
+ }
284
+ if (points.length < 2)
285
+ return colinearGraph; // empty
286
+ let prevNode = this.addEdgeWithEdgeTags(colinearGraph, points[0], points[1], indices ? indices[0] : 0, indices ? indices[1] : 0);
287
+ for (let i = 1; i < points.length - 1; i++) {
288
+ const nextNode = this.addEdgeWithEdgeTags(colinearGraph, points[i], points[i + 1], indices ? indices[i] : 0, indices ? indices[i + 1] : 0);
289
+ HalfEdge.pinch(prevNode.faceSuccessor, nextNode);
290
+ prevNode = nextNode;
291
+ }
292
+ colinearGraph.setMask(HalfEdgeMask.EXTERIOR | HalfEdgeMask.BOUNDARY_EDGE);
293
+ return colinearGraph;
294
+ }
295
+ /** Return a segment along the bisector of the given edge. Clip the bisector to the Voronoi boundary. */
296
+ static getEdgeBisector(edge, box) {
297
+ const v0 = edge;
298
+ const v1 = edge.faceSuccessor;
299
+ const midPoint = Point2d.createAdd2ScaledXY(v0.x, v0.y, 0.5, v1.x, v1.y, 0.5);
300
+ const perpendicular = Vector2d.createStartEnd(v0, v1);
301
+ [perpendicular.x, perpendicular.y] = [-perpendicular.y, perpendicular.x];
302
+ const bisector = Ray2d.createOriginAndDirectionCapture(midPoint, perpendicular);
303
+ const fractions = box.intersect(bisector);
304
+ const haveIntersections = undefined !== fractions && fractions.length > 1 && fractions[0] < 0 && fractions[1] > 0;
305
+ assert(haveIntersections, "Midpoints should be strictly inside bounding box");
306
+ return haveIntersections ? { start: bisector.fractionToPoint(fractions[0]), end: bisector.fractionToPoint(fractions[1]) } : undefined;
307
+ }
308
+ /** Construct a Voronoi instance from a graph representing a colinear linestring. */
309
+ static createFromColinearGraph(colinearGraph, distanceTol = Geometry.smallMetricDistance, boundingBox) {
310
+ const instance = new Voronoi(colinearGraph, true);
311
+ if (!instance.isValid)
312
+ return undefined;
313
+ let isValidVoronoi = true;
314
+ const box = new VoronoiBoundary(instance._inputGraphRange, boundingBox);
315
+ instance._inputGraph.announceEdges((_g, edge) => {
316
+ const bisector = Voronoi.getEdgeBisector(edge, box);
317
+ if (!bisector)
318
+ return isValidVoronoi = false; // edge midpoint outside box (shouldn't happen)
319
+ const faceTag0 = instance._idToIndexMap.get(edge.id);
320
+ const faceTag1 = instance._idToIndexMap.get(edge.edgeMate.id);
321
+ this.addEdgeWithFaceTags(instance._voronoiGraph, bisector.start, bisector.end, faceTag0, faceTag1);
322
+ return true;
323
+ });
324
+ if (!isValidVoronoi)
325
+ return undefined;
326
+ box.addEdgesToGraph(instance._voronoiGraph);
327
+ HalfEdgeGraphMerge.splitIntersectingEdges(instance._voronoiGraph, distanceTol);
328
+ HalfEdgeGraphMerge.clusterAndMergeXYTheta(instance._voronoiGraph, undefined, distanceTol);
329
+ instance.populateMasksAndFaceTags();
330
+ return instance;
331
+ }
332
+ /**
333
+ * Construct a Voronoi instance from a set of points.
334
+ * @param points An array of points. Z-coordinates are ignored. Points can be colinear.
335
+ * @param distanceTol Optional distance tolerance to use when comparing points; default is [[Geometry.smallMetricDistance]].
336
+ * @param boundingBox Optional nominal xy-bounding box for the Voronoi diagram. If unspecified, interior Voronoi cells are maximal.
337
+ * @returns a new instance containing the Voronoi diagram derived from the input points, or `undefined` if invalid input.
338
+ */
339
+ static createFromPoints(points, distanceTol = Geometry.smallMetricDistance, boundingBox) {
340
+ const sortedPoints = new SortedArray(Geometry.compareXY(distanceTol), DuplicatePolicy.Retain, (p) => p.clone());
341
+ points.forEach((pt) => sortedPoints.insert(pt));
342
+ const uniquePoints = sortedPoints.extractArray();
343
+ if (uniquePoints.length < 2)
344
+ return undefined;
345
+ if (PolylineOps.isColinear(uniquePoints, distanceTol, true)) {
346
+ const colinearGraph = Voronoi.createColinearXYGraph(uniquePoints);
347
+ return colinearGraph ? Voronoi.createFromColinearGraph(colinearGraph, distanceTol, boundingBox) : undefined;
348
+ }
349
+ else {
350
+ const delaunayGraph = Triangulator.createTriangulatedGraphFromPoints(uniquePoints, undefined, distanceTol);
351
+ return delaunayGraph ? Voronoi.createFromDelaunayGraph(delaunayGraph, distanceTol, boundingBox) : undefined;
352
+ }
353
+ }
354
+ /** Stroke the curve interior, and associate the stroke points to the given index. Return first and last point. */
355
+ static pushInteriorStrokePoints(pointToIndex, curve, index, strokeOptions, workPoint) {
356
+ const strokes = LineString3d.create();
357
+ curve.emitStrokes(strokes, strokeOptions);
358
+ let pt;
359
+ const n = strokes.numPoints();
360
+ for (let i = 1; i < n - 1; ++i) { // skip first and last point
361
+ if (pt = strokes.pointAt(i, workPoint))
362
+ pointToIndex.insert(pt, index);
363
+ }
364
+ assert(() => n > 2, "Expect at least 1 interior stroke point");
365
+ const p0 = (n > 2 ? strokes.pointAt(1) : undefined) ?? curve.fractionToPoint(0.5);
366
+ const p1 = (n > 2 ? strokes.pointAt(n - 2) : undefined) ?? p0;
367
+ return { p0, p1 };
368
+ }
369
+ /** Intersect the circle with the curve and return the intersection closest to the desired curve endpoint. */
370
+ static computeCircleIntersection(circle, curve, atCurveStart, distanceTol) {
371
+ const intersections = CurveCurve.intersectionProjectedXYPairs(undefined, circle, false, curve, false, distanceTol);
372
+ if (!intersections.length)
373
+ return undefined;
374
+ if (intersections.length > 1) { // detailB has the info for curve
375
+ if (atCurveStart)
376
+ intersections.sort((a, b) => a.detailB.fraction - b.detailB.fraction); // first intersection is closest to curve start
377
+ else
378
+ intersections.sort((a, b) => b.detailB.fraction - a.detailB.fraction); // first intersection is closest to curve end
379
+ }
380
+ return intersections[0].detailB.point;
381
+ }
382
+ ;
383
+ /** Intersect two consecutive curves with a tiny circle centered at their joint, and associate the intersection on each curve with its respective index. */
384
+ static pushSymmetricPointPairAtJoint = (pointToIndex, prevStroke, nextStroke, distanceTol, workArc) => {
385
+ const circle = Arc3d.createUnitCircle(workArc);
386
+ const joint = nextStroke.cp.startPoint(circle.centerRef);
387
+ // ensure the symmetric pair we add will be the last/first stroke points on prev/next curve
388
+ const radius = 0.5 * Math.min(prevStroke.pt.distance(joint), nextStroke.pt.distance(joint));
389
+ circle.matrixRef.setAt(0, 0, radius);
390
+ circle.matrixRef.setAt(1, 1, radius);
391
+ const prevPt = this.computeCircleIntersection(circle, prevStroke.cp, false, distanceTol);
392
+ const nextPt = this.computeCircleIntersection(circle, nextStroke.cp, true, distanceTol);
393
+ if (!prevPt || !nextPt) {
394
+ assert(() => false, "Failed to add symmetric strokes at joint");
395
+ return false;
396
+ }
397
+ pointToIndex.set(prevPt, prevStroke.i);
398
+ pointToIndex.set(nextPt, nextStroke.i);
399
+ return true;
400
+ };
401
+ /** Stroke each curve in the chain and associate each point with the index of its generating curve in the chain. */
402
+ static createStrokePointsWithIndices(curveChain, strokeOptions, distanceTol = Geometry.smallMetricDistance) {
403
+ const children = curveChain.children;
404
+ if (!children)
405
+ return undefined;
406
+ const numChildren = children.length;
407
+ if (numChildren < 2)
408
+ return undefined;
409
+ strokeOptions = strokeOptions?.clone() ?? StrokeOptions.createForCurves();
410
+ if (!strokeOptions.minStrokesPerPrimitive || strokeOptions.minStrokesPerPrimitive < 2)
411
+ strokeOptions.minStrokesPerPrimitive = 2; // ensure at least one interior point per primitive
412
+ const workPoint = Point3d.createZero();
413
+ const workCircle = Arc3d.createUnitCircle(Voronoi._workArc);
414
+ const workSegment0 = LineSegment3d.createXYXY(0, 0, 0, 0);
415
+ const workRay = Ray3d.createZero();
416
+ let stroke0;
417
+ let prevStroke;
418
+ let firstLastStroke;
419
+ // lambda for iterating the chain, splitting a linestring primitive into segments
420
+ const getNextCurve = (cp, index) => cp instanceof LineString3d ? cp.getIndexedSegment(index, workSegment0) : index ? undefined : cp;
421
+ const pointToIndex = new Dictionary(Geometry.compareXY(distanceTol), (p) => p.clone());
422
+ // Step 1: add open chain start/end point
423
+ const isClosedChain = curveChain.isPhysicallyClosedCurve(distanceTol, true);
424
+ if (!isClosedChain) {
425
+ if (curveChain.startPoint(workPoint))
426
+ pointToIndex.insert(workPoint, 0);
427
+ if (curveChain.endPoint(workPoint))
428
+ pointToIndex.insert(workPoint, numChildren - 1);
429
+ }
430
+ // Step 2: add interior stroke points for each chain primitive
431
+ // To ensure Voronoi edges exactly hit the chain joints, the joints themselves are omitted from the strokes
432
+ for (let i = 0; i < numChildren; i++) {
433
+ let child = children[i];
434
+ if (CurveOps.isColinear(child, { colinearRay: workRay, xyColinear: true, maxDeviation: distanceTol }))
435
+ child = LineSegment3d.createCapture(child.startPoint(), child.endPoint());
436
+ let j = 0;
437
+ for (let currCurve; currCurve = getNextCurve(child, j); j++) {
438
+ firstLastStroke = this.pushInteriorStrokePoints(pointToIndex, currCurve, i, strokeOptions, workPoint);
439
+ const currStroke = { pt: firstLastStroke.p0, cp: currCurve, i };
440
+ if (prevStroke)
441
+ this.pushSymmetricPointPairAtJoint(pointToIndex, prevStroke, currStroke, distanceTol, workCircle);
442
+ stroke0 = (isClosedChain && i === 0 && j === 0) ? currStroke : stroke0;
443
+ prevStroke = { pt: firstLastStroke.p1, cp: currCurve, i };
444
+ }
445
+ }
446
+ // Step 3: handle the seam if necessary
447
+ if (prevStroke && stroke0)
448
+ this.pushSymmetricPointPairAtJoint(pointToIndex, prevStroke, stroke0, distanceTol, workCircle);
449
+ return pointToIndex;
450
+ }
451
+ /** Construct a graph from unique xy points. */
452
+ static createGraphFromPointsWithIndices(pointToIndex, distanceTol) {
453
+ if (pointToIndex.size < 2)
454
+ return undefined;
455
+ let graph;
456
+ let isTriangulation = false;
457
+ const workPoint = Point3d.createZero();
458
+ const points = Array.from(pointToIndex.keys());
459
+ if (PolylineOps.isColinear(points, distanceTol, true)) {
460
+ graph = Voronoi.createColinearXYGraph(pointToIndex);
461
+ isTriangulation = false;
462
+ }
463
+ else {
464
+ // tighter triangulation tolerance to reduce vertex consolidation that might result in dictionary misses
465
+ graph = Triangulator.createTriangulatedGraphFromPoints(points, undefined, 0.1 * distanceTol);
466
+ if (isTriangulation = (graph !== undefined)) {
467
+ // tag every edge of the Delaunay graph with the index associated to its start vertex
468
+ graph.announceVertexLoops((_g, vertex) => {
469
+ const index = pointToIndex.get(vertex.getPoint3d(workPoint));
470
+ assert(index !== undefined, "Delaunay vertex must know its generating curve");
471
+ if (index !== undefined)
472
+ vertex.announceEdgesAroundVertex((edge) => edge.edgeTag = index);
473
+ return true;
474
+ });
475
+ }
476
+ }
477
+ return graph ? { graph, isTriangulation } : undefined;
478
+ }
479
+ /**
480
+ * Create a Voronoi instance from a curve chain.
481
+ * * This is the curve-based analog for point-based Voronoi cells.
482
+ * * Each curve in the chain is sampled and a Voronoi diagram is generated from the Delaunay triangulation of all samples.
483
+ * * The union of Voronoi cells generated by a single curve's samples is:
484
+ * * an approximation to the xy-region of points closest to the curve
485
+ * * represented in the Voronoi graph by a _super face_, a loop of edges from multiple adjacent faces
486
+ * * not necessarily convex
487
+ * * The generating curve with chain index `i` for the returned Voronoi super face `R` is encoded thusly:
488
+ * * Each Voronoi edge has `faceTag` set as per [[createFromDelaunayGraph]], referring to its generating Delaunay vertex.
489
+ * * Each Delaunay edge has `edgeTag` set to the index in `curveChain` of its generating curve.
490
+ * * For each [[HalfEdge]] `e` in the super face loop of `R`, `delaunayGraph.allHalfEdges[e.faceTag].edgeTag === i`.
491
+ * @param curveChain A curve chain consisting of at least two [[CurvePrimitive]]s. Z-coordinates are ignored.
492
+ * The length of each child should exceed `distanceTol`.
493
+ * @param strokeOptions Optional stroke options to control the sampling of the curve chain.
494
+ * @param distanceTol Optional distance tolerance to use when comparing points; default is [[Geometry.smallMetricDistance]].
495
+ * @param boundingBox Optional nominal xy-bounding box for the Voronoi diagram. If unspecified, interior Voronoi cells are maximal.
496
+ * @returns a new instance, or `undefined` for invalid input.
497
+ */
498
+ static createFromCurveChain(curveChain, strokeOptions, distanceTol = Geometry.smallMetricDistance, boundingBox) {
499
+ const pointsWithIndices = Voronoi.createStrokePointsWithIndices(curveChain, strokeOptions);
500
+ if (!pointsWithIndices)
501
+ return undefined; // no points created from the curve chain
502
+ const inputGraph = Voronoi.createGraphFromPointsWithIndices(pointsWithIndices, distanceTol);
503
+ if (!inputGraph)
504
+ return undefined; // no graph created from points
505
+ const instance = inputGraph.isTriangulation ?
506
+ Voronoi.createFromDelaunayGraph(inputGraph.graph, distanceTol, boundingBox) :
507
+ Voronoi.createFromColinearGraph(inputGraph.graph, distanceTol, boundingBox);
508
+ if (instance)
509
+ instance._isCurveBased = true;
510
+ return instance;
511
+ }
512
+ /**
513
+ * Test whether the edge is part of a curve-based Voronoi graph super face.
514
+ * @param curveIndex optional test for a _specific_ super face associated with the curve with the given index.
515
+ */
516
+ isEdgeInVoronoiSuperFace(edge, curveIndex) {
517
+ if (!this._isCurveBased || edge.faceTag === undefined)
518
+ return false;
519
+ const edgeIndex = this._inputGraph.allHalfEdges[edge.faceTag].edgeTag;
520
+ if (edge.edgeMate.isMaskSet(HalfEdgeMask.EXTERIOR)) // edge is part of an unbounded Voronoi super face clipped by the bounding box
521
+ return curveIndex === undefined ? true : curveIndex === edgeIndex;
522
+ if (edge.edgeMate.faceTag === undefined)
523
+ return false;
524
+ const mateIndex = this._inputGraph.allHalfEdges[edge.edgeMate.faceTag].edgeTag;
525
+ if (curveIndex !== undefined)
526
+ return edgeIndex === curveIndex && mateIndex !== curveIndex; // edge is in a specific super face
527
+ return edgeIndex !== mateIndex; // edge is part of a bounded Voronoi super face
528
+ }
529
+ /** Examine all edges in the curve-based Voronoi graph and return the first edge in an unvisited Voronoi super face. */
530
+ findNextVoronoiSuperFaceStart() {
531
+ if (!this._isCurveBased)
532
+ return undefined;
533
+ let start;
534
+ this._voronoiGraph.announceEdges((_g, edge) => {
535
+ if (edge.isMaskSet(HalfEdgeMask.EXTERIOR))
536
+ return true; // skip exterior face
537
+ if (edge.isMaskSet(this._superFaceMask))
538
+ return true; // skip previously visited super face
539
+ if (!this.isEdgeInVoronoiSuperFace(edge))
540
+ return true; // skip edge; keep searching
541
+ assert(() => edge.faceTag !== undefined, "Voronoi edge must know its generating Delaunay vertex");
542
+ assert(() => this._inputGraph.allHalfEdges[edge.faceTag].edgeTag !== undefined, "Delaunay vertex must know its generating curve");
543
+ start = edge;
544
+ return false; // stop search; we found an unvisited super face
545
+ });
546
+ return start;
547
+ }
548
+ /**
549
+ * Traverse the curve-based Voronoi graph and collect the edges comprising the Voronoi super face that starts with
550
+ * the given seed edge.
551
+ */
552
+ collectVoronoiSuperFace(seed) {
553
+ if (!this._isCurveBased || seed.faceTag === undefined)
554
+ return undefined;
555
+ const superFace = [];
556
+ const curveIndex = this._inputGraph.allHalfEdges[seed.faceTag].edgeTag;
557
+ const foundSuperFace = seed.announceEdgesInSuperFace((e) => !this.isEdgeInVoronoiSuperFace(e, curveIndex), // skipEdge
558
+ (e) => { superFace.push(e); e.setMask(this._superFaceMask); });
559
+ return (foundSuperFace && superFace.length > 2) ? superFace : undefined;
560
+ }
561
+ /**
562
+ * Compute super faces of a curve-based Voronoi diagram.
563
+ * * The instance must have been constructed with [[createFromCurveChain]].
564
+ * * Each super face corresponds to the planar region of points closer to one curve in the generating chain than to any other.
565
+ * * Each returned edge is masked for querying by subsequent methods.
566
+ * @param numSuperFaces maximum number of super faces to return.
567
+ * @returns up to `numSuperFaces` Voronoi super faces, sorted by curve index, or `undefined` if invalid input.
568
+ * Each super face is an array of HalfEdges that form a loop.
569
+ */
570
+ computeVoronoiSuperFaces(numSuperFaces) {
571
+ if (!this._isCurveBased || numSuperFaces < 1)
572
+ return undefined;
573
+ const superFaces = [];
574
+ if (this._superFaceMask === HalfEdgeMask.NULL_MASK)
575
+ this._superFaceMask = this._voronoiGraph.grabMask(false);
576
+ this._voronoiGraph.clearMask(this._superFaceMask);
577
+ for (let i = 0; i < numSuperFaces; i++) {
578
+ const start = this.findNextVoronoiSuperFaceStart();
579
+ if (!start)
580
+ break; // no more super faces to find
581
+ const superFace = this.collectVoronoiSuperFace(start);
582
+ if (!superFace)
583
+ return undefined; // invalid Voronoi graph
584
+ superFaces.push(superFace);
585
+ }
586
+ superFaces.sort((a, b) => {
587
+ const tagA = this._inputGraph.allHalfEdges[a[0].faceTag].edgeTag;
588
+ const tagB = this._inputGraph.allHalfEdges[b[0].faceTag].edgeTag;
589
+ return tagA - tagB;
590
+ });
591
+ return (superFaces.length > 0) ? superFaces : undefined;
592
+ }
593
+ /**
594
+ * Construct a clipper for each curve-based Voronoi super face in the input array.
595
+ * @param superFaces array returned by [[collectVoronoiSuperFaces]].
596
+ * @returns array of clippers; the i_th clipper corresponds to the i_th input super face.
597
+ * Returns `undefined` if input is invalid, or if a clipper construction failed.
598
+ */
599
+ generateClippersFromVoronoiSuperFaces(superFaces) {
600
+ if (!this._isCurveBased || this._superFaceMask === HalfEdgeMask.NULL_MASK)
601
+ return undefined;
602
+ const allClippers = [];
603
+ const superFaceOutsideMask = this._voronoiGraph.grabMask();
604
+ const visitedMask = this._voronoiGraph.grabMask();
605
+ const maskOutsideOfSuperFace = (startEdge, clearMask) => {
606
+ return startEdge.announceEdgesInSuperFace((e) => !e.isMaskSet(this._superFaceMask), (e) => e.edgeMate.applyMask(superFaceOutsideMask, clearMask));
607
+ };
608
+ // Step 0: split each super face into convex faces (clipper prerequisite)
609
+ // Disable triangle-flipping; we don't care about aspect ratio here.
610
+ Triangulator.triangulateAllInteriorFaces(this._voronoiGraph, false, true);
611
+ HalfEdgeGraphOps.expandConvexFaces(this._voronoiGraph, this._superFaceMask);
612
+ for (const superFace of superFaces) {
613
+ if (superFace.length < 3) {
614
+ allClippers.length = 0;
615
+ break; // invalid Voronoi graph
616
+ }
617
+ // Step 1: collect the convex faces for this super face
618
+ const convexFaces = [];
619
+ if (!maskOutsideOfSuperFace(superFace[0], false)) {
620
+ allClippers.length = 0;
621
+ break; // invalid Voronoi graph
622
+ }
623
+ HalfEdgeGraphSearch.exploreComponent(superFace[0], visitedMask, superFaceOutsideMask, undefined, convexFaces);
624
+ maskOutsideOfSuperFace(superFace[0], true);
625
+ // Step 2: generate a clipper for each convex face
626
+ const clippers = [];
627
+ for (const face of convexFaces) {
628
+ const clipPlanes = [];
629
+ face.announceEdgesInFace((edge) => {
630
+ if (!edge.isMaskSet(HalfEdgeMask.BOUNDARY_EDGE)) {
631
+ const clipPlane = ClipPlane.createMidPointEdgeXY(edge, edge.faceSuccessor);
632
+ if (clipPlane)
633
+ clipPlanes.push(clipPlane);
634
+ }
635
+ });
636
+ if (clipPlanes.length === face.countMaskAroundFace(HalfEdgeMask.BOUNDARY_EDGE, false))
637
+ clippers.push(ConvexClipPlaneSet.createPlanes(clipPlanes));
638
+ }
639
+ // Step 3: assemble the clippers for this super face
640
+ if (clippers.length === convexFaces.length)
641
+ allClippers.push(UnionOfConvexClipPlaneSets.createConvexSets(clippers));
642
+ }
643
+ this._voronoiGraph.dropMask(visitedMask);
644
+ this._voronoiGraph.dropMask(superFaceOutsideMask);
645
+ return allClippers.length === superFaces.length ? allClippers : undefined;
646
+ }
647
+ }
648
+ /**
649
+ * Interfaces used by the Voronoi class.
650
+ * @internal
651
+ */
652
+ (function (Voronoi) {
653
+ ;
654
+ ;
655
+ ;
656
+ })(Voronoi || (Voronoi = {}));
657
+ /**
658
+ * A class to represent a bounding box for a Voronoi diagram.
659
+ * * A Voronoi diagram is unbounded, so we create a large rectangle around the diagram to limit it.
660
+ * * To avoid clipping bounded Voronoi cells, this boundary should be large enough to contain the
661
+ * circumcenters of the Delaunay triangles.
662
+ * @internal
663
+ */
664
+ class VoronoiBoundary {
665
+ bbox;
666
+ /**
667
+ * Constructor that takes up to two ranges to union and expand by a margin.
668
+ * * For example, Delaunay graph range and circumcenter range.
669
+ */
670
+ constructor(r0, r1) {
671
+ this.bbox = Range2d.createFrom(r0);
672
+ if (r1)
673
+ this.bbox.union(r1, this.bbox);
674
+ if (!this.bbox.isNull && !this.bbox.isSinglePoint) {
675
+ const pad = 0.02473 * (this.bbox.xLength() + this.bbox.yLength()); // ~5% of average side length
676
+ this.bbox.expandInPlace(pad);
677
+ }
678
+ }
679
+ /** Compute the intersection fractions of the ray and this boundary. */
680
+ intersect(ray) {
681
+ const fractionalRange = ray.intersectionWithRange2d(this.bbox);
682
+ if (fractionalRange.isNull)
683
+ return undefined;
684
+ if (fractionalRange.isSinglePoint)
685
+ return [fractionalRange.low];
686
+ return [fractionalRange.low, fractionalRange.high];
687
+ }
688
+ /** Add edges of this boundary to the graph. */
689
+ addEdgesToGraph(graph) {
690
+ graph.addEdgeXY(this.bbox.low.x, this.bbox.low.y, this.bbox.high.x, this.bbox.low.y);
691
+ graph.addEdgeXY(this.bbox.high.x, this.bbox.low.y, this.bbox.high.x, this.bbox.high.y);
692
+ graph.addEdgeXY(this.bbox.high.x, this.bbox.high.y, this.bbox.low.x, this.bbox.high.y);
693
+ graph.addEdgeXY(this.bbox.low.x, this.bbox.high.y, this.bbox.low.x, this.bbox.low.y);
694
+ }
695
+ }
696
+ //# sourceMappingURL=Voronoi.js.map