pantograph2d 0.10.1 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/{QuadraticBezier-DCa0WGs0.js → QuadraticBezier-BeY2TXKH.js} +464 -433
  2. package/dist/QuadraticBezier-BeY2TXKH.js.map +1 -0
  3. package/dist/{QuadraticBezier-CuRsIP_D.cjs → QuadraticBezier-eSR75IzC.cjs} +9 -9
  4. package/dist/QuadraticBezier-eSR75IzC.cjs.map +1 -0
  5. package/dist/draw-BmJ8wIc9.cjs +2 -0
  6. package/dist/draw-BmJ8wIc9.cjs.map +1 -0
  7. package/dist/{draw-CJWiicbK.js → draw-DzKVhurb.js} +94 -89
  8. package/dist/draw-DzKVhurb.js.map +1 -0
  9. package/dist/{models-CFd5lRKc.js → models-BHeLX0dj.js} +544 -527
  10. package/dist/models-BHeLX0dj.js.map +1 -0
  11. package/dist/models-Fv9xfQBT.cjs +4 -0
  12. package/dist/models-Fv9xfQBT.cjs.map +1 -0
  13. package/dist/pantograph/drawShape.cjs +1 -1
  14. package/dist/pantograph/drawShape.js +2 -2
  15. package/dist/pantograph/models.cjs +1 -1
  16. package/dist/pantograph/models.js +2 -2
  17. package/dist/pantograph/svg.cjs +1 -1
  18. package/dist/pantograph/svg.js +1 -1
  19. package/dist/pantograph.cjs +2 -2
  20. package/dist/pantograph.cjs.map +1 -1
  21. package/dist/pantograph.js +677 -571
  22. package/dist/pantograph.js.map +1 -1
  23. package/dist/svg-BTO7h1ix.js +62 -0
  24. package/dist/svg-BTO7h1ix.js.map +1 -0
  25. package/dist/svg-b6SOnbda.cjs +8 -0
  26. package/dist/svg-b6SOnbda.cjs.map +1 -0
  27. package/dist/types/src/algorithms/offsets/offsetSegment.d.ts +1 -0
  28. package/dist/types/src/algorithms/tesselate/tesselateSegment.d.ts +7 -0
  29. package/dist/types/src/main.d.ts +1 -1
  30. package/dist/types/src/models/BoundingBox.d.ts +1 -0
  31. package/dist/types/src/models/Diagram.d.ts +1 -0
  32. package/dist/types/src/models/Figure.d.ts +1 -0
  33. package/dist/types/src/models/Loop.d.ts +1 -0
  34. package/dist/types/src/models/Strand.d.ts +5 -0
  35. package/dist/types/src/models/TransformationMatrix.d.ts +1 -0
  36. package/dist/types/src/models/segments/Arc.d.ts +1 -0
  37. package/dist/types/src/models/segments/CubicBezier.d.ts +1 -0
  38. package/dist/types/src/models/segments/EllipseArc.d.ts +1 -0
  39. package/dist/types/src/models/segments/Line.d.ts +2 -0
  40. package/dist/types/src/models/segments/QuadraticBezier.d.ts +1 -0
  41. package/dist/types/src/operations.d.ts +1 -0
  42. package/dist/types/src/tesselationOperations.d.ts +15 -0
  43. package/package.json +2 -2
  44. package/dist/QuadraticBezier-CuRsIP_D.cjs.map +0 -1
  45. package/dist/QuadraticBezier-DCa0WGs0.js.map +0 -1
  46. package/dist/draw-9Elv4xz6.cjs +0 -2
  47. package/dist/draw-9Elv4xz6.cjs.map +0 -1
  48. package/dist/draw-CJWiicbK.js.map +0 -1
  49. package/dist/models-CFd5lRKc.js.map +0 -1
  50. package/dist/models-LHGiMarC.cjs +0 -4
  51. package/dist/models-LHGiMarC.cjs.map +0 -1
  52. package/dist/svg-BzloQ9l1.cjs +0 -8
  53. package/dist/svg-BzloQ9l1.cjs.map +0 -1
  54. package/dist/svg-CD4q2GBE.js +0 -62
  55. package/dist/svg-CD4q2GBE.js.map +0 -1
