pantograph2d 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"file":"exportJSON-944c662d.cjs","sources":["../src/models/BoundingBox.ts","../src/utils/removeDuplicatePoints.ts","../src/vectorOperations.ts","../src/models/TransformationMatrix.ts","../src/models/utils/Transformable.ts","../src/models/segments/Segment.ts","../src/models/segments/Line.ts","../src/utils/range.ts","../src/utils/zip.ts","../src/utils/unitAngle.ts","../src/utils/angularDistance.ts","../src/algorithms/intersections/lineLineIntersection.ts","../src/models/segments/Arc.ts","../src/utils/projectPointOnLine.ts","../src/algorithms/intersections/lineArcIntersection.ts","../src/algorithms/intersections/arcArcIntersection.ts","../src/algorithms/intersections/index.ts","../src/utils/allCombinations.ts","../src/models/Figure.ts","../src/algorithms/organiseLoops.ts","../src/utils/allPairs.ts","../src/models/Stroke.ts","../src/algorithms/simplify.ts","../src/models/Strand.ts","../src/algorithms/intersections/rayIntersections.ts","../src/models/Loop.ts","../src/algorithms/boolean/loopBooleans.ts","../src/algorithms/boolean/figureBooleans.ts","../src/models/Diagram.ts","../src/export/json/jsonSegment.ts","../src/export/json/jsonLoop.ts","../src/export/json/jsonFigure.ts","../src/export/json/jsonDiagram.ts","../src/export/json/exportJSON.ts"],"sourcesContent":["import { Vector } from \"../definitions\";\n\nfunction overlap1D(\n min1: number,\n max1: number,\n min2: number,\n max2: number\n): boolean {\n return min1 <= max2 && max1 >= min2;\n}\n\nexport class BoundingBox {\n readonly xMin: number;\n readonly yMin: number;\n\n readonly xMax: number;\n readonly yMax: number;\n\n constructor(\n xMin = Infinity,\n yMin = Infinity,\n xMax = -Infinity,\n yMax = -Infinity\n ) {\n this.xMin = xMin;\n this.yMin = yMin;\n this.xMax = xMax;\n this.yMax = yMax;\n }\n\n get width(): number {\n return this.xMax - this.xMin;\n }\n\n get height(): number {\n return this.yMax - this.yMin;\n }\n\n contains(point: Vector): boolean {\n const [x, y] = point;\n return (\n overlap1D(this.xMin, this.xMax, x, x) &&\n overlap1D(this.yMin, this.yMax, y, y)\n );\n }\n\n overlaps(other: BoundingBox): boolean {\n return (\n overlap1D(this.xMin, this.xMax, other.xMin, other.xMax) &&\n overlap1D(this.yMin, this.yMax, other.yMin, other.yMax)\n );\n }\n\n addPoint(point: Vector): BoundingBox {\n const [x, y] = point;\n return new BoundingBox(\n Math.min(this.xMin, x),\n Math.min(this.yMin, y),\n\n Math.max(this.xMax, x),\n Math.max(this.yMax, y)\n );\n }\n\n merge(other: BoundingBox): BoundingBox {\n return new BoundingBox(\n Math.min(this.xMin, other.xMin),\n Math.min(this.yMin, other.yMin),\n Math.max(this.xMax, other.xMax),\n Math.max(this.yMax, other.yMax)\n );\n }\n}\n","import type { Vector } from \"../definitions\";\n\nconst asFixed = (p: number, precision = 1e-9): string => {\n let num = p;\n if (Math.abs(p) < precision) num = 0;\n return num.toFixed(-Math.log10(precision));\n};\nexport default function removeDuplicatePoints(\n points: Vector[],\n precision = 1e-9\n): Vector[] {\n return Array.from(\n new Map(\n points.map(([p0, p1]) => [\n `[${asFixed(p0, precision)},${asFixed(p1, precision)}]`,\n [p0, p1] as Vector,\n ])\n ).values()\n );\n}\n","import type { Vector } from \"./definitions\";\n\nexport const DEG2RAD = Math.PI / 180;\n\nexport const reprVector = (vector: Vector): string => {\n return `[${vector[0]}, ${vector[1]}]`;\n};\n\nexport const sameVector = (\n [x0, y0]: Vector,\n [x1, y1]: Vector,\n precision = 1e-9\n): boolean => {\n return Math.abs(x0 - x1) <= precision && Math.abs(y0 - y1) <= precision;\n};\n\nexport const add = ([x0, y0]: Vector, [x1, y1]: Vector): Vector => {\n return [x0 + x1, y0 + y1];\n};\n\nexport const subtract = ([x0, y0]: Vector, [x1, y1]: Vector): Vector => {\n return [x0 - x1, y0 - y1];\n};\n\nexport const squareLength = ([x, y]: Vector): number => {\n return x * x + y * y;\n};\n\nexport const length = ([x, y]: Vector): number => {\n return Math.sqrt(squareLength([x, y]));\n};\n\nexport const scalarMultiply = ([x0, y0]: Vector, scalar: number): Vector => {\n return [x0 * scalar, y0 * scalar];\n};\n\nexport const squareDistance = (\n [x0, y0]: Vector,\n [x1, y1]: Vector = [0, 0]\n): number => {\n return (x0 - x1) ** 2 + (y0 - y1) ** 2;\n};\n\nexport const distance = (p0: Vector, p1: Vector = [0, 0]): number => {\n return Math.sqrt(squareDistance(p0, p1));\n};\n\nexport function crossProduct([x0, y0]: Vector, [x1, y1]: Vector): number {\n return x0 * y1 - y0 * x1;\n}\n\nexport function dotProduct([x0, y0]: Vector, [x1, y1]: Vector): number {\n return x0 * x1 + y0 * y1;\n}\n\nexport const angle = ([x0, y0]: Vector, [x1, y1]: Vector = [0, 0]): number => {\n return Math.atan2(y1 * x0 - y0 * x1, x0 * x1 + y0 * y1);\n};\n\nexport function normalize([x0, y0]: Vector): Vector {\n const l = distance([x0, y0]);\n return [x0 / l, y0 / l];\n}\n\nexport function polarToCartesian(r: number, theta: number): Vector {\n const x = Math.cos(theta) * r;\n const y = Math.sin(theta) * r;\n return [x, y];\n}\n\nexport function polarAngle([x, y]: Vector): number {\n return Math.atan2(y, x);\n}\n\nexport function cartesianToPolar(v: Vector): [number, number] {\n const r = distance(v);\n const theta = polarAngle(v);\n\n return [r, theta];\n}\n\nexport function parallel(v1: Vector, v2: Vector, precision = 1e-9): boolean {\n const V1xV2 = crossProduct(v1, v2);\n\n const xLength = squareLength(v1);\n const yLength = squareLength(v2);\n\n return V1xV2 * V1xV2 < xLength * yLength * precision * precision;\n}\n\nexport function perpendicular(v: Vector): Vector {\n return [-v[1], v[0]];\n}\n\nexport function perpendicularClockwise(v: Vector): Vector {\n return [v[1], -v[0]];\n}\n","import { Vector } from \"../definitions\";\n\ntype Matrix = [\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number\n];\n\nconst matMult = (m1: Matrix, m2: Matrix): Matrix => {\n const [a, b, c, d, e, f, g, h, i] = m1;\n const [j, k, l, m, n, o, p, q, r] = m2;\n return [\n a * j + b * m + c * p,\n a * k + b * n + c * q,\n a * l + b * o + c * r,\n d * j + e * m + f * p,\n d * k + e * n + f * q,\n d * l + e * o + f * r,\n g * j + h * m + i * p,\n g * k + h * n + i * q,\n g * l + h * o + i * r,\n ];\n};\n\nexport class TransformationMatrix {\n private _matrix: Matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n\n translate(x: number, y: number): TransformationMatrix {\n this._matrix = matMult(this._matrix, [1, 0, x, 0, 1, y, 0, 0, 1]);\n return this;\n }\n\n rotate(angle: number, center?: Vector): TransformationMatrix {\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n\n const rotationMatrix: Matrix = [cos, -sin, 0, sin, cos, 0, 0, 0, 1];\n\n if (center) this.translate(center[0], center[1]);\n this._matrix = matMult(this._matrix, rotationMatrix);\n if (center) this.translate(-center[0], -center[1]);\n\n return this;\n }\n\n mirrorX(): TransformationMatrix {\n this._matrix = matMult(this._matrix, [1, 0, 0, 0, -1, 0, 0, 0, 1]);\n return this;\n }\n\n mirrorY(): TransformationMatrix {\n this._matrix = matMult(this._matrix, [-1, 0, 0, 0, 1, 0, 0, 0, 1]);\n return this;\n }\n\n mirrorLine(normal: Vector, point?: Vector): TransformationMatrix {\n const [a, b] = normal;\n\n const angle = Math.atan2(b, a);\n\n if (point) this.translate(point[0], point[1]);\n this.rotate(angle);\n this.mirrorX();\n this.rotate(-angle);\n if (point) this.translate(-point[0], -point[1]);\n return this;\n }\n\n mirrorCenter(center?: Vector): TransformationMatrix {\n if (center) this.translate(center[0], center[1]);\n this._matrix = matMult(this._matrix, [-1, 0, 0, 0, -1, 0, 0, 0, 1]);\n if (center) this.translate(-center[0], -center[1]);\n return this;\n }\n\n scale(scalar: number, center?: Vector): TransformationMatrix {\n if (center) this.translate(center[0], center[1]);\n this._matrix = matMult(this._matrix, [scalar, 0, 0, 0, scalar, 0, 0, 0, 1]);\n if (center) this.translate(-center[0], -center[1]);\n\n return this;\n }\n\n transform(point: Vector): Vector {\n const [x, y] = point;\n const [a, b, c, d, e, f] = this._matrix;\n return [a * x + b * y + c, d * x + e * y + f];\n }\n\n keepsOrientation(): boolean {\n const [a, , , , e] = this._matrix;\n return a * e > 0;\n }\n}\n","import { Vector } from \"../../definitions\";\nimport { DEG2RAD } from \"../../vectorOperations\";\nimport { TransformationMatrix } from \"../TransformationMatrix\";\n\nexport abstract class Transformable<T> {\n abstract transform(matrix: TransformationMatrix): T;\n translateX(x: number): T {\n const transform = new TransformationMatrix().translate(x, 0);\n return this.transform(transform);\n }\n\n translateY(y: number): T {\n const transform = new TransformationMatrix().translate(0, y);\n return this.transform(transform);\n }\n\n translate(x: number, y: number): T {\n const transform = new TransformationMatrix().translate(x, y);\n return this.transform(transform);\n }\n\n translateTo([x, y]: Vector): T {\n const transform = new TransformationMatrix().translate(x, y);\n return this.transform(transform);\n }\n\n rotate(angle: number, center?: Vector): T {\n const transform = new TransformationMatrix().rotate(\n angle * DEG2RAD,\n center\n );\n return this.transform(transform);\n }\n\n scale(factor: number, center?: Vector): T {\n const transform = new TransformationMatrix().scale(factor, center);\n return this.transform(transform);\n }\n\n mirrorCenter(center?: Vector): T {\n const transform = new TransformationMatrix().mirrorCenter(center);\n return this.transform(transform);\n }\n\n mirror(axis?: \"x\" | \"y\"): T;\n mirror(direction: Vector, center?: Vector): T;\n mirror(axisOrDirection: \"x\" | \"y\" | Vector = \"x\", center?: Vector): T {\n const transform = new TransformationMatrix();\n if (axisOrDirection === \"x\") {\n transform.mirrorX();\n } else if (axisOrDirection === \"y\") {\n transform.mirrorY();\n } else {\n transform.mirrorLine(axisOrDirection, center);\n }\n return this.transform(transform);\n }\n}\n","import type { Vector } from \"../../definitions\";\nimport { BoundingBox } from \"../BoundingBox\";\nimport type { TransformationMatrix } from \"../TransformationMatrix\";\nimport { reprVector } from \"../../vectorOperations\";\nimport { Transformable } from \"../utils/Transformable\";\n\nexport type Segment = AbstractSegment<any>;\n\nexport abstract class AbstractSegment<\n T extends AbstractSegment<T>\n> extends Transformable<T> {\n constructor(public firstPoint: Vector, public lastPoint: Vector) {\n super();\n this.firstPoint = firstPoint;\n this.lastPoint = lastPoint;\n }\n\n readonly precision: number = 1e-9;\n\n abstract segmentType: string;\n\n get repr() {\n return `${this.segmentType} ${reprVector(this.firstPoint)} - ${reprVector(\n this.lastPoint\n )}`;\n }\n\n abstract get midPoint(): Vector;\n\n abstract get boundingBox(): BoundingBox;\n\n abstract clone(): T;\n\n abstract reverse(): T;\n\n abstract isSame(other: AbstractSegment<any>): boolean;\n\n abstract distanceFrom(element: Vector): number;\n\n abstract isOnSegment(point: Vector): boolean;\n\n abstract tangentAt(point: Vector): Vector;\n\n abstract get tangentAtFirstPoint(): Vector;\n abstract get tangentAtLastPoint(): Vector;\n\n abstract splitAt(points: Vector[] | number[]): T[];\n\n abstract transform(matrix: TransformationMatrix): T;\n\n [Symbol.for(\"nodejs.util.inspect.custom\")]() {\n return this.repr;\n }\n\n abstract paramPoint(t: number): Vector;\n}\n","import { BoundingBox } from \"../BoundingBox\";\nimport { Vector } from \"../../definitions\";\nimport { TransformationMatrix } from \"../TransformationMatrix\";\nimport removeDuplicatePoints from \"../../utils/removeDuplicatePoints\";\nimport {\n add,\n distance,\n dotProduct,\n normalize,\n parallel,\n perpendicular,\n reprVector,\n sameVector,\n scalarMultiply,\n squareDistance,\n subtract,\n} from \"../../vectorOperations\";\nimport { Segment, AbstractSegment } from \"./Segment\";\n\nexport class Line extends AbstractSegment<Line> {\n segmentType = \"LINE\";\n isValidParameter(t: number): boolean {\n const linearPrecision = this.length * this.precision;\n return t >= -linearPrecision && 1 - t >= -linearPrecision;\n }\n\n paramPoint(t: number): Vector {\n return add(this.firstPoint, scalarMultiply(this.V, t));\n }\n\n get length(): number {\n return distance(this.firstPoint, this.lastPoint);\n }\n\n get squareLength(): number {\n return squareDistance(this.firstPoint, this.lastPoint);\n }\n\n private _V: Vector | null = null;\n get V(): Vector {\n if (this._V === null) {\n this._V = subtract(this.lastPoint, this.firstPoint);\n }\n return this._V;\n }\n\n get midPoint(): Vector {\n return add(this.firstPoint, scalarMultiply(this.V, 0.5));\n }\n\n isSame(other: Segment): boolean {\n if (!(other instanceof Line)) return false;\n return (\n (sameVector(this.firstPoint, other.firstPoint) &&\n sameVector(this.lastPoint, other.lastPoint)) ||\n (sameVector(this.lastPoint, other.firstPoint) &&\n sameVector(this.firstPoint, other.lastPoint))\n );\n }\n\n clone(): Line {\n return new Line(this.firstPoint, this.lastPoint);\n }\n\n reverse(): Line {\n return new Line(this.lastPoint, this.firstPoint);\n }\n\n private _boundingBox: BoundingBox | null = null;\n get boundingBox(): BoundingBox {\n if (this._boundingBox === null) {\n this._boundingBox = new BoundingBox(\n Math.min(this.firstPoint[0], this.lastPoint[0]) - this.precision,\n Math.min(this.firstPoint[1], this.lastPoint[1]) - this.precision,\n Math.max(this.firstPoint[0], this.lastPoint[0]) + this.precision,\n Math.max(this.firstPoint[1], this.lastPoint[1]) + this.precision\n );\n }\n return this._boundingBox;\n }\n\n distanceFrom(point: Vector): number {\n const delta = subtract(point, this.firstPoint);\n const u = dotProduct(delta, this.V) / this.squareLength;\n\n if (u < 0) {\n return distance(point, this.firstPoint);\n }\n\n if (u > 1) {\n return distance(point, this.lastPoint);\n }\n\n const intersection = this.paramPoint(u);\n return distance(point, intersection);\n }\n isOnSegment(point: Vector): boolean {\n if (sameVector(point, this.firstPoint, this.precision)) return true;\n const pointVec = subtract(point, this.firstPoint);\n\n if (!parallel(this.V, pointVec)) return false;\n\n const u = dotProduct(pointVec, this.V) / this.squareLength;\n return this.isValidParameter(u);\n }\n\n tangentAt(point: Vector): Vector {\n if (!this.isOnSegment(point)) throw new Error(\"Point is not on segment\");\n return normalize(this.V);\n }\n\n get normalVector() {\n return perpendicular(normalize(this.V));\n }\n\n get tangentAtFirstPoint(): Vector {\n return normalize(this.V);\n }\n\n get tangentAtLastPoint(): Vector {\n return normalize(this.V);\n }\n\n splitAt(points: Vector | Vector[]): Line[] {\n let splitPoints: Vector[];\n if (Array.isArray(points) && points.length === 0) {\n return [this];\n }\n if (!Array.isArray(points[0])) {\n splitPoints = [points as Vector];\n } else {\n splitPoints = points as Vector[];\n }\n\n // Check that all points are on the segment\n splitPoints.forEach((point) => {\n if (!this.isOnSegment(point))\n throw new Error(\n `Point ${reprVector(point)} is not on segment ${this.repr}`\n );\n });\n\n const allPoints = [this.firstPoint, ...splitPoints, this.lastPoint];\n const uniquePoints = removeDuplicatePoints(allPoints);\n\n // Sort the points to make sure they go from the first point to the last\n const xChange = this.lastPoint[0] - this.firstPoint[0];\n let defaultDir = Math.sign(xChange);\n let comparisonAxis = 0;\n\n if (Math.abs(xChange) < this.precision) {\n defaultDir = Math.sign(this.lastPoint[1] - this.firstPoint[1]);\n comparisonAxis = 1;\n }\n\n uniquePoints.sort(\n (a, b) => defaultDir * (a[comparisonAxis] - b[comparisonAxis])\n );\n\n return uniquePoints.flatMap((point, index) => {\n if (index === uniquePoints.length - 1) return [];\n return new Line(point, uniquePoints[index + 1]);\n });\n }\n\n transform(matrix: TransformationMatrix): Line {\n return new Line(\n matrix.transform(this.firstPoint),\n matrix.transform(this.lastPoint)\n );\n }\n}\n","export default function range(len: number): number[] {\n return Array.from(Array(len).keys());\n}\n","import range from \"./range\";\n\nexport default function zip<T extends unknown[][]>(\n arrays: T\n): { [K in keyof T]: T[K] extends (infer V)[] ? V : never }[] {\n const minLength = Math.min(...arrays.map((arr) => arr.length));\n // @ts-expect-error This is too much for ts\n return range(minLength).map((i) => arrays.map((arr) => arr[i]));\n}\n","// makes sure the angle is in one unit circle\nexport function unitAngle(angle: number) {\n if (angle < 0) {\n return angle + 2 * Math.PI;\n }\n if (angle >= 2 * Math.PI) {\n return angle % (2 * Math.PI);\n }\n return angle;\n}\n","export function angularDistance(\n angle1: number,\n angle2: number,\n clockwise: boolean\n) {\n let relDistance = angle2 - angle1;\n\n if (clockwise) {\n relDistance = -relDistance;\n }\n\n if (relDistance < 0) {\n relDistance += 2 * Math.PI;\n }\n return relDistance;\n}\n","import { crossProduct, squareLength, subtract } from \"../../vectorOperations\";\nimport { Line } from \"../../models/segments/Line\";\nimport { Vector } from \"../../definitions\";\nimport removeDuplicatePoints from \"../../utils/removeDuplicatePoints\";\n\nexport const lineLineParams = (\n line1: { V: Vector; firstPoint: Vector; precision: number },\n line2: { V: Vector; firstPoint: Vector; precision: number },\n precision?: number\n):\n | \"parallel\"\n | {\n intersectionParam1: number;\n intersectionParam2: number;\n } => {\n const V1xV2 = crossProduct(line1.V, line2.V);\n\n const xLength = squareLength(line1.V);\n const yLength = squareLength(line2.V);\n\n const squarePrecision = precision\n ? precision * precision\n : line1.precision * line2.precision;\n\n if (V1xV2 * V1xV2 < xLength * yLength * squarePrecision) {\n return \"parallel\";\n }\n\n const diffPoint = subtract(line2.firstPoint, line1.firstPoint);\n\n const intersectionParam1 = crossProduct(diffPoint, line2.V) / V1xV2;\n const intersectionParam2 = crossProduct(diffPoint, line1.V) / V1xV2;\n\n return {\n intersectionParam1,\n intersectionParam2,\n };\n};\n/**\n * Returns the intersection point between two segment of lines\n *\n * Note that collinear segments are not considered to intersect at all.\n * Additionally, if the segments intersect at a start or end point of one of the\n * segments, the intersection point is considered to be an intersection.\n *\n * @param line1\n * @param line2\n * @returns {Vector} the intersection point or null if the segments do not\n * intersect\n *\n **/\n\nexport function lineLineIntersection(\n line1: Line,\n line2: Line,\n includeOverlaps = false,\n precision?: number\n): null | Vector | Line {\n const intersectionParams = lineLineParams(line1, line2, precision);\n if (intersectionParams === \"parallel\") {\n if (!includeOverlaps) return null;\n if (line1.isSame(line2)) return line1;\n\n const points = removeDuplicatePoints(\n [\n line2.isOnSegment(line1.firstPoint) ? line1.firstPoint : null,\n line2.isOnSegment(line1.lastPoint) ? line1.lastPoint : null,\n line1.isOnSegment(line2.firstPoint) ? line2.firstPoint : null,\n line1.isOnSegment(line2.lastPoint) ? line2.lastPoint : null,\n ].filter((p) => p !== null) as Vector[]\n ).sort((a, b) => a[0] - b[0]);\n\n if (points.length === 0) return null;\n // We consider the case when the lines are collinear and touch only on\n // the last point. We consider that they do not overlap there\n // We might want to revisit this choice\n else if (points.length === 1) return null;\n else if (points.length === 2) return new Line(points[0], points[1]);\n else {\n console.error(points);\n throw new Error(\n \"Unexpected number of points while intersecting parallel lines\"\n );\n }\n }\n\n const { intersectionParam1, intersectionParam2 } = intersectionParams;\n if (!line1.isValidParameter(intersectionParam1)) return null;\n if (!line2.isValidParameter(intersectionParam2)) return null;\n\n return line1.paramPoint(intersectionParam1);\n}\n","import { BoundingBox } from \"../BoundingBox\";\nimport { Vector } from \"../../definitions\";\nimport { TransformationMatrix } from \"../TransformationMatrix\";\nimport {\n add,\n cartesianToPolar,\n crossProduct,\n distance,\n normalize,\n perpendicular,\n perpendicularClockwise,\n polarToCartesian,\n reprVector,\n sameVector,\n scalarMultiply,\n squareDistance,\n subtract,\n} from \"../../vectorOperations\";\nimport { Segment, AbstractSegment } from \"./Segment\";\nimport zip from \"../../utils/zip\";\nimport { unitAngle } from \"../../utils/unitAngle\";\nimport { angularDistance } from \"../../utils/angularDistance\";\nimport { Line } from \"./Line\";\nimport { lineLineParams } from \"../../algorithms/intersections/lineLineIntersection\";\n\nconst polarCoordsFromCenter = (point: Vector, center: Vector) => {\n const vector = subtract(point, center);\n return cartesianToPolar(vector);\n};\n\nexport class Arc extends AbstractSegment<Arc> {\n segmentType = \"ARC\";\n\n readonly center: Vector;\n readonly clockwise: boolean;\n\n constructor(\n firstPoint: Vector,\n lastPoint: Vector,\n center: Vector,\n clockwise = false,\n { ignoreChecks = false } = {}\n ) {\n super(firstPoint, lastPoint);\n this.center = center;\n this.clockwise = clockwise;\n\n if (!ignoreChecks) {\n if (sameVector(firstPoint, lastPoint)) {\n throw new Error(\"Invalid arc, cannot be a full circle\");\n }\n if (\n Math.abs(this.radius - distance(this.lastPoint, this.center)) >\n this.precision\n )\n throw new Error(\n \"Invalid arc, radius does not match between start and end\"\n );\n }\n }\n\n isValidParameter(t: number): boolean {\n return 1 - t >= -this.precision && t >= -this.precision;\n }\n\n angleToParam(angle: number): number {\n return (\n angularDistance(this.firstAngle, unitAngle(angle), this.clockwise) /\n this.angularLength\n );\n }\n\n private _angularLength: number | null = null;\n get angularLength() {\n if (!this._angularLength) {\n this._angularLength = angularDistance(\n this.firstAngle,\n this.lastAngle,\n this.clockwise\n );\n }\n return this._angularLength;\n }\n\n paramPoint(t: number): Vector {\n return add(\n this.center,\n polarToCartesian(\n this.radius,\n this.firstAngle + t * this.angularLength * (this.clockwise ? -1 : 1)\n )\n );\n }\n\n pointToParam(point: Vector): number {\n const [r, theta] = polarCoordsFromCenter(point, this.center);\n if (Math.abs(r - this.radius) > this.precision)\n throw new Error(\n `Point ${reprVector(point)} is not on segment ${this.repr}`\n );\n\n const param = this.angleToParam(theta);\n if (!this.isValidParameter(param))\n throw new Error(\n `Point ${reprVector(point)} is not on segment ${this.repr}`\n );\n\n return param;\n }\n\n private _radius: number | null = null;\n get radius(): number {\n if (this._radius === null) {\n this._radius = distance(this.firstPoint, this.center);\n }\n return this._radius;\n }\n\n private _firstAngle: number | null = null;\n get firstAngle(): number {\n if (this._firstAngle === null) {\n const [x, y] = subtract(this.firstPoint, this.center);\n this._firstAngle = unitAngle(Math.atan2(y, x));\n }\n return this._firstAngle;\n }\n\n private _lastAngle: number | null = null;\n get lastAngle(): number {\n if (this._lastAngle === null) {\n const [x, y] = subtract(this.lastPoint, this.center);\n this._lastAngle = unitAngle(Math.atan2(y, x));\n }\n return this._lastAngle;\n }\n\n get length(): number {\n return this.radius * this.angularLength;\n }\n\n get squareLength(): number {\n return this.length * this.length;\n }\n\n get midPoint(): Vector {\n return this.paramPoint(0.5);\n }\n\n isSame(other: Segment): boolean {\n if (!(other instanceof Arc)) return false;\n if (!sameVector(this.center, other.center)) return false;\n\n return (\n (sameVector(this.firstPoint, other.firstPoint) &&\n sameVector(this.lastPoint, other.lastPoint) &&\n this.clockwise === other.clockwise) ||\n (sameVector(this.lastPoint, other.firstPoint) &&\n sameVector(this.firstPoint, other.lastPoint) &&\n this.clockwise === !other.clockwise)\n );\n }\n\n clone(): Arc {\n return new Arc(\n this.firstPoint,\n this.lastPoint,\n this.center,\n this.clockwise\n );\n }\n\n reverse(): Arc {\n return new Arc(\n this.lastPoint,\n this.firstPoint,\n this.center,\n !this.clockwise\n );\n }\n\n private _boundingBox: BoundingBox | null = null;\n get boundingBox(): BoundingBox {\n if (this._boundingBox === null) {\n const extendedR = this.radius + this.precision;\n const validAngle = (angle: number) =>\n this.isValidParameter(this.angleToParam(angle));\n this._boundingBox = new BoundingBox(\n validAngle(Math.PI)\n ? this.center[0] - extendedR\n : Math.min(this.firstPoint[0], this.lastPoint[0]) - this.precision,\n validAngle(Math.PI * 1.5)\n ? this.center[1] - extendedR\n : Math.min(this.firstPoint[1], this.lastPoint[1]) - this.precision,\n validAngle(0)\n ? this.center[0] + extendedR\n : Math.max(this.firstPoint[0], this.lastPoint[0]) + this.precision,\n validAngle(Math.PI / 2)\n ? this.center[1] + extendedR\n : Math.max(this.firstPoint[1], this.lastPoint[1]) + this.precision\n );\n }\n return this._boundingBox;\n }\n\n distanceFrom(point: Vector): number {\n const [r, theta] = polarCoordsFromCenter(point, this.center);\n if (this.isValidParameter(this.angleToParam(theta))) {\n return Math.abs(r - this.radius);\n }\n return Math.sqrt(\n Math.min(\n squareDistance(point, this.firstPoint),\n squareDistance(point, this.lastPoint)\n )\n );\n }\n\n isOnSegment(point: Vector): boolean {\n const [r, theta] = polarCoordsFromCenter(point, this.center);\n if (Math.abs(r - this.radius) > this.precision) return false;\n\n const param = this.angleToParam(theta);\n return this.isValidParameter(param);\n }\n\n tangentAt(point: Vector): Vector {\n const [r, theta] = polarCoordsFromCenter(point, this.center);\n if (Math.abs(r - this.radius) > this.precision)\n throw new Error(\"Point is not on the arc\");\n\n const param = this.angleToParam(theta);\n if (!this.isValidParameter(param))\n throw new Error(\"Point is not on the arc\");\n\n const tangent = polarToCartesian(1, theta);\n const fcn = this.clockwise ? perpendicularClockwise : perpendicular;\n return fcn(normalize(tangent));\n }\n\n get tangentAtFirstPoint(): Vector {\n const tangent = polarToCartesian(1, this.firstAngle);\n const fcn = this.clockwise ? perpendicularClockwise : perpendicular;\n return fcn(normalize(tangent));\n }\n\n get tangentAtLastPoint(): Vector {\n const tangent = polarToCartesian(1, this.lastAngle);\n const fcn = this.clockwise ? perpendicularClockwise : perpendicular;\n return fcn(normalize(tangent));\n }\n\n splitAt(points: Vector | Vector[]): Arc[] {\n let splitPoints: Vector[];\n if (Array.isArray(points) && points.length === 0) {\n return [this];\n }\n if (!Array.isArray(points[0])) {\n splitPoints = [points as Vector];\n } else {\n splitPoints = points as Vector[];\n }\n\n // Point to param also checks that all points are on the segment\n const splitParams = splitPoints.map((point) => this.pointToParam(point));\n\n const allParams = [0, 1, ...splitParams];\n\n // We use a map here, because we want to keep the entered split points\n // exactly (no change from the transformation from and to params).\n const paramsMap = new Map<number, Vector>(\n zip([allParams, [this.firstPoint, this.lastPoint, ...splitPoints]]) as [\n number,\n Vector\n ][]\n );\n allParams.sort((a, b) => a - b);\n\n let skipped: null | number = null;\n return allParams.flatMap((param, index) => {\n if (index === allParams.length - 1) return [];\n const nextParam = allParams[index + 1];\n\n if (nextParam - param < this.precision) {\n if (skipped === null) skipped = param;\n return [];\n }\n\n const startParam = skipped === null ? param : skipped;\n const arc = new Arc(\n paramsMap.get(startParam) || this.paramPoint(startParam),\n paramsMap.get(nextParam) || this.paramPoint(nextParam),\n this.center,\n this.clockwise\n );\n skipped = null;\n return arc;\n });\n }\n\n transform(matrix: TransformationMatrix): Arc {\n return new Arc(\n matrix.transform(this.firstPoint),\n matrix.transform(this.lastPoint),\n matrix.transform(this.center),\n matrix.keepsOrientation() ? this.clockwise : !this.clockwise\n );\n }\n}\n\nexport function threePointsArc(\n firstPoint: Vector,\n midPoint: Vector,\n lastPoint: Vector\n) {\n const chord1 = new Line(midPoint, firstPoint);\n const chord2 = new Line(midPoint, lastPoint);\n\n const dir1 = perpendicular(chord1.tangentAtFirstPoint);\n const dir2 = perpendicular(chord2.tangentAtLastPoint);\n\n const result = lineLineParams(\n { firstPoint: chord1.midPoint, V: dir1, precision: 1e-9 },\n { firstPoint: chord2.midPoint, V: dir2, precision: 1e-9 }\n );\n\n if (result === \"parallel\")\n throw new Error(\"Cannot create an arc from three colinear points\");\n\n const clockwise =\n crossProduct(\n subtract(firstPoint, midPoint),\n subtract(lastPoint, midPoint)\n ) > 0;\n\n return new Arc(\n firstPoint,\n lastPoint,\n add(chord1.midPoint, scalarMultiply(dir1, result.intersectionParam1)),\n clockwise,\n { ignoreChecks: true }\n );\n}\n\nexport function tangentArc(\n firstPoint: Vector,\n lastPoint: Vector,\n tangentAtFirstPoint: Vector\n) {\n const chord = new Line(lastPoint, firstPoint);\n const dir = perpendicular(chord.tangentAtFirstPoint);\n\n const result = lineLineParams(\n { firstPoint: chord.midPoint, V: dir, precision: 1e-9 },\n {\n firstPoint: firstPoint,\n V: perpendicular(tangentAtFirstPoint),\n precision: 1e-9,\n }\n );\n\n if (result === \"parallel\")\n throw new Error(\"Cannot create an arc from three colinear points\");\n\n const center = add(\n chord.midPoint,\n scalarMultiply(dir, result.intersectionParam1)\n );\n\n const clockwise =\n crossProduct(\n subtract(center, firstPoint),\n add(firstPoint, tangentAtFirstPoint)\n ) > 0;\n\n return new Arc(firstPoint, lastPoint, center, clockwise, {\n ignoreChecks: true,\n });\n}\n","import type { Vector } from \"../definitions\";\nimport type { Line } from \"../models/segments/Line\";\n\nimport { dotProduct, subtract } from \"../vectorOperations\";\n\nexport function projectPointOnLine(line: Line, point: Vector): Vector {\n const delta = subtract(point, line.firstPoint);\n const u = dotProduct(delta, line.V) / line.squareLength;\n return line.paramPoint(u);\n}\n","import { add, scalarMultiply, distance } from \"../../vectorOperations\";\nimport { Line } from \"../../models/segments/Line\";\nimport { Vector } from \"../../definitions\";\nimport { Arc } from \"../../models/segments/Arc\";\nimport { projectPointOnLine } from \"../../utils/projectPointOnLine\";\n\nexport function lineArcIntersection(\n line: Line,\n arc: Arc,\n precision?: number\n): Vector[] {\n const epsilon = precision ? precision : line.precision;\n\n const centerOnLine = projectPointOnLine(line, arc.center);\n const centerDistance = distance(centerOnLine, arc.center);\n\n // the line does not touch the circle\n if (centerDistance > arc.radius + epsilon) return [];\n\n // The line is tangent to the arc\n if (Math.abs(centerDistance - arc.radius) < epsilon) {\n const intersectionPoint = centerOnLine;\n if (\n line.isOnSegment(intersectionPoint) &&\n arc.isOnSegment(intersectionPoint)\n ) {\n return [intersectionPoint];\n }\n return [];\n }\n\n // The line crosses the arc\n const intersections = [];\n\n // delta corresponds to the length between the project center on the line and\n // the crossing points\n const delta = Math.sqrt(\n arc.radius * arc.radius - centerDistance * centerDistance\n );\n\n // We might be able to optimise the check on segment, but it is not clear\n // that it is worth it\n const lineDir = line.tangentAtFirstPoint;\n const p1 = add(centerOnLine, scalarMultiply(lineDir, delta));\n if (line.isOnSegment(p1) && arc.isOnSegment(p1)) {\n intersections.push(p1);\n }\n\n const p2 = add(centerOnLine, scalarMultiply(lineDir, -delta));\n if (line.isOnSegment(p2) && arc.isOnSegment(p2)) {\n intersections.push(p2);\n }\n\n return intersections;\n}\n","import { Vector } from \"../../definitions\";\nimport { Arc } from \"../../models/segments/Arc\";\nimport removeDuplicatePoints from \"../../utils/removeDuplicatePoints\";\nimport {\n add,\n distance,\n normalize,\n perpendicular,\n sameVector,\n scalarMultiply,\n subtract,\n} from \"../../vectorOperations\";\n\nconst complementArc = (arc: Arc): Arc => {\n const { firstPoint, lastPoint, center, clockwise } = arc;\n return new Arc(lastPoint, firstPoint, center, clockwise, {\n ignoreChecks: true,\n });\n};\n\nconst handleOverlaps = (arc1: Arc, arc2: Arc): Arc[] => {\n // handle the case with common points at start or end first\n if (arc1.isSame(arc2)) {\n return [arc1];\n }\n // two arcs with common points at start and end (but not the same arc)\n\n const points = removeDuplicatePoints(\n [\n arc2.isOnSegment(arc1.firstPoint) ? arc1.firstPoint : null,\n arc2.isOnSegment(arc1.lastPoint) ? arc1.lastPoint : null,\n arc1.isOnSegment(arc2.firstPoint) ? arc2.firstPoint : null,\n arc1.isOnSegment(arc2.lastPoint) ? arc2.lastPoint : null,\n ].filter((p) => p !== null) as Vector[]\n // We sort by the param value of the first arc. This means that the points\n // will be sorted with the same orientation than arc1\n ).sort((a, b) => arc1.pointToParam(a) - arc1.pointToParam(b));\n\n if (points.length === 0) return [];\n // We consider the case when the arcs touch only on\n // the last point. We consider that they do not overlap there\n //\n // We might want to revisit this choice\n else if (points.length === 1) return [];\n else if (points.length === 2) {\n // Similar to the case with length 1, we ignore the double overlapping point\n if (arc1.isSame(complementArc(arc2))) return [];\n return [new Arc(points[0], points[1], arc1.center, arc1.clockwise)];\n } else if (points.length === 3) {\n // Similar to the case with length 1, we ignore the single overlapping point\n const startIndex =\n sameVector(points[0], arc2.lastPoint) ||\n sameVector(points[0], arc2.firstPoint)\n ? 1\n : 0;\n return [\n new Arc(\n points[0 + startIndex],\n points[1 + startIndex],\n arc1.center,\n arc1.clockwise\n ),\n ];\n } else if (points.length === 4) {\n return [\n new Arc(points[0], points[1], arc1.center, arc1.clockwise),\n new Arc(points[2], points[3], arc1.center, arc1.clockwise),\n ];\n }\n throw new Error(\"Bug in the arc arc overlap algorithm\");\n};\n\nexport function arcArcIntersection(\n arc1: Arc,\n arc2: Arc,\n includeOverlaps = false,\n precision?: number\n): Vector[] | Arc[] {\n const epsilon = precision ? precision : arc1.precision;\n const centersDistance = distance(arc1.center, arc2.center);\n\n const radiusSum = arc1.radius + arc2.radius;\n\n // The circles do not touch\n if (centersDistance > radiusSum + epsilon) {\n return [];\n }\n\n const radiusDifference = Math.abs(arc1.radius - arc2.radius);\n\n // The arcs are concentric\n if (centersDistance < radiusDifference - epsilon) {\n return [];\n }\n\n // With a common center we can have overlaps\n if (centersDistance < epsilon) {\n if (radiusDifference > epsilon) {\n return [];\n } else {\n if (!includeOverlaps) {\n return [];\n }\n return handleOverlaps(arc1, arc2);\n }\n }\n\n const centersVector = normalize(subtract(arc2.center, arc1.center));\n // The circles are tangent to each other\n const isOutsideTangent = centersDistance > radiusSum - epsilon;\n if (\n // circles are outside each other\n isOutsideTangent ||\n // circles are inside each other\n Math.abs(centersDistance - radiusDifference) < epsilon\n ) {\n const orientation = isOutsideTangent || arc1.radius > arc2.radius ? 1 : -1;\n const intersectionPoint = add(\n arc1.center,\n scalarMultiply(centersVector, orientation * arc1.radius)\n );\n\n if (\n arc1.isOnSegment(intersectionPoint) &&\n arc2.isOnSegment(intersectionPoint)\n ) {\n return [intersectionPoint];\n } else {\n return [];\n }\n }\n\n // The circles cross each other\n const radiusToChord =\n (arc1.radius * arc1.radius) / (2 * centersDistance) -\n (arc2.radius * arc2.radius) / (2 * centersDistance) +\n centersDistance / 2;\n\n const midPoint = add(\n arc1.center,\n scalarMultiply(centersVector, radiusToChord)\n );\n\n const halfChord = Math.sqrt(\n arc1.radius * arc1.radius - radiusToChord * radiusToChord\n );\n\n const chordVector = perpendicular(centersVector);\n\n const p1 = add(midPoint, scalarMultiply(chordVector, halfChord));\n const p2 = add(midPoint, scalarMultiply(chordVector, -halfChord));\n\n const intersections = [];\n if (arc1.isOnSegment(p1) && arc2.isOnSegment(p1)) {\n intersections.push(p1);\n }\n if (arc1.isOnSegment(p2) && arc2.isOnSegment(p2)) {\n intersections.push(p2);\n }\n\n return intersections;\n}\n","import { Line } from \"../../models/segments/Line\";\n\nimport type { Vector } from \"../../definitions\";\nimport { Segment } from \"../../models/segments/Segment\";\nimport { Arc } from \"../../models/segments/Arc\";\nimport { lineArcIntersection } from \"./lineArcIntersection\";\nimport { lineLineIntersection } from \"./lineLineIntersection\";\nimport { arcArcIntersection } from \"./arcArcIntersection\";\n\nexport function findIntersections(\n segment1: Segment,\n segment2: Segment,\n precision?: number\n): Vector[] {\n if (segment1 instanceof Line && segment2 instanceof Line) {\n const intersection = lineLineIntersection(\n segment1,\n segment2,\n false,\n precision\n );\n if (intersection === null) return [];\n return [intersection as Vector];\n }\n if (segment1 instanceof Line && segment2 instanceof Arc) {\n return lineArcIntersection(segment1, segment2, precision);\n }\n if (segment1 instanceof Arc && segment2 instanceof Line) {\n return lineArcIntersection(segment2, segment1, precision);\n }\n if (segment1 instanceof Arc && segment2 instanceof Arc) {\n return arcArcIntersection(segment1, segment2, false, precision) as Vector[];\n }\n\n throw new Error(\"Not implemented\");\n}\n\nexport function findIntersectionsAndOverlaps(\n segment1: Segment,\n segment2: Segment,\n precision?: number\n): { intersections: Vector[]; overlaps: Segment[]; count: number } {\n // If we have two lines, checks are fast enough to not use bounding boxes\n if (segment1 instanceof Line && segment2 instanceof Line) {\n const intersection = lineLineIntersection(\n segment1,\n segment2,\n true,\n precision\n );\n if (intersection === null)\n return { intersections: [], overlaps: [], count: 0 };\n if (intersection instanceof Line)\n return { intersections: [], overlaps: [intersection], count: 1 };\n return { intersections: [intersection], overlaps: [], count: 1 };\n }\n\n if (!segment1.boundingBox.overlaps(segment2.boundingBox)) {\n return { intersections: [], overlaps: [], count: 0 };\n }\n\n if (segment1 instanceof Line && segment2 instanceof Arc) {\n const intersections = lineArcIntersection(segment1, segment2, precision);\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (segment1 instanceof Arc && segment2 instanceof Line) {\n const intersections = lineArcIntersection(segment2, segment1, precision);\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (segment1 instanceof Arc && segment2 instanceof Arc) {\n const intersections = arcArcIntersection(\n segment1,\n segment2,\n true,\n precision\n );\n if (!intersections.length)\n return { intersections: [], overlaps: [], count: 0 };\n if (intersections[0] instanceof Arc)\n return {\n intersections: [],\n overlaps: intersections as Arc[],\n count: intersections.length,\n };\n return {\n intersections: intersections as Vector[],\n overlaps: [],\n count: intersections.length,\n };\n }\n\n throw new Error(\"Not implemented\");\n}\n","export function allCombinations(count: number): [number, number][] {\n const result: [number, number][] = [];\n\n for (let i = 0; i < count; i++) {\n for (let j = 0; j <= i; j++) {\n result.push([i, j]);\n }\n }\n\n return result;\n}\n\nexport function* combineDifferentValues<T>(array: T[]): Generator<[T, T]> {\n for (const [i, j] of allCombinations(array.length)) {\n if (i === j) continue;\n yield [array[i], array[j]];\n }\n}\n","import { Vector } from \"../definitions\";\nimport { TransformationMatrix } from \"./TransformationMatrix\";\nimport type { BoundingBox } from \"./BoundingBox\";\nimport { Loop } from \"./Loop\";\nimport { combineDifferentValues } from \"../utils/allCombinations\";\nimport { Transformable } from \"./utils/Transformable\";\nimport { exportJSON } from \"../main\";\n\nexport class Figure extends Transformable<Figure> {\n readonly contour: Loop;\n readonly holes: Loop[];\n\n constructor(\n contour: Loop,\n holes: Loop[] = [],\n { ignoreChecks = false } = {}\n ) {\n super();\n if (!ignoreChecks) checkIsValidFigure(contour, holes);\n this.contour = contour;\n this.holes = holes;\n }\n\n get boundingBox(): BoundingBox {\n return this.contour.boundingBox;\n }\n\n get isFull(): boolean {\n return this.holes.length === 0;\n }\n\n get allLoops(): Loop[] {\n return [this.contour, ...this.holes];\n }\n\n clone(): Figure {\n return new Figure(\n this.contour.clone(),\n this.holes.map((hole) => hole.clone())\n );\n }\n\n transform(matrix: TransformationMatrix): Figure {\n return new Figure(\n this.contour.transform(matrix),\n this.holes.map((hole) => hole.transform(matrix))\n );\n }\n\n contains(point: Vector): boolean {\n return (\n this.contour.contains(point) &&\n !this.holes.some((hole) => hole.contains(point))\n );\n }\n\n intersects(other: Figure): boolean {\n return this.allLoops.some((loop) =>\n other.allLoops.some((otherLoop) => loop.intersects(otherLoop))\n );\n }\n}\n\nexport function checkIsValidFigure(contour?: Loop, holes: Loop[] = []): void {\n if (!contour) throw new Error(\"Figure must have a contour\");\n for (const [loop1, loop2] of combineDifferentValues([contour, ...holes])) {\n if (loop1.intersects(loop2)) {\n throw new Error(\"Loops in a figure must not intersect\");\n }\n }\n\n if (holes.some((hole) => !contour.contains(hole.firstPoint))) {\n throw new Error(\"Holes must be inside the contour\");\n }\n\n for (const [hole1, hole2] of combineDifferentValues(holes)) {\n if (hole1.contains(hole2.firstPoint)) {\n console.error(exportJSON(hole1), exportJSON(hole2));\n throw new Error(\"Holes must not be inside other holes\");\n }\n }\n}\n","import { Figure } from \"../models/Figure\";\nimport { Loop } from \"../models/Loop\";\n\nconst groupByBoundingBoxOverlap = (loops: Loop[]): Loop[][] => {\n const overlaps = loops.map((loop, i) => {\n return loops\n .slice(i + 1)\n .map((v, j): [number, Loop] => [j + i + 1, v])\n .filter(([, other]) => loop.boundingBox.overlaps(other.boundingBox))\n .map(([index]) => index);\n });\n const groups: Loop[][] = [];\n const groupsInOverlaps = Array(overlaps.length);\n\n overlaps.forEach((indices, i) => {\n let myGroup = groupsInOverlaps[i];\n if (!myGroup) {\n myGroup = [];\n groups.push(myGroup);\n }\n\n myGroup.push(loops[i]);\n\n if (indices.length) {\n indices.forEach((index) => {\n groupsInOverlaps[index] = myGroup;\n });\n }\n });\n\n return groups;\n};\n\ninterface ContainedLoop {\n loop: Loop;\n isIn: Loop[];\n}\n\nconst addContainmentInfo = (groupedLoops: Loop[]): ContainedLoop[] => {\n return groupedLoops.map((loop, index) => {\n const firstCurve = loop.segments[0];\n const point = firstCurve.midPoint;\n\n const isIn = groupedLoops.filter((potentialOuterLoop, j) => {\n if (index === j) return false;\n return potentialOuterLoop.contains(point);\n });\n\n return {\n loop,\n isIn,\n };\n });\n};\n\nconst splitMultipleOuterLoops = (\n outerLoops: ContainedLoop[],\n allLoops: ContainedLoop[]\n): ContainedLoop[][] => {\n return outerLoops.flatMap(({ loop: outerLoop }) => {\n return cleanEdgeCases(\n allLoops.filter(\n ({ loop, isIn }) => loop === outerLoop || isIn.indexOf(outerLoop) !== -1\n )\n );\n });\n};\n\nconst handleNestedLoops = (\n nestedLoops: ContainedLoop[],\n allLoops: ContainedLoop[]\n): ContainedLoop[][] => {\n const firstLevelOuterLoops = allLoops.filter(({ isIn }) => isIn.length <= 1);\n\n const innerLevelsLoops = cleanEdgeCases(\n addContainmentInfo(nestedLoops.map(({ loop }) => loop))\n );\n return [firstLevelOuterLoops, ...innerLevelsLoops];\n};\n\nconst cleanEdgeCases = (groupedLoops: ContainedLoop[]): ContainedLoop[][] => {\n if (!groupedLoops.length) return [];\n\n const outerLoops = groupedLoops.filter(({ isIn }) => !isIn.length);\n const nestedLoops = groupedLoops.filter(({ isIn }) => isIn.length > 1);\n\n if (outerLoops.length === 1 && nestedLoops.length === 0) {\n return [groupedLoops];\n } else if (outerLoops.length > 1) {\n return splitMultipleOuterLoops(outerLoops, groupedLoops);\n } else {\n return handleNestedLoops(nestedLoops, groupedLoops);\n }\n};\n\n/**\n * Groups an array of loops such that loops that correspond to holes\n * in other loops are set in a Figure\n *\n * This algorithm assumes non intersecting loops.\n */\nexport function organiseLoops(loops: Loop[]): Figure[] {\n const basicGrouping =\n groupByBoundingBoxOverlap(loops).map(addContainmentInfo);\n return basicGrouping.flatMap(cleanEdgeCases).map((compounds) => {\n if (compounds.length === 1) return new Figure(compounds[0].loop);\n\n compounds.sort((a, b) => a.isIn.length - b.isIn.length);\n const [contour, ...holes] = compounds.map(({ loop }) => loop);\n return new Figure(contour, holes);\n });\n}\n","export function allPairs<S, T>(list1: T[], list2: S[]): [T, S][] {\n const result: [T, S][] = [];\n\n for (const l1 of list1) {\n for (const l2 of list2) {\n result.push([l1, l2]);\n }\n }\n\n return result;\n}\n","import { BoundingBox } from \"./BoundingBox\";\nimport { Vector } from \"../definitions\";\nimport { findIntersectionsAndOverlaps } from \"../algorithms/intersections\";\nimport { Segment } from \"./segments/Segment\";\nimport { TransformationMatrix } from \"./TransformationMatrix\";\nimport { allCombinations } from \"../utils/allCombinations\";\nimport zip from \"../utils/zip\";\nimport { sameVector } from \"../vectorOperations\";\nimport { Transformable } from \"./utils/Transformable\";\n\nexport type Stroke = AbstractStroke<any>;\n\nexport abstract class AbstractStroke<\n T extends AbstractStroke<T>\n> extends Transformable<T> {\n readonly segments: Segment[];\n\n abstract strokeType: string;\n\n get repr(): string {\n return this.segments.map((segment) => segment.repr).join(\"\\n\") + \"\\n\";\n }\n constructor(segments: Segment[], { ignoreChecks = false } = {}) {\n super();\n if (!ignoreChecks) checkValidStroke(segments);\n this.segments = segments;\n }\n\n get firstPoint(): Vector {\n return this.segments[0].firstPoint;\n }\n\n get lastPoint(): Vector {\n return this.segments[this.segments.length - 1].lastPoint;\n }\n\n get segmentsCount(): number {\n return this.segments.length;\n }\n\n onStroke(point: Vector): boolean {\n return this.segments.some((segment) => segment.isOnSegment(point));\n }\n\n intersects(other: Stroke): boolean {\n if (!this.boundingBox.overlaps(other.boundingBox)) return false;\n return this.segments.some((segment) =>\n other.segments.some(\n (otherSegment) =>\n findIntersectionsAndOverlaps(segment, otherSegment).count > 0\n )\n );\n }\n\n private _boundingBox: BoundingBox | null = null;\n get boundingBox(): BoundingBox {\n if (this._boundingBox === null) {\n let bbox = this.segments[0].boundingBox;\n\n this.segments.slice(1).forEach((segment) => {\n bbox = bbox.merge(segment.boundingBox);\n });\n this._boundingBox = bbox;\n }\n return this._boundingBox;\n }\n\n abstract reverse(): T;\n\n abstract clone(): T;\n\n abstract transform(matrix: TransformationMatrix): T;\n\n abstract simplify(): T;\n\n [Symbol.for(\"nodejs.util.inspect.custom\")]() {\n return this.repr;\n }\n}\n\nexport function checkSelfIntersections(\n segments: Segment[],\n type = \"Stroke\"\n): void {\n allCombinations(segments.length).forEach(\n ([segmentIndex, otherSegmentIndex]) => {\n if (segmentIndex === otherSegmentIndex) return;\n const segment = segments[segmentIndex];\n const otherSegment = segments[otherSegmentIndex];\n\n const intersections = findIntersectionsAndOverlaps(segment, otherSegment);\n if (intersections.count === 0) return;\n if (intersections.count === 1 && !intersections.overlaps.length) {\n const distance = segmentIndex - otherSegmentIndex;\n\n const intersection = intersections.intersections[0];\n\n if (distance === 1) {\n if (sameVector(segment.firstPoint, intersection)) return;\n }\n if (distance === -1) {\n if (sameVector(segment.lastPoint, intersection)) return;\n }\n if (distance === segments.length - 1) {\n if (\n sameVector(segment.lastPoint, intersection) &&\n sameVector(otherSegment.firstPoint, intersection)\n )\n return;\n }\n if (-distance === segments.length - 1) {\n if (\n sameVector(segment.firstPoint, intersection) &&\n sameVector(otherSegment.lastPoint, intersection)\n )\n return;\n }\n }\n throw new Error(\n `${type} segments must not intersect, but segments ${segment.repr} and ${otherSegment.repr} do`\n );\n }\n );\n}\n\nexport function checkValidStroke(segments: Segment[], type = \"Stroke\"): void {\n if (segments.length === 0)\n throw new Error(`${type} must have at least one segment`);\n\n zip([segments.slice(0, -1), segments.slice(1)]).forEach(\n ([segment, nextSegment]) => {\n if (!sameVector(segment.lastPoint, nextSegment.firstPoint))\n throw new Error(\n `${type} segments must be connected, but ${segment.repr} and ${nextSegment.repr} are not`\n );\n }\n );\n\n checkSelfIntersections(segments, type);\n}\n","import type { Stroke } from \"../models/Stroke\";\nimport { Line } from \"../models/segments/Line\";\nimport { Segment } from \"../models/segments/Segment\";\nimport { parallel, sameVector } from \"../vectorOperations\";\nimport { Arc } from \"../models/segments/Arc\";\n\nfunction canExtendSegment(segment1: Segment, segment2: Segment): boolean {\n if (segment1 instanceof Line && segment2 instanceof Line) {\n if (parallel(segment1.V, segment2.V)) {\n return true;\n }\n }\n\n if (segment1 instanceof Arc && segment2 instanceof Arc) {\n if (\n sameVector(segment1.center, segment2.center) &&\n segment1.radius - segment2.radius < segment1.precision\n ) {\n return true;\n }\n }\n return false;\n}\n\nfunction extendSegment(segment1: Segment, segment2: Segment): Segment {\n if (segment1 instanceof Line && segment2 instanceof Line) {\n return new Line(segment1.firstPoint, segment2.lastPoint);\n }\n if (segment1 instanceof Arc && segment2 instanceof Arc) {\n // clockwise is the same for both segments, we would otherwise have some\n // self-intersections in the stroke\n return new Arc(\n segment1.firstPoint,\n segment2.lastPoint,\n segment1.center,\n segment1.clockwise\n );\n }\n\n throw new Error(\"Not implemented\");\n}\n\nexport function simplifySegments(stroke: Stroke): Segment[] | null {\n let foundSimplification = false;\n const simplifiedSegments: Segment[] = [];\n\n for (const segment of stroke.segments) {\n if (simplifiedSegments.length === 0) {\n simplifiedSegments.push(segment);\n continue;\n }\n\n const lastSegment = simplifiedSegments[simplifiedSegments.length - 1];\n if (canExtendSegment(lastSegment, segment)) {\n foundSimplification = true;\n simplifiedSegments.pop();\n simplifiedSegments.push(extendSegment(lastSegment, segment));\n } else {\n simplifiedSegments.push(segment);\n }\n }\n\n if (sameVector(stroke.firstPoint, stroke.lastPoint)) {\n if (\n canExtendSegment(\n simplifiedSegments[0],\n simplifiedSegments[simplifiedSegments.length - 1]\n )\n ) {\n foundSimplification = true;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const lastSegment = simplifiedSegments.pop()!;\n simplifiedSegments[0] = extendSegment(lastSegment, simplifiedSegments[0]);\n }\n }\n\n if (!foundSimplification) return null;\n return simplifiedSegments;\n}\n","import { AbstractStroke } from \"./Stroke\";\n\nimport { TransformationMatrix } from \"./TransformationMatrix\";\nimport { sameVector } from \"../vectorOperations\";\nimport { simplifySegments } from \"../algorithms/simplify\";\n\nexport class Strand extends AbstractStroke<Strand> {\n strokeType = \"STRAND\";\n reverse(): Strand {\n const reversedSegments = this.segments.map((segment) => segment.reverse());\n reversedSegments.reverse();\n return new Strand(reversedSegments, { ignoreChecks: true });\n }\n\n clone(): Strand {\n return new Strand(\n this.segments.map((segment) => segment.clone()),\n { ignoreChecks: true }\n );\n }\n\n extend(strand: Strand): Strand {\n if (!sameVector(this.lastPoint, strand.firstPoint)) {\n console.error(this.repr, strand.repr);\n throw new Error(\"Cannot extend strand: connection point is not the same\");\n }\n return new Strand([...this.segments, ...strand.segments]);\n }\n\n simplify(): Strand {\n const newSegments = simplifySegments(this);\n if (!newSegments) return this;\n return new Strand(newSegments, { ignoreChecks: true });\n }\n\n transform(matrix: TransformationMatrix): Strand {\n return new Strand(\n this.segments.map((segment) => segment.transform(matrix)),\n { ignoreChecks: true }\n );\n }\n}\n","import { Line } from \"../../models/segments/Line\";\nimport { lineLineParams } from \"./lineLineIntersection\";\nimport type { Vector } from \"../../definitions\";\nimport { Segment } from \"../../models/segments/Segment\";\nimport { sameVector, squareDistance } from \"../../vectorOperations\";\nimport { Arc } from \"../../models/segments/Arc\";\n\nconst rayLineIntersectionsCount = (point: Vector, line: Line) => {\n const intersectionParams = lineLineParams(line, {\n V: [1, 0],\n firstPoint: point,\n precision: line.precision,\n });\n if (intersectionParams === \"parallel\") {\n // When the ray is parallel with the line, we can ignore its extremities.\n // They will be handled by the segments getting into and out of this one.\n return 0;\n }\n\n const { intersectionParam1, intersectionParam2 } = intersectionParams;\n\n if (!line.isValidParameter(intersectionParam1)) return 0;\n // With the ray we only check one side of the parameter\n if (intersectionParam2 <= -line.precision) return 0;\n\n // We need to check if the ray intersects the line segment at the extremities\n // In that case we considers that it crosses the segment if its midpoint is\n // above the line.\n\n if (\n Math.abs(intersectionParam1) < line.precision ||\n Math.abs(intersectionParam1 - 1) < line.precision\n ) {\n const [, y] = line.midPoint;\n return point[1] - y < 0 ? 1 : 0;\n }\n\n return 1;\n};\n\nconst rayArcIntersectionsCount = (point: Vector, arc: Arc) => {\n const epsilon = arc.precision;\n\n const verticalDistance = Math.abs(point[1] - arc.center[1]);\n\n // the line is above or below the circle\n if (verticalDistance > arc.radius + epsilon) return 0;\n\n const squareDist = squareDistance(point, arc.center);\n const squareR = arc.radius * arc.radius;\n const squareEpsilon = epsilon * epsilon;\n\n // On the border\n if (Math.abs(squareDist - squareR) < squareEpsilon) return 0;\n\n const pointOutsideCircle = squareDist - squareR > squareEpsilon;\n\n // the point is at the right of the circle\n if (pointOutsideCircle && arc.center[0] < point[0]) return 0;\n\n // delta corresponds to the length between the project center on the line and\n // the crossing points\n const delta = Math.sqrt(\n arc.radius * arc.radius - verticalDistance * verticalDistance\n );\n\n let intersectionsCount = 0;\n\n const updateIntersectionsCount = (intersectionPoint: Vector) => {\n if (!arc.isOnSegment(intersectionPoint)) return;\n\n // We extend the convention of the line ray interaction. We look at the\n // tangent at the point of intersection. If it is pointing to the top we\n // consider that the ray is crossing the arc.\n if (sameVector(intersectionPoint, arc.firstPoint)) {\n intersectionsCount += arc.tangentAtFirstPoint[1] > 0 ? 1 : 0;\n } else if (sameVector(intersectionPoint, arc.lastPoint)) {\n intersectionsCount += arc.tangentAtLastPoint[1] > 0 ? 0 : 1;\n } else {\n intersectionsCount += 1;\n }\n };\n\n // We might be able to optimise the check on segment, but it is not clear\n // that it is worth it\n updateIntersectionsCount([arc.center[0] + delta, point[1]]);\n\n if (pointOutsideCircle) {\n updateIntersectionsCount([arc.center[0] - delta, point[1]]);\n }\n\n return intersectionsCount;\n};\n\nexport function rayIntersectionsCount(point: Vector, segment: Segment): number {\n if (segment instanceof Line) {\n return rayLineIntersectionsCount(point, segment);\n }\n\n if (segment instanceof Arc) {\n return rayArcIntersectionsCount(point, segment);\n }\n\n throw new Error(\"Not implemented\");\n}\n","import type { Vector } from \"../definitions\";\nimport { rayIntersectionsCount } from \"../algorithms/intersections/rayIntersections\";\nimport { AbstractStroke, checkValidStroke } from \"./Stroke\";\nimport type { TransformationMatrix } from \"./TransformationMatrix\";\nimport { simplifySegments } from \"../algorithms/simplify\";\nimport { Segment } from \"./segments/Segment\";\nimport { sameVector } from \"../vectorOperations\";\nimport { Line } from \"./segments/Line\";\n\nexport class Loop extends AbstractStroke<Loop> {\n strokeType = \"LOOP\";\n\n constructor(segments: Segment[], { ignoreChecks = false } = {}) {\n super(segments, { ignoreChecks: true });\n if (!ignoreChecks) checkValidLoop(segments);\n }\n\n private _clockwise: boolean | null = null;\n get clockwise(): boolean {\n if (this._clockwise === null) {\n const vertices = this.segments.flatMap((c) => {\n if (!(c instanceof Line)) {\n // We just go with a simple approximation here, we should use some extrema\n // points instead, but this is quick (and good enough for now)\n return [c.firstPoint, c.paramPoint(0.5)];\n }\n return [c.firstPoint];\n });\n\n const approximateArea = vertices\n .map((v1, i) => {\n const v2 = vertices[(i + 1) % vertices.length];\n return (v2[0] - v1[0]) * (v2[1] + v1[1]);\n })\n .reduce((a, b) => a + b, 0);\n\n this._clockwise = approximateArea > 0;\n }\n return this._clockwise;\n }\n\n clone(): Loop {\n return new Loop(\n this.segments.map((segment) => segment.clone()),\n { ignoreChecks: true }\n );\n }\n\n reverse(): Loop {\n const reversedSegments = this.segments.map((segment) => segment.reverse());\n reversedSegments.reverse();\n return new Loop(reversedSegments, { ignoreChecks: true });\n }\n\n transform(matrix: TransformationMatrix): Loop {\n return new Loop(\n this.segments.map((segment) => segment.transform(matrix)),\n { ignoreChecks: true }\n );\n }\n\n contains(point: Vector): boolean {\n if (this.onStroke(point)) return false;\n if (!this.boundingBox.contains(point)) return false;\n\n const intersections = this.segments.reduce((acc, segment) => {\n return acc + rayIntersectionsCount(point, segment);\n }, 0);\n\n return intersections % 2 === 1;\n }\n\n simplify(): Loop {\n const newSegments = simplifySegments(this);\n if (!newSegments) return this;\n return new Loop(newSegments, { ignoreChecks: true });\n }\n}\n\nexport function checkValidLoop(segments: Segment[]): void {\n checkValidStroke(segments, \"Loop\");\n if (\n !sameVector(segments[0].firstPoint, segments[segments.length - 1].lastPoint)\n )\n throw new Error(\"Loop segment must be closed\");\n}\n","import { Vector } from \"../../definitions\";\nimport zip from \"../../utils/zip\";\n\nimport { Segment } from \"../../models/segments/Segment\";\nimport { Strand } from \"../../models/Strand\";\nimport { reprVector, sameVector } from \"../../vectorOperations\";\nimport { Loop } from \"../../models/Loop\";\nimport { findIntersectionsAndOverlaps } from \"../intersections\";\nimport removeDuplicatePoints from \"../../utils/removeDuplicatePoints\";\n\nconst rotateToStartAt = (segments: Segment[], point: Vector) => {\n const startIndex = segments.findIndex((segment: Segment) => {\n return sameVector(point, segment.firstPoint);\n });\n\n const start = segments.slice(0, startIndex);\n const end = segments.slice(startIndex);\n\n return end.concat(start);\n};\n\nconst rotateToStartAtSegment = (segments: Segment[], segment: Segment) => {\n let usedSegments = segments;\n\n const onSegment = (seg: Segment) => {\n return (\n sameVector(seg.firstPoint, segment.firstPoint) &&\n sameVector(seg.lastPoint, segment.lastPoint)\n );\n };\n\n let startIndex = segments.findIndex(onSegment);\n\n // it is also possible that the segment is oriented the other way. We still\n // need to align a start point\n if (startIndex === -1) {\n const reversedSegments = segments.map((s) => s.reverse());\n reversedSegments.reverse();\n startIndex = reversedSegments.findIndex(onSegment);\n if (startIndex === -1) {\n console.error(\n reversedSegments.map((c) => c.repr),\n segment.repr\n );\n throw new Error(\"Failed to rotate to segment start\");\n }\n usedSegments = reversedSegments;\n }\n\n const start = usedSegments.slice(0, startIndex);\n const end = usedSegments.slice(startIndex);\n\n return end.concat(start);\n};\n\nfunction* strandsBetweenIntersections(\n segments: Segment[],\n allIntersections: Vector[],\n allCommonSegments: Segment[]\n): Generator<Strand> {\n const endsAtIntersection = (segment: Segment) => {\n return allIntersections.some((intersection) => {\n return sameVector(intersection, segment.lastPoint);\n });\n };\n\n const isCommonSegment = (commonSegment: Segment) => {\n return allCommonSegments.some((segment) => {\n return commonSegment.isSame(segment);\n });\n };\n\n let currentCurves: Segment[] = [];\n for (const segment of segments) {\n // We ignore the checks at strand creation as these strands are part of\n // a loop and can be trusted to be valid\n if (endsAtIntersection(segment)) {\n currentCurves.push(segment);\n yield new Strand(currentCurves, { ignoreChecks: true });\n currentCurves = [];\n } else if (isCommonSegment(segment)) {\n if (currentCurves.length) {\n yield new Strand(currentCurves, { ignoreChecks: true });\n currentCurves = [];\n }\n yield new Strand([segment], { ignoreChecks: true });\n } else {\n currentCurves.push(segment);\n }\n }\n if (currentCurves.length) {\n yield new Strand(currentCurves, { ignoreChecks: true });\n }\n}\n\ntype IntersectionStrand = [Strand, Strand | \"same\"];\n\nfunction removeNonCrossingPoint(\n allIntersections: Vector[],\n segmentedCurve: Segment[],\n loopToCheck: Loop\n) {\n return allIntersections.filter((intersection: Vector) => {\n const segmentsOfIntersection = segmentedCurve.filter((s) => {\n return (\n sameVector(s.firstPoint, intersection) ||\n sameVector(s.lastPoint, intersection)\n );\n });\n if (segmentsOfIntersection.length % 2) {\n throw new Error(\"Bug in the intersection algo on non crossing point\");\n }\n\n const isInside = segmentsOfIntersection.map((segment: Segment): boolean => {\n return loopToCheck.contains(segment.midPoint);\n });\n\n // Either they are all inside or outside\n const segmentsOnTheSameSide =\n isInside.every((i) => i) || !isInside.some((i) => i);\n\n return !segmentsOnTheSameSide;\n });\n}\n\n/* When two shape intersect we cut them into segments between the intersection\n * points.\n *\n * This function returns the list of segments that have the same start and end\n * at the same intersection points or null if there is no intersection.\n */\nfunction loopIntersectionStrands(\n first: Loop,\n second: Loop,\n precision?: number\n): IntersectionStrand[] | null {\n // For each segment of each blueprint we figure out where the intersection\n // points are.\n let allIntersections: Vector[] = [];\n const allCommonSegments: Segment[] = [];\n\n const firstCurvePoints: Vector[][] = new Array(first.segments.length)\n .fill(0)\n .map(() => []);\n const secondCurvePoints: Vector[][] = new Array(second.segments.length)\n .fill(0)\n .map(() => []);\n\n first.segments.forEach((thisSegments, firstIndex) => {\n second.segments.forEach((otherSegments, secondIndex) => {\n const { intersections, overlaps } = findIntersectionsAndOverlaps(\n thisSegments,\n otherSegments,\n precision\n );\n\n allIntersections.push(...intersections);\n firstCurvePoints[firstIndex].push(...intersections);\n secondCurvePoints[secondIndex].push(...intersections);\n\n allCommonSegments.push(...overlaps);\n const commonSegmentsPoints = overlaps.flatMap((s) => [\n s.firstPoint,\n s.lastPoint,\n ]);\n allIntersections.push(...commonSegmentsPoints);\n firstCurvePoints[firstIndex].push(...commonSegmentsPoints);\n secondCurvePoints[secondIndex].push(...commonSegmentsPoints);\n });\n });\n\n allIntersections = removeDuplicatePoints(allIntersections, precision);\n\n // If there is only one intersection point we consider that the loops\n // are not intersecting\n if (!allIntersections.length || allIntersections.length === 1) return null;\n\n // We further split the segments at the intersections\n const cutCurve = ([segment, intersections]: [\n Segment,\n Vector[]\n ]): Segment[] => {\n if (!intersections.length) return [segment];\n return segment.splitAt(intersections);\n };\n let firstCurveSegments = zip([first.segments, firstCurvePoints] as [\n Segment[],\n Vector[][]\n ]).flatMap(cutCurve);\n\n let secondCurveSegments = zip([second.segments, secondCurvePoints] as [\n Segment[],\n Vector[][]\n ]).flatMap(cutCurve);\n\n // We need to remove intersection points that are not crossing into each\n // other (i.e. the two blueprints are only touching in one point and not\n // intersecting there.)\n allIntersections = removeNonCrossingPoint(\n allIntersections,\n firstCurveSegments,\n second\n );\n\n if (!allIntersections.length && !allCommonSegments.length) return null;\n\n // We align the beginning of the segments\n if (!allCommonSegments.length) {\n const startAt = allIntersections[0];\n firstCurveSegments = rotateToStartAt(firstCurveSegments, startAt);\n secondCurveSegments = rotateToStartAt(secondCurveSegments, startAt);\n } else {\n // When there are common segments we always start on one\n const startSegment = allCommonSegments[0];\n firstCurveSegments = rotateToStartAtSegment(\n firstCurveSegments,\n startSegment\n );\n secondCurveSegments = rotateToStartAtSegment(\n secondCurveSegments,\n startSegment\n );\n }\n\n // We group segments between intersections in strands\n const strandsFromFirst = Array.from(\n strandsBetweenIntersections(\n firstCurveSegments,\n allIntersections,\n allCommonSegments\n )\n );\n\n let strandsFromSecond = Array.from(\n strandsBetweenIntersections(\n secondCurveSegments,\n allIntersections,\n allCommonSegments\n )\n );\n\n if (\n !sameVector(\n strandsFromSecond[0].lastPoint,\n strandsFromFirst[0].lastPoint\n ) ||\n (allCommonSegments.length > 0 && strandsFromSecond[0].segmentsCount !== 1)\n ) {\n strandsFromSecond = strandsFromSecond.reverse().map((s) => s.reverse());\n }\n\n return zip([strandsFromFirst, strandsFromSecond]).map(([first, second]) => {\n if (\n first.segmentsCount === 1 &&\n allCommonSegments.some((commonSegment) => {\n return first.segments[0].isSame(commonSegment);\n })\n ) {\n return [first, \"same\"];\n }\n return [first, second];\n });\n}\n\nfunction mergeStrandsAsLoop(strands: Strand[]) {\n let outStrand = strands[0];\n\n for (const strand of strands.slice(1)) {\n outStrand = outStrand.extend(strand);\n }\n\n if (!sameVector(outStrand.firstPoint, outStrand.lastPoint)) {\n console.error(\n reprVector(outStrand.firstPoint),\n reprVector(outStrand.lastPoint)\n );\n throw new Error(\"Bug in the intersection algo on non closing strand\");\n }\n\n return new Loop(outStrand.segments);\n}\n\nfunction groupLoops(inputStrands: Strand[]): Loop[] {\n if (!inputStrands.length) return [];\n\n const startPoints = inputStrands.map((c) => c.firstPoint);\n let endPoints = inputStrands.map((c) => c.lastPoint);\n endPoints = endPoints.slice(-1).concat(endPoints.slice(0, -1));\n\n const discontinuities = zip([startPoints, endPoints]).flatMap(\n ([startPoint, endPoint], index) => {\n if (!sameVector(startPoint, endPoint)) {\n return index;\n }\n return [];\n }\n );\n\n if (!discontinuities.length) return [mergeStrandsAsLoop(inputStrands)];\n\n const strands = zip([\n discontinuities.slice(0, -1),\n discontinuities.slice(1),\n ]).map(([start, end]) => {\n return mergeStrandsAsLoop(inputStrands.slice(start, end));\n });\n\n let lastStrand = inputStrands.slice(\n discontinuities[discontinuities.length - 1]\n );\n if (discontinuities[0] !== 0) {\n lastStrand = lastStrand.concat(inputStrands.slice(0, discontinuities[0]));\n }\n strands.push(mergeStrandsAsLoop(lastStrand));\n\n return strands;\n}\n\nconst extendStrandList = (strandList: Strand[], strand: Strand) => {\n if (strandList.length === 0) return [strand];\n const lastStrand = strandList.at(-1)!;\n if (sameVector(lastStrand.lastPoint, strand.firstPoint)) {\n return strandList.slice(0, -1).concat([lastStrand.extend(strand)]);\n } else if (sameVector(lastStrand.lastPoint, strand.lastPoint)) {\n return strandList\n .slice(0, -1)\n .concat([lastStrand.extend(strand.reverse())]);\n } else {\n return strandList.concat([strand]);\n }\n};\n\nconst prependStrandList = (strandList: Strand[], strand: Strand) => {\n if (strandList.length === 0) return [strand];\n if (sameVector(strandList[0].firstPoint, strand.lastPoint)) {\n return [strand.extend(strandList[0])].concat(strandList.slice(1));\n } else {\n return [strand].concat(strandList);\n }\n};\n\nexport function loopBooleanOperation(\n first: Loop,\n second: Loop,\n {\n firstInside,\n secondInside,\n }: {\n firstInside: \"keep\" | \"remove\";\n secondInside: \"keep\" | \"remove\";\n }\n):\n | Loop[]\n | { identical: true }\n | {\n firstCurveInSecond: boolean;\n secondCurveInFirst: boolean;\n identical: false;\n } {\n const strands = loopIntersectionStrands(first, second);\n\n // The case where we have no intersections\n if (!strands) {\n const firstStrandPoint = first.segments[0].midPoint;\n const firstCurveInSecond = second.contains(firstStrandPoint);\n\n const secondStrandPoint = second.segments[0].midPoint;\n const secondCurveInFirst = first.contains(secondStrandPoint);\n\n return {\n identical: false,\n firstCurveInSecond,\n secondCurveInFirst,\n };\n }\n\n if (strands.every(([, secondStrand]) => secondStrand === \"same\")) {\n return { identical: true };\n }\n\n let lastWasSame: null | Strand = null;\n let strandsIn: number | null = null;\n\n const s = strands.flatMap(([firstStrand, secondStrand]) => {\n let mergedStrands: Strand[] = [];\n let strandsOut = 0;\n\n // When two strands are on top of each other we base our decision on the\n // fact that every point should have one strand entering, and one going\n // out.\n if (secondStrand === \"same\") {\n if (strandsIn === 1) {\n strandsIn = 1;\n return firstStrand;\n }\n\n if (strandsIn === 2 || strandsIn === 0) {\n strandsIn = null;\n return [];\n }\n\n if (strandsIn === null) {\n if (!lastWasSame) lastWasSame = firstStrand;\n else lastWasSame = lastWasSame.extend(firstStrand);\n return [];\n }\n\n console.error(\"weird situation\");\n return [];\n }\n\n // Every strand is kept or removed according to the fact that it is within\n // or not of the other closed loop\n\n const firstSegmentPoint = firstStrand.segments[0].midPoint;\n const firstSegmentInSecondShape = second.contains(firstSegmentPoint);\n\n if (\n (firstInside === \"keep\" && firstSegmentInSecondShape) ||\n (firstInside === \"remove\" && !firstSegmentInSecondShape)\n ) {\n strandsOut += 1;\n mergedStrands = extendStrandList(mergedStrands, firstStrand);\n }\n\n const secondSegmentPoint = secondStrand.segments[0].midPoint;\n const secondSegmentInFirstShape = first.contains(secondSegmentPoint);\n\n if (\n (secondInside === \"keep\" && secondSegmentInFirstShape) ||\n (secondInside === \"remove\" && !secondSegmentInFirstShape)\n ) {\n const strandToAdd = secondStrand;\n\n strandsOut += 1;\n\n if (strandsOut === 2 && mergedStrands.length) {\n mergedStrands = extendStrandList(mergedStrands, strandToAdd);\n lastWasSame = null;\n } else {\n mergedStrands = [strandToAdd];\n }\n }\n\n // This is the case where the information about the strands entering the\n // previous node where not known and no strand was selected\n if (strandsIn === null && strandsOut === 1 && lastWasSame) {\n mergedStrands = prependStrandList(mergedStrands, lastWasSame);\n }\n\n if (strandsOut === 1) {\n strandsIn = strandsOut;\n lastWasSame = null;\n }\n if (!mergedStrands.length) {\n lastWasSame = null;\n return [];\n }\n return mergedStrands;\n });\n\n // We now have a bunch of strands, we need to group them into loops\n return groupLoops(s);\n}\n\nexport const fuseLoops = (first: Loop, second: Loop): Loop[] => {\n const result = loopBooleanOperation(first, second, {\n firstInside: \"remove\",\n secondInside: \"remove\",\n });\n\n if (Array.isArray(result)) return result;\n\n if (result.identical) {\n return [first];\n }\n\n if (result.firstCurveInSecond) {\n return [second];\n }\n\n if (result.secondCurveInFirst) {\n return [first];\n }\n\n return [first, second];\n};\n\nexport const cutLoops = (first: Loop, second: Loop): Loop[] => {\n const result = loopBooleanOperation(first, second, {\n firstInside: \"remove\",\n secondInside: \"keep\",\n });\n\n if (Array.isArray(result)) return result;\n\n if (result.identical) {\n return [];\n }\n\n if (result.firstCurveInSecond) {\n return [];\n }\n\n if (result.secondCurveInFirst) {\n return [first, second];\n }\n\n return [first];\n};\n\nexport const intersectLoops = (first: Loop, second: Loop): Loop[] => {\n const result = loopBooleanOperation(first, second, {\n firstInside: \"keep\",\n secondInside: \"keep\",\n });\n\n if (Array.isArray(result)) return result;\n\n if (result.identical) {\n return [first];\n }\n\n if (result.firstCurveInSecond) {\n return [first];\n }\n\n if (result.secondCurveInFirst) {\n return [second];\n }\n\n return [];\n};\n","import { Figure } from \"../../models/Figure\";\nimport { organiseLoops } from \"../organiseLoops\";\nimport { allPairs } from \"../../utils/allPairs\";\nimport { cutLoops, fuseLoops, intersectLoops } from \"./loopBooleans\";\n\nexport function fuseIntersectingFigures(figures: Figure[]) {\n const fused = new Map();\n\n const output: { current: Figure[] }[] = [];\n\n figures.forEach((inputFigure, i) => {\n let savedFigures: {\n current: Figure[];\n fusedWith: Set<number>;\n };\n\n if (fused.has(i)) {\n savedFigures = fused.get(i);\n } else {\n savedFigures = { current: [inputFigure], fusedWith: new Set([i]) };\n output.push(savedFigures);\n }\n\n figures.slice(i + 1).forEach((inputOtherFigure, j) => {\n const figure = savedFigures.current;\n\n const currentIndex = i + j + 1;\n\n if (savedFigures.fusedWith.has(currentIndex)) return;\n\n let otherFigure = [inputOtherFigure];\n let otherIsFused = false;\n\n if (fused.has(currentIndex)) {\n otherFigure = fused.get(currentIndex).current;\n otherIsFused = true;\n }\n\n const doListIntersect = figure.some((f) =>\n otherFigure.some((s) => f.intersects(s))\n );\n if (!doListIntersect) return;\n\n let newFused: Figure[];\n if (figure.length > 1 || otherFigure.length > 1) {\n newFused = fuseFiguresLists(figure, otherFigure);\n } else {\n newFused = fuseFigures(figure[0], otherFigure[0]);\n }\n\n savedFigures.fusedWith.add(currentIndex);\n savedFigures.current = newFused;\n if (!otherIsFused) fused.set(currentIndex, savedFigures);\n });\n });\n\n return output.flatMap(({ current }) => current);\n}\n\nexport function fuseFigures(first: Figure, second: Figure) {\n const outerFused = fuseLoops(first.contour, second.contour);\n\n const inner1Fused = second.holes.flatMap((c) => cutLoops(c, first.contour));\n const inner2Fused = first.holes.flatMap((c) => cutLoops(c, second.contour));\n\n const innerIntersections = allPairs(first.holes, second.holes).flatMap(\n ([first, second]) => intersectLoops(first, second)\n );\n\n return organiseLoops([\n ...outerFused,\n ...inner1Fused,\n ...inner2Fused,\n ...innerIntersections,\n ]);\n}\n\nexport function cutFigures(first: Figure, second: Figure): Figure[] {\n if (first.isFull && second.isFull) {\n return organiseLoops(cutLoops(first.contour, second.contour));\n }\n\n if (first.isFull) {\n const cutContour = cutLoops(first.contour, second.contour);\n const cutHoles = second.holes.flatMap((c) =>\n intersectLoops(c, first.contour)\n );\n // We might be able to assume that the contour and the holes are already\n // distinct figures.\n return organiseLoops([...cutContour, ...cutHoles]);\n } else if (second.isFull) {\n if (!first.contour.intersects(second.contour)) {\n if (!first.contour.contains(second.contour.firstPoint)) {\n // nothing to do here, the second figure is outside the first\n return [first];\n } else {\n const fusedCuts = fuseFiguresLists(\n first.holes.map((h) => new Figure(h)),\n [second]\n );\n\n return organiseLoops([\n first.contour,\n ...fusedCuts.flatMap((f) => f.allLoops),\n ]);\n }\n }\n }\n\n // We turn the last case in one where the second is full\n let newFigures = cutFigures(new Figure(first.contour), second);\n first.holes.forEach((cut) => {\n newFigures = newFigures.flatMap((c) => cutFigures(c, new Figure(cut)));\n });\n\n return newFigures;\n}\n\nexport function intersectFigures(first: Figure, second: Figure): Figure[] {\n const outerIntersection = intersectLoops(first.contour, second.contour);\n if (!outerIntersection.length) return [];\n\n let out = organiseLoops(outerIntersection);\n out = cutFiguresLists(\n out,\n first.holes.map((h) => new Figure(h))\n );\n\n // Here we need to do the cut in two steps, because the holes might intersect\n return cutFiguresLists(\n out,\n second.holes.map((h) => new Figure(h))\n );\n}\n\nexport function fuseFiguresLists(first: Figure[], second: Figure[]): Figure[] {\n if (!first.length) return second;\n if (!second.length) return first;\n\n if (\n (first.length === 1 && second.length > 1) ||\n (second.length === 1 && first.length > 1)\n ) {\n return fuseIntersectingFigures([...first, ...second]);\n }\n\n if (first.length > 1 && second.length > 1) {\n let out = fuseFiguresLists([first[0]], second);\n\n first.slice(1).forEach((fig) => {\n out = fuseFiguresLists([fig], out);\n });\n return out;\n }\n\n if (first.length === 1 && second.length === 1) {\n return fuseFigures(first[0], second[0]);\n }\n\n return [];\n}\n\nexport function cutFiguresLists(first: Figure[], second: Figure[]): Figure[] {\n if (!first.length) return [];\n if (!second.length) return first;\n\n // The easy case\n if (first.length === 1 && second.length === 1) {\n return cutFigures(first[0], second[0]);\n }\n\n if (first.length > 1) {\n // All the figures here are independant, so we can cut them independently\n return first.flatMap((fig) => cutFiguresLists([fig], second));\n }\n\n // We are now in the case where there is only one figure in the first list\n // and multiple figures in the second list\n //\n // We turn it in the case with (potentially) multiple figures in the first list\n // and one figure in the second list\n\n let out = cutFigures(first[0], second[0]);\n second.slice(1).forEach((fig) => {\n out = cutFiguresLists(out, [fig]);\n });\n return out;\n}\n\nexport function intersectFiguresLists(\n first: Figure[],\n second: Figure[]\n): Figure[] {\n if (!first.length || !second.length) {\n return [];\n }\n\n if (first.length === 1 && second.length === 1) {\n return intersectFigures(first[0], second[0]);\n }\n\n if (first.length > 1) {\n return first.flatMap((fig) => intersectFiguresLists([fig], second));\n }\n\n return second.flatMap((fig) => intersectFiguresLists(first, [fig]));\n}\n","import type { Vector } from \"../definitions\";\nimport { BoundingBox } from \"./BoundingBox\";\nimport type { Figure } from \"./Figure\";\nimport type { TransformationMatrix } from \"./TransformationMatrix\";\n\nimport {\n cutFiguresLists,\n fuseFiguresLists,\n intersectFiguresLists,\n} from \"../algorithms/boolean/figureBooleans\";\nimport { combineDifferentValues } from \"../utils/allCombinations\";\nimport { Transformable } from \"./utils/Transformable\";\n\nexport class Diagram extends Transformable<Diagram> {\n figures: Figure[];\n\n constructor(figures: Figure[] = [], { ignoreChecks = false } = {}) {\n super();\n if (!ignoreChecks) checkIsValidDiagram(figures);\n this.figures = figures;\n }\n\n private _boundingBox: BoundingBox | null = null;\n\n get isEmpty(): boolean {\n return this.figures.length === 0;\n }\n\n get boundingBox(): BoundingBox {\n if (this.isEmpty) return new BoundingBox();\n if (this._boundingBox === null) {\n let boundingBox = this.figures[0].boundingBox;\n for (const figure of this.figures.slice(1)) {\n boundingBox = boundingBox.merge(figure.boundingBox);\n }\n this._boundingBox = boundingBox;\n }\n return this._boundingBox;\n }\n\n clone(): Diagram {\n return new Diagram(this.figures.map((figure) => figure.clone()));\n }\n\n transform(matrix: TransformationMatrix): Diagram {\n return new Diagram(this.figures.map((figure) => figure.transform(matrix)));\n }\n\n contains(point: Vector): boolean {\n return this.figures.some((figure) => figure.contains(point));\n }\n\n intersects(other: Diagram): boolean {\n return this.figures.some((figure) =>\n other.figures.some((otherFigure) => figure.intersects(otherFigure))\n );\n }\n\n fuse(other: Diagram): Diagram {\n return new Diagram(fuseFiguresLists(this.figures, other.figures));\n }\n\n cut(other: Diagram): Diagram {\n return new Diagram(cutFiguresLists(this.figures, other.figures));\n }\n\n intersect(other: Diagram): Diagram {\n return new Diagram(intersectFiguresLists(this.figures, other.figures));\n }\n}\n\nexport function checkIsValidDiagram(figures: Figure[]): void {\n for (const [figure, otherFigure] of combineDifferentValues(figures)) {\n if (figure.intersects(otherFigure)) {\n throw new Error(\"Diagram figures must not intersect\");\n }\n }\n}\n","import { Arc } from \"../../models/segments/Arc\";\nimport { Line } from \"../../models/segments/Line\";\nimport { Segment } from \"../../models/segments/Segment\";\n\nexport function jsonSegment(segment: Segment) {\n if (segment instanceof Line) {\n return {\n type: segment.segmentType,\n firstPoint: segment.firstPoint,\n lastPoint: segment.lastPoint,\n };\n }\n if (segment instanceof Arc) {\n return {\n type: segment.segmentType,\n firstPoint: segment.firstPoint,\n lastPoint: segment.lastPoint,\n center: segment.center,\n clockwise: segment.clockwise,\n };\n }\n\n throw new Error(\"Unknown segment type\");\n}\n","import type { Loop } from \"../../models/Loop\";\nimport { jsonSegment } from \"./jsonSegment\";\n\nexport function jsonLoop(loop: Loop) {\n return {\n type: \"LOOP\",\n segments: loop.segments.map(jsonSegment),\n };\n}\n","import type { Figure } from \"../../models/Figure\";\nimport { jsonLoop } from \"./jsonLoop\";\n\nexport function jsonFigure(figure: Figure) {\n return {\n type: \"FIGURE\",\n contour: jsonLoop(figure.contour),\n holes: figure.holes.map(jsonLoop),\n };\n}\n","import { Diagram } from \"../../models/Diagram\";\nimport { jsonFigure } from \"./jsonFigure\";\n\nexport function jsonDiagram(diagram: Diagram) {\n return {\n type: \"DIAGRAM\",\n figures: diagram.figures.map(jsonFigure),\n };\n}\n","import { Diagram } from \"../../models/Diagram\";\nimport { Figure } from \"../../models/Figure\";\nimport { Loop } from \"../../models/Loop\";\nimport { Arc } from \"../../models/segments/Arc\";\nimport { Line } from \"../../models/segments/Line\";\nimport { jsonDiagram } from \"./jsonDiagram\";\nimport { jsonFigure } from \"./jsonFigure\";\nimport { jsonLoop } from \"./jsonLoop\";\nimport { jsonSegment } from \"./jsonSegment\";\n\ntype Shape = Loop | Figure | Diagram | Arc | Line;\n\nexport function exportJSON(shape: Shape) {\n if (shape instanceof Diagram) {\n return jsonDiagram(shape);\n } else if (shape instanceof Figure) {\n return jsonFigure(shape);\n } else if (shape instanceof Loop) {\n return jsonLoop(shape);\n } else if (shape instanceof Arc || shape instanceof Line) {\n return jsonSegment(shape);\n } else {\n throw new Error(\"Unknown shape type\");\n }\n}\n"],"names":["overlap1D","min1","max1","min2","max2","BoundingBox","xMin","yMin","xMax","yMax","point","x","y","other","asFixed","p","precision","num","removeDuplicatePoints","points","p0","p1","DEG2RAD","reprVector","vector","sameVector","x0","y0","x1","y1","add","subtract","squareLength","scalarMultiply","scalar","squareDistance","distance","crossProduct","dotProduct","normalize","l","polarToCartesian","r","theta","polarAngle","cartesianToPolar","v","parallel","v1","v2","V1xV2","xLength","yLength","perpendicular","perpendicularClockwise","matMult","m1","m2","a","b","c","d","e","f","g","h","i","j","k","m","n","o","q","TransformationMatrix","angle","center","cos","sin","rotationMatrix","normal","Transformable","transform","factor","axisOrDirection","AbstractSegment","firstPoint","lastPoint","Line","linearPrecision","delta","u","intersection","pointVec","splitPoints","allPoints","uniquePoints","xChange","defaultDir","comparisonAxis","index","matrix","range","len","zip","arrays","minLength","arr","unitAngle","angularDistance","angle1","angle2","clockwise","relDistance","lineLineParams","line1","line2","squarePrecision","diffPoint","intersectionParam1","intersectionParam2","lineLineIntersection","includeOverlaps","intersectionParams","polarCoordsFromCenter","Arc","ignoreChecks","param","extendedR","validAngle","tangent","allParams","paramsMap","skipped","nextParam","startParam","arc","threePointsArc","midPoint","chord1","chord2","dir1","dir2","result","tangentArc","tangentAtFirstPoint","chord","dir","projectPointOnLine","line","lineArcIntersection","epsilon","centerOnLine","centerDistance","intersectionPoint","intersections","lineDir","p2","complementArc","handleOverlaps","arc1","arc2","startIndex","arcArcIntersection","centersDistance","radiusSum","radiusDifference","centersVector","isOutsideTangent","orientation","radiusToChord","halfChord","chordVector","findIntersections","segment1","segment2","findIntersectionsAndOverlaps","allCombinations","count","combineDifferentValues","array","Figure","contour","holes","checkIsValidFigure","hole","loop","otherLoop","loop1","loop2","hole1","hole2","exportJSON","groupByBoundingBoxOverlap","loops","overlaps","groups","groupsInOverlaps","indices","myGroup","addContainmentInfo","groupedLoops","isIn","potentialOuterLoop","splitMultipleOuterLoops","outerLoops","allLoops","outerLoop","cleanEdgeCases","handleNestedLoops","nestedLoops","firstLevelOuterLoops","innerLevelsLoops","organiseLoops","compounds","allPairs","list1","list2","l1","l2","AbstractStroke","segments","checkValidStroke","segment","otherSegment","bbox","checkSelfIntersections","type","segmentIndex","otherSegmentIndex","nextSegment","canExtendSegment","extendSegment","simplifySegments","stroke","foundSimplification","simplifiedSegments","lastSegment","Strand","reversedSegments","strand","newSegments","rayLineIntersectionsCount","rayArcIntersectionsCount","verticalDistance","squareDist","squareR","squareEpsilon","pointOutsideCircle","intersectionsCount","updateIntersectionsCount","rayIntersectionsCount","Loop","checkValidLoop","vertices","approximateArea","acc","rotateToStartAt","start","rotateToStartAtSegment","usedSegments","onSegment","seg","s","strandsBetweenIntersections","allIntersections","allCommonSegments","endsAtIntersection","isCommonSegment","commonSegment","currentCurves","removeNonCrossingPoint","segmentedCurve","loopToCheck","segmentsOfIntersection","isInside","loopIntersectionStrands","first","second","firstCurvePoints","secondCurvePoints","thisSegments","firstIndex","otherSegments","secondIndex","commonSegmentsPoints","cutCurve","firstCurveSegments","secondCurveSegments","startSegment","startAt","strandsFromFirst","strandsFromSecond","mergeStrandsAsLoop","strands","outStrand","groupLoops","inputStrands","startPoints","endPoints","discontinuities","startPoint","endPoint","end","lastStrand","extendStrandList","strandList","prependStrandList","loopBooleanOperation","firstInside","secondInside","firstStrandPoint","firstCurveInSecond","secondStrandPoint","secondCurveInFirst","secondStrand","lastWasSame","strandsIn","firstStrand","mergedStrands","strandsOut","firstSegmentPoint","firstSegmentInSecondShape","secondSegmentPoint","secondSegmentInFirstShape","strandToAdd","fuseLoops","cutLoops","intersectLoops","fuseIntersectingFigures","figures","fused","output","inputFigure","savedFigures","inputOtherFigure","figure","currentIndex","otherFigure","otherIsFused","newFused","fuseFiguresLists","fuseFigures","current","outerFused","inner1Fused","inner2Fused","innerIntersections","cutFigures","cutContour","cutHoles","fusedCuts","newFigures","cut","intersectFigures","outerIntersection","out","cutFiguresLists","fig","intersectFiguresLists","Diagram","checkIsValidDiagram","boundingBox","jsonSegment","jsonLoop","jsonFigure","jsonDiagram","diagram","shape"],"mappings":"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"}