pattapatta 0.3.0 → 0.4.0
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/CHANGELOG.md +6 -0
- package/dist/{circle-BDbKfrdR.d.ts → circle-CauDMv8V.d.ts} +1 -1
- package/dist/circlePacking/index.d.ts +2 -3
- package/dist/construction/index.d.ts +11 -3
- package/dist/construction/index.js +429 -2
- package/dist/construction/index.js.map +1 -1
- package/dist/contour/index.d.ts +3 -4
- package/dist/contour/index.js.map +1 -1
- package/dist/conversion/index.d.ts +2 -3
- package/dist/{group-BNjVVYSQ.d.ts → group-YVmSJuGo.d.ts} +1 -1
- package/dist/hatch/index.d.ts +70 -4
- package/dist/hatch/index.js +414 -3
- package/dist/hatch/index.js.map +1 -1
- package/dist/hull/index.d.ts +1 -2
- package/dist/index.d.ts +12 -13
- package/dist/index.js +1816 -1260
- package/dist/index.js.map +1 -1
- package/dist/meshing/index.d.ts +3 -4
- package/dist/morphology/index.d.ts +2 -3
- package/dist/optimisation/index.d.ts +2 -3
- package/dist/{path-0RjhYjJs.d.ts → path-Boeshk9L.d.ts} +9 -2
- package/dist/pointSet/index.d.ts +15 -2
- package/dist/pointSet/index.js +148 -2
- package/dist/pointSet/index.js.map +1 -1
- package/dist/polygonisation/index.d.ts +1 -2
- package/dist/polygonisation/index.js +54 -50
- package/dist/polygonisation/index.js.map +1 -1
- package/dist/predicates/index.d.ts +2 -3
- package/dist/processing/index.d.ts +3 -4
- package/dist/{segment-BKuIFMKD.d.ts → segment-CpLILSd7.d.ts} +1 -1
- package/dist/segmentSet/index.d.ts +41 -3
- package/dist/segmentSet/index.js +261 -1
- package/dist/segmentSet/index.js.map +1 -1
- package/dist/shapeBoolean/index.d.ts +2 -3
- package/dist/svg/index.d.ts +2 -3
- package/dist/tiling/index.d.ts +10 -4
- package/dist/tiling/index.js +148 -13
- package/dist/tiling/index.js.map +1 -1
- package/dist/transformation/index.d.ts +1 -2
- package/dist/triangulation/index.d.ts +1 -2
- package/dist/triangulation/index.js.map +1 -1
- package/dist/voronoi/index.d.ts +2 -3
- package/package.json +1 -1
- package/dist/vec2-CWyXN1Wj.d.ts +0 -10
package/dist/hatch/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types/vec2.ts","../../src/types/segment.ts","../../src/types/path.ts","../../src/segmentSet/index.ts","../../src/clipper/convert.ts","../../src/predicates/index.ts","../../src/segmentSet/clip.ts","../../src/hatch/index.ts"],"names":["path"],"mappings":"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","file":"index.js","sourcesContent":["/** 2D point / vector. */\nexport type Vec2 = {\n x: number\n y: number\n}\n\nexport function vec2(x: number, y: number): Vec2 {\n return { x, y }\n}\n\nexport function cloneVec2(v: Vec2): Vec2 {\n return { x: v.x, y: v.y }\n}\n\nexport function equalsVec2(a: Vec2, b: Vec2, eps = 1e-9): boolean {\n return Math.abs(a.x - b.x) <= eps && Math.abs(a.y - b.y) <= eps\n}\n","import type { Vec2 } from './vec2.js'\n\n/** Line segment between two points. */\nexport type Segment = {\n a: Vec2\n b: Vec2\n}\n\nexport function segment(a: Vec2, b: Vec2): Segment {\n return { a, b }\n}\n","import type { Vec2 } from './vec2.js'\nimport { cloneVec2, equalsVec2 } from './vec2.js'\n\n/** Ordered ring of vertices (typically without repeating the closing vertex). */\nexport type Ring = Vec2[]\n\n/**\n * A path: one exterior ring plus optional holes, or an open polyline.\n * `rings[0]` is the exterior (or the open polyline when `closed` is false).\n * Additional rings are holes (only meaningful when `closed` is true).\n */\nexport type Path = {\n rings: Ring[]\n closed: boolean\n}\n\nexport function path(rings: Ring[], closed = true): Path {\n return {\n rings: rings.map((ring) => ring.map(cloneVec2)),\n closed,\n }\n}\n\nexport function polyline(points: Ring): Path {\n return path([points], false)\n}\n\nexport function polygon(exterior: Ring, holes: Ring[] = []): Path {\n return path([exterior, ...holes], true)\n}\n\n/** Drop a trailing vertex that duplicates the first (SVG often closes this way). */\nexport function normalizeRing(ring: Ring, eps = 1e-9): Ring {\n if (ring.length < 2) return ring.map(cloneVec2)\n const first = ring[0]\n const last = ring[ring.length - 1]\n if (first && last && equalsVec2(first, last, eps)) {\n return ring.slice(0, -1).map(cloneVec2)\n }\n return ring.map(cloneVec2)\n}\n\nexport function clonePath(p: Path): Path {\n return {\n closed: p.closed,\n rings: p.rings.map((ring) => ring.map(cloneVec2)),\n }\n}\n","import type { Segment, Vec2 } from '../types/index.js'\nimport { segment, vec2 } from '../types/index.js'\n\n/** Match Processing `float` for PGS parity on hatch fixtures. */\nfunction f32(n: number): number {\n return Math.fround(n)\n}\n\n/**\n * Parallel segments through a center point (PGS `parallelSegments` semantics).\n * `length` is the half-length along the segment direction; full span is `2 * length`.\n * `angle` is radians along the segment; spacing is perpendicular.\n */\nexport function parallelSegments(\n centerX: number,\n centerY: number,\n length: number,\n spacing: number,\n angle: number,\n n: number,\n): Segment[] {\n const edges: Segment[] = []\n if (n < 1) return edges\n\n const center = vec2(f32(centerX), f32(centerY))\n let dx = f32(Math.cos(angle + Math.PI / 2) * spacing)\n let dy = f32(Math.sin(angle + Math.PI / 2) * spacing)\n const cos = f32(Math.cos(angle))\n const sin = f32(Math.sin(angle))\n const l = f32(length)\n\n let i: number\n let offX = 0\n let offY = 0\n\n if (n % 2 === 1) {\n const a = vec2(f32(center.x + cos * l), f32(center.y + sin * l))\n const b = vec2(f32(center.x + cos * -l), f32(center.y + sin * -l))\n edges.push(segment(a, b))\n i = 1\n } else {\n dx = f32(dx / 2)\n dy = f32(dy / 2)\n i = 1\n {\n let a = vec2(f32(center.x + dx * i), f32(center.y + dy * i))\n const b = vec2(f32(a.x + cos * l), f32(a.y + sin * l))\n a = vec2(f32(a.x + cos * -l), f32(a.y + sin * -l))\n edges.push(segment(a, b))\n }\n {\n let a = vec2(f32(center.x + dx * -i), f32(center.y + dy * -i))\n const b = vec2(f32(a.x + cos * l), f32(a.y + sin * l))\n a = vec2(f32(a.x + cos * -l), f32(a.y + sin * -l))\n edges.push(segment(a, b))\n }\n i = 2\n dx = f32(dx * 2)\n dy = f32(dy * 2)\n offX = f32(dx / 2)\n offY = f32(dy / 2)\n }\n\n for (; i < 1 + Math.floor(n / 2); i++) {\n {\n let a = vec2(\n f32(center.x + dx * i - offX),\n f32(center.y + dy * i - offY),\n )\n const b = vec2(f32(a.x + cos * l), f32(a.y + sin * l))\n a = vec2(f32(a.x + cos * -l), f32(a.y + sin * -l))\n edges.push(segment(a, b))\n }\n {\n let a = vec2(\n f32(center.x + dx * -i + offX),\n f32(center.y + dy * -i + offY),\n )\n const b = vec2(f32(a.x + cos * l), f32(a.y + sin * l))\n a = vec2(f32(a.x + cos * -l), f32(a.y + sin * -l))\n edges.push(segment(a, b))\n }\n }\n\n return edges\n}\n\nexport function filterByMinLength(\n segments: Segment[],\n minLength: number,\n): Segment[] {\n return segments.filter((s) => segmentLength(s) >= minLength)\n}\n\nexport function filterAxisAligned(\n segments: Segment[],\n angleDelta: number,\n): Segment[] {\n return segments.filter((s) => {\n const ang = Math.abs(Math.atan2(s.b.y - s.a.y, s.b.x - s.a.x))\n const norm = Math.min(ang % Math.PI, Math.PI - (ang % Math.PI))\n const nearH = norm <= angleDelta || Math.abs(norm - Math.PI) <= angleDelta\n const nearV = Math.abs(norm - Math.PI / 2) <= angleDelta\n return !(nearH || nearV)\n })\n}\n\nexport function segmentLength(s: Segment): number {\n const dx = s.b.x - s.a.x\n const dy = s.b.y - s.a.y\n return Math.hypot(dx, dy)\n}\n\nexport function segmentsToOpenPaths(segments: Segment[]) {\n return segments.map((s) => ({\n rings: [[s.a, s.b]],\n closed: false as const,\n }))\n}\n\nexport const segmentSet = {\n parallelSegments,\n filterByMinLength,\n filterAxisAligned,\n segmentLength,\n segmentsToOpenPaths,\n}\n\nexport type { Vec2 }\n","import {\n FillRule,\n areaD,\n differenceD,\n intersectD,\n isPositiveD,\n pointInPolygonD,\n PointInPolygonResult,\n unionD,\n xorD,\n type PathD,\n type PathsD,\n type PointD,\n} from 'clipper2-ts'\nimport type { Group, Path, Ring, Vec2 } from '../types/index.js'\nimport { group, normalizeRing, path, vec2 } from '../types/index.js'\n\nexport const DEFAULT_FILL_RULE = FillRule.NonZero\n\nexport function ringToPathD(ring: Ring): PathD {\n const pts: PointD[] = []\n for (const v of normalizeRing(ring)) {\n pts.push({ x: v.x, y: v.y, z: 0 })\n }\n return pts\n}\n\n/** Closed path → Clipper subject/clip paths (exterior + holes). */\nexport function pathToPathsD(p: Path): PathsD {\n if (!p.closed || p.rings.length === 0) {\n throw new Error('Boolean ops require a closed path with at least one ring')\n }\n return p.rings.map((ring) => ringToPathD(ring))\n}\n\nexport function pathsDToGroup(paths: PathsD): Group {\n if (paths.length === 0) return group([])\n\n const outers: { ring: Ring; holes: Ring[] }[] = []\n const holes: Ring[] = []\n\n for (const pd of paths) {\n const ring = pathDToRing(pd)\n if (ring.length < 3) continue\n if (isPositiveD(pd)) {\n outers.push({ ring, holes: [] })\n } else {\n holes.push(ring)\n }\n }\n\n for (const hole of holes) {\n const sample = hole[0]\n if (!sample) continue\n let assigned = false\n for (const outer of outers) {\n if (pointInRing(sample, outer.ring)) {\n outer.holes.push(hole)\n assigned = true\n break\n }\n }\n if (!assigned) {\n // Treat unmatched negative rings as their own outers (orientation flip).\n outers.push({ ring: [...hole].reverse(), holes: [] })\n }\n }\n\n return group(outers.map((o) => path([o.ring, ...o.holes], true)))\n}\n\nexport function pathDToRing(pd: PathD): Ring {\n return normalizeRing(pd.map((p) => vec2(p.x, p.y)))\n}\n\nexport function pointInRing(point: Vec2, ring: Ring): boolean {\n const result = pointInPolygonD(\n { x: point.x, y: point.y, z: 0 },\n ringToPathD(ring),\n )\n return (\n result === PointInPolygonResult.IsInside ||\n result === PointInPolygonResult.IsOn\n )\n}\n\nexport function clipUnion(a: PathsD, b: PathsD): PathsD {\n return unionD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function clipIntersect(a: PathsD, b: PathsD): PathsD {\n return intersectD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function clipDifference(a: PathsD, b: PathsD): PathsD {\n return differenceD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function clipXor(a: PathsD, b: PathsD): PathsD {\n return xorD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function pathsArea(paths: PathsD): number {\n let sum = 0\n for (const p of paths) {\n sum += Math.abs(areaD(p))\n }\n return sum\n}\n","import type { Group, Path, Vec2 } from '../types/index.js'\nimport { vec2 } from '../types/index.js'\nimport {\n pathToPathsD,\n pathsArea,\n pointInRing,\n} from '../clipper/convert.js'\n\n/** Signed area of a closed ring (shoelace). */\nexport function ringArea(ring: Vec2[]): number {\n if (ring.length < 3) return 0\n let sum = 0\n for (let i = 0; i < ring.length; i++) {\n const a = ring[i]!\n const b = ring[(i + 1) % ring.length]!\n sum += a.x * b.y - b.x * a.y\n }\n return sum / 2\n}\n\n/** Absolute area of a closed path (exterior minus holes). */\nexport function area(p: Path): number {\n if (!p.closed || p.rings.length === 0) return 0\n try {\n return pathsArea(pathToPathsD(p))\n } catch {\n let total = 0\n for (let i = 0; i < p.rings.length; i++) {\n const a = Math.abs(ringArea(p.rings[i]!))\n total += i === 0 ? a : -a\n }\n return Math.max(0, total)\n }\n}\n\nexport function areaGroup(g: Group): number {\n return g.paths.reduce((sum, p) => sum + area(p), 0)\n}\n\n/** Centroid of a closed exterior ring (ignores holes for Phase 2). */\nexport function centroid(p: Path): Vec2 {\n const ring = p.rings[0]\n if (!ring || ring.length === 0) return vec2(0, 0)\n const a = ringArea(ring)\n if (Math.abs(a) < 1e-12) {\n let sx = 0\n let sy = 0\n for (const v of ring) {\n sx += v.x\n sy += v.y\n }\n return vec2(sx / ring.length, sy / ring.length)\n }\n let cx = 0\n let cy = 0\n for (let i = 0; i < ring.length; i++) {\n const p0 = ring[i]!\n const p1 = ring[(i + 1) % ring.length]!\n const cross = p0.x * p1.y - p1.x * p0.y\n cx += (p0.x + p1.x) * cross\n cy += (p0.y + p1.y) * cross\n }\n return vec2(cx / (6 * a), cy / (6 * a))\n}\n\nexport function containsPoint(p: Path, point: Vec2): boolean {\n if (!p.closed || !p.rings[0]) return false\n if (!pointInRing(point, p.rings[0])) return false\n for (let i = 1; i < p.rings.length; i++) {\n const hole = p.rings[i]\n if (hole && pointInRing(point, hole)) return false\n }\n return true\n}\n\nexport function bounds(p: Path): {\n minX: number\n minY: number\n maxX: number\n maxY: number\n} {\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const ring of p.rings) {\n for (const v of ring) {\n minX = Math.min(minX, v.x)\n minY = Math.min(minY, v.y)\n maxX = Math.max(maxX, v.x)\n maxY = Math.max(maxY, v.y)\n }\n }\n if (!Number.isFinite(minX)) {\n return { minX: 0, minY: 0, maxX: 0, maxY: 0 }\n }\n return { minX, minY, maxX, maxY }\n}\n\nexport function width(p: Path): number {\n const b = bounds(p)\n return b.maxX - b.minX\n}\n\nexport function height(p: Path): number {\n const b = bounds(p)\n return b.maxY - b.minY\n}\n\n/** Rough polygon similarity via absolute area difference relative to max area. */\nexport function areaSimilarity(a: Path, b: Path): number {\n const aa = area(a)\n const bb = area(b)\n const denom = Math.max(aa, bb, 1e-12)\n return 1 - Math.abs(aa - bb) / denom\n}\n\nexport const predicates = {\n area,\n areaGroup,\n ringArea,\n centroid,\n containsPoint,\n bounds,\n width,\n height,\n areaSimilarity,\n}\n","import type { Path, Ring, Segment, Vec2 } from '../types/index.js'\nimport { segment, vec2 } from '../types/index.js'\nimport { containsPoint } from '../predicates/index.js'\n\ntype Hit = { t: number; p: Vec2 }\n\n/**\n * Clip an open segment to the interior of a closed path (exterior minus holes).\n * Returns zero or more interior sub-segments.\n */\nexport function clipSegmentToPath(seg: Segment, clip: Path): Segment[] {\n if (!clip.closed || !clip.rings[0]) return []\n\n const hits: Hit[] = []\n const pushHit = (t: number, p: Vec2) => {\n if (t < -1e-9 || t > 1 + 1e-9) return\n const tt = Math.min(1, Math.max(0, t))\n for (const h of hits) {\n if (Math.abs(h.t - tt) < 1e-9) return\n }\n hits.push({ t: tt, p })\n }\n\n if (containsPoint(clip, seg.a)) pushHit(0, seg.a)\n if (containsPoint(clip, seg.b)) pushHit(1, seg.b)\n\n for (const ring of clip.rings) {\n for (let i = 0; i < ring.length; i++) {\n const e0 = ring[i]!\n const e1 = ring[(i + 1) % ring.length]!\n const hit = segmentIntersection(seg.a, seg.b, e0, e1)\n if (hit) pushHit(hit.t, hit.p)\n }\n }\n\n hits.sort((a, b) => a.t - b.t)\n if (hits.length < 2) return []\n\n const out: Segment[] = []\n for (let i = 0; i + 1 < hits.length; i++) {\n const h0 = hits[i]!\n const h1 = hits[i + 1]!\n if (h1.t - h0.t < 1e-9) continue\n const mid = vec2((h0.p.x + h1.p.x) / 2, (h0.p.y + h1.p.y) / 2)\n if (containsPoint(clip, mid)) {\n out.push(segment(h0.p, h1.p))\n }\n }\n return out\n}\n\nexport function clipSegmentsToPath(\n segments: Segment[],\n clip: Path,\n): Segment[] {\n const out: Segment[] = []\n for (const s of segments) {\n out.push(...clipSegmentToPath(s, clip))\n }\n return out\n}\n\nfunction segmentIntersection(\n a: Vec2,\n b: Vec2,\n c: Vec2,\n d: Vec2,\n): { t: number; p: Vec2 } | null {\n const rX = b.x - a.x\n const rY = b.y - a.y\n const sX = d.x - c.x\n const sY = d.y - c.y\n const denom = rX * sY - rY * sX\n if (Math.abs(denom) < 1e-12) return null\n const t = ((c.x - a.x) * sY - (c.y - a.y) * sX) / denom\n const u = ((c.x - a.x) * rY - (c.y - a.y) * rX) / denom\n if (t < -1e-9 || t > 1 + 1e-9 || u < -1e-9 || u > 1 + 1e-9) return null\n return {\n t,\n p: vec2(a.x + t * rX, a.y + t * rY),\n }\n}\n\n/** @internal exported for tests */\nexport type { Ring }\n","import type { Path, Segment } from '../types/index.js'\nimport { parallelSegments } from '../segmentSet/index.js'\nimport { clipSegmentsToPath } from '../segmentSet/clip.js'\n\nexport type ParallelHatchOptions = {\n /** Hatch angle in radians (segment direction). Default `Math.PI / 4`. */\n angle?: number\n /** Perpendicular spacing between lines. Default `0.15`. */\n spacing?: number\n /**\n * Half-length of generated lines before clipping (PGS `length`).\n * Default: diagonal of path bounds.\n */\n length?: number\n /**\n * Number of parallel lines (PGS `n`).\n * Default: enough lines to cover the path AABB at the given spacing.\n */\n count?: number\n /** Hatch field center. Default: path centroid of exterior bounds center. */\n center?: { x: number; y: number }\n}\n\n/**\n * Fill a closed path with parallel hatch strokes (plotter-safe).\n * Composes `parallelSegments` + clip-to-path (PGS dysonHatching recipe).\n *\n * When `count` is omitted, line count is derived from `spacing` and the path\n * bounds so the hatch covers the whole region (no corner gaps).\n */\nexport function parallel(path: Path, options: ParallelHatchOptions = {}): Segment[] {\n if (!path.closed || !path.rings[0]) {\n throw new Error('hatch.parallel requires a closed path')\n }\n\n const bounds = pathBounds(path)\n const center = options.center ?? {\n x: (bounds.minX + bounds.maxX) / 2,\n y: (bounds.minY + bounds.maxY) / 2,\n }\n const diag = Math.hypot(bounds.maxX - bounds.minX, bounds.maxY - bounds.minY)\n const length = options.length ?? Math.max(diag, 1e-6)\n const spacing = Math.max(options.spacing ?? 0.15, 1e-9)\n const angle = options.angle ?? Math.PI / 4\n const count = options.count ?? hatchLineCount(bounds, spacing, angle)\n\n const raw = parallelSegments(\n center.x,\n center.y,\n length,\n spacing,\n angle,\n count,\n )\n return clipSegmentsToPath(raw, path)\n}\n\n/** Cross-hatch: two perpendicular parallel passes. */\nexport function cross(path: Path, options: ParallelHatchOptions = {}): Segment[] {\n const angle = options.angle ?? Math.PI / 4\n const a = parallel(path, options)\n const b = parallel(path, { ...options, angle: angle + Math.PI / 2 })\n return [...a, ...b]\n}\n\n/** Lines needed so perpendicular spacing covers the AABB at `angle`. */\nfunction hatchLineCount(\n bounds: { minX: number; minY: number; maxX: number; maxY: number },\n spacing: number,\n angle: number,\n): number {\n const nx = Math.cos(angle + Math.PI / 2)\n const ny = Math.sin(angle + Math.PI / 2)\n const corners: [number, number][] = [\n [bounds.minX, bounds.minY],\n [bounds.maxX, bounds.minY],\n [bounds.maxX, bounds.maxY],\n [bounds.minX, bounds.maxY],\n ]\n let minP = Infinity\n let maxP = -Infinity\n for (const [x, y] of corners) {\n const p = x * nx + y * ny\n minP = Math.min(minP, p)\n maxP = Math.max(maxP, p)\n }\n const extent = maxP - minP\n return Math.max(1, Math.ceil(extent / spacing) + 1)\n}\n\nfunction pathBounds(path: Path) {\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const ring of path.rings) {\n for (const v of ring) {\n minX = Math.min(minX, v.x)\n minY = Math.min(minY, v.y)\n maxX = Math.max(maxX, v.x)\n maxY = Math.max(maxY, v.y)\n }\n }\n return { minX, minY, maxX, maxY }\n}\n\nexport const hatch = {\n parallel,\n cross,\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/types/vec2.ts","../../src/types/segment.ts","../../src/types/path.ts","../../src/types/group.ts","../../src/segmentSet/index.ts","../../src/clipper/convert.ts","../../src/predicates/index.ts","../../src/segmentSet/clip.ts","../../src/morphology/buffer.ts","../../src/hatch/index.ts"],"names":["path"],"mappings":"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","file":"index.js","sourcesContent":["/** 2D point / vector. */\nexport type Vec2 = {\n x: number\n y: number\n}\n\nexport function vec2(x: number, y: number): Vec2 {\n return { x, y }\n}\n\nexport function cloneVec2(v: Vec2): Vec2 {\n return { x: v.x, y: v.y }\n}\n\nexport function equalsVec2(a: Vec2, b: Vec2, eps = 1e-9): boolean {\n return Math.abs(a.x - b.x) <= eps && Math.abs(a.y - b.y) <= eps\n}\n","import type { Vec2 } from './vec2.js'\n\n/** Line segment between two points. */\nexport type Segment = {\n a: Vec2\n b: Vec2\n}\n\nexport function segment(a: Vec2, b: Vec2): Segment {\n return { a, b }\n}\n","import type { Vec2 } from './vec2.js'\nimport { cloneVec2, equalsVec2 } from './vec2.js'\n\n/** Ordered ring of vertices (typically without repeating the closing vertex). */\nexport type Ring = Vec2[]\n\n/**\n * A path: one exterior ring plus optional holes, or an open polyline.\n * `rings[0]` is the exterior (or the open polyline when `closed` is false).\n * Additional rings are holes (only meaningful when `closed` is true).\n */\nexport type Path = {\n rings: Ring[]\n closed: boolean\n}\n\nexport function path(rings: Ring[], closed = true): Path {\n return {\n rings: rings.map((ring) => ring.map(cloneVec2)),\n closed,\n }\n}\n\nexport function polyline(points: Ring): Path {\n return path([points], false)\n}\n\nexport function polygon(exterior: Ring, holes: Ring[] = []): Path {\n return path([exterior, ...holes], true)\n}\n\n/** Drop a trailing vertex that duplicates the first (SVG often closes this way). */\nexport function normalizeRing(ring: Ring, eps = 1e-9): Ring {\n if (ring.length < 2) return ring.map(cloneVec2)\n const first = ring[0]\n const last = ring[ring.length - 1]\n if (first && last && equalsVec2(first, last, eps)) {\n return ring.slice(0, -1).map(cloneVec2)\n }\n return ring.map(cloneVec2)\n}\n\nexport function clonePath(p: Path): Path {\n return {\n closed: p.closed,\n rings: p.rings.map((ring) => ring.map(cloneVec2)),\n }\n}\n","import type { Path } from './path.js'\nimport { clonePath } from './path.js'\n\n/**\n * Ordered collection of paths. Later entries are “on top” for occlusion-style ops.\n */\nexport type Group = {\n paths: Path[]\n}\n\nexport function group(paths: Path[] = []): Group {\n return { paths: paths.map(clonePath) }\n}\n\nexport function groupFromPaths(...paths: Path[]): Group {\n return group(paths)\n}\n\nexport function cloneGroup(g: Group): Group {\n return group(g.paths)\n}\n","import type { Path, Segment, Vec2 } from '../types/index.js'\nimport { segment, vec2 } from '../types/index.js'\n\n/** Match Processing `float` for PGS parity on hatch fixtures. */\nfunction f32(n: number): number {\n return Math.fround(n)\n}\n\n/**\n * Parallel segments through a center point (PGS `parallelSegments` semantics).\n * `length` is the half-length along the segment direction; full span is `2 * length`.\n * `angle` is radians along the segment; spacing is perpendicular.\n */\nexport function parallelSegments(\n centerX: number,\n centerY: number,\n length: number,\n spacing: number,\n angle: number,\n n: number,\n): Segment[] {\n const edges: Segment[] = []\n if (n < 1) return edges\n\n const center = vec2(f32(centerX), f32(centerY))\n let dx = f32(Math.cos(angle + Math.PI / 2) * spacing)\n let dy = f32(Math.sin(angle + Math.PI / 2) * spacing)\n const cos = f32(Math.cos(angle))\n const sin = f32(Math.sin(angle))\n const l = f32(length)\n\n let i: number\n let offX = 0\n let offY = 0\n\n if (n % 2 === 1) {\n const a = vec2(f32(center.x + cos * l), f32(center.y + sin * l))\n const b = vec2(f32(center.x + cos * -l), f32(center.y + sin * -l))\n edges.push(segment(a, b))\n i = 1\n } else {\n dx = f32(dx / 2)\n dy = f32(dy / 2)\n i = 1\n {\n let a = vec2(f32(center.x + dx * i), f32(center.y + dy * i))\n const b = vec2(f32(a.x + cos * l), f32(a.y + sin * l))\n a = vec2(f32(a.x + cos * -l), f32(a.y + sin * -l))\n edges.push(segment(a, b))\n }\n {\n let a = vec2(f32(center.x + dx * -i), f32(center.y + dy * -i))\n const b = vec2(f32(a.x + cos * l), f32(a.y + sin * l))\n a = vec2(f32(a.x + cos * -l), f32(a.y + sin * -l))\n edges.push(segment(a, b))\n }\n i = 2\n dx = f32(dx * 2)\n dy = f32(dy * 2)\n offX = f32(dx / 2)\n offY = f32(dy / 2)\n }\n\n for (; i < 1 + Math.floor(n / 2); i++) {\n {\n let a = vec2(\n f32(center.x + dx * i - offX),\n f32(center.y + dy * i - offY),\n )\n const b = vec2(f32(a.x + cos * l), f32(a.y + sin * l))\n a = vec2(f32(a.x + cos * -l), f32(a.y + sin * -l))\n edges.push(segment(a, b))\n }\n {\n let a = vec2(\n f32(center.x + dx * -i + offX),\n f32(center.y + dy * -i + offY),\n )\n const b = vec2(f32(a.x + cos * l), f32(a.y + sin * l))\n a = vec2(f32(a.x + cos * -l), f32(a.y + sin * -l))\n edges.push(segment(a, b))\n }\n }\n\n return edges\n}\n\n/**\n * Random non-intersecting segments in a box anchored at `(originX, originY)`\n * with the given width/height (PGS `stochasticSegments`).\n *\n * Lengths are uniform in `[minLength, maxLength)` when the range differs;\n * use equal min/max for fixed length. Seeded via mulberry32.\n */\nexport function stochasticSegments(\n width: number,\n height: number,\n n: number,\n minLength?: number,\n maxLength?: number,\n seed = 1,\n originX = 0,\n originY = 0,\n): Segment[] {\n const minL =\n minLength ?? 1\n const maxL =\n maxLength ?? Math.min(width, height)\n if (n < 1 || width <= 0 || height <= 0) return []\n\n const monoLength = minL === maxL\n const rng = mulberry32(seed >>> 0)\n const edges: Segment[] = []\n const maxAttempts = Math.max(10_000, n * 500)\n let attempts = 0\n\n while (edges.length < n && attempts < maxAttempts) {\n attempts++\n const length = monoLength ? minL : minL + rng() * (maxL - minL)\n if (!(length > 0) || length * 2 >= width || length * 2 >= height) {\n continue\n }\n const ax = originX + rng() * (width - length * 2) + length\n const ay = originY + rng() * (height - length * 2) + length\n const theta = rng() * Math.PI * 2\n const bx = ax + Math.cos(theta) * length\n const by = ay + Math.sin(theta) * length\n const a = vec2(ax, ay)\n const b = vec2(bx, by)\n\n let hits = false\n for (const s of edges) {\n if (segmentsIntersect(a, b, s.a, s.b)) {\n hits = true\n break\n }\n }\n if (!hits) edges.push(segment(a, b))\n }\n\n return edges\n}\n\n/**\n * Fabric-like horizontal/vertical weave on a regular cell grid\n * (PGS `weaveSegments` / ABC auxetics).\n *\n * Domain is `[originX, originX+width] × [originY, originY+height]`.\n * A/B control weft/warp run lengths; C is the row phase shift (mod A+B).\n */\nexport function weaveSegments(\n width: number,\n height: number,\n cellSize: number,\n A = 1,\n B = 1,\n C = 1,\n options: WeaveSegmentsOptions = {},\n): Segment[] {\n if (!(cellSize > 0)) {\n throw new Error('weaveSegments: cellSize must be > 0')\n }\n if (A <= 0 || B <= 0) {\n throw new Error('weaveSegments: A and B must be > 0')\n }\n\n const {\n originX = 0,\n originY = 0,\n swapColors = false,\n cellFraction = 1,\n extendSingletonsToEdge = true,\n } = options\n\n if (!(cellFraction > 0)) {\n throw new Error('weaveSegments: cellFraction must be > 0')\n }\n\n const P = A + B\n const f = Math.max(0, Math.min(1, cellFraction))\n\n const cols = Math.max(1, Math.floor(width / cellSize))\n const rows = Math.max(1, Math.floor(height / cellSize))\n const gridW = cols * cellSize\n const gridH = rows * cellSize\n const dx = originX + (width - gridW) * 0.5\n const dy = originY + (height - gridH) * 0.5\n\n const gridLeft = dx\n const gridRight = dx + gridW\n const gridBottom = dy\n const gridTop = dy + gridH\n\n const weft: boolean[][] = Array.from({ length: rows }, () =>\n Array.from({ length: cols }, () => false),\n )\n for (let r = 0; r < rows; r++) {\n const shift = floorMod(r * C, P)\n for (let c = 0; c < cols; c++) {\n const idx = floorMod(c + shift, P)\n let isWeft = idx < A\n if (swapColors) isWeft = !isWeft\n weft[r]![c] = isWeft\n }\n }\n\n const segs: Segment[] = []\n\n for (let r = 0; r < rows; r++) {\n let c = 0\n while (c < cols) {\n if (!weft[r]![c]) {\n c++\n continue\n }\n const start = c\n while (c + 1 < cols && weft[r]![c + 1]) c++\n const end = c\n const runLen = end - start + 1\n const y = dy + (r + 0.5) * cellSize\n let x0 = dx + (start + (1 - f)) * cellSize\n let x1 = dx + (end + f) * cellSize\n\n if (extendSingletonsToEdge && runLen === 1) {\n const cx = dx + (start + 0.5) * cellSize\n if (start === 0) {\n x0 = gridLeft\n x1 = cx\n } else if (end === cols - 1) {\n x0 = cx\n x1 = gridRight\n }\n }\n\n x0 = clamp(x0, gridLeft, gridRight)\n x1 = clamp(x1, gridLeft, gridRight)\n segs.push(segment(vec2(x0, y), vec2(x1, y)))\n c++\n }\n }\n\n for (let c = 0; c < cols; c++) {\n let r = 0\n while (r < rows) {\n if (weft[r]![c]) {\n r++\n continue\n }\n const start = r\n while (r + 1 < rows && !weft[r + 1]![c]) r++\n const end = r\n const runLen = end - start + 1\n const x = dx + (c + 0.5) * cellSize\n let y0 = dy + (start + (1 - f)) * cellSize\n let y1 = dy + (end + f) * cellSize\n\n if (extendSingletonsToEdge && runLen === 1) {\n const cy = dy + (start + 0.5) * cellSize\n if (start === 0) {\n y0 = gridBottom\n y1 = cy\n } else if (end === rows - 1) {\n y0 = cy\n y1 = gridTop\n }\n }\n\n y0 = clamp(y0, gridBottom, gridTop)\n y1 = clamp(y1, gridBottom, gridTop)\n segs.push(segment(vec2(x, y0), vec2(x, y1)))\n r++\n }\n }\n\n return segs\n}\n\nexport type WeaveSegmentsOptions = {\n originX?: number\n originY?: number\n /** Swap weft/warp roles. */\n swapColors?: boolean\n /** Endpoint position inside run end cells (0.5..1 typical). Default `1`. */\n cellFraction?: number\n /** Extend single-cell boundary runs to the grid edge. Default `true`. */\n extendSingletonsToEdge?: boolean\n}\n\n/** Per-sample length for {@link perpendicularPathSegments}. */\nexport type SegmentLengthFn = (\n x: number,\n y: number,\n posFrac: number,\n normalAngle: number,\n) => number\n\n/**\n * Perpendicular ticks along each ring of `path`, centered on the boundary\n * (PGS `perpendicularPathSegments`). Outline texture, not an area fill.\n *\n * Closed rings are oriented CW so the left-hand normal points outward.\n */\nexport function perpendicularPathSegments(\n path: Path,\n interSegmentDistance: number,\n length: number | SegmentLengthFn,\n startOffset = 0,\n): Segment[] {\n if (!(interSegmentDistance > 0)) return []\n const lengthFn: SegmentLengthFn =\n typeof length === 'function' ? length : () => length\n\n const startNorm = ((startOffset % 1) + 1) % 1\n const edges: Segment[] = []\n\n for (const ring of path.rings) {\n if (ring.length < 2) continue\n const closed = path.closed\n let pts = ring.map((v) => vec2(v.x, v.y))\n if (closed && shoelace(pts) > 0) {\n pts = pts.slice().reverse()\n }\n\n const indexed = lengthIndex(pts, closed)\n const end = indexed.total\n if (!(end > 0)) continue\n\n const count = Math.max(1, Math.round(end / interSegmentDistance))\n const increment = 1 / count\n const eps = Math.max(\n end * 1e-4,\n Math.min(interSegmentDistance * 0.35, end * 0.01),\n )\n\n for (let i = 0; i < count; i++) {\n const posFrac = (startNorm + i * increment) % 1\n const idx = posFrac * end\n const idxM = closed\n ? wrapIndex(idx - eps, end)\n : clamp(idx - eps, 0, end)\n const idxP = closed\n ? wrapIndex(idx + eps, end)\n : clamp(idx + eps, 0, end)\n\n const pm = indexed.pointAt(idxM)\n const pp = indexed.pointAt(idxP)\n const pc = indexed.pointAt(idx)\n\n const tx = pp.x - pm.x\n const ty = pp.y - pm.y\n const tlen = Math.hypot(tx, ty)\n if (tlen === 0) continue\n\n const nx = -ty / tlen\n const ny = tx / tlen\n const normalAngle = Math.atan2(ny, nx)\n const L = lengthFn(pc.x, pc.y, posFrac, normalAngle)\n if (!(L > 0)) continue\n const half = L * 0.5\n edges.push(\n segment(\n vec2(pc.x - nx * half, pc.y - ny * half),\n vec2(pc.x + nx * half, pc.y + ny * half),\n ),\n )\n }\n }\n\n return edges\n}\n\nexport function filterByMinLength(\n segments: Segment[],\n minLength: number,\n): Segment[] {\n return segments.filter((s) => segmentLength(s) >= minLength)\n}\n\nexport function filterAxisAligned(\n segments: Segment[],\n angleDelta: number,\n): Segment[] {\n return segments.filter((s) => {\n const ang = Math.abs(Math.atan2(s.b.y - s.a.y, s.b.x - s.a.x))\n const norm = Math.min(ang % Math.PI, Math.PI - (ang % Math.PI))\n const nearH = norm <= angleDelta || Math.abs(norm - Math.PI) <= angleDelta\n const nearV = Math.abs(norm - Math.PI / 2) <= angleDelta\n return !(nearH || nearV)\n })\n}\n\nexport function segmentLength(s: Segment): number {\n const dx = s.b.x - s.a.x\n const dy = s.b.y - s.a.y\n return Math.hypot(dx, dy)\n}\n\nexport function segmentsToOpenPaths(segments: Segment[]) {\n return segments.map((s) => ({\n rings: [[s.a, s.b]],\n closed: false as const,\n }))\n}\n\nexport const segmentSet = {\n parallelSegments,\n stochasticSegments,\n weaveSegments,\n perpendicularPathSegments,\n filterByMinLength,\n filterAxisAligned,\n segmentLength,\n segmentsToOpenPaths,\n}\n\nfunction floorMod(n: number, m: number): number {\n return ((n % m) + m) % m\n}\n\nfunction clamp(v: number, lo: number, hi: number): number {\n return Math.max(lo, Math.min(hi, v))\n}\n\nfunction wrapIndex(idx: number, end: number): number {\n if (end <= 0) return 0\n let x = idx % end\n if (x < 0) x += end\n return x\n}\n\nfunction shoelace(ring: Vec2[]): number {\n let sum = 0\n for (let i = 0; i < ring.length; i++) {\n const a = ring[i]!\n const b = ring[(i + 1) % ring.length]!\n sum += a.x * b.y - b.x * a.y\n }\n return sum / 2\n}\n\n/** Proper segment intersection (shared endpoint counts as intersect). */\nfunction segmentsIntersect(a: Vec2, b: Vec2, c: Vec2, d: Vec2): boolean {\n return (\n ccw(a, c, d) !== ccw(b, c, d) && ccw(a, b, c) !== ccw(a, b, d)\n )\n}\n\nfunction ccw(a: Vec2, b: Vec2, c: Vec2): boolean {\n return (c.y - a.y) * (b.x - a.x) > (b.y - a.y) * (c.x - a.x)\n}\n\nfunction mulberry32(seed: number): () => number {\n return function () {\n let t = (seed += 0x6d2b79f5)\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\nfunction lengthIndex(ring: Vec2[], closed: boolean) {\n const n = ring.length\n const edgeCount = closed ? n : n - 1\n const lengths: number[] = []\n let total = 0\n for (let i = 0; i < edgeCount; i++) {\n const a = ring[i]!\n const b = ring[(i + 1) % n]!\n const L = Math.hypot(b.x - a.x, b.y - a.y)\n lengths.push(L)\n total += L\n }\n return {\n total,\n pointAt(dist: number): Vec2 {\n let remain = dist\n if (remain <= 0) return { ...ring[0]! }\n if (remain >= total) return { ...ring[closed ? 0 : n - 1]! }\n for (let i = 0; i < lengths.length; i++) {\n const L = lengths[i]!\n if (remain <= L || i === lengths.length - 1) {\n const t = L < 1e-12 ? 0 : remain / L\n const a = ring[i]!\n const b = ring[(i + 1) % n]!\n return {\n x: a.x + (b.x - a.x) * t,\n y: a.y + (b.y - a.y) * t,\n }\n }\n remain -= L\n }\n return { ...ring[0]! }\n },\n }\n}\n\nexport type { Vec2 }\n","import {\n FillRule,\n areaD,\n differenceD,\n intersectD,\n isPositiveD,\n pointInPolygonD,\n PointInPolygonResult,\n unionD,\n xorD,\n type PathD,\n type PathsD,\n type PointD,\n} from 'clipper2-ts'\nimport type { Group, Path, Ring, Vec2 } from '../types/index.js'\nimport { group, normalizeRing, path, vec2 } from '../types/index.js'\n\nexport const DEFAULT_FILL_RULE = FillRule.NonZero\n\nexport function ringToPathD(ring: Ring): PathD {\n const pts: PointD[] = []\n for (const v of normalizeRing(ring)) {\n pts.push({ x: v.x, y: v.y, z: 0 })\n }\n return pts\n}\n\n/** Closed path → Clipper subject/clip paths (exterior + holes). */\nexport function pathToPathsD(p: Path): PathsD {\n if (!p.closed || p.rings.length === 0) {\n throw new Error('Boolean ops require a closed path with at least one ring')\n }\n return p.rings.map((ring) => ringToPathD(ring))\n}\n\nexport function pathsDToGroup(paths: PathsD): Group {\n if (paths.length === 0) return group([])\n\n const outers: { ring: Ring; holes: Ring[] }[] = []\n const holes: Ring[] = []\n\n for (const pd of paths) {\n const ring = pathDToRing(pd)\n if (ring.length < 3) continue\n if (isPositiveD(pd)) {\n outers.push({ ring, holes: [] })\n } else {\n holes.push(ring)\n }\n }\n\n for (const hole of holes) {\n const sample = hole[0]\n if (!sample) continue\n let assigned = false\n for (const outer of outers) {\n if (pointInRing(sample, outer.ring)) {\n outer.holes.push(hole)\n assigned = true\n break\n }\n }\n if (!assigned) {\n // Treat unmatched negative rings as their own outers (orientation flip).\n outers.push({ ring: [...hole].reverse(), holes: [] })\n }\n }\n\n return group(outers.map((o) => path([o.ring, ...o.holes], true)))\n}\n\nexport function pathDToRing(pd: PathD): Ring {\n return normalizeRing(pd.map((p) => vec2(p.x, p.y)))\n}\n\nexport function pointInRing(point: Vec2, ring: Ring): boolean {\n const result = pointInPolygonD(\n { x: point.x, y: point.y, z: 0 },\n ringToPathD(ring),\n )\n return (\n result === PointInPolygonResult.IsInside ||\n result === PointInPolygonResult.IsOn\n )\n}\n\nexport function clipUnion(a: PathsD, b: PathsD): PathsD {\n return unionD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function clipIntersect(a: PathsD, b: PathsD): PathsD {\n return intersectD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function clipDifference(a: PathsD, b: PathsD): PathsD {\n return differenceD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function clipXor(a: PathsD, b: PathsD): PathsD {\n return xorD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function pathsArea(paths: PathsD): number {\n let sum = 0\n for (const p of paths) {\n sum += Math.abs(areaD(p))\n }\n return sum\n}\n","import type { Group, Path, Vec2 } from '../types/index.js'\nimport { vec2 } from '../types/index.js'\nimport {\n pathToPathsD,\n pathsArea,\n pointInRing,\n} from '../clipper/convert.js'\n\n/** Signed area of a closed ring (shoelace). */\nexport function ringArea(ring: Vec2[]): number {\n if (ring.length < 3) return 0\n let sum = 0\n for (let i = 0; i < ring.length; i++) {\n const a = ring[i]!\n const b = ring[(i + 1) % ring.length]!\n sum += a.x * b.y - b.x * a.y\n }\n return sum / 2\n}\n\n/** Absolute area of a closed path (exterior minus holes). */\nexport function area(p: Path): number {\n if (!p.closed || p.rings.length === 0) return 0\n try {\n return pathsArea(pathToPathsD(p))\n } catch {\n let total = 0\n for (let i = 0; i < p.rings.length; i++) {\n const a = Math.abs(ringArea(p.rings[i]!))\n total += i === 0 ? a : -a\n }\n return Math.max(0, total)\n }\n}\n\nexport function areaGroup(g: Group): number {\n return g.paths.reduce((sum, p) => sum + area(p), 0)\n}\n\n/** Centroid of a closed exterior ring (ignores holes for Phase 2). */\nexport function centroid(p: Path): Vec2 {\n const ring = p.rings[0]\n if (!ring || ring.length === 0) return vec2(0, 0)\n const a = ringArea(ring)\n if (Math.abs(a) < 1e-12) {\n let sx = 0\n let sy = 0\n for (const v of ring) {\n sx += v.x\n sy += v.y\n }\n return vec2(sx / ring.length, sy / ring.length)\n }\n let cx = 0\n let cy = 0\n for (let i = 0; i < ring.length; i++) {\n const p0 = ring[i]!\n const p1 = ring[(i + 1) % ring.length]!\n const cross = p0.x * p1.y - p1.x * p0.y\n cx += (p0.x + p1.x) * cross\n cy += (p0.y + p1.y) * cross\n }\n return vec2(cx / (6 * a), cy / (6 * a))\n}\n\nexport function containsPoint(p: Path, point: Vec2): boolean {\n if (!p.closed || !p.rings[0]) return false\n if (!pointInRing(point, p.rings[0])) return false\n for (let i = 1; i < p.rings.length; i++) {\n const hole = p.rings[i]\n if (hole && pointInRing(point, hole)) return false\n }\n return true\n}\n\nexport function bounds(p: Path): {\n minX: number\n minY: number\n maxX: number\n maxY: number\n} {\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const ring of p.rings) {\n for (const v of ring) {\n minX = Math.min(minX, v.x)\n minY = Math.min(minY, v.y)\n maxX = Math.max(maxX, v.x)\n maxY = Math.max(maxY, v.y)\n }\n }\n if (!Number.isFinite(minX)) {\n return { minX: 0, minY: 0, maxX: 0, maxY: 0 }\n }\n return { minX, minY, maxX, maxY }\n}\n\nexport function width(p: Path): number {\n const b = bounds(p)\n return b.maxX - b.minX\n}\n\nexport function height(p: Path): number {\n const b = bounds(p)\n return b.maxY - b.minY\n}\n\n/** Rough polygon similarity via absolute area difference relative to max area. */\nexport function areaSimilarity(a: Path, b: Path): number {\n const aa = area(a)\n const bb = area(b)\n const denom = Math.max(aa, bb, 1e-12)\n return 1 - Math.abs(aa - bb) / denom\n}\n\nexport const predicates = {\n area,\n areaGroup,\n ringArea,\n centroid,\n containsPoint,\n bounds,\n width,\n height,\n areaSimilarity,\n}\n","import type { Path, Ring, Segment, Vec2 } from '../types/index.js'\nimport { segment, vec2 } from '../types/index.js'\nimport { containsPoint } from '../predicates/index.js'\n\ntype Hit = { t: number; p: Vec2 }\n\n/**\n * Clip an open segment to the interior of a closed path (exterior minus holes).\n * Returns zero or more interior sub-segments.\n */\nexport function clipSegmentToPath(seg: Segment, clip: Path): Segment[] {\n if (!clip.closed || !clip.rings[0]) return []\n\n const hits: Hit[] = []\n const pushHit = (t: number, p: Vec2) => {\n if (t < -1e-9 || t > 1 + 1e-9) return\n const tt = Math.min(1, Math.max(0, t))\n for (const h of hits) {\n if (Math.abs(h.t - tt) < 1e-9) return\n }\n hits.push({ t: tt, p })\n }\n\n if (containsPoint(clip, seg.a)) pushHit(0, seg.a)\n if (containsPoint(clip, seg.b)) pushHit(1, seg.b)\n\n for (const ring of clip.rings) {\n for (let i = 0; i < ring.length; i++) {\n const e0 = ring[i]!\n const e1 = ring[(i + 1) % ring.length]!\n const hit = segmentIntersection(seg.a, seg.b, e0, e1)\n if (hit) pushHit(hit.t, hit.p)\n }\n }\n\n hits.sort((a, b) => a.t - b.t)\n if (hits.length < 2) return []\n\n const out: Segment[] = []\n for (let i = 0; i + 1 < hits.length; i++) {\n const h0 = hits[i]!\n const h1 = hits[i + 1]!\n if (h1.t - h0.t < 1e-9) continue\n const mid = vec2((h0.p.x + h1.p.x) / 2, (h0.p.y + h1.p.y) / 2)\n if (containsPoint(clip, mid)) {\n out.push(segment(h0.p, h1.p))\n }\n }\n return out\n}\n\nexport function clipSegmentsToPath(\n segments: Segment[],\n clip: Path,\n): Segment[] {\n const out: Segment[] = []\n for (const s of segments) {\n out.push(...clipSegmentToPath(s, clip))\n }\n return out\n}\n\nfunction segmentIntersection(\n a: Vec2,\n b: Vec2,\n c: Vec2,\n d: Vec2,\n): { t: number; p: Vec2 } | null {\n const rX = b.x - a.x\n const rY = b.y - a.y\n const sX = d.x - c.x\n const sY = d.y - c.y\n const denom = rX * sY - rY * sX\n if (Math.abs(denom) < 1e-12) return null\n const t = ((c.x - a.x) * sY - (c.y - a.y) * sX) / denom\n const u = ((c.x - a.x) * rY - (c.y - a.y) * rX) / denom\n if (t < -1e-9 || t > 1 + 1e-9 || u < -1e-9 || u > 1 + 1e-9) return null\n return {\n t,\n p: vec2(a.x + t * rX, a.y + t * rY),\n }\n}\n\n/** @internal exported for tests */\nexport type { Ring }\n","import type { Group, Path } from '../types/index.js'\nimport { group } from '../types/index.js'\nimport { inflatePathsD, JoinType, EndType } from 'clipper2-ts'\nimport { pathToPathsD, pathsDToGroup } from '../clipper/convert.js'\n\nexport type BufferOptions = {\n /** Join style for offset. Default round. */\n join?: 'round' | 'miter' | 'square'\n}\n\n/**\n * Offset / buffer a closed path by `delta` (positive = expand, negative = erode).\n * Returns a group of resulting closed paths (may split or vanish when eroding).\n */\nexport function buffer(\n path: Path,\n delta: number,\n options: BufferOptions = {},\n): Group {\n const subject = pathToPathsD(path)\n const join =\n options.join === 'miter'\n ? JoinType.Miter\n : options.join === 'square'\n ? JoinType.Square\n : JoinType.Round\n const inflated = inflatePathsD(subject, delta, join, EndType.Polygon)\n return pathsDToGroup(inflated)\n}\n\n/**\n * Erode by `|amount|` then dilate by `|amount|` (opening). Useful for cleaning.\n */\nexport function erosionDilation(p: Path, amount: number): Group {\n const a = Math.abs(amount)\n if (a < 1e-12) return group([p])\n const eroded = buffer(p, -a)\n if (eroded.paths.length === 0) return eroded\n const dilated: Path[] = []\n for (const q of eroded.paths) {\n dilated.push(...buffer(q, a).paths)\n }\n return group(dilated)\n}\n\n/**\n * Dilate by `|amount|` then erode by `|amount|` (closing). Fills small gaps.\n */\nexport function dilationErosion(p: Path, amount: number): Group {\n const a = Math.abs(amount)\n if (a < 1e-12) return group([p])\n const dilated = buffer(p, a)\n if (dilated.paths.length === 0) return dilated\n const eroded: Path[] = []\n for (const q of dilated.paths) {\n eroded.push(...buffer(q, -a).paths)\n }\n return group(eroded)\n}\n","import type { Path, Segment } from '../types/index.js'\nimport { path as makePath } from '../types/index.js'\nimport {\n parallelSegments,\n perpendicularPathSegments,\n stochasticSegments,\n weaveSegments,\n type SegmentLengthFn,\n type WeaveSegmentsOptions,\n} from '../segmentSet/index.js'\nimport { clipSegmentsToPath } from '../segmentSet/clip.js'\nimport { buffer } from '../morphology/buffer.js'\n\nexport type ParallelHatchOptions = {\n /** Hatch angle in radians (segment direction). Default `Math.PI / 4`. */\n angle?: number\n /** Perpendicular spacing between lines. Default `0.15`. */\n spacing?: number\n /**\n * Half-length of generated lines before clipping (PGS `length`).\n * Default: diagonal of path bounds.\n */\n length?: number\n /**\n * Number of parallel lines (PGS `n`).\n * Default: enough lines to cover the path AABB at the given spacing.\n */\n count?: number\n /** Hatch field center. Default: path centroid of exterior bounds center. */\n center?: { x: number; y: number }\n}\n\nexport type WeaveHatchOptions = {\n /** Grid cell size. Default: ~1/12 of the shorter AABB side. */\n cellSize?: number\n /** Weft (horizontal on-top) run length in cells. Default `1`. */\n A?: number\n /** Warp (vertical on-top) run length in cells. Default `1`. */\n B?: number\n /** Row phase shift in cells. Default `1`. */\n C?: number\n swapColors?: boolean\n cellFraction?: number\n extendSingletonsToEdge?: boolean\n}\n\nexport type StochasticHatchOptions = {\n /** Number of segments before clipping. Default `40`. */\n count?: number\n /** Fixed segment length (overrides min/max). */\n length?: number\n /** Minimum segment length. Default `1`. */\n minLength?: number\n /** Maximum segment length (exclusive when ≠ min). Default: min(AABB w,h). */\n maxLength?: number\n /** PRNG seed. Default `1`. */\n seed?: number\n}\n\nexport type PerpendicularHatchOptions = {\n /** Arc-length spacing between ticks. Default `0.15`. */\n spacing?: number\n /** Tick length, or a per-sample length function. Default `0.2`. */\n length?: number | SegmentLengthFn\n /** Fractional phase along each ring in `[0,1)`. Default `0`. */\n startOffset?: number\n}\n\nexport type ConcentricHatchOptions = {\n /** Inward offset step between shells. Default `0.15`. */\n spacing?: number\n /**\n * Max number of shells. Default: enough to erode until empty\n * (capped by AABB diagonal / spacing).\n */\n count?: number\n}\n\n/**\n * Fill a closed path with parallel hatch strokes (plotter-safe).\n * Composes `parallelSegments` + clip-to-path (PGS dysonHatching recipe).\n *\n * When `count` is omitted, line count is derived from `spacing` and the path\n * bounds so the hatch covers the whole region (no corner gaps).\n */\nexport function parallel(path: Path, options: ParallelHatchOptions = {}): Segment[] {\n if (!path.closed || !path.rings[0]) {\n throw new Error('hatch.parallel requires a closed path')\n }\n\n const bounds = pathBounds(path)\n const center = options.center ?? {\n x: (bounds.minX + bounds.maxX) / 2,\n y: (bounds.minY + bounds.maxY) / 2,\n }\n const diag = Math.hypot(bounds.maxX - bounds.minX, bounds.maxY - bounds.minY)\n const length = options.length ?? Math.max(diag, 1e-6)\n const spacing = Math.max(options.spacing ?? 0.15, 1e-9)\n const angle = options.angle ?? Math.PI / 4\n const count = options.count ?? hatchLineCount(bounds, spacing, angle)\n\n const raw = parallelSegments(\n center.x,\n center.y,\n length,\n spacing,\n angle,\n count,\n )\n return clipSegmentsToPath(raw, path)\n}\n\n/** Cross-hatch: two perpendicular parallel passes. */\nexport function cross(path: Path, options: ParallelHatchOptions = {}): Segment[] {\n const angle = options.angle ?? Math.PI / 4\n const a = parallel(path, options)\n const b = parallel(path, { ...options, angle: angle + Math.PI / 2 })\n return [...a, ...b]\n}\n\n/**\n * Weave fill: ABC fabric segments over the path AABB, clipped to the path\n * (PGS `weaveSegments` recipe).\n */\nexport function weave(path: Path, options: WeaveHatchOptions = {}): Segment[] {\n if (!path.closed || !path.rings[0]) {\n throw new Error('hatch.weave requires a closed path')\n }\n\n const bounds = pathBounds(path)\n const width = Math.max(bounds.maxX - bounds.minX, 1e-9)\n const height = Math.max(bounds.maxY - bounds.minY, 1e-9)\n const cellSize =\n options.cellSize ?? Math.max(Math.min(width, height) / 12, 1e-6)\n const weaveOpts: WeaveSegmentsOptions = {\n originX: bounds.minX,\n originY: bounds.minY,\n }\n if (options.swapColors !== undefined) weaveOpts.swapColors = options.swapColors\n if (options.cellFraction !== undefined) {\n weaveOpts.cellFraction = options.cellFraction\n }\n if (options.extendSingletonsToEdge !== undefined) {\n weaveOpts.extendSingletonsToEdge = options.extendSingletonsToEdge\n }\n const raw = weaveSegments(\n width,\n height,\n cellSize,\n options.A ?? 1,\n options.B ?? 1,\n options.C ?? 1,\n weaveOpts,\n )\n return clipSegmentsToPath(raw, path)\n}\n\n/**\n * Stochastic fill: random non-intersecting segments in the path AABB, clipped\n * to the path (PGS `stochasticSegments` recipe).\n */\nexport function stochastic(\n path: Path,\n options: StochasticHatchOptions = {},\n): Segment[] {\n if (!path.closed || !path.rings[0]) {\n throw new Error('hatch.stochastic requires a closed path')\n }\n\n const bounds = pathBounds(path)\n const width = Math.max(bounds.maxX - bounds.minX, 1e-9)\n const height = Math.max(bounds.maxY - bounds.minY, 1e-9)\n const count = options.count ?? 40\n const minLength = options.length ?? options.minLength ?? 1\n const maxLength =\n options.length ?? options.maxLength ?? Math.min(width, height)\n const raw = stochasticSegments(\n width,\n height,\n count,\n minLength,\n maxLength,\n options.seed ?? 1,\n bounds.minX,\n bounds.minY,\n )\n return clipSegmentsToPath(raw, path)\n}\n\n/**\n * Perimeter ticks: perpendicular segments centered on the path boundary\n * (PGS `perpendicularPathSegments`). Outline texture, not an area fill.\n */\nexport function perpendicular(\n path: Path,\n options: PerpendicularHatchOptions = {},\n): Segment[] {\n if (!path.rings[0]) {\n throw new Error('hatch.perpendicular requires a path with at least one ring')\n }\n const spacing = Math.max(options.spacing ?? 0.15, 1e-9)\n const length = options.length ?? 0.2\n return perpendicularPathSegments(\n path,\n spacing,\n length,\n options.startOffset ?? 0,\n )\n}\n\n/**\n * Concentric shells: repeated inward offsets as closed stroke paths.\n * Plotter-safe nested contours (not SVG paint).\n */\nexport function concentric(\n path: Path,\n options: ConcentricHatchOptions = {},\n): Path[] {\n if (!path.closed || !path.rings[0]) {\n throw new Error('hatch.concentric requires a closed path')\n }\n\n const spacing = Math.max(options.spacing ?? 0.15, 1e-9)\n const bounds = pathBounds(path)\n const diag = Math.hypot(bounds.maxX - bounds.minX, bounds.maxY - bounds.minY)\n const maxCount =\n options.count ?? Math.max(1, Math.floor(diag / (2 * spacing)))\n\n const out: Path[] = []\n for (let i = 1; i <= maxCount; i++) {\n const shell = buffer(path, -spacing * i)\n if (shell.paths.length === 0) break\n for (const p of shell.paths) {\n // Stroke as closed outline; clone rings so callers can mutate safely.\n out.push(\n makePath(\n p.rings.map((r) => r.map((v) => ({ x: v.x, y: v.y }))),\n true,\n ),\n )\n }\n }\n return out\n}\n\n/** Lines needed so perpendicular spacing covers the AABB at `angle`. */\nfunction hatchLineCount(\n bounds: { minX: number; minY: number; maxX: number; maxY: number },\n spacing: number,\n angle: number,\n): number {\n const nx = Math.cos(angle + Math.PI / 2)\n const ny = Math.sin(angle + Math.PI / 2)\n const corners: [number, number][] = [\n [bounds.minX, bounds.minY],\n [bounds.maxX, bounds.minY],\n [bounds.maxX, bounds.maxY],\n [bounds.minX, bounds.maxY],\n ]\n let minP = Infinity\n let maxP = -Infinity\n for (const [x, y] of corners) {\n const p = x * nx + y * ny\n minP = Math.min(minP, p)\n maxP = Math.max(maxP, p)\n }\n const extent = maxP - minP\n return Math.max(1, Math.ceil(extent / spacing) + 1)\n}\n\nfunction pathBounds(path: Path) {\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const ring of path.rings) {\n for (const v of ring) {\n minX = Math.min(minX, v.x)\n minY = Math.min(minY, v.y)\n maxX = Math.max(maxX, v.x)\n maxY = Math.max(maxY, v.y)\n }\n }\n return { minX, minY, maxX, maxY }\n}\n\nexport const hatch = {\n parallel,\n cross,\n weave,\n stochastic,\n perpendicular,\n concentric,\n}\n"]}
|
package/dist/hull/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { V as Vec2 } from '../
|
|
2
|
-
import { P as Path } from '../path-0RjhYjJs.js';
|
|
1
|
+
import { P as Path, V as Vec2 } from '../path-Boeshk9L.js';
|
|
3
2
|
|
|
4
3
|
/** Andrew's monotone-chain convex hull of a point set. */
|
|
5
4
|
declare function convexHull(points: Vec2[]): Path;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export { c as cloneGroup, g as group, a as groupFromPaths } from './group-BNjVVYSQ.js';
|
|
1
|
+
import { P as Path } from './path-Boeshk9L.js';
|
|
2
|
+
export { R as Ring, V as Vec2, c as clonePath, a as cloneVec2, e as equalsVec2, n as normalizeRing, p as path, b as polygon, d as polyline, v as vec2 } from './path-Boeshk9L.js';
|
|
3
|
+
export { C as Circle, c as circle, a as circleCenter } from './circle-CauDMv8V.js';
|
|
4
|
+
import { S as Segment } from './segment-CpLILSd7.js';
|
|
5
|
+
export { s as segment } from './segment-CpLILSd7.js';
|
|
6
|
+
import { G as Group } from './group-YVmSJuGo.js';
|
|
7
|
+
export { c as cloneGroup, g as group, a as groupFromPaths } from './group-YVmSJuGo.js';
|
|
9
8
|
export { ToSvgOptions, parsePathData, parseSvg, serializePathData, toSvg } from './svg/index.js';
|
|
10
9
|
export { complement, intersect, occlusionSubtract, overlapRegions, shapeBoolean, subtract, subtractAll, symDifference, union, unionAll } from './shapeBoolean/index.js';
|
|
11
10
|
export { area, areaGroup, areaSimilarity, bounds, centroid, containsPoint, height, predicates, ringArea, width } from './predicates/index.js';
|
|
12
|
-
export { filterAxisAligned, filterByMinLength, parallelSegments, segmentLength, segmentSet, segmentsToOpenPaths } from './segmentSet/index.js';
|
|
13
|
-
export { ParallelHatchOptions, hatch, cross as hatchCross, parallel as hatchParallel } from './hatch/index.js';
|
|
11
|
+
export { SegmentLengthFn, WeaveSegmentsOptions, filterAxisAligned, filterByMinLength, parallelSegments, perpendicularPathSegments, segmentLength, segmentSet, segmentsToOpenPaths, stochasticSegments, weaveSegments } from './segmentSet/index.js';
|
|
12
|
+
export { ConcentricHatchOptions, ParallelHatchOptions, PerpendicularHatchOptions, StochasticHatchOptions, WeaveHatchOptions, hatch, concentric as hatchConcentric, cross as hatchCross, parallel as hatchParallel, perpendicular as hatchPerpendicular, stochastic as hatchStochastic, weave as hatchWeave } from './hatch/index.js';
|
|
14
13
|
export { LatticePackMode, circleContainedInPath, circleOverlapsPath, circlePacking, frontChainPack, hexLatticePack, maximumInscribedPack, maximumInscribedPackUntil, obstaclePack, repulsionPack, squareLatticePack, stochasticPack } from './circlePacking/index.js';
|
|
15
14
|
export { BufferOptions, buffer, chaikinCut, dilationErosion, erosionDilation, minkDifference, minkSum, morphology, radialWarp, reducePrecision, simplify, sineWarp, smooth } from './morphology/index.js';
|
|
16
15
|
export { flipHorizontal, flipVertical, originScale, resizeByHeight, resizeByWidth, rotate, rotateAroundCenter, scale, shear, transformation, translate, translateCentroidTo, translateCornerTo, translateToOrigin } from './transformation/index.js';
|
|
@@ -19,11 +18,11 @@ export { conversion, copy, flatten, fromArray, fromContours, roundVertexCoords,
|
|
|
19
18
|
export { ScalarField, StraightSkeletonParts, centerLine, chordalAxis, contour, contrastField, dissolveSegments, distanceField, distanceTree, isolineZeroFromFunction, isolines, isolinesFromFunction, isolinesFromPoints, medialAxis, offsetCurvesInward, offsetCurvesOutward, straightSkeleton, straightSkeletonParts } from './contour/index.js';
|
|
20
19
|
export { boundingBox, convexHull, convexHullPath, hull } from './hull/index.js';
|
|
21
20
|
export { RefineOptions, delaunayTriangulation, delaunayTriangulationPoints, earCutTriangulation, poissonTriangulation, poissonTriangulationPoints, refine, triangulation } from './triangulation/index.js';
|
|
22
|
-
export { hexGrid, ring as pointRing, pointSet, poisson, prunePointsWithinDistance, random as randomPoints, squareGrid } from './pointSet/index.js';
|
|
21
|
+
export { findShortestTour, hexGrid, hilbertSort, ring as pointRing, pointSet, poisson, prunePointsWithinDistance, random as randomPoints, squareGrid } from './pointSet/index.js';
|
|
23
22
|
export { closestPoint, closestPointPair, closestVertex, envelope, farthestPointPair, largestEmptyCircle, largestEmptyCircles, maximumInscribedAARectangle, maximumInscribedCircle, minimumBoundingCircle, optimisation } from './optimisation/index.js';
|
|
24
23
|
export { VoronoiOptions, compoundVoronoi, innerVoronoi, innerVoronoiRaw, voronoi } from './voronoi/index.js';
|
|
25
|
-
export { construction, createArc, createCircle, createKochSnowflake, createRect, createRegularPolygon, createRing, createStar } from './construction/index.js';
|
|
26
|
-
export { hatchSubdivision, hexTiling, quadSubdivision, rectSubdivision, sliceDivision, squareGrid as squareTiling, tiling, triangleSubdivision } from './tiling/index.js';
|
|
24
|
+
export { construction, createArc, createCircle, createKochSnowflake, createRect, createRegularPolygon, createRing, createSponge, createStar } from './construction/index.js';
|
|
25
|
+
export { arcDivision, hatchSubdivision, hexTiling, quadSubdivision, rectSubdivision, sliceDivision, squareGrid as squareTiling, tiling, triangleSubdivision } from './tiling/index.js';
|
|
27
26
|
export { angular, circular, hilbert as hilbertPolygonise, maxArea, minArea, minPerimeter, onion, onionLayers, polygonisation, horizontal as polygoniseHorizontal, vertical as polygoniseVertical } from './polygonisation/index.js';
|
|
28
27
|
export { areaMerge, centroidQuadrangulation, centroidSortFaces, dualFaces, edgeCollapseQuadrangulation, extractInnerEdges, extractInnerVertices, findBreaks, findContainingFace, findIslands, fixBreaks, fixBrokenFaces, gabrielFaces, matchingQuadrangulation, meshing, radialSortFaces, relativeNeighborFaces, simplifyMesh, smoothMesh, spannerFaces, spiralQuadrangulation, splitEdges, splitQuadrangulation, stochasticMerge, subdivideMesh, urquhartFaces } from './meshing/index.js';
|
|
29
28
|
|