@@ -0,0 +1,2 @@
1
+ "use strict";var M=Object.defineProperty;var _=(e,t,n)=>t in e?M(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var f=(e,t,n)=>_(e,typeof t!="symbol"?t+"":t,n);const i=require("./QuadraticBezier-eSR75IzC.cjs"),d=require("./models-Fv9xfQBT.cjs"),b=(e,t,n)=>{const r=i.crossProduct(e.V,t.V),s=e.precision*t.precision;if(r*r<s)return"parallel";const o=i.subtract(t.firstPoint,e.firstPoint),a=i.crossProduct(o,t.V)/r;return i.add(e.firstPoint,i.scalarMultiply(e.V,a))},C=Symbol.for("pantograph:DegenerateSegment");class m{constructor(t,n){this.firstPoint=t,this.lastPoint=n,Object.defineProperty(this,C,{value:!0})}static isInstance(t){return!!t&&t[C]===!0}}function T(e,t){if(i.Line.isInstance(e))return F(e,t);if(i.Arc.isInstance(e))return V(e,t);if(i.QuadraticBezier.isInstance(e)||i.CubicBezier.isInstance(e))return B(e,t);throw new Error("Not implemented")}function F(e,t){const{firstPoint:n,lastPoint:r}=e,s=e.normalVector;return new i.Line(i.add(n,i.scalarMultiply(s,t)),i.add(r,i.scalarMultiply(s,t)))}function V(e,t){const n=i.add(e.firstPoint,i.scalarMultiply(i.perpendicular(e.tangentAtFirstPoint),t)),r=i.add(e.lastPoint,i.scalarMultiply(i.perpendicular(e.tangentAtLastPoint),t)),s=t*(e.clockwise?1:-1);return e.radius+s<e.precision?new m(n,r):new i.Arc(n,r,e.center,e.clockwise)}function w(e,t,n,r,s){const o=b({V:n,firstPoint:r,precision:s},{V:i.subtract(t,e),firstPoint:e,precision:s});if(o==="parallel")throw new Error("Parallel lines not expected in safe bezier offset control point calculation");return o}function B(e,t){const{firstPoint:n,lastPoint:r,normalAtFirstPoint:s,normalAtLastPoint:o}=e,a=b({V:s,firstPoint:n,precision:e.precision},{V:o,firstPoint:r,precision:e.precision}),c=i.add(n,i.scalarMultiply(s,t)),l=i.add(r,i.scalarMultiply(o,t));if(a==="parallel")throw new Error("Parallel lines not expected in safe bezier offset");if(i.dotProduct(i.subtract(a,n),s)*t>0&&Math.min(i.distance(n,a),i.distance(r,a))<t)return new m(c,l);if(i.QuadraticBezier.isInstance(e)){const g=w(a,e.controlPoint,e.tangentAtFirstPoint,c,e.precision);return new i.QuadraticBezier(c,l,g)}const p=w(a,e.firstControlPoint,e.tangentAtFirstPoint,c,e.precision),u=w(a,e.lastControlPoint,e.tangentAtLastPoint,l,e.precision);return new i.CubicBezier(c,l,p,u)}function L(e,t,n){const r=i.crossProduct(e.tangentAtLastPoint,t.tangentAtFirstPoint);if(Math.abs(r)<1e-10)return null;const s=r>0?1:-1,o=Math.abs(n)*s,a=T(e,o),c=T(t,o);if(m.isInstance(a)||m.isInstance(c))return null;let l;try{l=d.findIntersections(a,c,1e-9).at(-1)}catch{return null}if(!l)return null;const h=l,p=(P,D)=>{const y=D.tangentAt(h),x=i.perpendicularClockwise(y),z=i.add(h,i.scalarMultiply(x,o));return P.splitAt(z)},[u]=p(e,a),[,g]=p(t,c);return{first:u,second:g,center:h}}function A(e,t,n){const r=L(e,t,n);if(!r)return console.warn("Cannot fillet between segments",e.repr,t.repr),[e,t];const{first:s,second:o}=r;return[s,i.tangentArc(s.lastPoint,o.firstPoint,s.tangentAtLastPoint),o]}function S(e,t,n){const r=L(e,t,n);if(!r)return console.warn("Cannot chamfer between segments",e.repr,t.repr),[e,t];const{first:s,second:o}=r;return[s,new i.Line(s.lastPoint,o.firstPoint),o]}const I=e=>{let t;e?typeof e=="number"||Array.isArray(e)&&e.length===2?t={endTangent:e}:t={endTangent:0,...e}:t={endTangent:[1,0]};const{endTangent:n,startFactor:r=1,endFactor:s=1,startTangent:o}=t;let a;typeof n=="number"?a=i.polarToCartesian(1,n*i.DEG2RAD):a=n;let c;return typeof o=="number"?c=i.polarToCartesian(1,o*i.DEG2RAD):c=o,{endTangent:a,startFactor:r,endFactor:s,startTangent:c}};function E(e,{ignoreChecks:t=!1}={}){return new d.Diagram([new d.Figure(new d.Loop([...e],{ignoreChecks:t}))])}class v{constructor(t=[0,0]){f(this,"pointer");f(this,"firstPoint");f(this,"pendingSegments");f(this,"_nextCorner");this.pointer=t,this.firstPoint=t,this.pendingSegments=[],this._nextCorner=null}movePointerTo(t){if(this.pendingSegments.length)throw new Error("You can only move the pointer if there is no segment defined");return this.pointer=t,this.firstPoint=t,this}saveSegment(t){if(i.sameVector(t.firstPoint,t.lastPoint))throw new Error(`Segment has no length, ${t.repr}`);if(!this._nextCorner)return this.pendingSegments.push(t),this;const n=this.pendingSegments.pop();if(!n)throw new Error("bug in the custom corner algorithm");const r=this._nextCorner.mode==="chamfer"?S:A;return this.pendingSegments.push(...r(n,t,this._nextCorner.radius)),this._nextCorner=null,this}lineTo(t){const n=new i.Line(this.pointer,t);return this.pointer=t,this.saveSegment(n)}line(t,n){return this.lineTo([this.pointer[0]+t,this.pointer[1]+n])}vLine(t){return this.line(0,t)}hLine(t){return this.line(t,0)}vLineTo(t){return this.lineTo([this.pointer[0],t])}hLineTo(t){return this.lineTo([t,this.pointer[1]])}polarLineTo([t,n]){const r=n*i.DEG2RAD,s=i.polarToCartesian(t,r);return this.lineTo(s)}polarLine(t,n){const r=n*i.DEG2RAD,[s,o]=i.polarToCartesian(t,r);return this.line(s,o)}tangentLine(t){const n=this.pendingSegments.at(-1);if(!n)throw new Error("You need a previous segment to sketch a tangent line");const[r,s]=n.tangentAtLastPoint;return this.line(r*t,s*t)}threePointsArcTo(t,n){return this.saveSegment(i.threePointsArc(this.pointer,n,t)),this.pointer=t,this}threePointsArc(t,n,r,s){const[o,a]=this.pointer;return this.threePointsArcTo([o+t,a+n],[o+r,a+s])}sagittaArcTo(t,n){if(!n)return this.lineTo(t);const r=new i.Line(this.pointer,t),s=i.perpendicular(r.tangentAtFirstPoint),o=i.add(r.midPoint,i.scalarMultiply(s,n));return this.threePointsArcTo(t,o)}sagittaArc(t,n,r){return this.sagittaArcTo([t+this.pointer[0],n+this.pointer[1]],r)}vSagittaArc(t,n){return this.sagittaArc(0,t,n)}hSagittaArc(t,n){return this.sagittaArc(t,0,n)}bulgeArcTo(t,n){if(!n)return this.lineTo(t);const r=i.distance(this.pointer,t)/2,s=-n*r;return this.sagittaArcTo(t,s)}bulgeArc(t,n,r){return this.bulgeArcTo([t+this.pointer[0],n+this.pointer[1]],r)}vBulgeArc(t,n){return this.bulgeArc(0,t,n)}hBulgeArc(t,n){return this.bulgeArc(t,0,n)}tangentArcTo(t,n){const r=this.pendingSegments.at(-1);if(!r)throw new Error("You need a previous curve to sketch a tangent arc");return this.saveSegment(i.tangentArc(this.pointer,t,n??r.tangentAtLastPoint)),this.pointer=t,this}tangentArc(t,n,r){const[s,o]=this.pointer;return this.tangentArcTo([t+s,n+o],r)}ellipseTo(t,n,r,s,o,a){return this.saveSegment(i.svgEllipse(this.pointer,t,n,r,s,o,a)),this.pointer=t,this}ellipse(t,n,r,s,o,a,c){return this.ellipseTo([t+this.pointer[0],n+this.pointer[1]],r,s,o,a,c)}halfEllipseTo(t,n){const[r,s]=i.cartesianToPolar(i.subtract(t,this.pointer));return this.ellipseTo(t,r/2,Math.abs(n),s*i.RAD2DEG,!0,n>0)}halfEllipse(t,n,r){return this.halfEllipseTo([t+this.pointer[0],n+this.pointer[1]],r)}cubicBezierCurveTo(t,n,r){return this.saveSegment(new i.CubicBezier(this.pointer,t,n,r)),this.pointer=t,this}quadraticBezierCurveTo(t,n){return this.saveSegment(new i.QuadraticBezier(this.pointer,t,n)),this.pointer=t,this}smoothCurveTo(t,n){const{endTangent:r,startTangent:s,startFactor:o,endFactor:a}=I(n),c=this.pendingSegments.length?this.pendingSegments[this.pendingSegments.length-1]:null,l=i.distance(this.pointer,t)/3;let h;s?h=s:c?h=c.tangentAtLastPoint:h=[1,0],h=i.normalize(h);const p=[this.pointer[0]+h[0]*o*l,this.pointer[1]+h[1]*o*l];let u=r;u=i.normalize(u);const g=[t[0]-u[0]*a*l,t[1]-u[1]*a*l];return this.cubicBezierCurveTo(t,p,g)}smoothCurve(t,n,r){return this.smoothCurveTo([t+this.pointer[0],n+this.pointer[1]],r)}customCorner(t,n="fillet"){if(!this.pendingSegments.length)throw new Error("You need a segment defined to fillet the angle");return t?(this._nextCorner={mode:n,radius:t},this):this}_customCornerLastWithFirst(t,n="fillet"){if(!t)return;const r=this.pendingSegments.pop(),s=this.pendingSegments.shift();if(!r||!s)throw new Error("Not enough curves to close and fillet");const o=n==="chamfer"?S:A;this.pendingSegments.push(...o(r,s,t))}close(t=!1){if(!this.pendingSegments.length)throw new Error("No segments to close");const n=this.pendingSegments[0],r=this.pendingSegments.at(-1);return i.sameVector(n.firstPoint,r.lastPoint)||this.lineTo(n.firstPoint),this._nextCorner!==null&&(this._customCornerLastWithFirst(this._nextCorner.radius,this._nextCorner.mode),this._nextCorner=null),E(this.pendingSegments,{ignoreChecks:t})}closeWithMirror(t=!1){if(!this.pendingSegments.length)throw new Error("No segments to close");const n=this.pendingSegments[0],r=this.pendingSegments.at(-1),s=i.subtract(r.lastPoint,n.firstPoint),o=new i.TransformationMatrix().mirrorLine(s,n.firstPoint),a=this.pendingSegments.map(c=>c.transform(o).reverse());return a.reverse(),E([...this.pendingSegments,...a],{ignoreChecks:t})}asStrand(){return new d.Strand([...this.pendingSegments])}get isClosed(){var t;return i.sameVector(this.pointer,(t=this.pendingSegments[0])==null?void 0:t.firstPoint)}}function R(e=[0,0]){return new v(e)}exports.DegenerateSegment=m;exports.DrawingPen=v;exports.draw=R;exports.filletSegments=A;exports.offsetSegment=T;
2
+ //# sourceMappingURL=draw-BmJ8wIc9.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draw-BmJ8wIc9.cjs","sources":["../src/algorithms/intersections/fullLinesIntersection.ts","../src/algorithms/offsets/offsetSegment.ts","../src/algorithms/filletSegments.ts","../src/draw.ts"],"sourcesContent":["import { Vector } from \"../../definitions\";\nimport {\n add,\n crossProduct,\n scalarMultiply,\n subtract,\n} from \"../../vectorOperations\";\n\n/**\n * Returns the intersection point between two full lines\n *\n * Note that collinear lines are not considered to intersect at all.\n *\n * Lines are represented by a vector V with **unit length** and a point on the line.\n *\n */\nexport const fullLineIntersection = (\n line1: { V: Vector; firstPoint: Vector; precision: number },\n line2: { V: Vector; firstPoint: Vector; precision: number },\n precision?: number,\n): \"parallel\" | Vector => {\n const V1xV2 = crossProduct(line1.V, line2.V);\n\n /*\n const xLength = squareLength(line1.V);\n const yLength = squareLength(line2.V);\n */\n\n const squarePrecision = precision\n ? precision * precision\n : line1.precision * line2.precision;\n\n if (V1xV2 * V1xV2 < squarePrecision) {\n return \"parallel\";\n }\n\n const diffPoint = subtract(line2.firstPoint, line1.firstPoint);\n const intersectionParam = crossProduct(diffPoint, line2.V) / V1xV2;\n\n return add(line1.firstPoint, scalarMultiply(line1.V, intersectionParam));\n};\n","import { Line } from \"../../models/segments/Line.js\";\nimport { Arc } from \"../../models/segments/Arc.js\";\nimport { Segment } from \"../../models/segments/Segment.js\";\nimport {\n add,\n distance,\n dotProduct,\n perpendicular,\n scalarMultiply,\n subtract,\n} from \"../../vectorOperations\";\nimport { Vector } from \"../../definitions.js\";\nimport { CubicBezier, QuadraticBezier } from \"../../models/exports.js\";\nimport { fullLineIntersection } from \"../intersections/fullLinesIntersection.js\";\nimport {\n SafeCubicBezier,\n SafeQuadraticBezier,\n} from \"../conversions/bezierToSafeBezier.js\";\n\nconst DEGENERATE_SEGMENT_INSTANCE = Symbol.for(\n \"pantograph:DegenerateSegment\",\n);\n\nexport class DegenerateSegment {\n static isInstance(value: unknown): value is DegenerateSegment {\n return (\n !!value &&\n (value as { [DEGENERATE_SEGMENT_INSTANCE]?: boolean })[\n DEGENERATE_SEGMENT_INSTANCE\n ] === true\n );\n }\n\n constructor(\n public readonly firstPoint: Vector,\n public readonly lastPoint: Vector,\n ) {\n Object.defineProperty(this, DEGENERATE_SEGMENT_INSTANCE, { value: true });\n }\n}\n\nexport type OffsettableSegment =\n | Line\n | Arc\n | SafeCubicBezier\n | SafeQuadraticBezier;\n\nexport function offsetSegment(\n segment: OffsettableSegment,\n offset: number,\n): Segment | DegenerateSegment {\n if (Line.isInstance(segment)) {\n return offsetLine(segment, offset);\n }\n\n if (Arc.isInstance(segment)) {\n return offsetArc(segment, offset);\n }\n\n if (QuadraticBezier.isInstance(segment) || CubicBezier.isInstance(segment)) {\n return offsetSafeBezier(segment, offset);\n }\n\n throw new Error(\"Not implemented\");\n}\n\nexport function offsetLine(line: Line, offset: number): Line {\n const { firstPoint, lastPoint } = line;\n\n const normal = line.normalVector;\n return new Line(\n add(firstPoint, scalarMultiply(normal, offset)),\n add(lastPoint, scalarMultiply(normal, offset)),\n );\n}\n\nexport function offsetArc(arc: Arc, offset: number): Arc | DegenerateSegment {\n const offsetStartPoint = add(\n arc.firstPoint,\n scalarMultiply(perpendicular(arc.tangentAtFirstPoint), offset),\n );\n const offsetEndPoint = add(\n arc.lastPoint,\n scalarMultiply(perpendicular(arc.tangentAtLastPoint), offset),\n );\n\n const orientedOffset = offset * (arc.clockwise ? 1 : -1);\n const newRadius = arc.radius + orientedOffset;\n if (newRadius < arc.precision) {\n return new DegenerateSegment(offsetStartPoint, offsetEndPoint);\n }\n\n return new Arc(offsetStartPoint, offsetEndPoint, arc.center, arc.clockwise);\n}\n\nfunction computeControlPointOffset(\n origin: Vector,\n controlPoint: Vector,\n tangent: Vector,\n newPoint: Vector,\n precision: number,\n): Vector {\n const newControlPoint = fullLineIntersection(\n {\n V: tangent,\n firstPoint: newPoint,\n precision: precision,\n },\n {\n V: subtract(controlPoint, origin),\n firstPoint: origin,\n precision: precision,\n },\n );\n\n if (newControlPoint === \"parallel\") {\n throw new Error(\n \"Parallel lines not expected in safe bezier offset control point calculation\",\n );\n }\n\n return newControlPoint;\n}\n\nexport function offsetSafeBezier(\n curve: SafeQuadraticBezier | SafeCubicBezier,\n offset: number,\n): typeof curve | DegenerateSegment {\n const { firstPoint, lastPoint, normalAtFirstPoint, normalAtLastPoint } =\n curve;\n\n const origin = fullLineIntersection(\n { V: normalAtFirstPoint, firstPoint, precision: curve.precision },\n { V: normalAtLastPoint, firstPoint: lastPoint, precision: curve.precision },\n );\n\n const offsetStartPoint = add(\n firstPoint,\n scalarMultiply(normalAtFirstPoint, offset),\n );\n const offsetEndPoint = add(\n lastPoint,\n scalarMultiply(normalAtLastPoint, offset),\n );\n\n if (origin === \"parallel\") {\n throw new Error(\"Parallel lines not expected in safe bezier offset\");\n }\n\n const offsetTowardsOrigin =\n dotProduct(subtract(origin, firstPoint), normalAtFirstPoint) * offset > 0;\n if (offsetTowardsOrigin) {\n const minDistance = Math.min(\n distance(firstPoint, origin),\n distance(lastPoint, origin),\n );\n\n if (minDistance < offset) {\n return new DegenerateSegment(offsetStartPoint, offsetEndPoint);\n }\n }\n\n if (QuadraticBezier.isInstance(curve)) {\n const newControlPoint = computeControlPointOffset(\n origin,\n curve.controlPoint,\n curve.tangentAtFirstPoint,\n offsetStartPoint,\n curve.precision,\n );\n\n return new QuadraticBezier(\n offsetStartPoint,\n offsetEndPoint,\n newControlPoint,\n );\n }\n\n const newControlPoint1 = computeControlPointOffset(\n origin,\n curve.firstControlPoint,\n curve.tangentAtFirstPoint,\n offsetStartPoint,\n curve.precision,\n );\n const newControlPoint2 = computeControlPointOffset(\n origin,\n curve.lastControlPoint,\n curve.tangentAtLastPoint,\n offsetEndPoint,\n curve.precision,\n );\n\n return new CubicBezier(\n offsetStartPoint,\n offsetEndPoint,\n newControlPoint1,\n newControlPoint2,\n );\n}\n","import { Vector } from \"../definitions.js\";\nimport { Line } from \"../models/segments/Line.js\";\nimport { tangentArc } from \"../models/segments/Arc.js\";\nimport type { Segment } from \"../models/segments/Segment.js\";\nimport {\n add,\n crossProduct,\n perpendicular,\n perpendicularClockwise,\n scalarMultiply,\n} from \"../vectorOperations\";\nimport { findIntersections } from \"./intersections\";\nimport { DegenerateSegment, offsetSegment } from \"./offsets/offsetSegment.js\";\nimport { exportJSON } from \"../main.js\";\n\nfunction removeCorner(\n firstSegment: Segment,\n secondSegment: Segment,\n radius: number,\n) {\n const sinAngle = crossProduct(\n firstSegment.tangentAtLastPoint,\n secondSegment.tangentAtFirstPoint,\n );\n\n // This cover the case when the segments are colinear\n if (Math.abs(sinAngle) < 1e-10) return null;\n\n const orientationCorrection = sinAngle > 0 ? 1 : -1;\n const offset = Math.abs(radius) * orientationCorrection;\n\n const firstOffset = offsetSegment(firstSegment, offset);\n const secondOffset = offsetSegment(secondSegment, offset);\n\n if (\n DegenerateSegment.isInstance(firstOffset) ||\n DegenerateSegment.isInstance(secondOffset)\n ) {\n return null;\n }\n\n let potentialCenter: Vector | undefined;\n try {\n const intersections = findIntersections(firstOffset, secondOffset, 1e-9);\n\n // We need to work on the case where there are more than one intersections\n potentialCenter = intersections.at(-1);\n } catch (e) {\n return null;\n }\n\n if (!potentialCenter) {\n return null;\n }\n const center = potentialCenter;\n\n const splitForFillet = (segment: Segment, offsetSegment: Segment) => {\n const tgt = offsetSegment.tangentAt(center);\n const normal = perpendicularClockwise(tgt);\n const splitPoint = add(center, scalarMultiply(normal, offset));\n return segment.splitAt(splitPoint);\n };\n\n const [first] = splitForFillet(firstSegment, firstOffset);\n const [, second] = splitForFillet(secondSegment, secondOffset);\n\n return { first, second, center };\n}\n\nexport function filletSegments(\n firstSegment: Segment,\n secondSegment: Segment,\n radius: number,\n) {\n const cornerRemoved = removeCorner(firstSegment, secondSegment, radius);\n if (!cornerRemoved) {\n console.warn(\n \"Cannot fillet between segments\",\n firstSegment.repr,\n secondSegment.repr,\n );\n return [firstSegment, secondSegment];\n }\n\n const { first, second } = cornerRemoved;\n\n return [\n first,\n tangentArc(first.lastPoint, second.firstPoint, first.tangentAtLastPoint),\n second,\n ];\n}\n\nexport function chamferSegments(\n firstSegment: Segment,\n secondSegment: Segment,\n radius: number,\n) {\n const cornerRemoved = removeCorner(firstSegment, secondSegment, radius);\n if (!cornerRemoved) {\n console.warn(\n \"Cannot chamfer between segments\",\n firstSegment.repr,\n secondSegment.repr,\n );\n return [firstSegment, secondSegment];\n }\n\n const { first, second } = cornerRemoved;\n\n return [first, new Line(first.lastPoint, second.firstPoint), second];\n}\n","import {\n chamferSegments,\n filletSegments,\n} from \"./algorithms/filletSegments.js\";\nimport { Vector } from \"./definitions.js\";\nimport { Strand } from \"./models/Strand.js\";\nimport { Diagram } from \"./models/Diagram.js\";\nimport { Figure } from \"./models/Figure.js\";\nimport { Loop } from \"./models/Loop.js\";\nimport { tangentArc, threePointsArc } from \"./models/segments/Arc.js\";\nimport { Line } from \"./models/segments/Line.js\";\nimport { Segment } from \"./models/segments/Segment.js\";\nimport { TransformationMatrix } from \"./models/TransformationMatrix.js\";\nimport {\n polarToCartesian,\n DEG2RAD,\n subtract,\n sameVector,\n perpendicular,\n add,\n scalarMultiply,\n distance,\n cartesianToPolar,\n RAD2DEG,\n normalize,\n} from \"./vectorOperations.js\";\nimport { svgEllipse } from \"./models/segments/EllipseArc.js\";\nimport { QuadraticBezier } from \"./models/segments/QuadraticBezier.js\";\nimport { CubicBezier } from \"./models/segments/CubicBezier.js\";\n\nconst parseSmoothCurveConfig = (\n config?:\n | number\n | Vector\n | {\n endTangent?: number | Vector;\n startTangent?: number | Vector;\n startFactor?: number;\n endFactor?: number;\n },\n) => {\n let conf: {\n endTangent: number | Vector;\n startFactor?: number;\n endFactor?: number;\n startTangent?: number | Vector;\n };\n\n if (!config) conf = { endTangent: [1, 0] };\n else if (\n typeof config === \"number\" ||\n (Array.isArray(config) && config.length === 2)\n ) {\n conf = { endTangent: config };\n } else {\n conf = { endTangent: 0, ...config };\n }\n const {\n endTangent: endTgt,\n startFactor = 1,\n endFactor = 1,\n startTangent: startTgt,\n } = conf;\n\n let endTangent: Vector;\n if (typeof endTgt === \"number\") {\n endTangent = polarToCartesian(1, endTgt * DEG2RAD);\n } else {\n endTangent = endTgt;\n }\n\n let startTangent: Vector | undefined;\n if (typeof startTgt === \"number\") {\n startTangent = polarToCartesian(1, startTgt * DEG2RAD);\n } else {\n startTangent = startTgt;\n }\n\n return { endTangent, startFactor, endFactor, startTangent };\n};\n\nfunction loopySegmentsToDiagram(\n segments: Segment[],\n { ignoreChecks = false } = {},\n) {\n // Here we will need to do our best to fix cases where the drawing is\n // broken in some way (i.e. self-intersecting loops)\n\n return new Diagram([new Figure(new Loop([...segments], { ignoreChecks }))]);\n}\n\nexport class DrawingPen {\n pointer: Vector;\n protected firstPoint: Vector;\n protected pendingSegments: Segment[];\n\n protected _nextCorner: { radius: number; mode: \"fillet\" | \"chamfer\" } | null;\n\n constructor(origin: Vector = [0, 0]) {\n this.pointer = origin;\n this.firstPoint = origin;\n\n this.pendingSegments = [];\n this._nextCorner = null;\n }\n\n movePointerTo(point: Vector): this {\n if (this.pendingSegments.length)\n throw new Error(\n \"You can only move the pointer if there is no segment defined\",\n );\n\n this.pointer = point;\n this.firstPoint = point;\n return this;\n }\n\n protected saveSegment(segment: Segment) {\n if (sameVector(segment.firstPoint, segment.lastPoint)) {\n throw new Error(`Segment has no length, ${segment.repr}`);\n }\n\n if (!this._nextCorner) {\n this.pendingSegments.push(segment);\n return this;\n }\n\n const previousSegment = this.pendingSegments.pop();\n if (!previousSegment) throw new Error(\"bug in the custom corner algorithm\");\n\n const makeCorner =\n this._nextCorner.mode === \"chamfer\" ? chamferSegments : filletSegments;\n\n this.pendingSegments.push(\n ...makeCorner(previousSegment, segment, this._nextCorner.radius),\n );\n this._nextCorner = null;\n return this;\n }\n\n lineTo(point: Vector): this {\n const segment = new Line(this.pointer, point);\n this.pointer = point;\n return this.saveSegment(segment);\n }\n\n line(xDist: number, yDist: number): this {\n return this.lineTo([this.pointer[0] + xDist, this.pointer[1] + yDist]);\n }\n\n vLine(distance: number): this {\n return this.line(0, distance);\n }\n\n hLine(distance: number): this {\n return this.line(distance, 0);\n }\n\n vLineTo(yPos: number): this {\n return this.lineTo([this.pointer[0], yPos]);\n }\n\n hLineTo(xPos: number): this {\n return this.lineTo([xPos, this.pointer[1]]);\n }\n\n polarLineTo([r, theta]: Vector): this {\n const angleInRads = theta * DEG2RAD;\n const point = polarToCartesian(r, angleInRads);\n return this.lineTo(point);\n }\n\n polarLine(distance: number, angle: number): this {\n const angleInRads = angle * DEG2RAD;\n const [x, y] = polarToCartesian(distance, angleInRads);\n return this.line(x, y);\n }\n\n tangentLine(distance: number): this {\n const previousCurve = this.pendingSegments.at(-1);\n\n if (!previousCurve)\n throw new Error(\"You need a previous segment to sketch a tangent line\");\n\n const [xDir, yDir] = previousCurve.tangentAtLastPoint;\n return this.line(xDir * distance, yDir * distance);\n }\n\n threePointsArcTo(end: Vector, midPoint: Vector): this {\n this.saveSegment(threePointsArc(this.pointer, midPoint, end));\n this.pointer = end;\n return this;\n }\n\n threePointsArc(\n xDist: number,\n yDist: number,\n viaXDist: number,\n viaYDist: number,\n ): this {\n const [x0, y0] = this.pointer;\n return this.threePointsArcTo(\n [x0 + xDist, y0 + yDist],\n [x0 + viaXDist, y0 + viaYDist],\n );\n }\n\n sagittaArcTo(end: Vector, sagitta: number): this {\n if (!sagitta) return this.lineTo(end);\n const chord = new Line(this.pointer, end);\n const norm = perpendicular(chord.tangentAtFirstPoint);\n\n const sagPoint: Vector = add(chord.midPoint, scalarMultiply(norm, sagitta));\n\n return this.threePointsArcTo(end, sagPoint);\n }\n\n sagittaArc(xDist: number, yDist: number, sagitta: number): this {\n return this.sagittaArcTo(\n [xDist + this.pointer[0], yDist + this.pointer[1]],\n sagitta,\n );\n }\n\n vSagittaArc(distance: number, sagitta: number): this {\n return this.sagittaArc(0, distance, sagitta);\n }\n\n hSagittaArc(distance: number, sagitta: number): this {\n return this.sagittaArc(distance, 0, sagitta);\n }\n\n bulgeArcTo(end: Vector, bulge: number): this {\n if (!bulge) return this.lineTo(end);\n const halfChord = distance(this.pointer, end) / 2;\n const bulgeAsSagitta = -bulge * halfChord;\n\n return this.sagittaArcTo(end, bulgeAsSagitta);\n }\n\n bulgeArc(xDist: number, yDist: number, bulge: number): this {\n return this.bulgeArcTo(\n [xDist + this.pointer[0], yDist + this.pointer[1]],\n bulge,\n );\n }\n\n vBulgeArc(distance: number, bulge: number): this {\n return this.bulgeArc(0, distance, bulge);\n }\n\n hBulgeArc(distance: number, bulge: number): this {\n return this.bulgeArc(distance, 0, bulge);\n }\n\n tangentArcTo(end: Vector, tangentAtStart?: Vector): this {\n const previousCurve = this.pendingSegments.at(-1);\n\n if (!previousCurve)\n throw new Error(\"You need a previous curve to sketch a tangent arc\");\n\n this.saveSegment(\n tangentArc(\n this.pointer,\n end,\n tangentAtStart ?? previousCurve.tangentAtLastPoint,\n ),\n );\n\n this.pointer = end;\n return this;\n }\n\n tangentArc(xDist: number, yDist: number, tangentAtStart?: Vector): this {\n const [x0, y0] = this.pointer;\n return this.tangentArcTo([xDist + x0, yDist + y0], tangentAtStart);\n }\n\n ellipseTo(\n end: Vector,\n r0: number,\n r1: number,\n xAxisRotation: number,\n longArc: boolean,\n sweepFlag: boolean,\n ): this {\n this.saveSegment(\n svgEllipse(this.pointer, end, r0, r1, xAxisRotation, longArc, sweepFlag),\n );\n this.pointer = end;\n return this;\n }\n\n ellipse(\n xDist: number,\n yDist: number,\n r0: number,\n r1: number,\n xAxisRotation: number,\n longArc: boolean,\n sweepFlag: boolean,\n ): this {\n return this.ellipseTo(\n [xDist + this.pointer[0], yDist + this.pointer[1]],\n r0,\n r1,\n xAxisRotation,\n longArc,\n sweepFlag,\n );\n }\n\n halfEllipseTo(end: Vector, sagitta: number): this {\n const [distance, angle] = cartesianToPolar(subtract(end, this.pointer));\n\n return this.ellipseTo(\n end,\n distance / 2,\n Math.abs(sagitta),\n angle * RAD2DEG,\n true,\n sagitta > 0,\n );\n }\n\n halfEllipse(xDist: number, yDist: number, sagitta: number): this {\n return this.halfEllipseTo(\n [xDist + this.pointer[0], yDist + this.pointer[1]],\n sagitta,\n );\n }\n\n cubicBezierCurveTo(\n end: Vector,\n startControlPoint: Vector,\n endControlPoint: Vector,\n ): this {\n this.saveSegment(\n new CubicBezier(this.pointer, end, startControlPoint, endControlPoint),\n );\n this.pointer = end;\n return this;\n }\n\n quadraticBezierCurveTo(end: Vector, controlPoint: Vector): this {\n this.saveSegment(new QuadraticBezier(this.pointer, end, controlPoint));\n this.pointer = end;\n return this;\n }\n\n smoothCurveTo(\n end: Vector,\n config?:\n | number\n | Vector\n | {\n endTangent?: number | Vector;\n startTangent?: number | Vector;\n startFactor?: number;\n endFactor?: number;\n },\n ): this {\n const { endTangent, startTangent, startFactor, endFactor } =\n parseSmoothCurveConfig(config);\n\n const previousCurve = this.pendingSegments.length\n ? this.pendingSegments[this.pendingSegments.length - 1]\n : null;\n\n const defaultDistance = distance(this.pointer, end) / 3;\n\n let startPoleDirection: Vector;\n if (startTangent) {\n startPoleDirection = startTangent;\n } else if (!previousCurve) {\n startPoleDirection = [1, 0];\n } else {\n startPoleDirection = previousCurve.tangentAtLastPoint;\n }\n\n startPoleDirection = normalize(startPoleDirection);\n const startControl: Vector = [\n this.pointer[0] + startPoleDirection[0] * startFactor * defaultDistance,\n this.pointer[1] + startPoleDirection[1] * startFactor * defaultDistance,\n ];\n\n let endPoleDirection = endTangent;\n\n endPoleDirection = normalize(endPoleDirection);\n const endControl: Vector = [\n end[0] - endPoleDirection[0] * endFactor * defaultDistance,\n end[1] - endPoleDirection[1] * endFactor * defaultDistance,\n ];\n\n return this.cubicBezierCurveTo(end, startControl, endControl);\n }\n\n smoothCurve(\n xDist: number,\n yDist: number,\n config?:\n | number\n | Vector\n | {\n endTangent?: number | Vector;\n startTangent?: number | Vector;\n startFactor?: number;\n endFactor?: number;\n },\n ) {\n return this.smoothCurveTo(\n [xDist + this.pointer[0], yDist + this.pointer[1]],\n config,\n );\n }\n\n customCorner(radius: number, mode: \"fillet\" | \"chamfer\" = \"fillet\") {\n if (!this.pendingSegments.length)\n throw new Error(\"You need a segment defined to fillet the angle\");\n\n if (!radius) return this;\n\n this._nextCorner = { mode, radius };\n return this;\n }\n\n protected _customCornerLastWithFirst(\n radius: number,\n mode: \"fillet\" | \"chamfer\" = \"fillet\",\n ) {\n if (!radius) return;\n\n const lastSegment = this.pendingSegments.pop();\n const firstSegment = this.pendingSegments.shift();\n\n if (!lastSegment || !firstSegment)\n throw new Error(\"Not enough curves to close and fillet\");\n\n const makeCorner = mode === \"chamfer\" ? chamferSegments : filletSegments;\n\n this.pendingSegments.push(...makeCorner(lastSegment, firstSegment, radius));\n }\n\n close(ignoreChecks = false): Diagram {\n if (!this.pendingSegments.length) throw new Error(\"No segments to close\");\n const firstSegment = this.pendingSegments[0];\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const lastSegment = this.pendingSegments.at(-1)!;\n\n if (!sameVector(firstSegment.firstPoint, lastSegment.lastPoint)) {\n this.lineTo(firstSegment.firstPoint);\n }\n\n if (this._nextCorner !== null) {\n this._customCornerLastWithFirst(\n this._nextCorner.radius,\n this._nextCorner.mode,\n );\n this._nextCorner = null;\n }\n\n return loopySegmentsToDiagram(this.pendingSegments, { ignoreChecks });\n }\n\n closeWithMirror(ignoreChecks = false): Diagram {\n if (!this.pendingSegments.length) throw new Error(\"No segments to close\");\n\n const firstSegment = this.pendingSegments[0];\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const lastSegment = this.pendingSegments.at(-1)!;\n\n const mirrorVector = subtract(\n lastSegment.lastPoint,\n firstSegment.firstPoint,\n );\n const mirrorTranform = new TransformationMatrix().mirrorLine(\n mirrorVector,\n firstSegment.firstPoint,\n );\n\n const mirroredSegments = this.pendingSegments.map((segment) =>\n segment.transform(mirrorTranform).reverse(),\n );\n mirroredSegments.reverse();\n\n return loopySegmentsToDiagram(\n [...this.pendingSegments, ...mirroredSegments],\n { ignoreChecks },\n );\n }\n\n asStrand(): Strand {\n return new Strand([...this.pendingSegments]);\n }\n\n get isClosed(): boolean {\n return sameVector(this.pointer, this.pendingSegments[0]?.firstPoint);\n }\n}\n\nexport function draw(origin: Vector = [0, 0]): DrawingPen {\n return new DrawingPen(origin);\n}\n"],"names":["fullLineIntersection","line1","line2","precision","V1xV2","crossProduct","squarePrecision","diffPoint","subtract","intersectionParam","add","scalarMultiply","DEGENERATE_SEGMENT_INSTANCE","DegenerateSegment","firstPoint","lastPoint","value","offsetSegment","segment","offset","Line","offsetLine","Arc","offsetArc","QuadraticBezier","CubicBezier","offsetSafeBezier","line","normal","arc","offsetStartPoint","perpendicular","offsetEndPoint","orientedOffset","computeControlPointOffset","origin","controlPoint","tangent","newPoint","newControlPoint","curve","normalAtFirstPoint","normalAtLastPoint","dotProduct","distance","newControlPoint1","newControlPoint2","removeCorner","firstSegment","secondSegment","radius","sinAngle","orientationCorrection","firstOffset","secondOffset","potentialCenter","findIntersections","center","splitForFillet","tgt","perpendicularClockwise","splitPoint","first","second","filletSegments","cornerRemoved","tangentArc","chamferSegments","parseSmoothCurveConfig","config","conf","endTgt","startFactor","endFactor","startTgt","endTangent","polarToCartesian","DEG2RAD","startTangent","loopySegmentsToDiagram","segments","ignoreChecks","Diagram","Figure","Loop","DrawingPen","__publicField","point","sameVector","previousSegment","makeCorner","xDist","yDist","yPos","xPos","r","theta","angleInRads","angle","x","y","previousCurve","xDir","yDir","end","midPoint","threePointsArc","viaXDist","viaYDist","x0","y0","sagitta","chord","norm","sagPoint","bulge","halfChord","bulgeAsSagitta","tangentAtStart","r0","r1","xAxisRotation","longArc","sweepFlag","svgEllipse","cartesianToPolar","RAD2DEG","startControlPoint","endControlPoint","defaultDistance","startPoleDirection","normalize","startControl","endPoleDirection","endControl","mode","lastSegment","mirrorVector","mirrorTranform","TransformationMatrix","mirroredSegments","Strand","_a","draw"],"mappings":"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"}
@@ -1,47 +1,52 @@
1
1
  var W = Object.defineProperty;
2
- var q = (e, t, n) => t in e ? W(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
- var m = (e, t, n) => q(e, typeof t != "symbol" ? t + "" : t, n);
4
- import { a as l, s as u, c as x, b as P, L as d, A as R, Q as w, C as D, p as E, d as G, e as T, t as k, f as Q, g as L, h as j, i as $, j as H, R as J, T as K, k as A, n as F, D as C } from "./QuadraticBezier-DCa0WGs0.js";
5
- import { f as U, S as X, D as Z, F as tt, L as nt } from "./models-CFd5lRKc.js";
2
+ var j = (e, t, n) => t in e ? W(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
+ var m = (e, t, n) => j(e, typeof t != "symbol" ? t + "" : t, n);
4
+ import { a as l, s as u, c as b, b as P, L as d, A as z, Q as w, C as D, p as x, d as q, e as T, t as k, f as Q, g as v, h as $, i as H, j as J, R as K, T as U, k as A, n as F, D as S } from "./QuadraticBezier-BeY2TXKH.js";
5
+ import { f as X, S as Z, D as tt, F as nt, L as et } from "./models-BHeLX0dj.js";
6
6
  const B = (e, t, n) => {
7
- const r = x(e.V, t.V), i = e.precision * t.precision;
7
+ const r = b(e.V, t.V), i = e.precision * t.precision;
8
8
  if (r * r < i)
9
9
  return "parallel";
10
- const s = P(t.firstPoint, e.firstPoint), o = x(s, t.V) / r;
10
+ const s = P(t.firstPoint, e.firstPoint), o = b(s, t.V) / r;
11
11
  return l(e.firstPoint, u(e.V, o));
12
- };
13
- class S {
12
+ }, y = Symbol.for(
13
+ "pantograph:DegenerateSegment"
14
+ );
15
+ class C {
14
16
  constructor(t, n) {
15
- this.firstPoint = t, this.lastPoint = n;
17
+ this.firstPoint = t, this.lastPoint = n, Object.defineProperty(this, y, { value: !0 });
18
+ }
19
+ static isInstance(t) {
20
+ return !!t && t[y] === !0;
16
21
  }
17
22
  }
18
- function y(e, t) {
19
- if (e instanceof d)
20
- return et(e, t);
21
- if (e instanceof R)
23
+ function _(e, t) {
24
+ if (d.isInstance(e))
22
25
  return rt(e, t);
23
- if (e instanceof w || e instanceof D)
26
+ if (z.isInstance(e))
24
27
  return it(e, t);
28
+ if (w.isInstance(e) || D.isInstance(e))
29
+ return st(e, t);
25
30
  throw new Error("Not implemented");
26
31
  }
27
- function et(e, t) {
32
+ function rt(e, t) {
28
33
  const { firstPoint: n, lastPoint: r } = e, i = e.normalVector;
29
34
  return new d(
30
35
  l(n, u(i, t)),
31
36
  l(r, u(i, t))
32
37
  );
33
38
  }
34
- function rt(e, t) {
39
+ function it(e, t) {
35
40
  const n = l(
36
41
  e.firstPoint,
37
- u(E(e.tangentAtFirstPoint), t)
42
+ u(x(e.tangentAtFirstPoint), t)
38
43
  ), r = l(
39
44
  e.lastPoint,
40
- u(E(e.tangentAtLastPoint), t)
45
+ u(x(e.tangentAtLastPoint), t)
41
46
  ), i = t * (e.clockwise ? 1 : -1);
42
- return e.radius + i < e.precision ? new S(n, r) : new R(n, r, e.center, e.clockwise);
47
+ return e.radius + i < e.precision ? new C(n, r) : new z(n, r, e.center, e.clockwise);
43
48
  }
44
- function b(e, t, n, r, i) {
49
+ function L(e, t, n, r, i) {
45
50
  const s = B(
46
51
  {
47
52
  V: n,
@@ -60,26 +65,26 @@ function b(e, t, n, r, i) {
60
65
  );
61
66
  return s;
62
67
  }
63
- function it(e, t) {
68
+ function st(e, t) {
64
69
  const { firstPoint: n, lastPoint: r, normalAtFirstPoint: i, normalAtLastPoint: s } = e, o = B(
65
70
  { V: i, firstPoint: n, precision: e.precision },
66
71
  { V: s, firstPoint: r, precision: e.precision }
67
72
  ), a = l(
68
73
  n,
69
74
  u(i, t)
70
- ), h = l(
75
+ ), c = l(
71
76
  r,
72
77
  u(s, t)
73
78
  );
74
79
  if (o === "parallel")
75
80
  throw new Error("Parallel lines not expected in safe bezier offset");
76
- if (G(P(o, n), i) * t > 0 && Math.min(
81
+ if (q(P(o, n), i) * t > 0 && Math.min(
77
82
  T(n, o),
78
83
  T(r, o)
79
84
  ) < t)
80
- return new S(a, h);
81
- if (e instanceof w) {
82
- const g = b(
85
+ return new C(a, c);
86
+ if (w.isInstance(e)) {
87
+ const f = L(
83
88
  o,
84
89
  e.controlPoint,
85
90
  e.tangentAtFirstPoint,
@@ -88,54 +93,54 @@ function it(e, t) {
88
93
  );
89
94
  return new w(
90
95
  a,
91
- h,
92
- g
96
+ c,
97
+ f
93
98
  );
94
99
  }
95
- const p = b(
100
+ const g = L(
96
101
  o,
97
102
  e.firstControlPoint,
98
103
  e.tangentAtFirstPoint,
99
104
  a,
100
105
  e.precision
101
- ), f = b(
106
+ ), p = L(
102
107
  o,
103
108
  e.lastControlPoint,
104
109
  e.tangentAtLastPoint,
105
- h,
110
+ c,
106
111
  e.precision
107
112
  );
108
113
  return new D(
109
114
  a,
110
- h,
111
- p,
112
- f
115
+ c,
116
+ g,
117
+ p
113
118
  );
114
119
  }
115
120
  function M(e, t, n) {
116
- const r = x(
121
+ const r = b(
117
122
  e.tangentAtLastPoint,
118
123
  t.tangentAtFirstPoint
119
124
  );
120
125
  if (Math.abs(r) < 1e-10) return null;
121
- const i = r > 0 ? 1 : -1, s = Math.abs(n) * i, o = y(e, s), a = y(t, s);
122
- if (o instanceof S || a instanceof S)
126
+ const i = r > 0 ? 1 : -1, s = Math.abs(n) * i, o = _(e, s), a = _(t, s);
127
+ if (C.isInstance(o) || C.isInstance(a))
123
128
  return null;
124
- let h;
129
+ let c;
125
130
  try {
126
- h = U(o, a, 1e-9).at(-1);
131
+ c = X(o, a, 1e-9).at(-1);
127
132
  } catch {
128
133
  return null;
129
134
  }
130
- if (!h)
135
+ if (!c)
131
136
  return null;
132
- const c = h, p = (v, O) => {
133
- const I = O.tangentAt(c), N = Q(I), Y = l(c, u(N, s));
134
- return v.splitAt(Y);
135
- }, [f] = p(e, o), [, g] = p(t, a);
136
- return { first: f, second: g, center: c };
137
+ const h = c, g = (E, N) => {
138
+ const O = N.tangentAt(h), G = Q(O), Y = l(h, u(G, s));
139
+ return E.splitAt(Y);
140
+ }, [p] = g(e, o), [, f] = g(t, a);
141
+ return { first: p, second: f, center: h };
137
142
  }
138
- function V(e, t, n) {
143
+ function I(e, t, n) {
139
144
  const r = M(e, t, n);
140
145
  if (!r)
141
146
  return console.warn(
@@ -150,7 +155,7 @@ function V(e, t, n) {
150
155
  s
151
156
  ];
152
157
  }
153
- function _(e, t, n) {
158
+ function V(e, t, n) {
154
159
  const r = M(e, t, n);
155
160
  if (!r)
156
161
  return console.warn(
@@ -161,7 +166,7 @@ function _(e, t, n) {
161
166
  const { first: i, second: s } = r;
162
167
  return [i, new d(i.lastPoint, s.firstPoint), s];
163
168
  }
164
- const st = (e) => {
169
+ const ot = (e) => {
165
170
  let t;
166
171
  e ? typeof e == "number" || Array.isArray(e) && e.length === 2 ? t = { endTangent: e } : t = { endTangent: 0, ...e } : t = { endTangent: [1, 0] };
167
172
  const {
@@ -171,14 +176,14 @@ const st = (e) => {
171
176
  startTangent: s
172
177
  } = t;
173
178
  let o;
174
- typeof n == "number" ? o = A(1, n * C) : o = n;
179
+ typeof n == "number" ? o = A(1, n * S) : o = n;
175
180
  let a;
176
- return typeof s == "number" ? a = A(1, s * C) : a = s, { endTangent: o, startFactor: r, endFactor: i, startTangent: a };
181
+ return typeof s == "number" ? a = A(1, s * S) : a = s, { endTangent: o, startFactor: r, endFactor: i, startTangent: a };
177
182
  };
178
- function z(e, { ignoreChecks: t = !1 } = {}) {
179
- return new Z([new tt(new nt([...e], { ignoreChecks: t }))]);
183
+ function R(e, { ignoreChecks: t = !1 } = {}) {
184
+ return new tt([new nt(new et([...e], { ignoreChecks: t }))]);
180
185
  }
181
- class ot {
186
+ class at {
182
187
  constructor(t = [0, 0]) {
183
188
  m(this, "pointer");
184
189
  m(this, "firstPoint");
@@ -194,13 +199,13 @@ class ot {
194
199
  return this.pointer = t, this.firstPoint = t, this;
195
200
  }
196
201
  saveSegment(t) {
197
- if (L(t.firstPoint, t.lastPoint))
202
+ if (v(t.firstPoint, t.lastPoint))
198
203
  throw new Error(`Segment has no length, ${t.repr}`);
199
204
  if (!this._nextCorner)
200
205
  return this.pendingSegments.push(t), this;
201
206
  const n = this.pendingSegments.pop();
202
207
  if (!n) throw new Error("bug in the custom corner algorithm");
203
- const r = this._nextCorner.mode === "chamfer" ? _ : V;
208
+ const r = this._nextCorner.mode === "chamfer" ? V : I;
204
209
  return this.pendingSegments.push(
205
210
  ...r(n, t, this._nextCorner.radius)
206
211
  ), this._nextCorner = null, this;
@@ -225,11 +230,11 @@ class ot {
225
230
  return this.lineTo([t, this.pointer[1]]);
226
231
  }
227
232
  polarLineTo([t, n]) {
228
- const r = n * C, i = A(t, r);
233
+ const r = n * S, i = A(t, r);
229
234
  return this.lineTo(i);
230
235
  }
231
236
  polarLine(t, n) {
232
- const r = n * C, [i, s] = A(t, r);
237
+ const r = n * S, [i, s] = A(t, r);
233
238
  return this.line(i, s);
234
239
  }
235
240
  tangentLine(t) {
@@ -240,7 +245,7 @@ class ot {
240
245
  return this.line(r * t, i * t);
241
246
  }
242
247
  threePointsArcTo(t, n) {
243
- return this.saveSegment(j(this.pointer, n, t)), this.pointer = t, this;
248
+ return this.saveSegment($(this.pointer, n, t)), this.pointer = t, this;
244
249
  }
245
250
  threePointsArc(t, n, r, i) {
246
251
  const [s, o] = this.pointer;
@@ -251,7 +256,7 @@ class ot {
251
256
  }
252
257
  sagittaArcTo(t, n) {
253
258
  if (!n) return this.lineTo(t);
254
- const r = new d(this.pointer, t), i = E(r.tangentAtFirstPoint), s = l(r.midPoint, u(i, n));
259
+ const r = new d(this.pointer, t), i = x(r.tangentAtFirstPoint), s = l(r.midPoint, u(i, n));
255
260
  return this.threePointsArcTo(t, s);
256
261
  }
257
262
  sagittaArc(t, n, r) {
@@ -301,7 +306,7 @@ class ot {
301
306
  }
302
307
  ellipseTo(t, n, r, i, s, o) {
303
308
  return this.saveSegment(
304
- $(this.pointer, t, n, r, i, s, o)
309
+ H(this.pointer, t, n, r, i, s, o)
305
310
  ), this.pointer = t, this;
306
311
  }
307
312
  ellipse(t, n, r, i, s, o, a) {
@@ -315,12 +320,12 @@ class ot {
315
320
  );
316
321
  }
317
322
  halfEllipseTo(t, n) {
318
- const [r, i] = H(P(t, this.pointer));
323
+ const [r, i] = J(P(t, this.pointer));
319
324
  return this.ellipseTo(
320
325
  t,
321
326
  r / 2,
322
327
  Math.abs(n),
323
- i * J,
328
+ i * K,
324
329
  !0,
325
330
  n > 0
326
331
  );
@@ -340,20 +345,20 @@ class ot {
340
345
  return this.saveSegment(new w(this.pointer, t, n)), this.pointer = t, this;
341
346
  }
342
347
  smoothCurveTo(t, n) {
343
- const { endTangent: r, startTangent: i, startFactor: s, endFactor: o } = st(n), a = this.pendingSegments.length ? this.pendingSegments[this.pendingSegments.length - 1] : null, h = T(this.pointer, t) / 3;
344
- let c;
345
- i ? c = i : a ? c = a.tangentAtLastPoint : c = [1, 0], c = F(c);
346
- const p = [
347
- this.pointer[0] + c[0] * s * h,
348
- this.pointer[1] + c[1] * s * h
349
- ];
350
- let f = r;
351
- f = F(f);
348
+ const { endTangent: r, startTangent: i, startFactor: s, endFactor: o } = ot(n), a = this.pendingSegments.length ? this.pendingSegments[this.pendingSegments.length - 1] : null, c = T(this.pointer, t) / 3;
349
+ let h;
350
+ i ? h = i : a ? h = a.tangentAtLastPoint : h = [1, 0], h = F(h);
352
351
  const g = [
353
- t[0] - f[0] * o * h,
354
- t[1] - f[1] * o * h
352
+ this.pointer[0] + h[0] * s * c,
353
+ this.pointer[1] + h[1] * s * c
354
+ ];
355
+ let p = r;
356
+ p = F(p);
357
+ const f = [
358
+ t[0] - p[0] * o * c,
359
+ t[1] - p[1] * o * c
355
360
  ];
356
- return this.cubicBezierCurveTo(t, p, g);
361
+ return this.cubicBezierCurveTo(t, g, f);
357
362
  }
358
363
  smoothCurve(t, n, r) {
359
364
  return this.smoothCurveTo(
@@ -371,49 +376,49 @@ class ot {
371
376
  const r = this.pendingSegments.pop(), i = this.pendingSegments.shift();
372
377
  if (!r || !i)
373
378
  throw new Error("Not enough curves to close and fillet");
374
- const s = n === "chamfer" ? _ : V;
379
+ const s = n === "chamfer" ? V : I;
375
380
  this.pendingSegments.push(...s(r, i, t));
376
381
  }
377
382
  close(t = !1) {
378
383
  if (!this.pendingSegments.length) throw new Error("No segments to close");
379
384
  const n = this.pendingSegments[0], r = this.pendingSegments.at(-1);
380
- return L(n.firstPoint, r.lastPoint) || this.lineTo(n.firstPoint), this._nextCorner !== null && (this._customCornerLastWithFirst(
385
+ return v(n.firstPoint, r.lastPoint) || this.lineTo(n.firstPoint), this._nextCorner !== null && (this._customCornerLastWithFirst(
381
386
  this._nextCorner.radius,
382
387
  this._nextCorner.mode
383
- ), this._nextCorner = null), z(this.pendingSegments, { ignoreChecks: t });
388
+ ), this._nextCorner = null), R(this.pendingSegments, { ignoreChecks: t });
384
389
  }
385
390
  closeWithMirror(t = !1) {
386
391
  if (!this.pendingSegments.length) throw new Error("No segments to close");
387
392
  const n = this.pendingSegments[0], r = this.pendingSegments.at(-1), i = P(
388
393
  r.lastPoint,
389
394
  n.firstPoint
390
- ), s = new K().mirrorLine(
395
+ ), s = new U().mirrorLine(
391
396
  i,
392
397
  n.firstPoint
393
398
  ), o = this.pendingSegments.map(
394
399
  (a) => a.transform(s).reverse()
395
400
  );
396
- return o.reverse(), z(
401
+ return o.reverse(), R(
397
402
  [...this.pendingSegments, ...o],
398
403
  { ignoreChecks: t }
399
404
  );
400
405
  }
401
406
  asStrand() {
402
- return new X([...this.pendingSegments]);
407
+ return new Z([...this.pendingSegments]);
403
408
  }
404
409
  get isClosed() {
405
410
  var t;
406
- return L(this.pointer, (t = this.pendingSegments[0]) == null ? void 0 : t.firstPoint);
411
+ return v(this.pointer, (t = this.pendingSegments[0]) == null ? void 0 : t.firstPoint);
407
412
  }
408
413
  }
409
- function lt(e = [0, 0]) {
410
- return new ot(e);
414
+ function ut(e = [0, 0]) {
415
+ return new at(e);
411
416
  }
412
417
  export {
413
- S as D,
414
- ot as a,
415
- lt as d,
416
- V as f,
417
- y as o
418
+ C as D,
419
+ at as a,
420
+ ut as d,
421
+ I as f,
422
+ _ as o
418
423
  };
419
- //# sourceMappingURL=draw-CJWiicbK.js.map
424
+ //# sourceMappingURL=draw-DzKVhurb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draw-DzKVhurb.js","sources":["../src/algorithms/intersections/fullLinesIntersection.ts","../src/algorithms/offsets/offsetSegment.ts","../src/algorithms/filletSegments.ts","../src/draw.ts"],"sourcesContent":["import { Vector } from \"../../definitions\";\nimport {\n add,\n crossProduct,\n scalarMultiply,\n subtract,\n} from \"../../vectorOperations\";\n\n/**\n * Returns the intersection point between two full lines\n *\n * Note that collinear lines are not considered to intersect at all.\n *\n * Lines are represented by a vector V with **unit length** and a point on the line.\n *\n */\nexport const fullLineIntersection = (\n line1: { V: Vector; firstPoint: Vector; precision: number },\n line2: { V: Vector; firstPoint: Vector; precision: number },\n precision?: number,\n): \"parallel\" | Vector => {\n const V1xV2 = crossProduct(line1.V, line2.V);\n\n /*\n const xLength = squareLength(line1.V);\n const yLength = squareLength(line2.V);\n */\n\n const squarePrecision = precision\n ? precision * precision\n : line1.precision * line2.precision;\n\n if (V1xV2 * V1xV2 < squarePrecision) {\n return \"parallel\";\n }\n\n const diffPoint = subtract(line2.firstPoint, line1.firstPoint);\n const intersectionParam = crossProduct(diffPoint, line2.V) / V1xV2;\n\n return add(line1.firstPoint, scalarMultiply(line1.V, intersectionParam));\n};\n","import { Line } from \"../../models/segments/Line.js\";\nimport { Arc } from \"../../models/segments/Arc.js\";\nimport { Segment } from \"../../models/segments/Segment.js\";\nimport {\n add,\n distance,\n dotProduct,\n perpendicular,\n scalarMultiply,\n subtract,\n} from \"../../vectorOperations\";\nimport { Vector } from \"../../definitions.js\";\nimport { CubicBezier, QuadraticBezier } from \"../../models/exports.js\";\nimport { fullLineIntersection } from \"../intersections/fullLinesIntersection.js\";\nimport {\n SafeCubicBezier,\n SafeQuadraticBezier,\n} from \"../conversions/bezierToSafeBezier.js\";\n\nconst DEGENERATE_SEGMENT_INSTANCE = Symbol.for(\n \"pantograph:DegenerateSegment\",\n);\n\nexport class DegenerateSegment {\n static isInstance(value: unknown): value is DegenerateSegment {\n return (\n !!value &&\n (value as { [DEGENERATE_SEGMENT_INSTANCE]?: boolean })[\n DEGENERATE_SEGMENT_INSTANCE\n ] === true\n );\n }\n\n constructor(\n public readonly firstPoint: Vector,\n public readonly lastPoint: Vector,\n ) {\n Object.defineProperty(this, DEGENERATE_SEGMENT_INSTANCE, { value: true });\n }\n}\n\nexport type OffsettableSegment =\n | Line\n | Arc\n | SafeCubicBezier\n | SafeQuadraticBezier;\n\nexport function offsetSegment(\n segment: OffsettableSegment,\n offset: number,\n): Segment | DegenerateSegment {\n if (Line.isInstance(segment)) {\n return offsetLine(segment, offset);\n }\n\n if (Arc.isInstance(segment)) {\n return offsetArc(segment, offset);\n }\n\n if (QuadraticBezier.isInstance(segment) || CubicBezier.isInstance(segment)) {\n return offsetSafeBezier(segment, offset);\n }\n\n throw new Error(\"Not implemented\");\n}\n\nexport function offsetLine(line: Line, offset: number): Line {\n const { firstPoint, lastPoint } = line;\n\n const normal = line.normalVector;\n return new Line(\n add(firstPoint, scalarMultiply(normal, offset)),\n add(lastPoint, scalarMultiply(normal, offset)),\n );\n}\n\nexport function offsetArc(arc: Arc, offset: number): Arc | DegenerateSegment {\n const offsetStartPoint = add(\n arc.firstPoint,\n scalarMultiply(perpendicular(arc.tangentAtFirstPoint), offset),\n );\n const offsetEndPoint = add(\n arc.lastPoint,\n scalarMultiply(perpendicular(arc.tangentAtLastPoint), offset),\n );\n\n const orientedOffset = offset * (arc.clockwise ? 1 : -1);\n const newRadius = arc.radius + orientedOffset;\n if (newRadius < arc.precision) {\n return new DegenerateSegment(offsetStartPoint, offsetEndPoint);\n }\n\n return new Arc(offsetStartPoint, offsetEndPoint, arc.center, arc.clockwise);\n}\n\nfunction computeControlPointOffset(\n origin: Vector,\n controlPoint: Vector,\n tangent: Vector,\n newPoint: Vector,\n precision: number,\n): Vector {\n const newControlPoint = fullLineIntersection(\n {\n V: tangent,\n firstPoint: newPoint,\n precision: precision,\n },\n {\n V: subtract(controlPoint, origin),\n firstPoint: origin,\n precision: precision,\n },\n );\n\n if (newControlPoint === \"parallel\") {\n throw new Error(\n \"Parallel lines not expected in safe bezier offset control point calculation\",\n );\n }\n\n return newControlPoint;\n}\n\nexport function offsetSafeBezier(\n curve: SafeQuadraticBezier | SafeCubicBezier,\n offset: number,\n): typeof curve | DegenerateSegment {\n const { firstPoint, lastPoint, normalAtFirstPoint, normalAtLastPoint } =\n curve;\n\n const origin = fullLineIntersection(\n { V: normalAtFirstPoint, firstPoint, precision: curve.precision },\n { V: normalAtLastPoint, firstPoint: lastPoint, precision: curve.precision },\n );\n\n const offsetStartPoint = add(\n firstPoint,\n scalarMultiply(normalAtFirstPoint, offset),\n );\n const offsetEndPoint = add(\n lastPoint,\n scalarMultiply(normalAtLastPoint, offset),\n );\n\n if (origin === \"parallel\") {\n throw new Error(\"Parallel lines not expected in safe bezier offset\");\n }\n\n const offsetTowardsOrigin =\n dotProduct(subtract(origin, firstPoint), normalAtFirstPoint) * offset > 0;\n if (offsetTowardsOrigin) {\n const minDistance = Math.min(\n distance(firstPoint, origin),\n distance(lastPoint, origin),\n );\n\n if (minDistance < offset) {\n return new DegenerateSegment(offsetStartPoint, offsetEndPoint);\n }\n }\n\n if (QuadraticBezier.isInstance(curve)) {\n const newControlPoint = computeControlPointOffset(\n origin,\n curve.controlPoint,\n curve.tangentAtFirstPoint,\n offsetStartPoint,\n curve.precision,\n );\n\n return new QuadraticBezier(\n offsetStartPoint,\n offsetEndPoint,\n newControlPoint,\n );\n }\n\n const newControlPoint1 = computeControlPointOffset(\n origin,\n curve.firstControlPoint,\n curve.tangentAtFirstPoint,\n offsetStartPoint,\n curve.precision,\n );\n const newControlPoint2 = computeControlPointOffset(\n origin,\n curve.lastControlPoint,\n curve.tangentAtLastPoint,\n offsetEndPoint,\n curve.precision,\n );\n\n return new CubicBezier(\n offsetStartPoint,\n offsetEndPoint,\n newControlPoint1,\n newControlPoint2,\n );\n}\n","import { Vector } from \"../definitions.js\";\nimport { Line } from \"../models/segments/Line.js\";\nimport { tangentArc } from \"../models/segments/Arc.js\";\nimport type { Segment } from \"../models/segments/Segment.js\";\nimport {\n add,\n crossProduct,\n perpendicular,\n perpendicularClockwise,\n scalarMultiply,\n} from \"../vectorOperations\";\nimport { findIntersections } from \"./intersections\";\nimport { DegenerateSegment, offsetSegment } from \"./offsets/offsetSegment.js\";\nimport { exportJSON } from \"../main.js\";\n\nfunction removeCorner(\n firstSegment: Segment,\n secondSegment: Segment,\n radius: number,\n) {\n const sinAngle = crossProduct(\n firstSegment.tangentAtLastPoint,\n secondSegment.tangentAtFirstPoint,\n );\n\n // This cover the case when the segments are colinear\n if (Math.abs(sinAngle) < 1e-10) return null;\n\n const orientationCorrection = sinAngle > 0 ? 1 : -1;\n const offset = Math.abs(radius) * orientationCorrection;\n\n const firstOffset = offsetSegment(firstSegment, offset);\n const secondOffset = offsetSegment(secondSegment, offset);\n\n if (\n DegenerateSegment.isInstance(firstOffset) ||\n DegenerateSegment.isInstance(secondOffset)\n ) {\n return null;\n }\n\n let potentialCenter: Vector | undefined;\n try {\n const intersections = findIntersections(firstOffset, secondOffset, 1e-9);\n\n // We need to work on the case where there are more than one intersections\n potentialCenter = intersections.at(-1);\n } catch (e) {\n return null;\n }\n\n if (!potentialCenter) {\n return null;\n }\n const center = potentialCenter;\n\n const splitForFillet = (segment: Segment, offsetSegment: Segment) => {\n const tgt = offsetSegment.tangentAt(center);\n const normal = perpendicularClockwise(tgt);\n const splitPoint = add(center, scalarMultiply(normal, offset));\n return segment.splitAt(splitPoint);\n };\n\n const [first] = splitForFillet(firstSegment, firstOffset);\n const [, second] = splitForFillet(secondSegment, secondOffset);\n\n return { first, second, center };\n}\n\nexport function filletSegments(\n firstSegment: Segment,\n secondSegment: Segment,\n radius: number,\n) {\n const cornerRemoved = removeCorner(firstSegment, secondSegment, radius);\n if (!cornerRemoved) {\n console.warn(\n \"Cannot fillet between segments\",\n firstSegment.repr,\n secondSegment.repr,\n );\n return [firstSegment, secondSegment];\n }\n\n const { first, second } = cornerRemoved;\n\n return [\n first,\n tangentArc(first.lastPoint, second.firstPoint, first.tangentAtLastPoint),\n second,\n ];\n}\n\nexport function chamferSegments(\n firstSegment: Segment,\n secondSegment: Segment,\n radius: number,\n) {\n const cornerRemoved = removeCorner(firstSegment, secondSegment, radius);\n if (!cornerRemoved) {\n console.warn(\n \"Cannot chamfer between segments\",\n firstSegment.repr,\n secondSegment.repr,\n );\n return [firstSegment, secondSegment];\n }\n\n const { first, second } = cornerRemoved;\n\n return [first, new Line(first.lastPoint, second.firstPoint), second];\n}\n","import {\n chamferSegments,\n filletSegments,\n} from \"./algorithms/filletSegments.js\";\nimport { Vector } from \"./definitions.js\";\nimport { Strand } from \"./models/Strand.js\";\nimport { Diagram } from \"./models/Diagram.js\";\nimport { Figure } from \"./models/Figure.js\";\nimport { Loop } from \"./models/Loop.js\";\nimport { tangentArc, threePointsArc } from \"./models/segments/Arc.js\";\nimport { Line } from \"./models/segments/Line.js\";\nimport { Segment } from \"./models/segments/Segment.js\";\nimport { TransformationMatrix } from \"./models/TransformationMatrix.js\";\nimport {\n polarToCartesian,\n DEG2RAD,\n subtract,\n sameVector,\n perpendicular,\n add,\n scalarMultiply,\n distance,\n cartesianToPolar,\n RAD2DEG,\n normalize,\n} from \"./vectorOperations.js\";\nimport { svgEllipse } from \"./models/segments/EllipseArc.js\";\nimport { QuadraticBezier } from \"./models/segments/QuadraticBezier.js\";\nimport { CubicBezier } from \"./models/segments/CubicBezier.js\";\n\nconst parseSmoothCurveConfig = (\n config?:\n | number\n | Vector\n | {\n endTangent?: number | Vector;\n startTangent?: number | Vector;\n startFactor?: number;\n endFactor?: number;\n },\n) => {\n let conf: {\n endTangent: number | Vector;\n startFactor?: number;\n endFactor?: number;\n startTangent?: number | Vector;\n };\n\n if (!config) conf = { endTangent: [1, 0] };\n else if (\n typeof config === \"number\" ||\n (Array.isArray(config) && config.length === 2)\n ) {\n conf = { endTangent: config };\n } else {\n conf = { endTangent: 0, ...config };\n }\n const {\n endTangent: endTgt,\n startFactor = 1,\n endFactor = 1,\n startTangent: startTgt,\n } = conf;\n\n let endTangent: Vector;\n if (typeof endTgt === \"number\") {\n endTangent = polarToCartesian(1, endTgt * DEG2RAD);\n } else {\n endTangent = endTgt;\n }\n\n let startTangent: Vector | undefined;\n if (typeof startTgt === \"number\") {\n startTangent = polarToCartesian(1, startTgt * DEG2RAD);\n } else {\n startTangent = startTgt;\n }\n\n return { endTangent, startFactor, endFactor, startTangent };\n};\n\nfunction loopySegmentsToDiagram(\n segments: Segment[],\n { ignoreChecks = false } = {},\n) {\n // Here we will need to do our best to fix cases where the drawing is\n // broken in some way (i.e. self-intersecting loops)\n\n return new Diagram([new Figure(new Loop([...segments], { ignoreChecks }))]);\n}\n\nexport class DrawingPen {\n pointer: Vector;\n protected firstPoint: Vector;\n protected pendingSegments: Segment[];\n\n protected _nextCorner: { radius: number; mode: \"fillet\" | \"chamfer\" } | null;\n\n constructor(origin: Vector = [0, 0]) {\n this.pointer = origin;\n this.firstPoint = origin;\n\n this.pendingSegments = [];\n this._nextCorner = null;\n }\n\n movePointerTo(point: Vector): this {\n if (this.pendingSegments.length)\n throw new Error(\n \"You can only move the pointer if there is no segment defined\",\n );\n\n this.pointer = point;\n this.firstPoint = point;\n return this;\n }\n\n protected saveSegment(segment: Segment) {\n if (sameVector(segment.firstPoint, segment.lastPoint)) {\n throw new Error(`Segment has no length, ${segment.repr}`);\n }\n\n if (!this._nextCorner) {\n this.pendingSegments.push(segment);\n return this;\n }\n\n const previousSegment = this.pendingSegments.pop();\n if (!previousSegment) throw new Error(\"bug in the custom corner algorithm\");\n\n const makeCorner =\n this._nextCorner.mode === \"chamfer\" ? chamferSegments : filletSegments;\n\n this.pendingSegments.push(\n ...makeCorner(previousSegment, segment, this._nextCorner.radius),\n );\n this._nextCorner = null;\n return this;\n }\n\n lineTo(point: Vector): this {\n const segment = new Line(this.pointer, point);\n this.pointer = point;\n return this.saveSegment(segment);\n }\n\n line(xDist: number, yDist: number): this {\n return this.lineTo([this.pointer[0] + xDist, this.pointer[1] + yDist]);\n }\n\n vLine(distance: number): this {\n return this.line(0, distance);\n }\n\n hLine(distance: number): this {\n return this.line(distance, 0);\n }\n\n vLineTo(yPos: number): this {\n return this.lineTo([this.pointer[0], yPos]);\n }\n\n hLineTo(xPos: number): this {\n return this.lineTo([xPos, this.pointer[1]]);\n }\n\n polarLineTo([r, theta]: Vector): this {\n const angleInRads = theta * DEG2RAD;\n const point = polarToCartesian(r, angleInRads);\n return this.lineTo(point);\n }\n\n polarLine(distance: number, angle: number): this {\n const angleInRads = angle * DEG2RAD;\n const [x, y] = polarToCartesian(distance, angleInRads);\n return this.line(x, y);\n }\n\n tangentLine(distance: number): this {\n const previousCurve = this.pendingSegments.at(-1);\n\n if (!previousCurve)\n throw new Error(\"You need a previous segment to sketch a tangent line\");\n\n const [xDir, yDir] = previousCurve.tangentAtLastPoint;\n return this.line(xDir * distance, yDir * distance);\n }\n\n threePointsArcTo(end: Vector, midPoint: Vector): this {\n this.saveSegment(threePointsArc(this.pointer, midPoint, end));\n this.pointer = end;\n return this;\n }\n\n threePointsArc(\n xDist: number,\n yDist: number,\n viaXDist: number,\n viaYDist: number,\n ): this {\n const [x0, y0] = this.pointer;\n return this.threePointsArcTo(\n [x0 + xDist, y0 + yDist],\n [x0 + viaXDist, y0 + viaYDist],\n );\n }\n\n sagittaArcTo(end: Vector, sagitta: number): this {\n if (!sagitta) return this.lineTo(end);\n const chord = new Line(this.pointer, end);\n const norm = perpendicular(chord.tangentAtFirstPoint);\n\n const sagPoint: Vector = add(chord.midPoint, scalarMultiply(norm, sagitta));\n\n return this.threePointsArcTo(end, sagPoint);\n }\n\n sagittaArc(xDist: number, yDist: number, sagitta: number): this {\n return this.sagittaArcTo(\n [xDist + this.pointer[0], yDist + this.pointer[1]],\n sagitta,\n );\n }\n\n vSagittaArc(distance: number, sagitta: number): this {\n return this.sagittaArc(0, distance, sagitta);\n }\n\n hSagittaArc(distance: number, sagitta: number): this {\n return this.sagittaArc(distance, 0, sagitta);\n }\n\n bulgeArcTo(end: Vector, bulge: number): this {\n if (!bulge) return this.lineTo(end);\n const halfChord = distance(this.pointer, end) / 2;\n const bulgeAsSagitta = -bulge * halfChord;\n\n return this.sagittaArcTo(end, bulgeAsSagitta);\n }\n\n bulgeArc(xDist: number, yDist: number, bulge: number): this {\n return this.bulgeArcTo(\n [xDist + this.pointer[0], yDist + this.pointer[1]],\n bulge,\n );\n }\n\n vBulgeArc(distance: number, bulge: number): this {\n return this.bulgeArc(0, distance, bulge);\n }\n\n hBulgeArc(distance: number, bulge: number): this {\n return this.bulgeArc(distance, 0, bulge);\n }\n\n tangentArcTo(end: Vector, tangentAtStart?: Vector): this {\n const previousCurve = this.pendingSegments.at(-1);\n\n if (!previousCurve)\n throw new Error(\"You need a previous curve to sketch a tangent arc\");\n\n this.saveSegment(\n tangentArc(\n this.pointer,\n end,\n tangentAtStart ?? previousCurve.tangentAtLastPoint,\n ),\n );\n\n this.pointer = end;\n return this;\n }\n\n tangentArc(xDist: number, yDist: number, tangentAtStart?: Vector): this {\n const [x0, y0] = this.pointer;\n return this.tangentArcTo([xDist + x0, yDist + y0], tangentAtStart);\n }\n\n ellipseTo(\n end: Vector,\n r0: number,\n r1: number,\n xAxisRotation: number,\n longArc: boolean,\n sweepFlag: boolean,\n ): this {\n this.saveSegment(\n svgEllipse(this.pointer, end, r0, r1, xAxisRotation, longArc, sweepFlag),\n );\n this.pointer = end;\n return this;\n }\n\n ellipse(\n xDist: number,\n yDist: number,\n r0: number,\n r1: number,\n xAxisRotation: number,\n longArc: boolean,\n sweepFlag: boolean,\n ): this {\n return this.ellipseTo(\n [xDist + this.pointer[0], yDist + this.pointer[1]],\n r0,\n r1,\n xAxisRotation,\n longArc,\n sweepFlag,\n );\n }\n\n halfEllipseTo(end: Vector, sagitta: number): this {\n const [distance, angle] = cartesianToPolar(subtract(end, this.pointer));\n\n return this.ellipseTo(\n end,\n distance / 2,\n Math.abs(sagitta),\n angle * RAD2DEG,\n true,\n sagitta > 0,\n );\n }\n\n halfEllipse(xDist: number, yDist: number, sagitta: number): this {\n return this.halfEllipseTo(\n [xDist + this.pointer[0], yDist + this.pointer[1]],\n sagitta,\n );\n }\n\n cubicBezierCurveTo(\n end: Vector,\n startControlPoint: Vector,\n endControlPoint: Vector,\n ): this {\n this.saveSegment(\n new CubicBezier(this.pointer, end, startControlPoint, endControlPoint),\n );\n this.pointer = end;\n return this;\n }\n\n quadraticBezierCurveTo(end: Vector, controlPoint: Vector): this {\n this.saveSegment(new QuadraticBezier(this.pointer, end, controlPoint));\n this.pointer = end;\n return this;\n }\n\n smoothCurveTo(\n end: Vector,\n config?:\n | number\n | Vector\n | {\n endTangent?: number | Vector;\n startTangent?: number | Vector;\n startFactor?: number;\n endFactor?: number;\n },\n ): this {\n const { endTangent, startTangent, startFactor, endFactor } =\n parseSmoothCurveConfig(config);\n\n const previousCurve = this.pendingSegments.length\n ? this.pendingSegments[this.pendingSegments.length - 1]\n : null;\n\n const defaultDistance = distance(this.pointer, end) / 3;\n\n let startPoleDirection: Vector;\n if (startTangent) {\n startPoleDirection = startTangent;\n } else if (!previousCurve) {\n startPoleDirection = [1, 0];\n } else {\n startPoleDirection = previousCurve.tangentAtLastPoint;\n }\n\n startPoleDirection = normalize(startPoleDirection);\n const startControl: Vector = [\n this.pointer[0] + startPoleDirection[0] * startFactor * defaultDistance,\n this.pointer[1] + startPoleDirection[1] * startFactor * defaultDistance,\n ];\n\n let endPoleDirection = endTangent;\n\n endPoleDirection = normalize(endPoleDirection);\n const endControl: Vector = [\n end[0] - endPoleDirection[0] * endFactor * defaultDistance,\n end[1] - endPoleDirection[1] * endFactor * defaultDistance,\n ];\n\n return this.cubicBezierCurveTo(end, startControl, endControl);\n }\n\n smoothCurve(\n xDist: number,\n yDist: number,\n config?:\n | number\n | Vector\n | {\n endTangent?: number | Vector;\n startTangent?: number | Vector;\n startFactor?: number;\n endFactor?: number;\n },\n ) {\n return this.smoothCurveTo(\n [xDist + this.pointer[0], yDist + this.pointer[1]],\n config,\n );\n }\n\n customCorner(radius: number, mode: \"fillet\" | \"chamfer\" = \"fillet\") {\n if (!this.pendingSegments.length)\n throw new Error(\"You need a segment defined to fillet the angle\");\n\n if (!radius) return this;\n\n this._nextCorner = { mode, radius };\n return this;\n }\n\n protected _customCornerLastWithFirst(\n radius: number,\n mode: \"fillet\" | \"chamfer\" = \"fillet\",\n ) {\n if (!radius) return;\n\n const lastSegment = this.pendingSegments.pop();\n const firstSegment = this.pendingSegments.shift();\n\n if (!lastSegment || !firstSegment)\n throw new Error(\"Not enough curves to close and fillet\");\n\n const makeCorner = mode === \"chamfer\" ? chamferSegments : filletSegments;\n\n this.pendingSegments.push(...makeCorner(lastSegment, firstSegment, radius));\n }\n\n close(ignoreChecks = false): Diagram {\n if (!this.pendingSegments.length) throw new Error(\"No segments to close\");\n const firstSegment = this.pendingSegments[0];\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const lastSegment = this.pendingSegments.at(-1)!;\n\n if (!sameVector(firstSegment.firstPoint, lastSegment.lastPoint)) {\n this.lineTo(firstSegment.firstPoint);\n }\n\n if (this._nextCorner !== null) {\n this._customCornerLastWithFirst(\n this._nextCorner.radius,\n this._nextCorner.mode,\n );\n this._nextCorner = null;\n }\n\n return loopySegmentsToDiagram(this.pendingSegments, { ignoreChecks });\n }\n\n closeWithMirror(ignoreChecks = false): Diagram {\n if (!this.pendingSegments.length) throw new Error(\"No segments to close\");\n\n const firstSegment = this.pendingSegments[0];\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const lastSegment = this.pendingSegments.at(-1)!;\n\n const mirrorVector = subtract(\n lastSegment.lastPoint,\n firstSegment.firstPoint,\n );\n const mirrorTranform = new TransformationMatrix().mirrorLine(\n mirrorVector,\n firstSegment.firstPoint,\n );\n\n const mirroredSegments = this.pendingSegments.map((segment) =>\n segment.transform(mirrorTranform).reverse(),\n );\n mirroredSegments.reverse();\n\n return loopySegmentsToDiagram(\n [...this.pendingSegments, ...mirroredSegments],\n { ignoreChecks },\n );\n }\n\n asStrand(): Strand {\n return new Strand([...this.pendingSegments]);\n }\n\n get isClosed(): boolean {\n return sameVector(this.pointer, this.pendingSegments[0]?.firstPoint);\n }\n}\n\nexport function draw(origin: Vector = [0, 0]): DrawingPen {\n return new DrawingPen(origin);\n}\n"],"names":["fullLineIntersection","line1","line2","precision","V1xV2","crossProduct","squarePrecision","diffPoint","subtract","intersectionParam","add","scalarMultiply","DEGENERATE_SEGMENT_INSTANCE","DegenerateSegment","firstPoint","lastPoint","value","offsetSegment","segment","offset","Line","offsetLine","Arc","offsetArc","QuadraticBezier","CubicBezier","offsetSafeBezier","line","normal","arc","offsetStartPoint","perpendicular","offsetEndPoint","orientedOffset","computeControlPointOffset","origin","controlPoint","tangent","newPoint","newControlPoint","curve","normalAtFirstPoint","normalAtLastPoint","dotProduct","distance","newControlPoint1","newControlPoint2","removeCorner","firstSegment","secondSegment","radius","sinAngle","orientationCorrection","firstOffset","secondOffset","potentialCenter","findIntersections","center","splitForFillet","tgt","perpendicularClockwise","splitPoint","first","second","filletSegments","cornerRemoved","tangentArc","chamferSegments","parseSmoothCurveConfig","config","conf","endTgt","startFactor","endFactor","startTgt","endTangent","polarToCartesian","DEG2RAD","startTangent","loopySegmentsToDiagram","segments","ignoreChecks","Diagram","Figure","Loop","DrawingPen","__publicField","point","sameVector","previousSegment","makeCorner","xDist","yDist","yPos","xPos","r","theta","angleInRads","angle","x","y","previousCurve","xDir","yDir","end","midPoint","threePointsArc","viaXDist","viaYDist","x0","y0","sagitta","chord","norm","sagPoint","bulge","halfChord","bulgeAsSagitta","tangentAtStart","r0","r1","xAxisRotation","longArc","sweepFlag","svgEllipse","cartesianToPolar","RAD2DEG","startControlPoint","endControlPoint","defaultDistance","startPoleDirection","normalize","startControl","endPoleDirection","endControl","mode","lastSegment","mirrorVector","mirrorTranform","TransformationMatrix","mirroredSegments","Strand","_a","draw"],"mappings":"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"}