@math.gl/geometry 5.0.0-alpha.2 → 5.0.0-alpha.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +97 -49
- package/README.md +16 -1
- package/THIRD-PARTY-NOTICES.md +18 -0
- package/dist/culling/constants.d.ts +3 -0
- package/dist/culling/constants.d.ts.map +1 -0
- package/dist/culling/constants.js +5 -0
- package/dist/culling/constants.js.map +1 -0
- package/dist/culling/index.cjs +2014 -0
- package/dist/culling/index.cjs.map +6 -0
- package/dist/culling/index.d.ts +29 -0
- package/dist/culling/index.d.ts.map +1 -0
- package/dist/culling/index.js +23 -0
- package/dist/culling/index.js.map +1 -0
- package/dist/culling/lib/algorithms/bounding-box-from-points.d.ts +15 -0
- package/dist/culling/lib/algorithms/bounding-box-from-points.d.ts.map +1 -0
- package/dist/culling/lib/algorithms/bounding-box-from-points.js +137 -0
- package/dist/culling/lib/algorithms/bounding-box-from-points.js.map +1 -0
- package/dist/culling/lib/algorithms/bounding-sphere-from-points.d.ts +14 -0
- package/dist/culling/lib/algorithms/bounding-sphere-from-points.d.ts.map +1 -0
- package/dist/culling/lib/algorithms/bounding-sphere-from-points.js +146 -0
- package/dist/culling/lib/algorithms/bounding-sphere-from-points.js.map +1 -0
- package/dist/culling/lib/algorithms/compute-eigen-decomposition.d.ts +37 -0
- package/dist/culling/lib/algorithms/compute-eigen-decomposition.d.ts.map +1 -0
- package/dist/culling/lib/algorithms/compute-eigen-decomposition.js +137 -0
- package/dist/culling/lib/algorithms/compute-eigen-decomposition.js.map +1 -0
- package/dist/culling/lib/algorithms/oriented-bounding-box-quaternion.d.ts +7 -0
- package/dist/culling/lib/algorithms/oriented-bounding-box-quaternion.d.ts.map +1 -0
- package/dist/culling/lib/algorithms/oriented-bounding-box-quaternion.js +26 -0
- package/dist/culling/lib/algorithms/oriented-bounding-box-quaternion.js.map +1 -0
- package/dist/culling/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +56 -0
- package/dist/culling/lib/bounding-volumes/axis-aligned-bounding-box.d.ts.map +1 -0
- package/dist/culling/lib/bounding-volumes/axis-aligned-bounding-box.js +116 -0
- package/dist/culling/lib/bounding-volumes/axis-aligned-bounding-box.js.map +1 -0
- package/dist/culling/lib/bounding-volumes/bounding-sphere.d.ts +40 -0
- package/dist/culling/lib/bounding-volumes/bounding-sphere.d.ts.map +1 -0
- package/dist/culling/lib/bounding-volumes/bounding-sphere.js +123 -0
- package/dist/culling/lib/bounding-volumes/bounding-sphere.js.map +1 -0
- package/dist/culling/lib/bounding-volumes/bounding-volume.d.ts +30 -0
- package/dist/culling/lib/bounding-volumes/bounding-volume.d.ts.map +1 -0
- package/dist/culling/lib/bounding-volumes/bounding-volume.js +7 -0
- package/dist/culling/lib/bounding-volumes/bounding-volume.js.map +1 -0
- package/dist/culling/lib/bounding-volumes/oriented-bounding-box.d.ts +62 -0
- package/dist/culling/lib/bounding-volumes/oriented-bounding-box.d.ts.map +1 -0
- package/dist/culling/lib/bounding-volumes/oriented-bounding-box.js +230 -0
- package/dist/culling/lib/bounding-volumes/oriented-bounding-box.js.map +1 -0
- package/dist/culling/lib/culling-volume.d.ts +46 -0
- package/dist/culling/lib/culling-volume.d.ts.map +1 -0
- package/dist/culling/lib/culling-volume.js +126 -0
- package/dist/culling/lib/culling-volume.js.map +1 -0
- package/dist/culling/lib/perspective-frustum.d.ts +153 -0
- package/dist/culling/lib/perspective-frustum.d.ts.map +1 -0
- package/dist/culling/lib/perspective-frustum.js +191 -0
- package/dist/culling/lib/perspective-frustum.js.map +1 -0
- package/dist/culling/lib/perspective-off-center-frustum.d.ts +158 -0
- package/dist/culling/lib/perspective-off-center-frustum.d.ts.map +1 -0
- package/dist/culling/lib/perspective-off-center-frustum.js +276 -0
- package/dist/culling/lib/perspective-off-center-frustum.js.map +1 -0
- package/dist/culling/lib/plane.d.ts +35 -0
- package/dist/culling/lib/plane.d.ts.map +1 -0
- package/dist/culling/lib/plane.js +90 -0
- package/dist/culling/lib/plane.js.map +1 -0
- package/dist/culling/lib/ray.d.ts +13 -0
- package/dist/culling/lib/ray.d.ts.map +1 -0
- package/dist/culling/lib/ray.js +30 -0
- package/dist/culling/lib/ray.js.map +1 -0
- package/dist/culling/lib/shapes/box-shape.d.ts +19 -0
- package/dist/culling/lib/shapes/box-shape.d.ts.map +1 -0
- package/dist/culling/lib/shapes/box-shape.js +69 -0
- package/dist/culling/lib/shapes/box-shape.js.map +1 -0
- package/dist/culling/lib/shapes/capsule-shape.d.ts +23 -0
- package/dist/culling/lib/shapes/capsule-shape.d.ts.map +1 -0
- package/dist/culling/lib/shapes/capsule-shape.js +151 -0
- package/dist/culling/lib/shapes/capsule-shape.js.map +1 -0
- package/dist/culling/lib/shapes/cylinder-shape.d.ts +22 -0
- package/dist/culling/lib/shapes/cylinder-shape.d.ts.map +1 -0
- package/dist/culling/lib/shapes/cylinder-shape.js +99 -0
- package/dist/culling/lib/shapes/cylinder-shape.js.map +1 -0
- package/dist/culling/lib/shapes/implicit-shape.d.ts +56 -0
- package/dist/culling/lib/shapes/implicit-shape.d.ts.map +1 -0
- package/dist/culling/lib/shapes/implicit-shape.js +142 -0
- package/dist/culling/lib/shapes/implicit-shape.js.map +1 -0
- package/dist/culling/lib/shapes/plane-shape.d.ts +27 -0
- package/dist/culling/lib/shapes/plane-shape.d.ts.map +1 -0
- package/dist/culling/lib/shapes/plane-shape.js +71 -0
- package/dist/culling/lib/shapes/plane-shape.js.map +1 -0
- package/dist/culling/lib/shapes/sphere-shape.d.ts +18 -0
- package/dist/culling/lib/shapes/sphere-shape.d.ts.map +1 -0
- package/dist/culling/lib/shapes/sphere-shape.js +43 -0
- package/dist/culling/lib/shapes/sphere-shape.js.map +1 -0
- package/dist/culling/oriented-box-2d.cjs +73 -0
- package/dist/culling/oriented-box-2d.cjs.map +6 -0
- package/dist/culling/oriented-box-2d.d.ts +22 -0
- package/dist/culling/oriented-box-2d.d.ts.map +1 -0
- package/dist/culling/oriented-box-2d.js +86 -0
- package/dist/culling/oriented-box-2d.js.map +1 -0
- package/dist/culling/queries.cjs +161 -0
- package/dist/culling/queries.cjs.map +6 -0
- package/dist/culling/queries.d.ts +20 -0
- package/dist/culling/queries.d.ts.map +1 -0
- package/dist/culling/queries.js +139 -0
- package/dist/culling/queries.js.map +1 -0
- package/dist/curves/bezier-curves.d.ts +18 -0
- package/dist/curves/bezier-curves.d.ts.map +1 -0
- package/dist/curves/bezier-curves.js +54 -0
- package/dist/curves/bezier-curves.js.map +1 -0
- package/dist/curves/catmull-rom-curve.d.ts +15 -0
- package/dist/curves/catmull-rom-curve.d.ts.map +1 -0
- package/dist/curves/catmull-rom-curve.js +77 -0
- package/dist/curves/catmull-rom-curve.js.map +1 -0
- package/dist/curves/curve-arc-length.d.ts +17 -0
- package/dist/curves/curve-arc-length.d.ts.map +1 -0
- package/dist/curves/curve-arc-length.js +58 -0
- package/dist/curves/curve-arc-length.js.map +1 -0
- package/dist/curves/curve.d.ts +23 -0
- package/dist/curves/curve.d.ts.map +1 -0
- package/dist/curves/curve.js +77 -0
- package/dist/curves/curve.js.map +1 -0
- package/dist/curves/hermite-curve.d.ts +9 -0
- package/dist/curves/hermite-curve.d.ts.map +1 -0
- package/dist/curves/hermite-curve.js +24 -0
- package/dist/curves/hermite-curve.js.map +1 -0
- package/dist/curves/index.cjs +293 -0
- package/dist/curves/index.cjs.map +6 -0
- package/dist/curves/index.d.ts +8 -0
- package/dist/curves/index.d.ts.map +1 -0
- package/dist/curves/index.js +9 -0
- package/dist/curves/index.js.map +1 -0
- package/dist/geometries/box-geometry.js +1 -1
- package/dist/geometries/box-geometry.js.map +1 -1
- package/dist/geometries/capsule-geometry.js +1 -1
- package/dist/geometries/capsule-geometry.js.map +1 -1
- package/dist/geometries/cylinder-geometry.js +1 -1
- package/dist/geometries/cylinder-geometry.js.map +1 -1
- package/dist/geometries/geometry-helpers.js +1 -1
- package/dist/geometries/geometry-helpers.js.map +1 -1
- package/dist/geometries/ico-sphere-geometry.js +1 -1
- package/dist/geometries/ico-sphere-geometry.js.map +1 -1
- package/dist/geometries/plane-geometry.js +1 -1
- package/dist/geometries/plane-geometry.js.map +1 -1
- package/dist/geometries/primitive-mesh-builder.d.ts +24 -0
- package/dist/geometries/primitive-mesh-builder.d.ts.map +1 -0
- package/dist/geometries/primitive-mesh-builder.js +74 -0
- package/dist/geometries/primitive-mesh-builder.js.map +1 -0
- package/dist/geometries/prism-geometry.d.ts +13 -0
- package/dist/geometries/prism-geometry.d.ts.map +1 -0
- package/dist/geometries/prism-geometry.js +34 -0
- package/dist/geometries/prism-geometry.js.map +1 -0
- package/dist/geometries/ring-geometry.d.ts +15 -0
- package/dist/geometries/ring-geometry.d.ts.map +1 -0
- package/dist/geometries/ring-geometry.js +64 -0
- package/dist/geometries/ring-geometry.js.map +1 -0
- package/dist/geometries/sphere-geometry.js +1 -1
- package/dist/geometries/sphere-geometry.js.map +1 -1
- package/dist/geometries/surface-of-revolution.js +1 -1
- package/dist/geometries/surface-of-revolution.js.map +1 -1
- package/dist/geometries/truncated-cone-geometry.js +1 -1
- package/dist/geometries/truncated-cone-geometry.js.map +1 -1
- package/dist/index.cjs +290 -9
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/geometry-utils.js +1 -1
- package/dist/lib/geometry-utils.js.map +1 -1
- package/dist/lib/geometry.d.ts +1 -1
- package/dist/lib/geometry.d.ts.map +1 -1
- package/dist/lib/geometry.js +1 -1
- package/dist/lib/geometry.js.map +1 -1
- package/dist/lib/hinge-tree.d.ts +33 -0
- package/dist/lib/hinge-tree.d.ts.map +1 -0
- package/dist/lib/hinge-tree.js +144 -0
- package/dist/lib/hinge-tree.js.map +1 -0
- package/dist/parametric/lathe-geometry.d.ts +14 -0
- package/dist/parametric/lathe-geometry.d.ts.map +1 -0
- package/dist/parametric/lathe-geometry.js +48 -0
- package/dist/parametric/lathe-geometry.js.map +1 -0
- package/dist/parametric/parametric-geometry.d.ts +20 -0
- package/dist/parametric/parametric-geometry.d.ts.map +1 -0
- package/dist/parametric/parametric-geometry.js +88 -0
- package/dist/parametric/parametric-geometry.js.map +1 -0
- package/dist/parametric/torus-geometry.d.ts +19 -0
- package/dist/parametric/torus-geometry.d.ts.map +1 -0
- package/dist/parametric/torus-geometry.js +89 -0
- package/dist/parametric/torus-geometry.js.map +1 -0
- package/dist/parametric.cjs +328 -0
- package/dist/parametric.cjs.map +6 -0
- package/dist/parametric.d.ts +7 -0
- package/dist/parametric.d.ts.map +1 -0
- package/dist/parametric.js +7 -0
- package/dist/parametric.js.map +1 -0
- package/dist/polygon/cut-by-grid.d.ts +24 -0
- package/dist/polygon/cut-by-grid.d.ts.map +1 -0
- package/dist/polygon/cut-by-grid.js +221 -0
- package/dist/polygon/cut-by-grid.js.map +1 -0
- package/dist/polygon/cut-by-mercator-bounds.d.ts +17 -0
- package/dist/polygon/cut-by-mercator-bounds.d.ts.map +1 -0
- package/dist/polygon/cut-by-mercator-bounds.js +149 -0
- package/dist/polygon/cut-by-mercator-bounds.js.map +1 -0
- package/dist/polygon/earcut.d.ts +13 -0
- package/dist/polygon/earcut.d.ts.map +1 -0
- package/dist/polygon/earcut.js +627 -0
- package/dist/polygon/earcut.js.map +1 -0
- package/dist/polygon/index.cjs +1437 -0
- package/dist/polygon/index.cjs.map +6 -0
- package/dist/polygon/index.d.ts +12 -0
- package/dist/polygon/index.d.ts.map +1 -0
- package/dist/polygon/index.js +12 -0
- package/dist/polygon/index.js.map +1 -0
- package/dist/polygon/lineclip.d.ts +31 -0
- package/dist/polygon/lineclip.d.ts.map +1 -0
- package/dist/polygon/lineclip.js +184 -0
- package/dist/polygon/lineclip.js.map +1 -0
- package/dist/polygon/polygon-utils.d.ts +103 -0
- package/dist/polygon/polygon-utils.d.ts.map +1 -0
- package/dist/polygon/polygon-utils.js +155 -0
- package/dist/polygon/polygon-utils.js.map +1 -0
- package/dist/polygon/polygon.d.ts +41 -0
- package/dist/polygon/polygon.d.ts.map +1 -0
- package/dist/polygon/polygon.js +76 -0
- package/dist/polygon/polygon.js.map +1 -0
- package/dist/polygon/subdivide-polyline.d.ts +56 -0
- package/dist/polygon/subdivide-polyline.d.ts.map +1 -0
- package/dist/polygon/subdivide-polyline.js +141 -0
- package/dist/polygon/subdivide-polyline.js.map +1 -0
- package/dist/polygon/subdivide-triangle-mesh.d.ts +68 -0
- package/dist/polygon/subdivide-triangle-mesh.d.ts.map +1 -0
- package/dist/polygon/subdivide-triangle-mesh.js +228 -0
- package/dist/polygon/subdivide-triangle-mesh.js.map +1 -0
- package/dist/polygon/utils.d.ts +5 -0
- package/dist/polygon/utils.d.ts.map +1 -0
- package/dist/polygon/utils.js +38 -0
- package/dist/polygon/utils.js.map +1 -0
- package/dist/spatial-index/box-index.cjs +328 -0
- package/dist/spatial-index/box-index.cjs.map +6 -0
- package/dist/spatial-index/box-index.d.ts +65 -0
- package/dist/spatial-index/box-index.d.ts.map +1 -0
- package/dist/spatial-index/box-index.js +263 -0
- package/dist/spatial-index/box-index.js.map +1 -0
- package/dist/spatial-index/index.cjs +494 -0
- package/dist/spatial-index/index.cjs.map +6 -0
- package/dist/spatial-index/index.d.ts +5 -0
- package/dist/spatial-index/index.d.ts.map +1 -0
- package/dist/spatial-index/index.js +6 -0
- package/dist/spatial-index/index.js.map +1 -0
- package/dist/spatial-index/triangle-bvh.d.ts +53 -0
- package/dist/spatial-index/triangle-bvh.d.ts.map +1 -0
- package/dist/spatial-index/triangle-bvh.js +102 -0
- package/dist/spatial-index/triangle-bvh.js.map +1 -0
- package/dist/utils/attribute-compression.d.ts +50 -0
- package/dist/utils/attribute-compression.d.ts.map +1 -0
- package/dist/utils/attribute-compression.js +186 -0
- package/dist/utils/attribute-compression.js.map +1 -0
- package/dist/utils/attribute-iterator.d.ts +8 -0
- package/dist/utils/attribute-iterator.d.ts.map +1 -0
- package/dist/utils/attribute-iterator.js +25 -0
- package/dist/utils/attribute-iterator.js.map +1 -0
- package/dist/utils/compute-vertex-normals.d.ts +4 -0
- package/dist/utils/compute-vertex-normals.d.ts.map +1 -0
- package/dist/utils/compute-vertex-normals.js +54 -0
- package/dist/utils/compute-vertex-normals.js.map +1 -0
- package/dist/utils/constants.d.ts +52 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +39 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/coordinates.d.ts +3 -0
- package/dist/utils/coordinates.d.ts.map +1 -0
- package/dist/utils/coordinates.js +8 -0
- package/dist/utils/coordinates.js.map +1 -0
- package/dist/utils/geometry.d.ts +20 -0
- package/dist/utils/geometry.d.ts.map +1 -0
- package/dist/utils/geometry.js +31 -0
- package/dist/utils/geometry.js.map +1 -0
- package/dist/utils/gl-type.d.ts +17 -0
- package/dist/utils/gl-type.d.ts.map +1 -0
- package/dist/utils/gl-type.js +69 -0
- package/dist/utils/gl-type.js.map +1 -0
- package/dist/utils/index.cjs +965 -0
- package/dist/utils/index.cjs.map +6 -0
- package/dist/utils/index.d.ts +18 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +16 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/interpolate-packed-attributes.cjs +176 -0
- package/dist/utils/interpolate-packed-attributes.cjs.map +6 -0
- package/dist/utils/interpolate-packed-attributes.d.ts +43 -0
- package/dist/utils/interpolate-packed-attributes.d.ts.map +1 -0
- package/dist/utils/interpolate-packed-attributes.js +192 -0
- package/dist/utils/interpolate-packed-attributes.js.map +1 -0
- package/dist/utils/mesh-processing.d.ts +18 -0
- package/dist/utils/mesh-processing.d.ts.map +1 -0
- package/dist/utils/mesh-processing.js +300 -0
- package/dist/utils/mesh-processing.js.map +1 -0
- package/dist/utils/primitive-iterator.d.ts +21 -0
- package/dist/utils/primitive-iterator.d.ts.map +1 -0
- package/dist/utils/primitive-iterator.js +117 -0
- package/dist/utils/primitive-iterator.js.map +1 -0
- package/dist/utils/rgb565.d.ts +5 -0
- package/dist/utils/rgb565.d.ts.map +1 -0
- package/dist/utils/rgb565.js +24 -0
- package/dist/utils/rgb565.js.map +1 -0
- package/dist/utils/typed-array-utils.d.ts +3 -0
- package/dist/utils/typed-array-utils.d.ts.map +1 -0
- package/dist/utils/typed-array-utils.js +16 -0
- package/dist/utils/typed-array-utils.js.map +1 -0
- package/package.json +57 -4
- package/src/culling/constants.ts +6 -0
- package/src/culling/index.ts +45 -0
- package/src/culling/lib/algorithms/bounding-box-from-points.ts +174 -0
- package/src/culling/lib/algorithms/bounding-sphere-from-points.ts +175 -0
- package/src/culling/lib/algorithms/compute-eigen-decomposition.ts +171 -0
- package/src/culling/lib/algorithms/oriented-bounding-box-quaternion.ts +32 -0
- package/src/culling/lib/bounding-volumes/axis-aligned-bounding-box.ts +153 -0
- package/src/culling/lib/bounding-volumes/bounding-sphere.ts +154 -0
- package/src/culling/lib/bounding-volumes/bounding-volume.ts +38 -0
- package/src/culling/lib/bounding-volumes/oriented-bounding-box.ts +320 -0
- package/src/culling/lib/culling-volume.ts +163 -0
- package/src/culling/lib/perspective-frustum.ts +288 -0
- package/src/culling/lib/perspective-off-center-frustum.ts +381 -0
- package/src/culling/lib/plane.ts +118 -0
- package/src/culling/lib/ray.ts +33 -0
- package/src/culling/lib/shapes/box-shape.ts +78 -0
- package/src/culling/lib/shapes/capsule-shape.ts +232 -0
- package/src/culling/lib/shapes/cylinder-shape.ts +133 -0
- package/src/culling/lib/shapes/implicit-shape.ts +209 -0
- package/src/culling/lib/shapes/plane-shape.ts +78 -0
- package/src/culling/lib/shapes/sphere-shape.ts +60 -0
- package/src/culling/oriented-box-2d.ts +165 -0
- package/src/culling/queries.ts +155 -0
- package/src/curves/bezier-curves.ts +62 -0
- package/src/curves/catmull-rom-curve.ts +89 -0
- package/src/curves/curve-arc-length.ts +70 -0
- package/src/curves/curve.ts +96 -0
- package/src/curves/hermite-curve.ts +34 -0
- package/src/curves/index.ts +15 -0
- package/src/geometries/box-geometry.ts +1 -1
- package/src/geometries/capsule-geometry.ts +1 -1
- package/src/geometries/cylinder-geometry.ts +1 -1
- package/src/geometries/geometry-helpers.ts +1 -1
- package/src/geometries/ico-sphere-geometry.ts +1 -1
- package/src/geometries/plane-geometry.ts +1 -1
- package/src/geometries/primitive-mesh-builder.ts +84 -0
- package/src/geometries/prism-geometry.ts +57 -0
- package/src/geometries/ring-geometry.ts +102 -0
- package/src/geometries/sphere-geometry.ts +1 -1
- package/src/geometries/surface-of-revolution.ts +1 -1
- package/src/geometries/truncated-cone-geometry.ts +1 -1
- package/src/index.ts +10 -1
- package/src/lib/geometry-utils.ts +2 -2
- package/src/lib/geometry.ts +2 -2
- package/src/lib/hinge-tree.ts +170 -0
- package/src/parametric/lathe-geometry.ts +70 -0
- package/src/parametric/parametric-geometry.ts +118 -0
- package/src/parametric/torus-geometry.ts +118 -0
- package/src/parametric.ts +9 -0
- package/src/polygon/cut-by-grid.ts +313 -0
- package/src/polygon/cut-by-mercator-bounds.ts +204 -0
- package/src/polygon/earcut.ts +798 -0
- package/src/polygon/index.ts +35 -0
- package/src/polygon/lineclip.ts +218 -0
- package/src/polygon/polygon-utils.ts +273 -0
- package/src/polygon/polygon.ts +105 -0
- package/src/polygon/subdivide-polyline.ts +223 -0
- package/src/polygon/subdivide-triangle-mesh.ts +322 -0
- package/src/polygon/utils.ts +50 -0
- package/src/spatial-index/box-index.ts +343 -0
- package/src/spatial-index/index.ts +18 -0
- package/src/spatial-index/triangle-bvh.ts +162 -0
- package/src/utils/attribute-compression.ts +234 -0
- package/src/utils/attribute-iterator.ts +28 -0
- package/src/utils/compute-vertex-normals.ts +63 -0
- package/src/utils/constants.ts +42 -0
- package/src/utils/coordinates.ts +8 -0
- package/src/utils/geometry.ts +49 -0
- package/src/utils/gl-type.ts +87 -0
- package/src/utils/index.ts +55 -0
- package/src/utils/interpolate-packed-attributes.ts +284 -0
- package/src/utils/mesh-processing.ts +377 -0
- package/src/utils/primitive-iterator.ts +145 -0
- package/src/utils/rgb565.ts +26 -0
- package/src/utils/typed-array-utils.ts +16 -0
|
@@ -0,0 +1,1437 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// dist/polygon/index.js
|
|
20
|
+
var index_exports = {};
|
|
21
|
+
__export(index_exports, {
|
|
22
|
+
Polygon: () => Polygon,
|
|
23
|
+
clipPolygon: () => clipPolygon,
|
|
24
|
+
clipPolyline: () => clipPolyline,
|
|
25
|
+
cutPolygonByGrid: () => cutPolygonByGrid,
|
|
26
|
+
cutPolygonByMercatorBounds: () => cutPolygonByMercatorBounds,
|
|
27
|
+
cutPolylineByGrid: () => cutPolylineByGrid,
|
|
28
|
+
cutPolylineByMercatorBounds: () => cutPolylineByMercatorBounds,
|
|
29
|
+
earcut: () => earcut,
|
|
30
|
+
forEachSegmentInPolygon: () => forEachSegmentInPolygon,
|
|
31
|
+
getPolygonSignedArea: () => getPolygonSignedArea,
|
|
32
|
+
getPolygonWindingDirection: () => getPolygonWindingDirection,
|
|
33
|
+
modifyPolygonWindingDirection: () => modifyPolygonWindingDirection,
|
|
34
|
+
subdividePolyline: () => subdividePolyline,
|
|
35
|
+
subdivideTriangleMesh: () => subdivideTriangleMesh
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(index_exports);
|
|
38
|
+
|
|
39
|
+
// dist/polygon/polygon.js
|
|
40
|
+
var import_core2 = require("@math.gl/core");
|
|
41
|
+
|
|
42
|
+
// dist/polygon/polygon-utils.js
|
|
43
|
+
var import_core = require("@math.gl/core");
|
|
44
|
+
function modifyPolygonWindingDirection(points, direction, options = {}) {
|
|
45
|
+
const windingDirection = getPolygonWindingDirection(points, options);
|
|
46
|
+
if (windingDirection !== direction) {
|
|
47
|
+
reversePolygon(points, options);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
function getPolygonWindingDirection(points, options = {}) {
|
|
53
|
+
return getWindingDirection(getPolygonSignedArea(points, options));
|
|
54
|
+
}
|
|
55
|
+
var DimIndex = {
|
|
56
|
+
x: 0,
|
|
57
|
+
y: 1,
|
|
58
|
+
z: 2
|
|
59
|
+
};
|
|
60
|
+
function getPolygonSignedArea(points, options = {}) {
|
|
61
|
+
const { start = 0, end = points.length, plane = "xy" } = options;
|
|
62
|
+
const dim = options.size || 2;
|
|
63
|
+
let area2 = 0;
|
|
64
|
+
const i0 = DimIndex[plane[0]];
|
|
65
|
+
const i1 = DimIndex[plane[1]];
|
|
66
|
+
for (let i = start, j = end - dim; i < end; i += dim) {
|
|
67
|
+
area2 += (points[i + i0] - points[j + i0]) * (points[i + i1] + points[j + i1]);
|
|
68
|
+
j = i;
|
|
69
|
+
}
|
|
70
|
+
return area2 / 2;
|
|
71
|
+
}
|
|
72
|
+
function forEachSegmentInPolygon(points, visitor, options = {}) {
|
|
73
|
+
const { start = 0, end = points.length, size = 2, isClosed } = options;
|
|
74
|
+
const numPoints = (end - start) / size;
|
|
75
|
+
for (let i = 0; i < numPoints - 1; ++i) {
|
|
76
|
+
visitor(points[start + i * size], points[start + i * size + 1], points[start + (i + 1) * size], points[start + (i + 1) * size + 1], i, i + 1);
|
|
77
|
+
}
|
|
78
|
+
const endPointIndex = start + (numPoints - 1) * size;
|
|
79
|
+
const isClosedEx = isClosed || (0, import_core.equals)(points[start], points[endPointIndex]) && (0, import_core.equals)(points[start + 1], points[endPointIndex + 1]);
|
|
80
|
+
if (!isClosedEx) {
|
|
81
|
+
visitor(points[endPointIndex], points[endPointIndex + 1], points[start], points[start + 1], numPoints - 1, 0);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function reversePolygon(points, options) {
|
|
85
|
+
const { start = 0, end = points.length, size = 2 } = options;
|
|
86
|
+
const numPoints = (end - start) / size;
|
|
87
|
+
const numSwaps = Math.floor(numPoints / 2);
|
|
88
|
+
for (let i = 0; i < numSwaps; ++i) {
|
|
89
|
+
const b1 = start + i * size;
|
|
90
|
+
const b2 = start + (numPoints - 1 - i) * size;
|
|
91
|
+
for (let j = 0; j < size; ++j) {
|
|
92
|
+
const tmp = points[b1 + j];
|
|
93
|
+
points[b1 + j] = points[b2 + j];
|
|
94
|
+
points[b2 + j] = tmp;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function modifyPolygonWindingDirectionPoints(points, direction, options = {}) {
|
|
99
|
+
const currentDirection = getPolygonWindingDirectionPoints(points, options);
|
|
100
|
+
if (currentDirection !== direction) {
|
|
101
|
+
points.reverse();
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
function getPolygonWindingDirectionPoints(points, options = {}) {
|
|
107
|
+
return getWindingDirection(getPolygonSignedAreaPoints(points, options));
|
|
108
|
+
}
|
|
109
|
+
function getWindingDirection(signedArea) {
|
|
110
|
+
if (signedArea > 0)
|
|
111
|
+
return "clockwise";
|
|
112
|
+
if (signedArea < 0)
|
|
113
|
+
return "counter-clockwise";
|
|
114
|
+
return "none";
|
|
115
|
+
}
|
|
116
|
+
function getPolygonSignedAreaPoints(points, options = {}) {
|
|
117
|
+
const { start = 0, end = points.length, plane = "xy" } = options;
|
|
118
|
+
let area2 = 0;
|
|
119
|
+
const i0 = DimIndex[plane[0]];
|
|
120
|
+
const i1 = DimIndex[plane[1]];
|
|
121
|
+
for (let i = start, j = end - 1; i < end; ++i) {
|
|
122
|
+
area2 += (points[i][i0] - points[j][i0]) * (points[i][i1] + points[j][i1]);
|
|
123
|
+
j = i;
|
|
124
|
+
}
|
|
125
|
+
return area2 / 2;
|
|
126
|
+
}
|
|
127
|
+
function forEachSegmentInPolygonPoints(points, visitor, options = {}) {
|
|
128
|
+
const { start = 0, end = points.length, isClosed } = options;
|
|
129
|
+
for (let i = start; i < end - 1; ++i) {
|
|
130
|
+
visitor(points[i], points[i + 1], i, i + 1);
|
|
131
|
+
}
|
|
132
|
+
const isClosedEx = isClosed || (0, import_core.equals)(points[end - 1], points[0]);
|
|
133
|
+
if (!isClosedEx) {
|
|
134
|
+
visitor(points[end - 1], points[0], end - 1, 0);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// dist/polygon/polygon.js
|
|
139
|
+
var Polygon = class {
|
|
140
|
+
constructor(points, options = {}) {
|
|
141
|
+
this.points = points;
|
|
142
|
+
this.isFlatArray = !(0, import_core2.isArray)(points[0]);
|
|
143
|
+
this.options = {
|
|
144
|
+
start: options.start || 0,
|
|
145
|
+
end: options.end || points.length,
|
|
146
|
+
size: options.size || 2,
|
|
147
|
+
isClosed: options.isClosed
|
|
148
|
+
};
|
|
149
|
+
Object.freeze(this);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Returns signed area of the polygon.
|
|
153
|
+
* @returns Signed area of the polygon.
|
|
154
|
+
*/
|
|
155
|
+
getSignedArea() {
|
|
156
|
+
if (this.isFlatArray)
|
|
157
|
+
return getPolygonSignedArea(this.points, this.options);
|
|
158
|
+
return getPolygonSignedAreaPoints(this.points, this.options);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Returns absolute area of the polygon.
|
|
162
|
+
* @returns Absolute area of the polygon.
|
|
163
|
+
*/
|
|
164
|
+
getArea() {
|
|
165
|
+
return Math.abs(this.getSignedArea());
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Returns winding direction of the polygon.
|
|
169
|
+
* @returns `'clockwise'`, `'counter-clockwise'`, or `'none'` for a degenerate polygon.
|
|
170
|
+
*/
|
|
171
|
+
getWindingDirection() {
|
|
172
|
+
const signedArea = this.getSignedArea();
|
|
173
|
+
if (signedArea > 0)
|
|
174
|
+
return "clockwise";
|
|
175
|
+
if (signedArea < 0)
|
|
176
|
+
return "counter-clockwise";
|
|
177
|
+
return "none";
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Calls the visitor callback for each segment in the polygon.
|
|
181
|
+
* @param visitor A callback to call for each segment.
|
|
182
|
+
*/
|
|
183
|
+
forEachSegment(visitor) {
|
|
184
|
+
if (this.isFlatArray) {
|
|
185
|
+
forEachSegmentInPolygon(
|
|
186
|
+
this.points,
|
|
187
|
+
// eslint-disable-next-line max-params
|
|
188
|
+
(x1, y1, x2, y2, i1, i2) => {
|
|
189
|
+
visitor([x1, y1], [x2, y2], i1, i2);
|
|
190
|
+
},
|
|
191
|
+
this.options
|
|
192
|
+
);
|
|
193
|
+
} else {
|
|
194
|
+
forEachSegmentInPolygonPoints(this.points, visitor, this.options);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Checks winding direction of the polygon and reverses the polygon in case of opposite winding direction.
|
|
199
|
+
* @param direction Requested winding direction.
|
|
200
|
+
* @return Returns true if the winding direction was changed.
|
|
201
|
+
*/
|
|
202
|
+
modifyWindingDirection(direction) {
|
|
203
|
+
if (this.isFlatArray) {
|
|
204
|
+
return modifyPolygonWindingDirection(this.points, direction, this.options);
|
|
205
|
+
}
|
|
206
|
+
return modifyPolygonWindingDirectionPoints(this.points, direction, this.options);
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// dist/polygon/earcut.js
|
|
211
|
+
function earcut(positions, holeIndices, dim = 2, areas, plane = "xy") {
|
|
212
|
+
const hasHoles = holeIndices && holeIndices.length;
|
|
213
|
+
const outerLen = hasHoles ? holeIndices[0] * dim : positions.length;
|
|
214
|
+
let outerNode = linkedList(positions, 0, outerLen, dim, true, areas && areas[0], plane);
|
|
215
|
+
const triangles = [];
|
|
216
|
+
if (!outerNode || outerNode.next === outerNode.prev)
|
|
217
|
+
return triangles;
|
|
218
|
+
let invSize;
|
|
219
|
+
let maxX;
|
|
220
|
+
let maxY;
|
|
221
|
+
let minX;
|
|
222
|
+
let minY;
|
|
223
|
+
let x;
|
|
224
|
+
let y;
|
|
225
|
+
if (hasHoles)
|
|
226
|
+
outerNode = eliminateHoles(positions, holeIndices, outerNode, dim, areas, plane);
|
|
227
|
+
if (positions.length > 80 * dim) {
|
|
228
|
+
minX = maxX = positions[0];
|
|
229
|
+
minY = maxY = positions[1];
|
|
230
|
+
for (let i = dim; i < outerLen; i += dim) {
|
|
231
|
+
x = positions[i];
|
|
232
|
+
y = positions[i + 1];
|
|
233
|
+
if (x < minX)
|
|
234
|
+
minX = x;
|
|
235
|
+
if (y < minY)
|
|
236
|
+
minY = y;
|
|
237
|
+
if (x > maxX)
|
|
238
|
+
maxX = x;
|
|
239
|
+
if (y > maxY)
|
|
240
|
+
maxY = y;
|
|
241
|
+
}
|
|
242
|
+
invSize = Math.max(maxX - minX, maxY - minY);
|
|
243
|
+
invSize = invSize !== 0 ? 32767 / invSize : 0;
|
|
244
|
+
}
|
|
245
|
+
earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);
|
|
246
|
+
return triangles;
|
|
247
|
+
}
|
|
248
|
+
function linkedList(data, start, end, dim, clockwise, area2, plane) {
|
|
249
|
+
let i;
|
|
250
|
+
let last;
|
|
251
|
+
if (area2 === void 0) {
|
|
252
|
+
area2 = getPolygonSignedArea(data, { start, end, size: dim, plane });
|
|
253
|
+
}
|
|
254
|
+
let i0 = DimIndex[plane[0]];
|
|
255
|
+
let i1 = DimIndex[plane[1]];
|
|
256
|
+
if (clockwise === area2 < 0) {
|
|
257
|
+
for (i = start; i < end; i += dim)
|
|
258
|
+
last = insertNode(i, data[i + i0], data[i + i1], last);
|
|
259
|
+
} else {
|
|
260
|
+
for (i = end - dim; i >= start; i -= dim)
|
|
261
|
+
last = insertNode(i, data[i + i0], data[i + i1], last);
|
|
262
|
+
}
|
|
263
|
+
if (last && equals2(last, last.next)) {
|
|
264
|
+
removeNode(last);
|
|
265
|
+
last = last.next;
|
|
266
|
+
}
|
|
267
|
+
return last;
|
|
268
|
+
}
|
|
269
|
+
function filterPoints(start, end) {
|
|
270
|
+
if (!start)
|
|
271
|
+
return start;
|
|
272
|
+
if (!end)
|
|
273
|
+
end = start;
|
|
274
|
+
let p = start;
|
|
275
|
+
let again;
|
|
276
|
+
do {
|
|
277
|
+
again = false;
|
|
278
|
+
if (!p.steiner && (equals2(p, p.next) || area(p.prev, p, p.next) === 0)) {
|
|
279
|
+
removeNode(p);
|
|
280
|
+
p = end = p.prev;
|
|
281
|
+
if (p === p.next)
|
|
282
|
+
break;
|
|
283
|
+
again = true;
|
|
284
|
+
} else {
|
|
285
|
+
p = p.next;
|
|
286
|
+
}
|
|
287
|
+
} while (again || p !== end);
|
|
288
|
+
return end;
|
|
289
|
+
}
|
|
290
|
+
function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
|
|
291
|
+
if (!ear)
|
|
292
|
+
return;
|
|
293
|
+
if (!pass && invSize)
|
|
294
|
+
indexCurve(ear, minX, minY, invSize);
|
|
295
|
+
let stop = ear;
|
|
296
|
+
let prev;
|
|
297
|
+
let next;
|
|
298
|
+
while (ear.prev !== ear.next) {
|
|
299
|
+
prev = ear.prev;
|
|
300
|
+
next = ear.next;
|
|
301
|
+
if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
|
|
302
|
+
triangles.push(prev.i / dim | 0);
|
|
303
|
+
triangles.push(ear.i / dim | 0);
|
|
304
|
+
triangles.push(next.i / dim | 0);
|
|
305
|
+
removeNode(ear);
|
|
306
|
+
ear = next.next;
|
|
307
|
+
stop = next.next;
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
ear = next;
|
|
311
|
+
if (ear === stop) {
|
|
312
|
+
if (!pass) {
|
|
313
|
+
earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);
|
|
314
|
+
} else if (pass === 1) {
|
|
315
|
+
ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
|
|
316
|
+
earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);
|
|
317
|
+
} else if (pass === 2) {
|
|
318
|
+
splitEarcut(ear, triangles, dim, minX, minY, invSize);
|
|
319
|
+
}
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function isEar(ear) {
|
|
325
|
+
const a = ear.prev;
|
|
326
|
+
const b = ear;
|
|
327
|
+
const c = ear.next;
|
|
328
|
+
if (area(a, b, c) >= 0)
|
|
329
|
+
return false;
|
|
330
|
+
const ax = a.x;
|
|
331
|
+
const bx = b.x;
|
|
332
|
+
const cx = c.x;
|
|
333
|
+
const ay = a.y;
|
|
334
|
+
const by = b.y;
|
|
335
|
+
const cy = c.y;
|
|
336
|
+
const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx;
|
|
337
|
+
const y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy;
|
|
338
|
+
const x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx;
|
|
339
|
+
const y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
|
|
340
|
+
let p = c.next;
|
|
341
|
+
while (p !== a) {
|
|
342
|
+
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0)
|
|
343
|
+
return false;
|
|
344
|
+
p = p.next;
|
|
345
|
+
}
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
function isEarHashed(ear, minX, minY, invSize) {
|
|
349
|
+
const a = ear.prev;
|
|
350
|
+
const b = ear;
|
|
351
|
+
const c = ear.next;
|
|
352
|
+
if (area(a, b, c) >= 0)
|
|
353
|
+
return false;
|
|
354
|
+
const ax = a.x;
|
|
355
|
+
const bx = b.x;
|
|
356
|
+
const cx = c.x;
|
|
357
|
+
const ay = a.y;
|
|
358
|
+
const by = b.y;
|
|
359
|
+
const cy = c.y;
|
|
360
|
+
const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx;
|
|
361
|
+
const y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy;
|
|
362
|
+
const x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx;
|
|
363
|
+
const y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
|
|
364
|
+
const minZ = zOrder(x0, y0, minX, minY, invSize);
|
|
365
|
+
const maxZ = zOrder(x1, y1, minX, minY, invSize);
|
|
366
|
+
let p = ear.prevZ;
|
|
367
|
+
let n = ear.nextZ;
|
|
368
|
+
while (p && p.z >= minZ && n && n.z <= maxZ) {
|
|
369
|
+
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0)
|
|
370
|
+
return false;
|
|
371
|
+
p = p.prevZ;
|
|
372
|
+
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0)
|
|
373
|
+
return false;
|
|
374
|
+
n = n.nextZ;
|
|
375
|
+
}
|
|
376
|
+
while (p && p.z >= minZ) {
|
|
377
|
+
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0)
|
|
378
|
+
return false;
|
|
379
|
+
p = p.prevZ;
|
|
380
|
+
}
|
|
381
|
+
while (n && n.z <= maxZ) {
|
|
382
|
+
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0)
|
|
383
|
+
return false;
|
|
384
|
+
n = n.nextZ;
|
|
385
|
+
}
|
|
386
|
+
return true;
|
|
387
|
+
}
|
|
388
|
+
function cureLocalIntersections(start, triangles, dim) {
|
|
389
|
+
let p = start;
|
|
390
|
+
do {
|
|
391
|
+
const a = p.prev;
|
|
392
|
+
const b = p.next.next;
|
|
393
|
+
if (!equals2(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
|
|
394
|
+
triangles.push(a.i / dim | 0);
|
|
395
|
+
triangles.push(p.i / dim | 0);
|
|
396
|
+
triangles.push(b.i / dim | 0);
|
|
397
|
+
removeNode(p);
|
|
398
|
+
removeNode(p.next);
|
|
399
|
+
p = start = b;
|
|
400
|
+
}
|
|
401
|
+
p = p.next;
|
|
402
|
+
} while (p !== start);
|
|
403
|
+
return filterPoints(p);
|
|
404
|
+
}
|
|
405
|
+
function splitEarcut(start, triangles, dim, minX, minY, invSize) {
|
|
406
|
+
let a = start;
|
|
407
|
+
do {
|
|
408
|
+
let b = a.next.next;
|
|
409
|
+
while (b !== a.prev) {
|
|
410
|
+
if (a.i !== b.i && isValidDiagonal(a, b)) {
|
|
411
|
+
let c = splitPolygon(a, b);
|
|
412
|
+
a = filterPoints(a, a.next);
|
|
413
|
+
c = filterPoints(c, c.next);
|
|
414
|
+
earcutLinked(a, triangles, dim, minX, minY, invSize, 0);
|
|
415
|
+
earcutLinked(c, triangles, dim, minX, minY, invSize, 0);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
b = b.next;
|
|
419
|
+
}
|
|
420
|
+
a = a.next;
|
|
421
|
+
} while (a !== start);
|
|
422
|
+
}
|
|
423
|
+
function eliminateHoles(data, holeIndices, outerNode, dim, areas, plane) {
|
|
424
|
+
const queue = [];
|
|
425
|
+
let i;
|
|
426
|
+
let len;
|
|
427
|
+
let start;
|
|
428
|
+
let end;
|
|
429
|
+
let list;
|
|
430
|
+
for (i = 0, len = holeIndices.length; i < len; i++) {
|
|
431
|
+
start = holeIndices[i] * dim;
|
|
432
|
+
end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
|
|
433
|
+
list = linkedList(data, start, end, dim, false, areas && areas[i + 1], plane);
|
|
434
|
+
if (list === list.next)
|
|
435
|
+
list.steiner = true;
|
|
436
|
+
queue.push(getLeftmost(list));
|
|
437
|
+
}
|
|
438
|
+
queue.sort(compareX);
|
|
439
|
+
for (i = 0; i < queue.length; i++) {
|
|
440
|
+
outerNode = eliminateHole(queue[i], outerNode);
|
|
441
|
+
}
|
|
442
|
+
return outerNode;
|
|
443
|
+
}
|
|
444
|
+
function compareX(a, b) {
|
|
445
|
+
return a.x - b.x;
|
|
446
|
+
}
|
|
447
|
+
function eliminateHole(hole, outerNode) {
|
|
448
|
+
const bridge = findHoleBridge(hole, outerNode);
|
|
449
|
+
if (!bridge) {
|
|
450
|
+
return outerNode;
|
|
451
|
+
}
|
|
452
|
+
const bridgeReverse = splitPolygon(bridge, hole);
|
|
453
|
+
filterPoints(bridgeReverse, bridgeReverse.next);
|
|
454
|
+
return filterPoints(bridge, bridge.next);
|
|
455
|
+
}
|
|
456
|
+
function findHoleBridge(hole, outerNode) {
|
|
457
|
+
let p = outerNode;
|
|
458
|
+
const hx = hole.x;
|
|
459
|
+
const hy = hole.y;
|
|
460
|
+
let qx = -Infinity;
|
|
461
|
+
let m;
|
|
462
|
+
do {
|
|
463
|
+
if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
|
|
464
|
+
const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
|
|
465
|
+
if (x <= hx && x > qx) {
|
|
466
|
+
qx = x;
|
|
467
|
+
m = p.x < p.next.x ? p : p.next;
|
|
468
|
+
if (x === hx)
|
|
469
|
+
return m;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
p = p.next;
|
|
473
|
+
} while (p !== outerNode);
|
|
474
|
+
if (!m)
|
|
475
|
+
return null;
|
|
476
|
+
const stop = m;
|
|
477
|
+
const mx = m.x;
|
|
478
|
+
const my = m.y;
|
|
479
|
+
let tanMin = Infinity;
|
|
480
|
+
let tan;
|
|
481
|
+
p = m;
|
|
482
|
+
do {
|
|
483
|
+
if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
|
|
484
|
+
tan = Math.abs(hy - p.y) / (hx - p.x);
|
|
485
|
+
if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) {
|
|
486
|
+
m = p;
|
|
487
|
+
tanMin = tan;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
p = p.next;
|
|
491
|
+
} while (p !== stop);
|
|
492
|
+
return m;
|
|
493
|
+
}
|
|
494
|
+
function sectorContainsSector(m, p) {
|
|
495
|
+
return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
|
|
496
|
+
}
|
|
497
|
+
function indexCurve(start, minX, minY, invSize) {
|
|
498
|
+
let p = start;
|
|
499
|
+
do {
|
|
500
|
+
if (p.z === 0)
|
|
501
|
+
p.z = zOrder(p.x, p.y, minX, minY, invSize);
|
|
502
|
+
p.prevZ = p.prev;
|
|
503
|
+
p.nextZ = p.next;
|
|
504
|
+
p = p.next;
|
|
505
|
+
} while (p !== start);
|
|
506
|
+
p.prevZ.nextZ = null;
|
|
507
|
+
p.prevZ = null;
|
|
508
|
+
sortLinked(p);
|
|
509
|
+
}
|
|
510
|
+
function sortLinked(list) {
|
|
511
|
+
let e;
|
|
512
|
+
let i;
|
|
513
|
+
let inSize = 1;
|
|
514
|
+
let numMerges;
|
|
515
|
+
let p;
|
|
516
|
+
let pSize;
|
|
517
|
+
let q;
|
|
518
|
+
let qSize;
|
|
519
|
+
let tail;
|
|
520
|
+
do {
|
|
521
|
+
p = list;
|
|
522
|
+
list = null;
|
|
523
|
+
tail = null;
|
|
524
|
+
numMerges = 0;
|
|
525
|
+
while (p) {
|
|
526
|
+
numMerges++;
|
|
527
|
+
q = p;
|
|
528
|
+
pSize = 0;
|
|
529
|
+
for (i = 0; i < inSize; i++) {
|
|
530
|
+
pSize++;
|
|
531
|
+
q = q.nextZ;
|
|
532
|
+
if (!q)
|
|
533
|
+
break;
|
|
534
|
+
}
|
|
535
|
+
qSize = inSize;
|
|
536
|
+
while (pSize > 0 || qSize > 0 && q) {
|
|
537
|
+
if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
|
|
538
|
+
e = p;
|
|
539
|
+
p = p.nextZ;
|
|
540
|
+
pSize--;
|
|
541
|
+
} else {
|
|
542
|
+
e = q;
|
|
543
|
+
q = q.nextZ;
|
|
544
|
+
qSize--;
|
|
545
|
+
}
|
|
546
|
+
if (tail)
|
|
547
|
+
tail.nextZ = e;
|
|
548
|
+
else
|
|
549
|
+
list = e;
|
|
550
|
+
e.prevZ = tail;
|
|
551
|
+
tail = e;
|
|
552
|
+
}
|
|
553
|
+
p = q;
|
|
554
|
+
}
|
|
555
|
+
tail.nextZ = null;
|
|
556
|
+
inSize *= 2;
|
|
557
|
+
} while (numMerges > 1);
|
|
558
|
+
return list;
|
|
559
|
+
}
|
|
560
|
+
function zOrder(x, y, minX, minY, invSize) {
|
|
561
|
+
x = (x - minX) * invSize | 0;
|
|
562
|
+
y = (y - minY) * invSize | 0;
|
|
563
|
+
x = (x | x << 8) & 16711935;
|
|
564
|
+
x = (x | x << 4) & 252645135;
|
|
565
|
+
x = (x | x << 2) & 858993459;
|
|
566
|
+
x = (x | x << 1) & 1431655765;
|
|
567
|
+
y = (y | y << 8) & 16711935;
|
|
568
|
+
y = (y | y << 4) & 252645135;
|
|
569
|
+
y = (y | y << 2) & 858993459;
|
|
570
|
+
y = (y | y << 1) & 1431655765;
|
|
571
|
+
return x | y << 1;
|
|
572
|
+
}
|
|
573
|
+
function getLeftmost(start) {
|
|
574
|
+
let p = start;
|
|
575
|
+
let leftmost = start;
|
|
576
|
+
do {
|
|
577
|
+
if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y)
|
|
578
|
+
leftmost = p;
|
|
579
|
+
p = p.next;
|
|
580
|
+
} while (p !== start);
|
|
581
|
+
return leftmost;
|
|
582
|
+
}
|
|
583
|
+
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
|
|
584
|
+
return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py);
|
|
585
|
+
}
|
|
586
|
+
function isValidDiagonal(a, b) {
|
|
587
|
+
return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges
|
|
588
|
+
(locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible
|
|
589
|
+
(area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors
|
|
590
|
+
equals2(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0);
|
|
591
|
+
}
|
|
592
|
+
function area(p, q, r) {
|
|
593
|
+
return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
|
|
594
|
+
}
|
|
595
|
+
function equals2(p1, p2) {
|
|
596
|
+
return p1.x === p2.x && p1.y === p2.y;
|
|
597
|
+
}
|
|
598
|
+
function intersects(p1, q1, p2, q2) {
|
|
599
|
+
const o1 = sign(area(p1, q1, p2));
|
|
600
|
+
const o2 = sign(area(p1, q1, q2));
|
|
601
|
+
const o3 = sign(area(p2, q2, p1));
|
|
602
|
+
const o4 = sign(area(p2, q2, q1));
|
|
603
|
+
if (o1 !== o2 && o3 !== o4)
|
|
604
|
+
return true;
|
|
605
|
+
if (o1 === 0 && onSegment(p1, p2, q1))
|
|
606
|
+
return true;
|
|
607
|
+
if (o2 === 0 && onSegment(p1, q2, q1))
|
|
608
|
+
return true;
|
|
609
|
+
if (o3 === 0 && onSegment(p2, p1, q2))
|
|
610
|
+
return true;
|
|
611
|
+
if (o4 === 0 && onSegment(p2, q1, q2))
|
|
612
|
+
return true;
|
|
613
|
+
return false;
|
|
614
|
+
}
|
|
615
|
+
function onSegment(p, q, r) {
|
|
616
|
+
return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
|
|
617
|
+
}
|
|
618
|
+
function sign(num) {
|
|
619
|
+
return num > 0 ? 1 : num < 0 ? -1 : 0;
|
|
620
|
+
}
|
|
621
|
+
function intersectsPolygon(a, b) {
|
|
622
|
+
let p = a;
|
|
623
|
+
do {
|
|
624
|
+
if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b))
|
|
625
|
+
return true;
|
|
626
|
+
p = p.next;
|
|
627
|
+
} while (p !== a);
|
|
628
|
+
return false;
|
|
629
|
+
}
|
|
630
|
+
function locallyInside(a, b) {
|
|
631
|
+
return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
|
|
632
|
+
}
|
|
633
|
+
function middleInside(a, b) {
|
|
634
|
+
let p = a;
|
|
635
|
+
let inside = false;
|
|
636
|
+
const px = (a.x + b.x) / 2;
|
|
637
|
+
const py = (a.y + b.y) / 2;
|
|
638
|
+
do {
|
|
639
|
+
if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)
|
|
640
|
+
inside = !inside;
|
|
641
|
+
p = p.next;
|
|
642
|
+
} while (p !== a);
|
|
643
|
+
return inside;
|
|
644
|
+
}
|
|
645
|
+
function splitPolygon(a, b) {
|
|
646
|
+
const a2 = new Vertex(a.i, a.x, a.y);
|
|
647
|
+
const b2 = new Vertex(b.i, b.x, b.y);
|
|
648
|
+
const an = a.next;
|
|
649
|
+
const bp = b.prev;
|
|
650
|
+
a.next = b;
|
|
651
|
+
b.prev = a;
|
|
652
|
+
a2.next = an;
|
|
653
|
+
an.prev = a2;
|
|
654
|
+
b2.next = a2;
|
|
655
|
+
a2.prev = b2;
|
|
656
|
+
bp.next = b2;
|
|
657
|
+
b2.prev = bp;
|
|
658
|
+
return b2;
|
|
659
|
+
}
|
|
660
|
+
function insertNode(i, x, y, last) {
|
|
661
|
+
const p = new Vertex(i, x, y);
|
|
662
|
+
if (!last) {
|
|
663
|
+
p.prev = p;
|
|
664
|
+
p.next = p;
|
|
665
|
+
} else {
|
|
666
|
+
p.next = last.next;
|
|
667
|
+
p.prev = last;
|
|
668
|
+
last.next.prev = p;
|
|
669
|
+
last.next = p;
|
|
670
|
+
}
|
|
671
|
+
return p;
|
|
672
|
+
}
|
|
673
|
+
function removeNode(p) {
|
|
674
|
+
p.next.prev = p.prev;
|
|
675
|
+
p.prev.next = p.next;
|
|
676
|
+
if (p.prevZ)
|
|
677
|
+
p.prevZ.nextZ = p.nextZ;
|
|
678
|
+
if (p.nextZ)
|
|
679
|
+
p.nextZ.prevZ = p.prevZ;
|
|
680
|
+
}
|
|
681
|
+
var Vertex = class {
|
|
682
|
+
constructor(i, x, y) {
|
|
683
|
+
this.prev = null;
|
|
684
|
+
this.next = null;
|
|
685
|
+
this.z = 0;
|
|
686
|
+
this.prevZ = null;
|
|
687
|
+
this.nextZ = null;
|
|
688
|
+
this.steiner = false;
|
|
689
|
+
this.i = i;
|
|
690
|
+
this.x = x;
|
|
691
|
+
this.y = y;
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
// dist/polygon/utils.js
|
|
696
|
+
function push(target, source) {
|
|
697
|
+
const size = source.length;
|
|
698
|
+
const startIndex = target.length;
|
|
699
|
+
if (startIndex > 0) {
|
|
700
|
+
let isDuplicate = true;
|
|
701
|
+
for (let i = 0; i < size; i++) {
|
|
702
|
+
if (target[startIndex - size + i] !== source[i]) {
|
|
703
|
+
isDuplicate = false;
|
|
704
|
+
break;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
if (isDuplicate) {
|
|
708
|
+
return false;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
for (let i = 0; i < size; i++) {
|
|
712
|
+
target[startIndex + i] = source[i];
|
|
713
|
+
}
|
|
714
|
+
return true;
|
|
715
|
+
}
|
|
716
|
+
function copy(target, source) {
|
|
717
|
+
const size = source.length;
|
|
718
|
+
for (let i = 0; i < size; i++) {
|
|
719
|
+
target[i] = source[i];
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
function getPointAtIndex(positions, index, size, offset, out = []) {
|
|
723
|
+
const startI = offset + index * size;
|
|
724
|
+
for (let i = 0; i < size; i++) {
|
|
725
|
+
out[i] = positions[startI + i];
|
|
726
|
+
}
|
|
727
|
+
return out;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
// dist/polygon/lineclip.js
|
|
731
|
+
function clipPolyline(positions, bbox, options) {
|
|
732
|
+
const { size = 2, startIndex = 0, endIndex = positions.length } = options || {};
|
|
733
|
+
const numPoints = (endIndex - startIndex) / size;
|
|
734
|
+
const result = [];
|
|
735
|
+
let part = [];
|
|
736
|
+
let a;
|
|
737
|
+
let b;
|
|
738
|
+
let codeA = -1;
|
|
739
|
+
let codeB;
|
|
740
|
+
let lastCode;
|
|
741
|
+
for (let i = 1; i < numPoints; i++) {
|
|
742
|
+
a = getPointAtIndex(positions, i - 1, size, startIndex, a);
|
|
743
|
+
b = getPointAtIndex(positions, i, size, startIndex, b);
|
|
744
|
+
if (codeA < 0) {
|
|
745
|
+
codeA = bitCode(a, bbox);
|
|
746
|
+
}
|
|
747
|
+
codeB = lastCode = bitCode(b, bbox);
|
|
748
|
+
while (true) {
|
|
749
|
+
if (!(codeA | codeB)) {
|
|
750
|
+
push(part, a);
|
|
751
|
+
if (codeB !== lastCode) {
|
|
752
|
+
push(part, b);
|
|
753
|
+
if (i < numPoints - 1) {
|
|
754
|
+
result.push(part);
|
|
755
|
+
part = [];
|
|
756
|
+
}
|
|
757
|
+
} else if (i === numPoints - 1) {
|
|
758
|
+
push(part, b);
|
|
759
|
+
}
|
|
760
|
+
break;
|
|
761
|
+
} else if (codeA & codeB) {
|
|
762
|
+
break;
|
|
763
|
+
} else if (codeA) {
|
|
764
|
+
intersect(a, b, codeA, bbox, a);
|
|
765
|
+
codeA = bitCode(a, bbox);
|
|
766
|
+
} else {
|
|
767
|
+
intersect(a, b, codeB, bbox, b);
|
|
768
|
+
codeB = bitCode(b, bbox);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
codeA = lastCode;
|
|
772
|
+
}
|
|
773
|
+
if (part.length)
|
|
774
|
+
result.push(part);
|
|
775
|
+
return result;
|
|
776
|
+
}
|
|
777
|
+
function clipPolygon(positions, bbox, options) {
|
|
778
|
+
const { size = 2, endIndex = positions.length } = options || {};
|
|
779
|
+
let { startIndex = 0 } = options || {};
|
|
780
|
+
let numPoints = (endIndex - startIndex) / size;
|
|
781
|
+
let result;
|
|
782
|
+
let p;
|
|
783
|
+
let prev;
|
|
784
|
+
let inside;
|
|
785
|
+
let prevInside;
|
|
786
|
+
for (let edge = 1; edge <= 8; edge *= 2) {
|
|
787
|
+
result = [];
|
|
788
|
+
prev = getPointAtIndex(positions, numPoints - 1, size, startIndex, prev);
|
|
789
|
+
prevInside = !(bitCode(prev, bbox) & edge);
|
|
790
|
+
for (let i = 0; i < numPoints; i++) {
|
|
791
|
+
p = getPointAtIndex(positions, i, size, startIndex, p);
|
|
792
|
+
inside = !(bitCode(p, bbox) & edge);
|
|
793
|
+
if (inside !== prevInside)
|
|
794
|
+
push(result, intersect(prev, p, edge, bbox));
|
|
795
|
+
if (inside)
|
|
796
|
+
push(result, p);
|
|
797
|
+
copy(prev, p);
|
|
798
|
+
prevInside = inside;
|
|
799
|
+
}
|
|
800
|
+
positions = result;
|
|
801
|
+
startIndex = 0;
|
|
802
|
+
numPoints = result.length / size;
|
|
803
|
+
if (!numPoints)
|
|
804
|
+
break;
|
|
805
|
+
}
|
|
806
|
+
return result;
|
|
807
|
+
}
|
|
808
|
+
function intersect(a, b, edge, bbox, out = []) {
|
|
809
|
+
let t;
|
|
810
|
+
let snap;
|
|
811
|
+
if (edge & 8) {
|
|
812
|
+
t = (bbox[3] - a[1]) / (b[1] - a[1]);
|
|
813
|
+
snap = 3;
|
|
814
|
+
} else if (edge & 4) {
|
|
815
|
+
t = (bbox[1] - a[1]) / (b[1] - a[1]);
|
|
816
|
+
snap = 1;
|
|
817
|
+
} else if (edge & 2) {
|
|
818
|
+
t = (bbox[2] - a[0]) / (b[0] - a[0]);
|
|
819
|
+
snap = 2;
|
|
820
|
+
} else if (edge & 1) {
|
|
821
|
+
t = (bbox[0] - a[0]) / (b[0] - a[0]);
|
|
822
|
+
snap = 0;
|
|
823
|
+
} else {
|
|
824
|
+
return null;
|
|
825
|
+
}
|
|
826
|
+
for (let i = 0; i < a.length; i++) {
|
|
827
|
+
out[i] = (snap & 1) === i ? bbox[snap] : t * (b[i] - a[i]) + a[i];
|
|
828
|
+
}
|
|
829
|
+
return out;
|
|
830
|
+
}
|
|
831
|
+
function bitCode(p, bbox) {
|
|
832
|
+
let code = 0;
|
|
833
|
+
if (p[0] < bbox[0])
|
|
834
|
+
code |= 1;
|
|
835
|
+
else if (p[0] > bbox[2])
|
|
836
|
+
code |= 2;
|
|
837
|
+
if (p[1] < bbox[1])
|
|
838
|
+
code |= 4;
|
|
839
|
+
else if (p[1] > bbox[3])
|
|
840
|
+
code |= 8;
|
|
841
|
+
return code;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// dist/polygon/cut-by-grid.js
|
|
845
|
+
function cutPolylineByGrid(positions, options) {
|
|
846
|
+
const { size = 2, broken = false, gridResolution = 10, gridOffset = [0, 0], startIndex = 0, endIndex = positions.length } = options || {};
|
|
847
|
+
const numPoints = (endIndex - startIndex) / size;
|
|
848
|
+
let part = [];
|
|
849
|
+
const result = [part];
|
|
850
|
+
const a = getPointAtIndex(positions, 0, size, startIndex);
|
|
851
|
+
let b;
|
|
852
|
+
let codeB;
|
|
853
|
+
const cell = getGridCell(a, gridResolution, gridOffset, []);
|
|
854
|
+
const scratchPoint = [];
|
|
855
|
+
push(part, a);
|
|
856
|
+
for (let i = 1; i < numPoints; i++) {
|
|
857
|
+
b = getPointAtIndex(positions, i, size, startIndex, b);
|
|
858
|
+
codeB = bitCode(b, cell);
|
|
859
|
+
while (codeB) {
|
|
860
|
+
intersect(a, b, codeB, cell, scratchPoint);
|
|
861
|
+
const codeAlt = bitCode(scratchPoint, cell);
|
|
862
|
+
if (codeAlt) {
|
|
863
|
+
intersect(a, scratchPoint, codeAlt, cell, scratchPoint);
|
|
864
|
+
codeB = codeAlt;
|
|
865
|
+
}
|
|
866
|
+
push(part, scratchPoint);
|
|
867
|
+
copy(a, scratchPoint);
|
|
868
|
+
moveToNeighborCell(cell, gridResolution, codeB);
|
|
869
|
+
if (broken && part.length > size) {
|
|
870
|
+
part = [];
|
|
871
|
+
result.push(part);
|
|
872
|
+
push(part, a);
|
|
873
|
+
}
|
|
874
|
+
codeB = bitCode(b, cell);
|
|
875
|
+
}
|
|
876
|
+
push(part, b);
|
|
877
|
+
copy(a, b);
|
|
878
|
+
}
|
|
879
|
+
return broken ? result : result[0];
|
|
880
|
+
}
|
|
881
|
+
var TYPE_INSIDE = 0;
|
|
882
|
+
var TYPE_BORDER = 1;
|
|
883
|
+
function cutPolygonByGrid(positions, holeIndices = null, options) {
|
|
884
|
+
if (!positions.length) {
|
|
885
|
+
return [];
|
|
886
|
+
}
|
|
887
|
+
const { size = 2, gridResolution = 10, gridOffset = [0, 0], edgeTypes = false } = options || {};
|
|
888
|
+
const result = [];
|
|
889
|
+
const queue = [
|
|
890
|
+
{
|
|
891
|
+
pos: positions,
|
|
892
|
+
types: edgeTypes ? new Array(positions.length / size).fill(TYPE_BORDER) : null,
|
|
893
|
+
holes: holeIndices || []
|
|
894
|
+
}
|
|
895
|
+
];
|
|
896
|
+
const bbox = [[], []];
|
|
897
|
+
let cell = [];
|
|
898
|
+
while (queue.length) {
|
|
899
|
+
const { pos, types, holes } = queue.shift();
|
|
900
|
+
getBoundingBox(pos, size, holes[0] || pos.length, bbox);
|
|
901
|
+
cell = getGridCell(bbox[0], gridResolution, gridOffset, cell);
|
|
902
|
+
const code = bitCode(bbox[1], cell);
|
|
903
|
+
if (code) {
|
|
904
|
+
let parts = bisectPolygon(pos, types, size, 0, holes[0] || pos.length, cell, code);
|
|
905
|
+
const polygonLow = { pos: parts[0].pos, types: parts[0].types, holes: [] };
|
|
906
|
+
const polygonHigh = { pos: parts[1].pos, types: parts[1].types, holes: [] };
|
|
907
|
+
queue.push(polygonLow, polygonHigh);
|
|
908
|
+
for (let i = 0; i < holes.length; i++) {
|
|
909
|
+
parts = bisectPolygon(pos, types, size, holes[i], holes[i + 1] || pos.length, cell, code);
|
|
910
|
+
if (parts[0]) {
|
|
911
|
+
polygonLow.holes.push(polygonLow.pos.length);
|
|
912
|
+
polygonLow.pos = concatInPlace(polygonLow.pos, parts[0].pos);
|
|
913
|
+
if (edgeTypes) {
|
|
914
|
+
polygonLow.types = concatInPlace(polygonLow.types, parts[0].types);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
if (parts[1]) {
|
|
918
|
+
polygonHigh.holes.push(polygonHigh.pos.length);
|
|
919
|
+
polygonHigh.pos = concatInPlace(polygonHigh.pos, parts[1].pos);
|
|
920
|
+
if (edgeTypes) {
|
|
921
|
+
polygonHigh.types = concatInPlace(polygonHigh.types, parts[1].types);
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
} else {
|
|
926
|
+
const polygon = { positions: pos };
|
|
927
|
+
if (edgeTypes) {
|
|
928
|
+
polygon.edgeTypes = types;
|
|
929
|
+
}
|
|
930
|
+
if (holes.length) {
|
|
931
|
+
polygon.holeIndices = holes;
|
|
932
|
+
}
|
|
933
|
+
result.push(polygon);
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
return result;
|
|
937
|
+
}
|
|
938
|
+
function bisectPolygon(positions, edgeTypes, size, startIndex, endIndex, bbox, edge) {
|
|
939
|
+
const numPoints = (endIndex - startIndex) / size;
|
|
940
|
+
const resultLow = [];
|
|
941
|
+
const resultHigh = [];
|
|
942
|
+
const typesLow = [];
|
|
943
|
+
const typesHigh = [];
|
|
944
|
+
const scratchPoint = [];
|
|
945
|
+
let p;
|
|
946
|
+
let side;
|
|
947
|
+
let type;
|
|
948
|
+
const prev = getPointAtIndex(positions, numPoints - 1, size, startIndex);
|
|
949
|
+
let prevSide = Math.sign(edge & 8 ? prev[1] - bbox[3] : prev[0] - bbox[2]);
|
|
950
|
+
let prevType = edgeTypes && edgeTypes[numPoints - 1];
|
|
951
|
+
let lowPointCount = 0;
|
|
952
|
+
let highPointCount = 0;
|
|
953
|
+
for (let i = 0; i < numPoints; i++) {
|
|
954
|
+
p = getPointAtIndex(positions, i, size, startIndex, p);
|
|
955
|
+
side = Math.sign(edge & 8 ? p[1] - bbox[3] : p[0] - bbox[2]);
|
|
956
|
+
type = edgeTypes && edgeTypes[startIndex / size + i];
|
|
957
|
+
if (side && prevSide && prevSide !== side) {
|
|
958
|
+
intersect(prev, p, edge, bbox, scratchPoint);
|
|
959
|
+
push(resultLow, scratchPoint) && typesLow.push(prevType);
|
|
960
|
+
push(resultHigh, scratchPoint) && typesHigh.push(prevType);
|
|
961
|
+
}
|
|
962
|
+
if (side <= 0) {
|
|
963
|
+
push(resultLow, p) && typesLow.push(type);
|
|
964
|
+
lowPointCount -= side;
|
|
965
|
+
} else if (typesLow.length) {
|
|
966
|
+
typesLow[typesLow.length - 1] = TYPE_INSIDE;
|
|
967
|
+
}
|
|
968
|
+
if (side >= 0) {
|
|
969
|
+
push(resultHigh, p) && typesHigh.push(type);
|
|
970
|
+
highPointCount += side;
|
|
971
|
+
} else if (typesHigh.length) {
|
|
972
|
+
typesHigh[typesHigh.length - 1] = TYPE_INSIDE;
|
|
973
|
+
}
|
|
974
|
+
copy(prev, p);
|
|
975
|
+
prevSide = side;
|
|
976
|
+
prevType = type;
|
|
977
|
+
}
|
|
978
|
+
return [
|
|
979
|
+
lowPointCount ? { pos: resultLow, types: edgeTypes && typesLow } : null,
|
|
980
|
+
highPointCount ? { pos: resultHigh, types: edgeTypes && typesHigh } : null
|
|
981
|
+
];
|
|
982
|
+
}
|
|
983
|
+
function getGridCell(p, gridResolution, gridOffset, out) {
|
|
984
|
+
const left = Math.floor((p[0] - gridOffset[0]) / gridResolution) * gridResolution + gridOffset[0];
|
|
985
|
+
const bottom = Math.floor((p[1] - gridOffset[1]) / gridResolution) * gridResolution + gridOffset[1];
|
|
986
|
+
out[0] = left;
|
|
987
|
+
out[1] = bottom;
|
|
988
|
+
out[2] = left + gridResolution;
|
|
989
|
+
out[3] = bottom + gridResolution;
|
|
990
|
+
return out;
|
|
991
|
+
}
|
|
992
|
+
function moveToNeighborCell(cell, gridResolution, edge) {
|
|
993
|
+
if (edge & 8) {
|
|
994
|
+
cell[1] += gridResolution;
|
|
995
|
+
cell[3] += gridResolution;
|
|
996
|
+
} else if (edge & 4) {
|
|
997
|
+
cell[1] -= gridResolution;
|
|
998
|
+
cell[3] -= gridResolution;
|
|
999
|
+
} else if (edge & 2) {
|
|
1000
|
+
cell[0] += gridResolution;
|
|
1001
|
+
cell[2] += gridResolution;
|
|
1002
|
+
} else if (edge & 1) {
|
|
1003
|
+
cell[0] -= gridResolution;
|
|
1004
|
+
cell[2] -= gridResolution;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
function getBoundingBox(positions, size, endIndex, out) {
|
|
1008
|
+
let minX = Infinity;
|
|
1009
|
+
let maxX = -Infinity;
|
|
1010
|
+
let minY = Infinity;
|
|
1011
|
+
let maxY = -Infinity;
|
|
1012
|
+
for (let i = 0; i < endIndex; i += size) {
|
|
1013
|
+
const x = positions[i];
|
|
1014
|
+
const y = positions[i + 1];
|
|
1015
|
+
minX = x < minX ? x : minX;
|
|
1016
|
+
maxX = x > maxX ? x : maxX;
|
|
1017
|
+
minY = y < minY ? y : minY;
|
|
1018
|
+
maxY = y > maxY ? y : maxY;
|
|
1019
|
+
}
|
|
1020
|
+
out[0][0] = minX;
|
|
1021
|
+
out[0][1] = minY;
|
|
1022
|
+
out[1][0] = maxX;
|
|
1023
|
+
out[1][1] = maxY;
|
|
1024
|
+
return out;
|
|
1025
|
+
}
|
|
1026
|
+
function concatInPlace(arr1, arr2) {
|
|
1027
|
+
for (let i = 0; i < arr2.length; i++) {
|
|
1028
|
+
arr1.push(arr2[i]);
|
|
1029
|
+
}
|
|
1030
|
+
return arr1;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
// dist/polygon/cut-by-mercator-bounds.js
|
|
1034
|
+
var DEFAULT_MAX_LATITUDE = 85.051129;
|
|
1035
|
+
function cutPolylineByMercatorBounds(positions, options) {
|
|
1036
|
+
const { size = 2, startIndex = 0, endIndex = positions.length, normalize = true } = options || {};
|
|
1037
|
+
const newPositions = positions.slice(startIndex, endIndex);
|
|
1038
|
+
wrapLongitudesForShortestPath(newPositions, size, 0, endIndex - startIndex);
|
|
1039
|
+
const parts = cutPolylineByGrid(newPositions, {
|
|
1040
|
+
size,
|
|
1041
|
+
broken: true,
|
|
1042
|
+
gridResolution: 360,
|
|
1043
|
+
gridOffset: [-180, -180]
|
|
1044
|
+
});
|
|
1045
|
+
if (normalize) {
|
|
1046
|
+
for (const part of parts) {
|
|
1047
|
+
shiftLongitudesIntoRange(part, size);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
return parts;
|
|
1051
|
+
}
|
|
1052
|
+
function cutPolygonByMercatorBounds(positions, holeIndices = null, options) {
|
|
1053
|
+
const { size = 2, normalize = true, edgeTypes = false } = options || {};
|
|
1054
|
+
holeIndices = holeIndices || [];
|
|
1055
|
+
const newPositions = [];
|
|
1056
|
+
const newHoleIndices = [];
|
|
1057
|
+
let srcStartIndex = 0;
|
|
1058
|
+
let targetIndex = 0;
|
|
1059
|
+
for (let ringIndex = 0; ringIndex <= holeIndices.length; ringIndex++) {
|
|
1060
|
+
const srcEndIndex = holeIndices[ringIndex] || positions.length;
|
|
1061
|
+
const targetStartIndex = targetIndex;
|
|
1062
|
+
const splitIndex = findSplitIndex(positions, size, srcStartIndex, srcEndIndex);
|
|
1063
|
+
for (let i = splitIndex; i < srcEndIndex; i++) {
|
|
1064
|
+
newPositions[targetIndex++] = positions[i];
|
|
1065
|
+
}
|
|
1066
|
+
for (let i = srcStartIndex; i < splitIndex; i++) {
|
|
1067
|
+
newPositions[targetIndex++] = positions[i];
|
|
1068
|
+
}
|
|
1069
|
+
wrapLongitudesForShortestPath(newPositions, size, targetStartIndex, targetIndex);
|
|
1070
|
+
insertPoleVertices(newPositions, size, targetStartIndex, targetIndex, options == null ? void 0 : options.maxLatitude);
|
|
1071
|
+
srcStartIndex = srcEndIndex;
|
|
1072
|
+
newHoleIndices[ringIndex] = targetIndex;
|
|
1073
|
+
}
|
|
1074
|
+
newHoleIndices.pop();
|
|
1075
|
+
const parts = cutPolygonByGrid(newPositions, newHoleIndices, {
|
|
1076
|
+
size,
|
|
1077
|
+
gridResolution: 360,
|
|
1078
|
+
gridOffset: [-180, -180],
|
|
1079
|
+
edgeTypes
|
|
1080
|
+
});
|
|
1081
|
+
if (normalize) {
|
|
1082
|
+
for (const part of parts) {
|
|
1083
|
+
shiftLongitudesIntoRange(part.positions, size);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
return parts;
|
|
1087
|
+
}
|
|
1088
|
+
function findSplitIndex(positions, size, startIndex, endIndex) {
|
|
1089
|
+
let maxLat = -1;
|
|
1090
|
+
let pointIndex = -1;
|
|
1091
|
+
for (let i = startIndex + 1; i < endIndex; i += size) {
|
|
1092
|
+
const lat = Math.abs(positions[i]);
|
|
1093
|
+
if (lat > maxLat) {
|
|
1094
|
+
maxLat = lat;
|
|
1095
|
+
pointIndex = i - 1;
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
return pointIndex;
|
|
1099
|
+
}
|
|
1100
|
+
function insertPoleVertices(positions, size, startIndex, endIndex, maxLatitude = DEFAULT_MAX_LATITUDE) {
|
|
1101
|
+
const firstLng = positions[startIndex];
|
|
1102
|
+
const lastLng = positions[endIndex - size];
|
|
1103
|
+
if (Math.abs(firstLng - lastLng) > 180) {
|
|
1104
|
+
const p = getPointAtIndex(positions, 0, size, startIndex);
|
|
1105
|
+
p[0] += Math.round((lastLng - firstLng) / 360) * 360;
|
|
1106
|
+
push(positions, p);
|
|
1107
|
+
p[1] = Math.sign(p[1]) * maxLatitude;
|
|
1108
|
+
push(positions, p);
|
|
1109
|
+
p[0] = firstLng;
|
|
1110
|
+
push(positions, p);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
function wrapLongitudesForShortestPath(positions, size, startIndex, endIndex) {
|
|
1114
|
+
let prevLng = positions[0];
|
|
1115
|
+
let lng;
|
|
1116
|
+
for (let i = startIndex; i < endIndex; i += size) {
|
|
1117
|
+
lng = positions[i];
|
|
1118
|
+
const delta = lng - prevLng;
|
|
1119
|
+
if (delta > 180 || delta < -180) {
|
|
1120
|
+
lng -= Math.round(delta / 360) * 360;
|
|
1121
|
+
}
|
|
1122
|
+
positions[i] = prevLng = lng;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
function shiftLongitudesIntoRange(positions, size) {
|
|
1126
|
+
let refLng;
|
|
1127
|
+
const pointCount = positions.length / size;
|
|
1128
|
+
for (let i = 0; i < pointCount; i++) {
|
|
1129
|
+
refLng = positions[i * size];
|
|
1130
|
+
if ((refLng + 180) % 360 !== 0) {
|
|
1131
|
+
break;
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
const delta = -Math.round(refLng / 360) * 360;
|
|
1135
|
+
if (delta === 0) {
|
|
1136
|
+
return;
|
|
1137
|
+
}
|
|
1138
|
+
for (let i = 0; i < pointCount; i++) {
|
|
1139
|
+
positions[i * size] += delta;
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
// dist/polygon/subdivide-polyline.js
|
|
1144
|
+
function subdividePolyline(input, options) {
|
|
1145
|
+
const { transform, tolerance, createEdgeSampler, size = 2, targetSize = size, maxSegmentLength = Infinity, maxDepth = 16, maxVertices = 65536 } = options;
|
|
1146
|
+
if (typeof transform !== "function" || createEdgeSampler !== void 0 && typeof createEdgeSampler !== "function" || !Number.isFinite(tolerance) || tolerance <= 0 || size !== 2 && size !== 3 || targetSize !== 2 && targetSize !== 3 || !(maxSegmentLength > 0) || !Number.isFinite(maxSegmentLength) && maxSegmentLength !== Infinity || !Number.isInteger(maxDepth) || maxDepth < 0 || maxDepth > 30 || !Number.isSafeInteger(maxVertices) || maxVertices < 1 || maxVertices > 4294967295 || !Number.isSafeInteger(input.length) || input.length < 0 || input.length % size !== 0) {
|
|
1147
|
+
throw new RangeError("Invalid polyline subdivision options or input length");
|
|
1148
|
+
}
|
|
1149
|
+
const vertexCount = input.length / size;
|
|
1150
|
+
if (vertexCount > maxVertices)
|
|
1151
|
+
throw new RangeError("Polyline exceeds maxVertices");
|
|
1152
|
+
const sources = [];
|
|
1153
|
+
for (let i = 0; i < input.length; i++) {
|
|
1154
|
+
const value = input[i];
|
|
1155
|
+
if (!Number.isFinite(value))
|
|
1156
|
+
throw new RangeError("Source positions must be finite");
|
|
1157
|
+
sources.push(value);
|
|
1158
|
+
}
|
|
1159
|
+
const sourcePositions = [];
|
|
1160
|
+
const positions = [];
|
|
1161
|
+
const segmentIndices = [];
|
|
1162
|
+
const segmentFractions = [];
|
|
1163
|
+
function sample(source, fraction) {
|
|
1164
|
+
const projected = transform(source.slice());
|
|
1165
|
+
if (!projected || projected.length !== targetSize) {
|
|
1166
|
+
throw new RangeError("Transform must return a position with targetSize components");
|
|
1167
|
+
}
|
|
1168
|
+
const target = Array.from(projected);
|
|
1169
|
+
if (!target.every(Number.isFinite))
|
|
1170
|
+
throw new RangeError("Transform returned nonfinite coordinates");
|
|
1171
|
+
return { source, target, fraction };
|
|
1172
|
+
}
|
|
1173
|
+
function append(point, segment) {
|
|
1174
|
+
if (segmentIndices.length >= maxVertices) {
|
|
1175
|
+
throw new RangeError("Polyline subdivision exceeded maxVertices");
|
|
1176
|
+
}
|
|
1177
|
+
for (const value of point.source)
|
|
1178
|
+
sourcePositions.push(value);
|
|
1179
|
+
for (const value of point.target)
|
|
1180
|
+
positions.push(value);
|
|
1181
|
+
segmentIndices.push(segment);
|
|
1182
|
+
segmentFractions.push(point.fraction);
|
|
1183
|
+
}
|
|
1184
|
+
function sampledSource(sampler, fraction) {
|
|
1185
|
+
const value = sampler.sample(fraction);
|
|
1186
|
+
if (!value || value.length !== size)
|
|
1187
|
+
throw new RangeError("Invalid source-edge sample size");
|
|
1188
|
+
const source = Array.from(value);
|
|
1189
|
+
if (!source.every(Number.isFinite))
|
|
1190
|
+
throw new RangeError("Nonfinite source-edge sample");
|
|
1191
|
+
return source;
|
|
1192
|
+
}
|
|
1193
|
+
function interpolate(a, b, fraction, sampler) {
|
|
1194
|
+
const originalFraction = a.fraction * (1 - fraction) + b.fraction * fraction;
|
|
1195
|
+
const source = sampler ? sampledSource(sampler, originalFraction) : a.source.map((value, i) => value * (1 - fraction) + b.source[i] * fraction);
|
|
1196
|
+
return sample(source, originalFraction);
|
|
1197
|
+
}
|
|
1198
|
+
function subdivide(a, b, segment, depth, sampler) {
|
|
1199
|
+
let error = 0;
|
|
1200
|
+
let midpoint;
|
|
1201
|
+
for (const fraction of [0.25, 0.5, 0.75]) {
|
|
1202
|
+
const point = interpolate(a, b, fraction, sampler);
|
|
1203
|
+
if (fraction === 0.5)
|
|
1204
|
+
midpoint = point;
|
|
1205
|
+
const delta = point.target.map((value, i) => value - (a.target[i] * (1 - fraction) + b.target[i] * fraction));
|
|
1206
|
+
error = Math.max(error, Math.hypot(...delta));
|
|
1207
|
+
}
|
|
1208
|
+
const sourceLength = sampler ? sampler.length * (b.fraction - a.fraction) : Math.hypot(...a.source.map((value, i) => value - b.source[i]));
|
|
1209
|
+
if (error <= tolerance && sourceLength <= maxSegmentLength) {
|
|
1210
|
+
append(b, segment);
|
|
1211
|
+
return;
|
|
1212
|
+
}
|
|
1213
|
+
if (depth >= maxDepth) {
|
|
1214
|
+
throw new RangeError(`Polyline subdivision exceeded maxDepth on input edge ${segment}`);
|
|
1215
|
+
}
|
|
1216
|
+
subdivide(a, midpoint, segment, depth + 1, sampler);
|
|
1217
|
+
subdivide(midpoint, b, segment, depth + 1, sampler);
|
|
1218
|
+
}
|
|
1219
|
+
if (vertexCount) {
|
|
1220
|
+
let previous = sample(sources.slice(0, size), 0);
|
|
1221
|
+
append(previous, 0);
|
|
1222
|
+
for (let i = 1; i < vertexCount; i++) {
|
|
1223
|
+
const next = sample(sources.slice(i * size, (i + 1) * size), 1);
|
|
1224
|
+
const start = { ...previous, fraction: 0 };
|
|
1225
|
+
const sampler = createEdgeSampler == null ? void 0 : createEdgeSampler(start.source.slice(), next.source.slice(), i - 1);
|
|
1226
|
+
if (createEdgeSampler) {
|
|
1227
|
+
if (!sampler || typeof sampler.sample !== "function" || !Number.isFinite(sampler.length) || sampler.length < 0) {
|
|
1228
|
+
throw new RangeError("Invalid source-edge sampler");
|
|
1229
|
+
}
|
|
1230
|
+
for (const endpoint of [start, next]) {
|
|
1231
|
+
const sampled = sampledSource(sampler, endpoint.fraction);
|
|
1232
|
+
if (sampled.some((value, component) => value !== endpoint.source[component])) {
|
|
1233
|
+
throw new RangeError("Source-edge sampler endpoints must match input");
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
subdivide(start, next, i - 1, 0, sampler);
|
|
1238
|
+
previous = next;
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
return {
|
|
1242
|
+
sourcePositions: new Float64Array(sourcePositions),
|
|
1243
|
+
positions: new Float64Array(positions),
|
|
1244
|
+
segmentIndices: new Uint32Array(segmentIndices),
|
|
1245
|
+
segmentFractions: new Float64Array(segmentFractions)
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// dist/polygon/subdivide-triangle-mesh.js
|
|
1250
|
+
var EDGE_FRACTIONS = [0.25, 0.5, 0.75];
|
|
1251
|
+
var FACE_WEIGHTS = [
|
|
1252
|
+
[1 / 3, 1 / 3, 1 / 3],
|
|
1253
|
+
[0.5, 0.25, 0.25],
|
|
1254
|
+
[0.25, 0.5, 0.25],
|
|
1255
|
+
[0.25, 0.25, 0.5]
|
|
1256
|
+
];
|
|
1257
|
+
function subdivideTriangleMesh(mesh, options) {
|
|
1258
|
+
const { transform, tolerance, refinement = "transform-error", size = 2, targetSize = size, maxEdgeLength = Infinity, maxDepth = 10, maxVertices = 65536, maxTriangles = 131072 } = options;
|
|
1259
|
+
validateOptions();
|
|
1260
|
+
const vertices = [];
|
|
1261
|
+
let faces = [];
|
|
1262
|
+
for (let i = 0; i < mesh.positions.length; i += size) {
|
|
1263
|
+
const source = Array.from({ length: size }, (_, j) => mesh.positions[i + j]);
|
|
1264
|
+
if (!source.every(Number.isFinite))
|
|
1265
|
+
throw new RangeError("Source positions must be finite");
|
|
1266
|
+
vertices.push({ source, target: project(source), weights: /* @__PURE__ */ new Map([[i / size, 1]]) });
|
|
1267
|
+
}
|
|
1268
|
+
for (let i = 0; i < mesh.indices.length; i += 3) {
|
|
1269
|
+
const indices = Array.from({ length: 3 }, (_, j) => mesh.indices[i + j]);
|
|
1270
|
+
if (!indices.every((index) => Number.isInteger(index) && index >= 0 && index < vertices.length)) {
|
|
1271
|
+
throw new RangeError("Triangle indices must reference input vertices");
|
|
1272
|
+
}
|
|
1273
|
+
faces.push({ vertices: indices, sourceTriangle: i / 3 });
|
|
1274
|
+
}
|
|
1275
|
+
for (let depth = 0; ; depth++) {
|
|
1276
|
+
const splitEdges = /* @__PURE__ */ new Set();
|
|
1277
|
+
for (const face of faces) {
|
|
1278
|
+
if (refinement === "source-edge") {
|
|
1279
|
+
for (let edge = 0; edge < 3; edge++) {
|
|
1280
|
+
const a = face.vertices[edge];
|
|
1281
|
+
const b = face.vertices[(edge + 1) % 3];
|
|
1282
|
+
if (sourceEdgeLength(vertices[a], vertices[b]) > maxEdgeLength) {
|
|
1283
|
+
splitEdges.add(edgeKey(a, b));
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
} else if (needsRefinement(face)) {
|
|
1287
|
+
const [a, b, c] = face.vertices;
|
|
1288
|
+
splitEdges.add(edgeKey(a, b));
|
|
1289
|
+
splitEdges.add(edgeKey(b, c));
|
|
1290
|
+
splitEdges.add(edgeKey(c, a));
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
if (!splitEdges.size)
|
|
1294
|
+
return buildResult();
|
|
1295
|
+
if (depth >= maxDepth)
|
|
1296
|
+
throw new RangeError("Triangle mesh subdivision exceeded maxDepth");
|
|
1297
|
+
const midpoints = /* @__PURE__ */ new Map();
|
|
1298
|
+
const refined = [];
|
|
1299
|
+
for (const face of faces) {
|
|
1300
|
+
splitFace(face, refined, splitEdges, midpoints);
|
|
1301
|
+
}
|
|
1302
|
+
faces = refined;
|
|
1303
|
+
}
|
|
1304
|
+
function validateOptions() {
|
|
1305
|
+
if (typeof transform !== "function" || refinement !== "transform-error" && refinement !== "source-edge" || refinement === "transform-error" && (tolerance === void 0 || !Number.isFinite(tolerance) || tolerance <= 0) || refinement === "source-edge" && (tolerance !== void 0 || !Number.isFinite(maxEdgeLength)) || size !== 2 && size !== 3 || targetSize !== 2 && targetSize !== 3 || !(maxEdgeLength > 0) || !Number.isFinite(maxEdgeLength) && maxEdgeLength !== Infinity || !Number.isInteger(maxDepth) || maxDepth < 0 || maxDepth > 30 || !validLimit(maxVertices) || !validLimit(maxTriangles) || !Number.isSafeInteger(mesh.positions.length) || mesh.positions.length < 0 || mesh.positions.length % size !== 0 || !Number.isSafeInteger(mesh.indices.length) || mesh.indices.length < 0 || mesh.indices.length % 3 !== 0)
|
|
1306
|
+
throw new RangeError("Invalid triangle mesh subdivision options or input lengths");
|
|
1307
|
+
if (mesh.positions.length / size > maxVertices || mesh.indices.length / 3 > maxTriangles) {
|
|
1308
|
+
throw new RangeError("Input mesh exceeds subdivision limits");
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
function project(source) {
|
|
1312
|
+
const result = transform(source.slice());
|
|
1313
|
+
if (!result || result.length !== targetSize) {
|
|
1314
|
+
throw new RangeError("Transform must return targetSize components");
|
|
1315
|
+
}
|
|
1316
|
+
const target = Array.from(result);
|
|
1317
|
+
if (!target.every(Number.isFinite))
|
|
1318
|
+
throw new RangeError("Transform returned nonfinite coordinates");
|
|
1319
|
+
return target;
|
|
1320
|
+
}
|
|
1321
|
+
function error(points, weights) {
|
|
1322
|
+
const source = blend(points.map((p) => p.source), weights);
|
|
1323
|
+
const linearTarget = blend(points.map((p) => p.target), weights);
|
|
1324
|
+
return Math.hypot(...project(source).map((value, i) => value - linearTarget[i]));
|
|
1325
|
+
}
|
|
1326
|
+
function needsRefinement(face) {
|
|
1327
|
+
const points = face.vertices.map((index) => vertices[index]);
|
|
1328
|
+
let exceedsTolerance = false;
|
|
1329
|
+
for (let i = 0; i < 3; i++) {
|
|
1330
|
+
const a = points[i];
|
|
1331
|
+
const b = points[(i + 1) % 3];
|
|
1332
|
+
const length = sourceEdgeLength(a, b);
|
|
1333
|
+
if (length > maxEdgeLength)
|
|
1334
|
+
exceedsTolerance = true;
|
|
1335
|
+
for (const fraction of EDGE_FRACTIONS) {
|
|
1336
|
+
if (error([a, b], [1 - fraction, fraction]) > (tolerance ?? Infinity))
|
|
1337
|
+
exceedsTolerance = true;
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
for (const weights of FACE_WEIGHTS) {
|
|
1341
|
+
if (error(points, weights) > (tolerance ?? Infinity))
|
|
1342
|
+
exceedsTolerance = true;
|
|
1343
|
+
}
|
|
1344
|
+
return exceedsTolerance;
|
|
1345
|
+
}
|
|
1346
|
+
function midpoint(a, b, midpoints) {
|
|
1347
|
+
const key = edgeKey(a, b);
|
|
1348
|
+
const existing = midpoints.get(key);
|
|
1349
|
+
if (existing !== void 0)
|
|
1350
|
+
return existing;
|
|
1351
|
+
if (vertices.length >= maxVertices)
|
|
1352
|
+
throw new RangeError("Triangle mesh subdivision exceeded maxVertices");
|
|
1353
|
+
const source = blend([vertices[a].source, vertices[b].source], [0.5, 0.5]);
|
|
1354
|
+
const weights = /* @__PURE__ */ new Map();
|
|
1355
|
+
for (const vertex of [vertices[a], vertices[b]]) {
|
|
1356
|
+
for (const [index2, weight] of vertex.weights) {
|
|
1357
|
+
weights.set(index2, (weights.get(index2) || 0) + weight * 0.5);
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
if (weights.size > 3)
|
|
1361
|
+
throw new Error("Inconsistent mesh provenance");
|
|
1362
|
+
const index = vertices.length;
|
|
1363
|
+
vertices.push({ source, target: project(source), weights });
|
|
1364
|
+
midpoints.set(key, index);
|
|
1365
|
+
return index;
|
|
1366
|
+
}
|
|
1367
|
+
function splitFace(face, output, splitEdges, midpoints) {
|
|
1368
|
+
const [a, b, c] = face.vertices;
|
|
1369
|
+
const ab = splitEdges.has(edgeKey(a, b)) ? midpoint(a, b, midpoints) : -1;
|
|
1370
|
+
const bc = splitEdges.has(edgeKey(b, c)) ? midpoint(b, c, midpoints) : -1;
|
|
1371
|
+
const ca = splitEdges.has(edgeKey(c, a)) ? midpoint(c, a, midpoints) : -1;
|
|
1372
|
+
const count = Number(ab >= 0) + Number(bc >= 0) + Number(ca >= 0);
|
|
1373
|
+
if (count === 0)
|
|
1374
|
+
emit(a, b, c);
|
|
1375
|
+
else if (count === 3) {
|
|
1376
|
+
emit(a, ab, ca);
|
|
1377
|
+
emit(ab, b, bc);
|
|
1378
|
+
emit(ca, bc, c);
|
|
1379
|
+
emit(ab, bc, ca);
|
|
1380
|
+
} else {
|
|
1381
|
+
const corners = [a, b, c];
|
|
1382
|
+
const edges = [ab, bc, ca];
|
|
1383
|
+
const start = count === 1 ? edges.findIndex((v) => v >= 0) : edges.findIndex((v) => v < 0);
|
|
1384
|
+
const rotation = count === 1 ? start : (start + 1) % 3;
|
|
1385
|
+
const x = corners[rotation];
|
|
1386
|
+
const y = corners[(rotation + 1) % 3];
|
|
1387
|
+
const z = corners[(rotation + 2) % 3];
|
|
1388
|
+
const xy = edges[rotation];
|
|
1389
|
+
if (count === 1) {
|
|
1390
|
+
emit(x, xy, z);
|
|
1391
|
+
emit(xy, y, z);
|
|
1392
|
+
} else {
|
|
1393
|
+
const yz = edges[(rotation + 1) % 3];
|
|
1394
|
+
emit(y, yz, xy);
|
|
1395
|
+
emit(x, xy, z);
|
|
1396
|
+
emit(xy, yz, z);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
function emit(x, y, z) {
|
|
1400
|
+
if (output.length >= maxTriangles)
|
|
1401
|
+
throw new RangeError("Triangle mesh subdivision exceeded maxTriangles");
|
|
1402
|
+
output.push({ vertices: [x, y, z], sourceTriangle: face.sourceTriangle });
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
function buildResult() {
|
|
1406
|
+
const sourceVertexIndices = new Uint32Array(vertices.length * 3);
|
|
1407
|
+
const sourceVertexWeights = new Float64Array(vertices.length * 3);
|
|
1408
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
1409
|
+
let slot = 0;
|
|
1410
|
+
for (const [index, weight] of vertices[i].weights) {
|
|
1411
|
+
sourceVertexIndices[i * 3 + slot] = index;
|
|
1412
|
+
sourceVertexWeights[i * 3 + slot++] = weight;
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
return {
|
|
1416
|
+
sourcePositions: new Float64Array(vertices.flatMap((v) => v.source)),
|
|
1417
|
+
positions: new Float64Array(vertices.flatMap((v) => v.target)),
|
|
1418
|
+
indices: new Uint32Array(faces.flatMap((f) => f.vertices)),
|
|
1419
|
+
sourceVertexIndices,
|
|
1420
|
+
sourceVertexWeights,
|
|
1421
|
+
sourceTriangleIndices: new Uint32Array(faces.map((f) => f.sourceTriangle))
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
function sourceEdgeLength(a, b) {
|
|
1426
|
+
return Math.hypot(...a.source.map((value, component) => value - b.source[component]));
|
|
1427
|
+
}
|
|
1428
|
+
function edgeKey(a, b) {
|
|
1429
|
+
return a <= b ? `${a}:${b}` : `${b}:${a}`;
|
|
1430
|
+
}
|
|
1431
|
+
function validLimit(value) {
|
|
1432
|
+
return Number.isSafeInteger(value) && value > 0 && value <= 4294967295;
|
|
1433
|
+
}
|
|
1434
|
+
function blend(positions, weights) {
|
|
1435
|
+
return positions[0].map((_, i) => positions.reduce((sum, p, j) => sum + p[i] * weights[j], 0));
|
|
1436
|
+
}
|
|
1437
|
+
//# sourceMappingURL=index.cjs.map
|