pantograph2d 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/Diagram-2450b2e6.js +1750 -0
  2. package/dist/Diagram-2450b2e6.js.map +1 -0
  3. package/dist/Diagram-57e17509.cjs +4 -0
  4. package/dist/Diagram-57e17509.cjs.map +1 -0
  5. package/dist/QuadraticBezier-e116a2d6.js +3647 -0
  6. package/dist/QuadraticBezier-e116a2d6.js.map +1 -0
  7. package/dist/QuadraticBezier-e3d7218b.cjs +9 -0
  8. package/dist/QuadraticBezier-e3d7218b.cjs.map +1 -0
  9. package/dist/api/svg.d.ts +1 -0
  10. package/dist/draw-27ac6dae.cjs +2 -0
  11. package/dist/draw-27ac6dae.cjs.map +1 -0
  12. package/dist/{draw-825692f1.js → draw-c7b2705c.js} +117 -109
  13. package/dist/draw-c7b2705c.js.map +1 -0
  14. package/dist/export/svg/api.d.ts +6 -0
  15. package/dist/{types/export → export}/svg/wrapSVG.d.ts +1 -1
  16. package/dist/{types/models → models}/exports.d.ts +2 -0
  17. package/dist/pantograph/drawShape.cjs +1 -1
  18. package/dist/pantograph/drawShape.cjs.map +1 -1
  19. package/dist/pantograph/drawShape.js +12 -11
  20. package/dist/pantograph/drawShape.js.map +1 -1
  21. package/dist/pantograph/models.cjs +1 -1
  22. package/dist/pantograph/models.js +15 -12
  23. package/dist/pantograph/models.js.map +1 -1
  24. package/dist/pantograph/svg.cjs +2 -0
  25. package/dist/pantograph/svg.cjs.map +1 -0
  26. package/dist/pantograph/svg.js +11 -0
  27. package/dist/pantograph/svg.js.map +1 -0
  28. package/dist/pantograph.cjs +2 -8
  29. package/dist/pantograph.cjs.map +1 -1
  30. package/dist/pantograph.js +405 -440
  31. package/dist/pantograph.js.map +1 -1
  32. package/dist/wrapSVG-02b823ac.cjs +8 -0
  33. package/dist/wrapSVG-02b823ac.cjs.map +1 -0
  34. package/dist/wrapSVG-0ec8a111.js +62 -0
  35. package/dist/wrapSVG-0ec8a111.js.map +1 -0
  36. package/package.json +31 -23
  37. package/dist/Diagram-8c3c5e1b.js +0 -5301
  38. package/dist/Diagram-8c3c5e1b.js.map +0 -1
  39. package/dist/Diagram-d8288579.cjs +0 -11
  40. package/dist/Diagram-d8288579.cjs.map +0 -1
  41. package/dist/draw-3ee546c3.cjs +0 -2
  42. package/dist/draw-3ee546c3.cjs.map +0 -1
  43. package/dist/draw-825692f1.js.map +0 -1
  44. /package/dist/{types/algorithms → algorithms}/boolean/figureBooleans.d.ts +0 -0
  45. /package/dist/{types/algorithms → algorithms}/boolean/loopBooleans.d.ts +0 -0
  46. /package/dist/{types/algorithms → algorithms}/boolean/strandBoolean.d.ts +0 -0
  47. /package/dist/{types/algorithms → algorithms}/boolean/strandsBetweenIntersections.d.ts +0 -0
  48. /package/dist/{types/algorithms → algorithms}/distances/arcArcDistance.d.ts +0 -0
  49. /package/dist/{types/algorithms → algorithms}/distances/genericDistance.d.ts +0 -0
  50. /package/dist/{types/algorithms → algorithms}/distances/index.d.ts +0 -0
  51. /package/dist/{types/algorithms → algorithms}/distances/lineArcDistance.d.ts +0 -0
  52. /package/dist/{types/algorithms → algorithms}/distances/lineLineDistance.d.ts +0 -0
  53. /package/dist/{types/algorithms → algorithms}/filletSegments.d.ts +0 -0
  54. /package/dist/{types/algorithms → algorithms}/intersections/arcArcIntersection.d.ts +0 -0
  55. /package/dist/{types/algorithms → algorithms}/intersections/arcEllipseArcIntersection.d.ts +0 -0
  56. /package/dist/{types/algorithms → algorithms}/intersections/arcsCubicBezierIntersection.d.ts +0 -0
  57. /package/dist/{types/algorithms → algorithms}/intersections/arcsQuadraticBezierIntersection.d.ts +0 -0
  58. /package/dist/{types/algorithms → algorithms}/intersections/bezierClip.d.ts +0 -0
  59. /package/dist/{types/algorithms → algorithms}/intersections/cubicBezierCubicBezierIntersection.d.ts +0 -0
  60. /package/dist/{types/algorithms → algorithms}/intersections/ellipseArcEllipseArcIntersection.d.ts +0 -0
  61. /package/dist/{types/algorithms → algorithms}/intersections/ellipseEllipseIntersection.d.ts +0 -0
  62. /package/dist/{types/algorithms → algorithms}/intersections/index.d.ts +0 -0
  63. /package/dist/{types/algorithms → algorithms}/intersections/lineArcIntersection.d.ts +0 -0
  64. /package/dist/{types/algorithms → algorithms}/intersections/lineBezierIntersection.d.ts +0 -0
  65. /package/dist/{types/algorithms → algorithms}/intersections/lineEllipseArcIntersection.d.ts +0 -0
  66. /package/dist/{types/algorithms → algorithms}/intersections/lineLineIntersection.d.ts +0 -0
  67. /package/dist/{types/algorithms → algorithms}/intersections/quadraticBezierQuadraticBezierIntersection.d.ts +0 -0
  68. /package/dist/{types/algorithms → algorithms}/intersections/rayIntersections.d.ts +0 -0
  69. /package/dist/{types/algorithms → algorithms}/offsets/offsetFigure.d.ts +0 -0
  70. /package/dist/{types/algorithms → algorithms}/offsets/offsetSegment.d.ts +0 -0
  71. /package/dist/{types/algorithms → algorithms}/offsets/offsetStroke.d.ts +0 -0
  72. /package/dist/{types/algorithms → algorithms}/optimisation/Brent.d.ts +0 -0
  73. /package/dist/{types/algorithms → algorithms}/optimisation/DiRect.d.ts +0 -0
  74. /package/dist/{types/algorithms → algorithms}/organiseLoops.d.ts +0 -0
  75. /package/dist/{types/algorithms → algorithms}/simplify.d.ts +0 -0
  76. /package/dist/{types/algorithms → algorithms}/solvers/solvePolynomials.d.ts +0 -0
  77. /package/dist/{types/algorithms → algorithms}/stitchSegments.d.ts +0 -0
  78. /package/dist/{types/api → api}/drawShape.d.ts +0 -0
  79. /package/dist/{types/api → api}/models.d.ts +0 -0
  80. /package/dist/{types/booleanOperations.d.ts → booleanOperations.d.ts} +0 -0
  81. /package/dist/{types/definitions.d.ts → definitions.d.ts} +0 -0
  82. /package/dist/{types/draw.d.ts → draw.d.ts} +0 -0
  83. /package/dist/{types/drawShape → drawShape}/drawCircle.d.ts +0 -0
  84. /package/dist/{types/drawShape → drawShape}/drawRect.d.ts +0 -0
  85. /package/dist/{types/export → export}/json/exportJSON.d.ts +0 -0
  86. /package/dist/{types/export → export}/json/jsonDiagram.d.ts +0 -0
  87. /package/dist/{types/export → export}/json/jsonFigure.d.ts +0 -0
  88. /package/dist/{types/export → export}/json/jsonLoop.d.ts +0 -0
  89. /package/dist/{types/export → export}/json/jsonSegment.d.ts +0 -0
  90. /package/dist/{types/export → export}/svg/exportSVG.d.ts +0 -0
  91. /package/dist/{types/export → export}/svg/svgDiagram.d.ts +0 -0
  92. /package/dist/{types/export → export}/svg/svgFigure.d.ts +0 -0
  93. /package/dist/{types/export → export}/svg/svgLoop.d.ts +0 -0
  94. /package/dist/{types/export → export}/svg/svgSegment.d.ts +0 -0
  95. /package/dist/{types/export → export}/svg/svgStrand.d.ts +0 -0
  96. /package/dist/{types/import → import}/json/importJSON.d.ts +0 -0
  97. /package/dist/{types/main.d.ts → main.d.ts} +0 -0
  98. /package/dist/{types/models → models}/BoundingBox.d.ts +0 -0
  99. /package/dist/{types/models → models}/Diagram.d.ts +0 -0
  100. /package/dist/{types/models → models}/Figure.d.ts +0 -0
  101. /package/dist/{types/models → models}/Loop.d.ts +0 -0
  102. /package/dist/{types/models → models}/Strand.d.ts +0 -0
  103. /package/dist/{types/models → models}/Stroke.d.ts +0 -0
  104. /package/dist/{types/models → models}/TransformationMatrix.d.ts +0 -0
  105. /package/dist/{types/models → models}/segments/Arc.d.ts +0 -0
  106. /package/dist/{types/models → models}/segments/CubicBezier.d.ts +0 -0
  107. /package/dist/{types/models → models}/segments/EllipseArc.d.ts +0 -0
  108. /package/dist/{types/models → models}/segments/Line.d.ts +0 -0
  109. /package/dist/{types/models → models}/segments/QuadraticBezier.d.ts +0 -0
  110. /package/dist/{types/models → models}/segments/Segment.d.ts +0 -0
  111. /package/dist/{types/models → models}/segments/utils/deCasteljau.d.ts +0 -0
  112. /package/dist/{types/models → models}/segments/utils/isSegment.d.ts +0 -0
  113. /package/dist/{types/models → models}/utils/Transformable.d.ts +0 -0
  114. /package/dist/{types/offsetOperations.d.ts → offsetOperations.d.ts} +0 -0
  115. /package/dist/{types/operations.d.ts → operations.d.ts} +0 -0
  116. /package/dist/{types/utils → utils}/allCombinations.d.ts +0 -0
  117. /package/dist/{types/utils → utils}/allPairs.d.ts +0 -0
  118. /package/dist/{types/utils → utils}/angularDistance.d.ts +0 -0
  119. /package/dist/{types/utils → utils}/listOfFigures.d.ts +0 -0
  120. /package/dist/{types/utils → utils}/projectPointOnLine.d.ts +0 -0
  121. /package/dist/{types/utils → utils}/range.d.ts +0 -0
  122. /package/dist/{types/utils → utils}/removeDuplicatePoints.d.ts +0 -0
  123. /package/dist/{types/utils → utils}/removeDuplicateValues.d.ts +0 -0
  124. /package/dist/{types/utils → utils}/unitAngle.d.ts +0 -0
  125. /package/dist/{types/utils → utils}/zip.d.ts +0 -0
  126. /package/dist/{types/vectorOperations.d.ts → vectorOperations.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ export * from "../export/svg/api.js";
@@ -0,0 +1,2 @@
1
+ "use strict";var b=Object.defineProperty;var y=(i,t,e)=>t in i?b(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var g=(i,t,e)=>(y(i,typeof t!="symbol"?t+"":t,e),e);const r=require("./QuadraticBezier-e3d7218b.cjs"),p=require("./Diagram-57e17509.cjs");class m{constructor(t,e){this.firstPoint=t,this.lastPoint=e}}function A(i,t){if(i instanceof r.Line)return x(i,t);if(i instanceof r.Arc)return _(i,t);throw new Error("Not implemented")}function x(i,t){const{firstPoint:e,lastPoint:n}=i,s=i.normalVector;return new r.Line(r.add(e,r.scalarMultiply(s,t)),r.add(n,r.scalarMultiply(s,t)))}function _(i,t){const e=r.add(i.firstPoint,r.scalarMultiply(r.perpendicular(i.tangentAtFirstPoint),t)),n=r.add(i.lastPoint,r.scalarMultiply(r.perpendicular(i.tangentAtLastPoint),t)),s=t*(i.clockwise?1:-1);return i.radius+s<i.precision?new m(e,n):new r.Arc(e,n,i.center,i.clockwise)}function C(i,t,e){const n=r.crossProduct(i.tangentAtLastPoint,t.tangentAtFirstPoint);if(Math.abs(n)<1e-10)return null;const s=n>0?1:-1,o=Math.abs(e)*s,a=A(i,o),h=A(t,o);if(a instanceof m||h instanceof m)return null;let c;try{c=p.findIntersections(a,h,1e-9).at(-1)}catch{return null}if(!c)return null;const l=c,f=(T,v)=>{const L=v.tangentAt(l),D=r.perpendicularClockwise(L),E=r.add(l,r.scalarMultiply(D,o));return T.splitAt(E)},[u]=f(i,a),[,d]=f(t,h);return{first:u,second:d,center:l}}function P(i,t,e){const n=C(i,t,e);if(!n)return console.warn("Cannot fillet between segments",i.repr,t.repr),[i,t];const{first:s,second:o}=n;return[s,r.tangentArc(s.lastPoint,o.firstPoint,s.tangentAtLastPoint),o]}function w(i,t,e){const n=C(i,t,e);if(!n)return console.warn("Cannot chamfer between segments",i.repr,t.repr),[i,t];const{first:s,second:o}=n;return[s,new r.Line(s.lastPoint,o.firstPoint),o]}const F=i=>{let t;i?typeof i=="number"||Array.isArray(i)&&i.length===2?t={endTangent:i}:t={endTangent:0,...i}:t={endTangent:[1,0]};const{endTangent:e,startFactor:n=1,endFactor:s=1,startTangent:o}=t;let a;typeof e=="number"?a=r.polarToCartesian(1,e*r.DEG2RAD):a=e;let h;return typeof o=="number"?h=r.polarToCartesian(1,o*r.DEG2RAD):h=o,{endTangent:a,startFactor:n,endFactor:s,startTangent:h}};function S(i,{ignoreChecks:t=!1}={}){return new p.Diagram([new p.Figure(new p.Loop([...i],{ignoreChecks:t}))])}class M{constructor(t=[0,0]){g(this,"pointer");g(this,"firstPoint");g(this,"pendingSegments");g(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(r.sameVector(t.firstPoint,t.lastPoint))throw new Error(`Segment has no length, ${t.repr}`);if(!this._nextCorner)return this.pendingSegments.push(t),this;const e=this.pendingSegments.pop();if(!e)throw new Error("bug in the custom corner algorithm");const n=this._nextCorner.mode==="chamfer"?w:P;return this.pendingSegments.push(...n(e,t,this._nextCorner.radius)),this._nextCorner=null,this}lineTo(t){const e=new r.Line(this.pointer,t);return this.pointer=t,this.saveSegment(e)}line(t,e){return this.lineTo([this.pointer[0]+t,this.pointer[1]+e])}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,e]){const n=e*r.DEG2RAD,s=r.polarToCartesian(t,n);return this.lineTo(s)}polarLine(t,e){const n=e*r.DEG2RAD,[s,o]=r.polarToCartesian(t,n);return this.line(s,o)}tangentLine(t){const e=this.pendingSegments.at(-1);if(!e)throw new Error("You need a previous segment to sketch a tangent line");const[n,s]=e.tangentAtLastPoint;return this.line(n*t,s*t)}threePointsArcTo(t,e){return this.saveSegment(r.threePointsArc(this.pointer,e,t)),this.pointer=t,this}threePointsArc(t,e,n,s){const[o,a]=this.pointer;return this.threePointsArcTo([o+t,a+e],[o+n,a+s])}sagittaArcTo(t,e){if(!e)return this.lineTo(t);const n=new r.Line(this.pointer,t),s=r.perpendicular(n.tangentAtFirstPoint),o=r.add(n.midPoint,r.scalarMultiply(s,e));return this.threePointsArcTo(t,o)}sagittaArc(t,e,n){return this.sagittaArcTo([t+this.pointer[0],e+this.pointer[1]],n)}vSagittaArc(t,e){return this.sagittaArc(0,t,e)}hSagittaArc(t,e){return this.sagittaArc(t,0,e)}bulgeArcTo(t,e){if(!e)return this.lineTo(t);const n=r.distance(this.pointer,t)/2,s=-e*n;return this.sagittaArcTo(t,s)}bulgeArc(t,e,n){return this.bulgeArcTo([t+this.pointer[0],e+this.pointer[1]],n)}vBulgeArc(t,e){return this.bulgeArc(0,t,e)}hBulgeArc(t,e){return this.bulgeArc(t,0,e)}tangentArcTo(t,e){const n=this.pendingSegments.at(-1);if(!n)throw new Error("You need a previous curve to sketch a tangent arc");return this.saveSegment(r.tangentArc(this.pointer,t,e??n.tangentAtLastPoint)),this.pointer=t,this}tangentArc(t,e,n){const[s,o]=this.pointer;return this.tangentArcTo([t+s,e+o],n)}ellipseTo(t,e,n,s,o,a){return this.saveSegment(r.svgEllipse(this.pointer,t,e,n,s,o,a)),this.pointer=t,this}ellipse(t,e,n,s,o,a,h){return this.ellipseTo([t+this.pointer[0],e+this.pointer[1]],n,s,o,a,h)}halfEllipseTo(t,e){const[n,s]=r.cartesianToPolar(r.subtract(t,this.pointer));return this.ellipseTo(t,n/2,Math.abs(e),s*r.RAD2DEG,!0,e>0)}halfEllipse(t,e,n){return this.halfEllipseTo([t+this.pointer[0],e+this.pointer[1]],n)}cubicBezierCurveTo(t,e,n){return this.saveSegment(new r.CubicBezier(this.pointer,t,e,n)),this.pointer=t,this}quadraticBezierCurveTo(t,e){return this.saveSegment(new r.QuadraticBezier(this.pointer,t,e)),this.pointer=t,this}smoothCurveTo(t,e){const{endTangent:n,startTangent:s,startFactor:o,endFactor:a}=F(e),h=this.pendingSegments.length?this.pendingSegments[this.pendingSegments.length-1]:null,c=r.distance(this.pointer,t)/3;let l;s?l=s:h?l=h.tangentAtLastPoint:l=[1,0],l=r.normalize(l);const f=[this.pointer[0]+l[0]*o*c,this.pointer[1]+l[1]*o*c];let u=n;u=r.normalize(u);const d=[t[0]-u[0]*a*c,t[1]-u[1]*a*c];return this.cubicBezierCurveTo(t,f,d)}smoothCurve(t,e,n){return this.smoothCurveTo([t+this.pointer[0],e+this.pointer[1]],n)}customCorner(t,e="fillet"){if(!this.pendingSegments.length)throw new Error("You need a segment defined to fillet the angle");return t?(this._nextCorner={mode:e,radius:t},this):this}_customCornerLastWithFirst(t,e="fillet"){if(!t)return;const n=this.pendingSegments.pop(),s=this.pendingSegments.shift();if(!n||!s)throw new Error("Not enough curves to close and fillet");const o=e==="chamfer"?w:P;this.pendingSegments.push(...o(n,s,t))}close(t=!1){if(!this.pendingSegments.length)throw new Error("No segments to close");const e=this.pendingSegments[0],n=this.pendingSegments.at(-1);return r.sameVector(e.firstPoint,n.lastPoint)||this.lineTo(e.firstPoint),this._nextCorner!==null&&(this._customCornerLastWithFirst(this._nextCorner.radius,this._nextCorner.mode),this._nextCorner=null),S(this.pendingSegments,{ignoreChecks:t})}closeWithMirror(t=!1){if(!this.pendingSegments.length)throw new Error("No segments to close");const e=this.pendingSegments[0],n=this.pendingSegments.at(-1),s=r.subtract(n.lastPoint,e.firstPoint),o=new r.TransformationMatrix().mirrorLine(s,e.firstPoint),a=this.pendingSegments.map(h=>h.transform(o).reverse());return a.reverse(),S([...this.pendingSegments,...a],{ignoreChecks:t})}asStrand(){return new p.Strand([...this.pendingSegments])}get isClosed(){var t;return r.sameVector(this.pointer,(t=this.pendingSegments[0])==null?void 0:t.firstPoint)}}function R(i=[0,0]){return new M(i)}exports.DegenerateSegment=m;exports.draw=R;exports.offsetSegment=A;
2
+ //# sourceMappingURL=draw-27ac6dae.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draw-27ac6dae.cjs","sources":["../src/algorithms/offsets/offsetSegment.ts","../src/algorithms/filletSegments.ts","../src/draw.ts"],"sourcesContent":["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 normalize,\n perpendicular,\n scalarMultiply,\n subtract,\n} from \"../../vectorOperations\";\nimport { Vector } from \"../../definitions.js\";\n\nexport class DegenerateSegment {\n constructor(\n public readonly firstPoint: Vector,\n public readonly lastPoint: Vector,\n ) {}\n}\n\nexport function offsetSegment(\n segment: Segment,\n offset: number,\n): Segment | DegenerateSegment {\n if (segment instanceof Line) {\n return offsetLine(segment, offset);\n }\n\n if (segment instanceof Arc) {\n return offsetArc(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","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 firstOffset instanceof DegenerateSegment ||\n secondOffset instanceof DegenerateSegment\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":["DegenerateSegment","firstPoint","lastPoint","offsetSegment","segment","offset","Line","offsetLine","Arc","offsetArc","line","normal","add","scalarMultiply","arc","offsetStartPoint","perpendicular","offsetEndPoint","orientedOffset","removeCorner","firstSegment","secondSegment","radius","sinAngle","crossProduct","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","origin","__publicField","point","sameVector","previousSegment","makeCorner","xDist","yDist","distance","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","subtract","RAD2DEG","startControlPoint","endControlPoint","CubicBezier","controlPoint","QuadraticBezier","defaultDistance","startPoleDirection","normalize","startControl","endPoleDirection","endControl","mode","lastSegment","mirrorVector","mirrorTranform","TransformationMatrix","mirroredSegments","Strand","_a","draw"],"mappings":"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"}
@@ -1,102 +1,110 @@
1
- import { o as p, A as y, g as u, h as g, G as A, u as F, v as z, H as N, I, t as w, J as O, d as C, K as Y, M as G, e as v, R as V, C as W, Q, T as q, S as H, D as J, F as K, L as $, N as m, n as L, O as d } from "./Diagram-8c3c5e1b.js";
2
- class S {
1
+ var N = Object.defineProperty;
2
+ var Y = (r, t, e) => t in r ? N(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
+ var p = (r, t, e) => (Y(r, typeof t != "symbol" ? t + "" : t, e), e);
4
+ import { L as f, A as F, a as u, b as g, h as S, t as _, f as I, i as O, e as A, j as V, d as v, k as W, m as G, s as L, R as Q, C as j, Q as q, T as $, o as d, n as b, D as T } from "./QuadraticBezier-e116a2d6.js";
5
+ import { h as H, S as J, D as K, F as U, L as X } from "./Diagram-2450b2e6.js";
6
+ class C {
3
7
  constructor(t, e) {
4
8
  this.firstPoint = t, this.lastPoint = e;
5
9
  }
6
10
  }
7
- function b(s, t) {
8
- if (s instanceof p)
9
- return j(s, t);
10
- if (s instanceof y)
11
- return U(s, t);
11
+ function x(r, t) {
12
+ if (r instanceof f)
13
+ return Z(r, t);
14
+ if (r instanceof F)
15
+ return tt(r, t);
12
16
  throw new Error("Not implemented");
13
17
  }
14
- function j(s, t) {
15
- const { firstPoint: e, lastPoint: n } = s, r = s.normalVector;
16
- return new p(
17
- u(e, g(r, t)),
18
- u(n, g(r, t))
18
+ function Z(r, t) {
19
+ const { firstPoint: e, lastPoint: n } = r, i = r.normalVector;
20
+ return new f(
21
+ u(e, g(i, t)),
22
+ u(n, g(i, t))
19
23
  );
20
24
  }
21
- function U(s, t) {
25
+ function tt(r, t) {
22
26
  const e = u(
23
- s.firstPoint,
24
- g(A(s.tangentAtFirstPoint), t)
27
+ r.firstPoint,
28
+ g(S(r.tangentAtFirstPoint), t)
25
29
  ), n = u(
26
- s.lastPoint,
27
- g(A(s.tangentAtLastPoint), t)
28
- ), r = t * (s.clockwise ? 1 : -1);
29
- return s.radius + r < s.precision ? new S(e, n) : new y(e, n, s.center, s.clockwise);
30
+ r.lastPoint,
31
+ g(S(r.tangentAtLastPoint), t)
32
+ ), i = t * (r.clockwise ? 1 : -1);
33
+ return r.radius + i < r.precision ? new C(e, n) : new F(e, n, r.center, r.clockwise);
30
34
  }
31
- function _(s, t, e) {
32
- const n = z(
33
- s.tangentAtLastPoint,
35
+ function R(r, t, e) {
36
+ const n = I(
37
+ r.tangentAtLastPoint,
34
38
  t.tangentAtFirstPoint
35
39
  );
36
40
  if (Math.abs(n) < 1e-10)
37
41
  return null;
38
- const r = n > 0 ? 1 : -1, i = Math.abs(e) * r, o = b(s, i), a = b(t, i);
39
- if (o instanceof S || a instanceof S)
42
+ const i = n > 0 ? 1 : -1, s = Math.abs(e) * i, o = x(r, s), a = x(t, s);
43
+ if (o instanceof C || a instanceof C)
40
44
  return null;
41
45
  let c;
42
46
  try {
43
- c = N(o, a, 1e-9).at(-1);
47
+ c = H(o, a, 1e-9).at(-1);
44
48
  } catch {
45
49
  return null;
46
50
  }
47
51
  if (!c)
48
52
  return null;
49
- const h = c, f = (P, R) => {
50
- const k = R.tangentAt(h), B = I(k), M = u(h, g(B, i));
51
- return P.splitAt(M);
52
- }, [l] = f(s, o), [, T] = f(t, a);
53
- return { first: l, second: T, center: h };
53
+ const h = c, m = (w, k) => {
54
+ const B = k.tangentAt(h), z = O(B), M = u(h, g(z, s));
55
+ return w.splitAt(M);
56
+ }, [l] = m(r, o), [, P] = m(t, a);
57
+ return { first: l, second: P, center: h };
54
58
  }
55
- function E(s, t, e) {
56
- const n = _(s, t, e);
59
+ function E(r, t, e) {
60
+ const n = R(r, t, e);
57
61
  if (!n)
58
62
  return console.warn(
59
63
  "Cannot fillet between segments",
60
- s.repr,
64
+ r.repr,
61
65
  t.repr
62
- ), [s, t];
63
- const { first: r, second: i } = n;
66
+ ), [r, t];
67
+ const { first: i, second: s } = n;
64
68
  return [
65
- r,
66
- F(r.lastPoint, i.firstPoint, r.tangentAtLastPoint),
67
- i
69
+ i,
70
+ _(i.lastPoint, s.firstPoint, i.tangentAtLastPoint),
71
+ s
68
72
  ];
69
73
  }
70
- function x(s, t, e) {
71
- const n = _(s, t, e);
74
+ function D(r, t, e) {
75
+ const n = R(r, t, e);
72
76
  if (!n)
73
77
  return console.warn(
74
78
  "Cannot chamfer between segments",
75
- s.repr,
79
+ r.repr,
76
80
  t.repr
77
- ), [s, t];
78
- const { first: r, second: i } = n;
79
- return [r, new p(r.lastPoint, i.firstPoint), i];
81
+ ), [r, t];
82
+ const { first: i, second: s } = n;
83
+ return [i, new f(i.lastPoint, s.firstPoint), s];
80
84
  }
81
- const X = (s) => {
85
+ const et = (r) => {
82
86
  let t;
83
- s ? typeof s == "number" || Array.isArray(s) && s.length === 2 ? t = { endTangent: s } : t = { endTangent: 0, ...s } : t = { endTangent: [1, 0] };
87
+ r ? typeof r == "number" || Array.isArray(r) && r.length === 2 ? t = { endTangent: r } : t = { endTangent: 0, ...r } : t = { endTangent: [1, 0] };
84
88
  const {
85
89
  endTangent: e,
86
90
  startFactor: n = 1,
87
- endFactor: r = 1,
88
- startTangent: i
91
+ endFactor: i = 1,
92
+ startTangent: s
89
93
  } = t;
90
94
  let o;
91
- typeof e == "number" ? o = m(1, e * d) : o = e;
95
+ typeof e == "number" ? o = d(1, e * T) : o = e;
92
96
  let a;
93
- return typeof i == "number" ? a = m(1, i * d) : a = i, { endTangent: o, startFactor: n, endFactor: r, startTangent: a };
97
+ return typeof s == "number" ? a = d(1, s * T) : a = s, { endTangent: o, startFactor: n, endFactor: i, startTangent: a };
94
98
  };
95
- function D(s, { ignoreChecks: t = !1 } = {}) {
96
- return new J([new K(new $([...s], { ignoreChecks: t }))]);
99
+ function y(r, { ignoreChecks: t = !1 } = {}) {
100
+ return new K([new U(new X([...r], { ignoreChecks: t }))]);
97
101
  }
98
- class Z {
102
+ class nt {
99
103
  constructor(t = [0, 0]) {
104
+ p(this, "pointer");
105
+ p(this, "firstPoint");
106
+ p(this, "pendingSegments");
107
+ p(this, "_nextCorner");
100
108
  this.pointer = t, this.firstPoint = t, this.pendingSegments = [], this._nextCorner = null;
101
109
  }
102
110
  movePointerTo(t) {
@@ -107,20 +115,20 @@ class Z {
107
115
  return this.pointer = t, this.firstPoint = t, this;
108
116
  }
109
117
  saveSegment(t) {
110
- if (w(t.firstPoint, t.lastPoint))
118
+ if (A(t.firstPoint, t.lastPoint))
111
119
  throw new Error(`Segment has no length, ${t.repr}`);
112
120
  if (!this._nextCorner)
113
121
  return this.pendingSegments.push(t), this;
114
122
  const e = this.pendingSegments.pop();
115
123
  if (!e)
116
124
  throw new Error("bug in the custom corner algorithm");
117
- const n = this._nextCorner.mode === "chamfer" ? x : E;
125
+ const n = this._nextCorner.mode === "chamfer" ? D : E;
118
126
  return this.pendingSegments.push(
119
127
  ...n(e, t, this._nextCorner.radius)
120
128
  ), this._nextCorner = null, this;
121
129
  }
122
130
  lineTo(t) {
123
- const e = new p(this.pointer, t);
131
+ const e = new f(this.pointer, t);
124
132
  return this.pointer = t, this.saveSegment(e);
125
133
  }
126
134
  line(t, e) {
@@ -139,35 +147,35 @@ class Z {
139
147
  return this.lineTo([t, this.pointer[1]]);
140
148
  }
141
149
  polarLineTo([t, e]) {
142
- const n = e * d, r = m(t, n);
143
- return this.lineTo(r);
150
+ const n = e * T, i = d(t, n);
151
+ return this.lineTo(i);
144
152
  }
145
153
  polarLine(t, e) {
146
- const n = e * d, [r, i] = m(t, n);
147
- return this.line(r, i);
154
+ const n = e * T, [i, s] = d(t, n);
155
+ return this.line(i, s);
148
156
  }
149
157
  tangentLine(t) {
150
158
  const e = this.pendingSegments.at(-1);
151
159
  if (!e)
152
160
  throw new Error("You need a previous segment to sketch a tangent line");
153
- const [n, r] = e.tangentAtLastPoint;
154
- return this.line(n * t, r * t);
161
+ const [n, i] = e.tangentAtLastPoint;
162
+ return this.line(n * t, i * t);
155
163
  }
156
164
  threePointsArcTo(t, e) {
157
- return this.saveSegment(O(this.pointer, e, t)), this.pointer = t, this;
165
+ return this.saveSegment(V(this.pointer, e, t)), this.pointer = t, this;
158
166
  }
159
- threePointsArc(t, e, n, r) {
160
- const [i, o] = this.pointer;
167
+ threePointsArc(t, e, n, i) {
168
+ const [s, o] = this.pointer;
161
169
  return this.threePointsArcTo(
162
- [i + t, o + e],
163
- [i + n, o + r]
170
+ [s + t, o + e],
171
+ [s + n, o + i]
164
172
  );
165
173
  }
166
174
  sagittaArcTo(t, e) {
167
175
  if (!e)
168
176
  return this.lineTo(t);
169
- const n = new p(this.pointer, t), r = A(n.tangentAtFirstPoint), i = u(n.midPoint, g(r, e));
170
- return this.threePointsArcTo(t, i);
177
+ const n = new f(this.pointer, t), i = S(n.tangentAtFirstPoint), s = u(n.midPoint, g(i, e));
178
+ return this.threePointsArcTo(t, s);
171
179
  }
172
180
  sagittaArc(t, e, n) {
173
181
  return this.sagittaArcTo(
@@ -184,8 +192,8 @@ class Z {
184
192
  bulgeArcTo(t, e) {
185
193
  if (!e)
186
194
  return this.lineTo(t);
187
- const n = C(this.pointer, t) / 2, r = -e * n;
188
- return this.sagittaArcTo(t, r);
195
+ const n = v(this.pointer, t) / 2, i = -e * n;
196
+ return this.sagittaArcTo(t, i);
189
197
  }
190
198
  bulgeArc(t, e, n) {
191
199
  return this.bulgeArcTo(
@@ -204,7 +212,7 @@ class Z {
204
212
  if (!n)
205
213
  throw new Error("You need a previous curve to sketch a tangent arc");
206
214
  return this.saveSegment(
207
- F(
215
+ _(
208
216
  this.pointer,
209
217
  t,
210
218
  e ?? n.tangentAtLastPoint
@@ -212,31 +220,31 @@ class Z {
212
220
  ), this.pointer = t, this;
213
221
  }
214
222
  tangentArc(t, e, n) {
215
- const [r, i] = this.pointer;
216
- return this.tangentArcTo([t + r, e + i], n);
223
+ const [i, s] = this.pointer;
224
+ return this.tangentArcTo([t + i, e + s], n);
217
225
  }
218
- ellipseTo(t, e, n, r, i, o) {
226
+ ellipseTo(t, e, n, i, s, o) {
219
227
  return this.saveSegment(
220
- Y(this.pointer, t, e, n, r, i, o)
228
+ W(this.pointer, t, e, n, i, s, o)
221
229
  ), this.pointer = t, this;
222
230
  }
223
- ellipse(t, e, n, r, i, o, a) {
231
+ ellipse(t, e, n, i, s, o, a) {
224
232
  return this.ellipseTo(
225
233
  [t + this.pointer[0], e + this.pointer[1]],
226
234
  n,
227
- r,
228
235
  i,
236
+ s,
229
237
  o,
230
238
  a
231
239
  );
232
240
  }
233
241
  halfEllipseTo(t, e) {
234
- const [n, r] = G(v(t, this.pointer));
242
+ const [n, i] = G(L(t, this.pointer));
235
243
  return this.ellipseTo(
236
244
  t,
237
245
  n / 2,
238
246
  Math.abs(e),
239
- r * V,
247
+ i * Q,
240
248
  !0,
241
249
  e > 0
242
250
  );
@@ -249,27 +257,27 @@ class Z {
249
257
  }
250
258
  cubicBezierCurveTo(t, e, n) {
251
259
  return this.saveSegment(
252
- new W(this.pointer, t, e, n)
260
+ new j(this.pointer, t, e, n)
253
261
  ), this.pointer = t, this;
254
262
  }
255
263
  quadraticBezierCurveTo(t, e) {
256
- return this.saveSegment(new Q(this.pointer, t, e)), this.pointer = t, this;
264
+ return this.saveSegment(new q(this.pointer, t, e)), this.pointer = t, this;
257
265
  }
258
266
  smoothCurveTo(t, e) {
259
- const { endTangent: n, startTangent: r, startFactor: i, endFactor: o } = X(e), a = this.pendingSegments.length ? this.pendingSegments[this.pendingSegments.length - 1] : null, c = C(this.pointer, t) / 3;
267
+ const { endTangent: n, startTangent: i, startFactor: s, endFactor: o } = et(e), a = this.pendingSegments.length ? this.pendingSegments[this.pendingSegments.length - 1] : null, c = v(this.pointer, t) / 3;
260
268
  let h;
261
- r ? h = r : a ? h = a.tangentAtLastPoint : h = [1, 0], h = L(h);
262
- const f = [
263
- this.pointer[0] + h[0] * i * c,
264
- this.pointer[1] + h[1] * i * c
269
+ i ? h = i : a ? h = a.tangentAtLastPoint : h = [1, 0], h = b(h);
270
+ const m = [
271
+ this.pointer[0] + h[0] * s * c,
272
+ this.pointer[1] + h[1] * s * c
265
273
  ];
266
274
  let l = n;
267
- l = L(l);
268
- const T = [
275
+ l = b(l);
276
+ const P = [
269
277
  t[0] - l[0] * o * c,
270
278
  t[1] - l[1] * o * c
271
279
  ];
272
- return this.cubicBezierCurveTo(t, f, T);
280
+ return this.cubicBezierCurveTo(t, m, P);
273
281
  }
274
282
  smoothCurve(t, e, n) {
275
283
  return this.smoothCurveTo(
@@ -285,52 +293,52 @@ class Z {
285
293
  _customCornerLastWithFirst(t, e = "fillet") {
286
294
  if (!t)
287
295
  return;
288
- const n = this.pendingSegments.pop(), r = this.pendingSegments.shift();
289
- if (!n || !r)
296
+ const n = this.pendingSegments.pop(), i = this.pendingSegments.shift();
297
+ if (!n || !i)
290
298
  throw new Error("Not enough curves to close and fillet");
291
- const i = e === "chamfer" ? x : E;
292
- this.pendingSegments.push(...i(n, r, t));
299
+ const s = e === "chamfer" ? D : E;
300
+ this.pendingSegments.push(...s(n, i, t));
293
301
  }
294
302
  close(t = !1) {
295
303
  if (!this.pendingSegments.length)
296
304
  throw new Error("No segments to close");
297
305
  const e = this.pendingSegments[0], n = this.pendingSegments.at(-1);
298
- return w(e.firstPoint, n.lastPoint) || this.lineTo(e.firstPoint), this._nextCorner !== null && (this._customCornerLastWithFirst(
306
+ return A(e.firstPoint, n.lastPoint) || this.lineTo(e.firstPoint), this._nextCorner !== null && (this._customCornerLastWithFirst(
299
307
  this._nextCorner.radius,
300
308
  this._nextCorner.mode
301
- ), this._nextCorner = null), D(this.pendingSegments, { ignoreChecks: t });
309
+ ), this._nextCorner = null), y(this.pendingSegments, { ignoreChecks: t });
302
310
  }
303
311
  closeWithMirror(t = !1) {
304
312
  if (!this.pendingSegments.length)
305
313
  throw new Error("No segments to close");
306
- const e = this.pendingSegments[0], n = this.pendingSegments.at(-1), r = v(
314
+ const e = this.pendingSegments[0], n = this.pendingSegments.at(-1), i = L(
307
315
  n.lastPoint,
308
316
  e.firstPoint
309
- ), i = new q().mirrorLine(
310
- r,
317
+ ), s = new $().mirrorLine(
318
+ i,
311
319
  e.firstPoint
312
320
  ), o = this.pendingSegments.map(
313
- (a) => a.transform(i).reverse()
321
+ (a) => a.transform(s).reverse()
314
322
  );
315
- return o.reverse(), D(
323
+ return o.reverse(), y(
316
324
  [...this.pendingSegments, ...o],
317
325
  { ignoreChecks: t }
318
326
  );
319
327
  }
320
328
  asStrand() {
321
- return new H([...this.pendingSegments]);
329
+ return new J([...this.pendingSegments]);
322
330
  }
323
331
  get isClosed() {
324
332
  var t;
325
- return w(this.pointer, (t = this.pendingSegments[0]) == null ? void 0 : t.firstPoint);
333
+ return A(this.pointer, (t = this.pendingSegments[0]) == null ? void 0 : t.firstPoint);
326
334
  }
327
335
  }
328
- function et(s = [0, 0]) {
329
- return new Z(s);
336
+ function ot(r = [0, 0]) {
337
+ return new nt(r);
330
338
  }
331
339
  export {
332
- S as D,
333
- et as d,
334
- b as o
340
+ C as D,
341
+ ot as d,
342
+ x as o
335
343
  };
336
- //# sourceMappingURL=draw-825692f1.js.map
344
+ //# sourceMappingURL=draw-c7b2705c.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draw-c7b2705c.js","sources":["../src/algorithms/offsets/offsetSegment.ts","../src/algorithms/filletSegments.ts","../src/draw.ts"],"sourcesContent":["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 normalize,\n perpendicular,\n scalarMultiply,\n subtract,\n} from \"../../vectorOperations\";\nimport { Vector } from \"../../definitions.js\";\n\nexport class DegenerateSegment {\n constructor(\n public readonly firstPoint: Vector,\n public readonly lastPoint: Vector,\n ) {}\n}\n\nexport function offsetSegment(\n segment: Segment,\n offset: number,\n): Segment | DegenerateSegment {\n if (segment instanceof Line) {\n return offsetLine(segment, offset);\n }\n\n if (segment instanceof Arc) {\n return offsetArc(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","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 firstOffset instanceof DegenerateSegment ||\n secondOffset instanceof DegenerateSegment\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":["DegenerateSegment","firstPoint","lastPoint","offsetSegment","segment","offset","Line","offsetLine","Arc","offsetArc","line","normal","add","scalarMultiply","arc","offsetStartPoint","perpendicular","offsetEndPoint","orientedOffset","removeCorner","firstSegment","secondSegment","radius","sinAngle","crossProduct","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","origin","__publicField","point","sameVector","previousSegment","makeCorner","xDist","yDist","distance","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","subtract","RAD2DEG","startControlPoint","endControlPoint","CubicBezier","controlPoint","QuadraticBezier","defaultDistance","startPoleDirection","normalize","startControl","endPoleDirection","endControl","mode","lastSegment","mirrorVector","mirrorTranform","TransformationMatrix","mirroredSegments","Strand","_a","draw"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { svgDiagram } from "./svgDiagram.js";
2
+ export { svgFigure } from "./svgFigure.js";
3
+ export { svgLoop } from "./svgLoop.js";
4
+ export { svgSegmentToPath } from "./svgSegment.js";
5
+ export { svgStrand } from "./svgStrand.js";
6
+ export { svgViewbox } from "./wrapSVG.js";
@@ -1,4 +1,4 @@
1
1
  import { BoundingBox } from "../../models/BoundingBox.js";
2
- export declare function SVGViewbox(bbox: BoundingBox, margin?: number): string;
2
+ export declare function svgViewbox(bbox: BoundingBox, margin?: number): string;
3
3
  export type SVGUnit = "mm" | "cm" | "in" | "pc" | "px" | "pt";
4
4
  export declare function wrapSVG(body: string, boundingBox: BoundingBox, margin: number | undefined, unit: null | SVGUnit): string;
@@ -9,5 +9,7 @@ export { Line } from "./segments/Line.js";
9
9
  export { Arc } from "./segments/Arc.js";
10
10
  export { EllipseArc } from "./segments/EllipseArc.js";
11
11
  export { CubicBezier } from "./segments/CubicBezier.js";
12
+ export { QuadraticBezier } from "./segments/QuadraticBezier.js";
12
13
  export type { Segment } from "./segments/Segment.js";
14
+ export { isSegment } from "./segments/utils/isSegment.js";
13
15
  export { Transformable } from "./utils/Transformable.js";
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("../draw-3ee546c3.cjs");require("../Diagram-d8288579.cjs");function R(n){return f.draw([-n,0]).sagittaArc(2*n,0,n).sagittaArc(-2*n,0,n).close()}function p(n,c,a=0){const{rx:u=0,ry:m=0}=typeof a=="number"?{ry:a,rx:a}:a;let e=Math.min(u??a??0,n/2),r=Math.min(m??a??0,c/2);const l=e&&r;l||(e=0,r=0);const y=e===r,t=f.draw([Math.min(0,-(n/2-e)),-c/2]),i=(o,s)=>{l&&(y?t.tangentArc(o,s):t.ellipse(o,s,e,r,0,!1,!1))};return e<n/2&&t.hLine(n-2*e),i(e,r),r<c/2&&t.vLine(c-2*r),i(-e,r),e<n/2&&t.hLine(-(n-2*e)),i(-e,-r),r<c/2&&t.vLine(-(c-2*r)),i(e,-r),t.close()}exports.drawCircle=R;exports.drawRect=p;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("../draw-27ac6dae.cjs");require("../QuadraticBezier-e3d7218b.cjs");require("../Diagram-57e17509.cjs");function R(n){return f.draw([-n,0]).sagittaArc(2*n,0,n).sagittaArc(-2*n,0,n).close()}function p(n,c,a=0){const{rx:u=0,ry:m=0}=typeof a=="number"?{ry:a,rx:a}:a;let e=Math.min(u??a??0,n/2),r=Math.min(m??a??0,c/2);const l=e&&r;l||(e=0,r=0);const y=e===r,t=f.draw([Math.min(0,-(n/2-e)),-c/2]),i=(o,s)=>{l&&(y?t.tangentArc(o,s):t.ellipse(o,s,e,r,0,!1,!1))};return e<n/2&&t.hLine(n-2*e),i(e,r),r<c/2&&t.vLine(c-2*r),i(-e,r),e<n/2&&t.hLine(-(n-2*e)),i(-e,-r),r<c/2&&t.vLine(-(c-2*r)),i(e,-r),t.close()}exports.drawCircle=R;exports.drawRect=p;
2
2
  //# sourceMappingURL=drawShape.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"drawShape.cjs","sources":["../../src/drawShape/drawCircle.ts","../../src/drawShape/drawRect.ts"],"sourcesContent":["import { draw } from \"../draw.js\";\nimport type { Diagram } from \"../models/Diagram.js\";\n\nexport function drawCircle(radius: number): Diagram {\n return draw([-radius, 0])\n .sagittaArc(2 * radius, 0, radius)\n .sagittaArc(-2 * radius, 0, radius)\n .close();\n}\n","import { draw } from \"../draw.js\";\nimport type { Diagram } from \"../models/Diagram.js\";\n\nexport function drawRect(\n width: number,\n height: number,\n r: number | { rx?: number; ry?: number } = 0\n): Diagram {\n const { rx: inputRx = 0, ry: inputRy = 0 } =\n typeof r === \"number\" ? { ry: r, rx: r } : r;\n let rx = Math.min(inputRx ?? r ?? 0, width / 2);\n let ry = Math.min(inputRy ?? r ?? 0, height / 2);\n\n const withRadius = rx && ry;\n if (!withRadius) {\n rx = 0;\n ry = 0;\n }\n const symmetricRadius = rx === ry;\n\n const sk = draw([Math.min(0, -(width / 2 - rx)), -height / 2]);\n\n const addFillet = (xDist: number, yDist: number) => {\n if (withRadius) {\n if (symmetricRadius) sk.tangentArc(xDist, yDist);\n else {\n sk.ellipse(xDist, yDist, rx, ry, 0, false, false);\n }\n }\n };\n\n if (rx < width / 2) {\n sk.hLine(width - 2 * rx);\n }\n addFillet(rx, ry);\n if (ry < height / 2) {\n sk.vLine(height - 2 * ry);\n }\n addFillet(-rx, ry);\n if (rx < width / 2) {\n sk.hLine(-(width - 2 * rx));\n }\n addFillet(-rx, -ry);\n if (ry < height / 2) {\n sk.vLine(-(height - 2 * ry));\n }\n addFillet(rx, -ry);\n return sk.close();\n}\n"],"names":["drawCircle","radius","draw","drawRect","width","height","r","inputRx","inputRy","rx","ry","withRadius","symmetricRadius","sk","addFillet","xDist","yDist"],"mappings":"2JAGO,SAASA,EAAWC,EAAyB,CAClD,OAAOC,OAAK,CAAC,CAACD,EAAQ,CAAC,CAAC,EACrB,WAAW,EAAIA,EAAQ,EAAGA,CAAM,EAChC,WAAW,GAAKA,EAAQ,EAAGA,CAAM,EACjC,OACL,CCLO,SAASE,EACdC,EACAC,EACAC,EAA2C,EAClC,CACT,KAAM,CAAE,GAAIC,EAAU,EAAG,GAAIC,EAAU,CAAE,EACvC,OAAOF,GAAM,SAAW,CAAE,GAAIA,EAAG,GAAIA,CAAM,EAAAA,EAC7C,IAAIG,EAAK,KAAK,IAAIF,GAAWD,GAAK,EAAGF,EAAQ,CAAC,EAC1CM,EAAK,KAAK,IAAIF,GAAWF,GAAK,EAAGD,EAAS,CAAC,EAE/C,MAAMM,EAAaF,GAAMC,EACpBC,IACEF,EAAA,EACAC,EAAA,GAEP,MAAME,EAAkBH,IAAOC,EAEzBG,EAAKX,EAAA,KAAK,CAAC,KAAK,IAAI,EAAG,EAAEE,EAAQ,EAAIK,EAAG,EAAG,CAACJ,EAAS,CAAC,CAAC,EAEvDS,EAAY,CAACC,EAAeC,IAAkB,CAC9CL,IACEC,EAAoBC,EAAA,WAAWE,EAAOC,CAAK,EAE7CH,EAAG,QAAQE,EAAOC,EAAOP,EAAIC,EAAI,EAAG,GAAO,EAAK,EAEpD,EAGE,OAAAD,EAAKL,EAAQ,GACZS,EAAA,MAAMT,EAAQ,EAAIK,CAAE,EAEzBK,EAAUL,EAAIC,CAAE,EACZA,EAAKL,EAAS,GACbQ,EAAA,MAAMR,EAAS,EAAIK,CAAE,EAEhBI,EAAA,CAACL,EAAIC,CAAE,EACbD,EAAKL,EAAQ,GACfS,EAAG,MAAM,EAAET,EAAQ,EAAIK,EAAG,EAElBK,EAAA,CAACL,EAAI,CAACC,CAAE,EACdA,EAAKL,EAAS,GAChBQ,EAAG,MAAM,EAAER,EAAS,EAAIK,EAAG,EAEnBI,EAAAL,EAAI,CAACC,CAAE,EACVG,EAAG,OACZ"}
1
+ {"version":3,"file":"drawShape.cjs","sources":["../../src/drawShape/drawCircle.ts","../../src/drawShape/drawRect.ts"],"sourcesContent":["import { draw } from \"../draw.js\";\nimport type { Diagram } from \"../models/Diagram.js\";\n\nexport function drawCircle(radius: number): Diagram {\n return draw([-radius, 0])\n .sagittaArc(2 * radius, 0, radius)\n .sagittaArc(-2 * radius, 0, radius)\n .close();\n}\n","import { draw } from \"../draw.js\";\nimport type { Diagram } from \"../models/Diagram.js\";\n\nexport function drawRect(\n width: number,\n height: number,\n r: number | { rx?: number; ry?: number } = 0,\n): Diagram {\n const { rx: inputRx = 0, ry: inputRy = 0 } =\n typeof r === \"number\" ? { ry: r, rx: r } : r;\n let rx = Math.min(inputRx ?? r ?? 0, width / 2);\n let ry = Math.min(inputRy ?? r ?? 0, height / 2);\n\n const withRadius = rx && ry;\n if (!withRadius) {\n rx = 0;\n ry = 0;\n }\n const symmetricRadius = rx === ry;\n\n const sk = draw([Math.min(0, -(width / 2 - rx)), -height / 2]);\n\n const addFillet = (xDist: number, yDist: number) => {\n if (withRadius) {\n if (symmetricRadius) sk.tangentArc(xDist, yDist);\n else {\n sk.ellipse(xDist, yDist, rx, ry, 0, false, false);\n }\n }\n };\n\n if (rx < width / 2) {\n sk.hLine(width - 2 * rx);\n }\n addFillet(rx, ry);\n if (ry < height / 2) {\n sk.vLine(height - 2 * ry);\n }\n addFillet(-rx, ry);\n if (rx < width / 2) {\n sk.hLine(-(width - 2 * rx));\n }\n addFillet(-rx, -ry);\n if (ry < height / 2) {\n sk.vLine(-(height - 2 * ry));\n }\n addFillet(rx, -ry);\n return sk.close();\n}\n"],"names":["drawCircle","radius","draw","drawRect","width","height","r","inputRx","inputRy","rx","ry","withRadius","symmetricRadius","sk","addFillet","xDist","yDist"],"mappings":"sMAGO,SAASA,EAAWC,EAAyB,CAClD,OAAOC,OAAK,CAAC,CAACD,EAAQ,CAAC,CAAC,EACrB,WAAW,EAAIA,EAAQ,EAAGA,CAAM,EAChC,WAAW,GAAKA,EAAQ,EAAGA,CAAM,EACjC,OACL,CCLO,SAASE,EACdC,EACAC,EACAC,EAA2C,EAClC,CACT,KAAM,CAAE,GAAIC,EAAU,EAAG,GAAIC,EAAU,CAAE,EACvC,OAAOF,GAAM,SAAW,CAAE,GAAIA,EAAG,GAAIA,CAAM,EAAAA,EAC7C,IAAIG,EAAK,KAAK,IAAIF,GAAWD,GAAK,EAAGF,EAAQ,CAAC,EAC1CM,EAAK,KAAK,IAAIF,GAAWF,GAAK,EAAGD,EAAS,CAAC,EAE/C,MAAMM,EAAaF,GAAMC,EACpBC,IACEF,EAAA,EACAC,EAAA,GAEP,MAAME,EAAkBH,IAAOC,EAEzBG,EAAKX,EAAA,KAAK,CAAC,KAAK,IAAI,EAAG,EAAEE,EAAQ,EAAIK,EAAG,EAAG,CAACJ,EAAS,CAAC,CAAC,EAEvDS,EAAY,CAACC,EAAeC,IAAkB,CAC9CL,IACEC,EAAoBC,EAAA,WAAWE,EAAOC,CAAK,EAE7CH,EAAG,QAAQE,EAAOC,EAAOP,EAAIC,EAAI,EAAG,GAAO,EAAK,EAEpD,EAGE,OAAAD,EAAKL,EAAQ,GACZS,EAAA,MAAMT,EAAQ,EAAIK,CAAE,EAEzBK,EAAUL,EAAIC,CAAE,EACZA,EAAKL,EAAS,GACbQ,EAAA,MAAMR,EAAS,EAAIK,CAAE,EAEhBI,EAAA,CAACL,EAAIC,CAAE,EACbD,EAAKL,EAAQ,GACfS,EAAG,MAAM,EAAET,EAAQ,EAAIK,EAAG,EAElBK,EAAA,CAACL,EAAI,CAACC,CAAE,EACdA,EAAKL,EAAS,GAChBQ,EAAG,MAAM,EAAER,EAAS,EAAIK,EAAG,EAEnBI,EAAAL,EAAI,CAACC,CAAE,EACVG,EAAG,OACZ"}