@excalidraw/math 0.18.0-063e025 → 0.18.0-1118751

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 (154) hide show
  1. package/dist/dev/index.js +278 -109
  2. package/dist/dev/index.js.map +4 -4
  3. package/dist/prod/index.js +1 -1
  4. package/dist/types/common/src/colors.d.ts +22 -0
  5. package/dist/types/common/src/constants.d.ts +54 -0
  6. package/dist/types/common/src/keys.d.ts +4 -0
  7. package/dist/types/common/src/points.d.ts +1 -1
  8. package/dist/types/common/src/random.d.ts +7 -0
  9. package/dist/types/common/src/utils.d.ts +1 -1
  10. package/dist/types/element/src/Scene.d.ts +1 -1
  11. package/dist/types/element/src/arrowEndpointText.d.ts +49 -0
  12. package/dist/types/element/src/arrows/focus.d.ts +5 -2
  13. package/dist/types/element/src/binding.d.ts +15 -8
  14. package/dist/types/element/src/bucketFill.d.ts +110 -0
  15. package/dist/types/element/src/collision.d.ts +8 -5
  16. package/dist/types/element/src/comparisons.d.ts +7 -5
  17. package/dist/types/element/src/convertToShape.d.ts +23 -0
  18. package/dist/types/element/src/delta.d.ts +23 -1
  19. package/dist/types/element/src/dragElements.d.ts +27 -0
  20. package/dist/types/element/src/duplicate.d.ts +60 -0
  21. package/dist/types/element/src/flowchart.d.ts +10 -6
  22. package/dist/types/element/src/frame.d.ts +2 -2
  23. package/dist/types/element/src/groups.d.ts +1 -1
  24. package/dist/types/element/src/index.d.ts +4 -0
  25. package/dist/types/element/src/linearElementEditor.d.ts +17 -0
  26. package/dist/types/element/src/mutateElement.d.ts +1 -1
  27. package/dist/types/element/src/newElement.d.ts +37 -2
  28. package/dist/types/element/src/renderElement.d.ts +21 -4
  29. package/dist/types/element/src/selection.d.ts +1 -1
  30. package/dist/types/element/src/shape.d.ts +27 -1
  31. package/dist/types/element/src/sizeHelpers.d.ts +6 -0
  32. package/dist/types/element/src/sortElements.d.ts +10 -0
  33. package/dist/types/element/src/stickyNote.d.ts +183 -0
  34. package/dist/types/element/src/textElement.d.ts +7 -3
  35. package/dist/types/element/src/transform.d.ts +25 -6
  36. package/dist/types/element/src/typeChecks.d.ts +3 -2
  37. package/dist/types/element/src/types.d.ts +35 -6
  38. package/dist/types/element/src/utils.d.ts +15 -4
  39. package/dist/types/element/src/zindex.d.ts +1 -1
  40. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +48 -9
  41. package/dist/types/excalidraw/actions/actionAlign.d.ts +6 -6
  42. package/dist/types/excalidraw/actions/actionBoundText.d.ts +32 -6
  43. package/dist/types/excalidraw/actions/actionCanvas.d.ts +173 -576
  44. package/dist/types/excalidraw/actions/actionClipboard.d.ts +32 -6
  45. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +16 -3
  46. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +50 -10
  47. package/dist/types/excalidraw/actions/actionDeselect.d.ts +13 -3
  48. package/dist/types/excalidraw/actions/actionDistribute.d.ts +2 -2
  49. package/dist/types/excalidraw/actions/actionElementLink.d.ts +16 -3
  50. package/dist/types/excalidraw/actions/actionElementLock.d.ts +32 -6
  51. package/dist/types/excalidraw/actions/actionExport.d.ts +34 -8
  52. package/dist/types/excalidraw/actions/actionFinalize.d.ts +1 -0
  53. package/dist/types/excalidraw/actions/actionFrame.d.ts +99 -185
  54. package/dist/types/excalidraw/actions/actionGroup.d.ts +33 -7
  55. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +68 -4
  56. package/dist/types/excalidraw/actions/actionLink.d.ts +16 -3
  57. package/dist/types/excalidraw/actions/actionMenu.d.ts +16 -3
  58. package/dist/types/excalidraw/actions/actionProperties.d.ts +45 -12
  59. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +16 -3
  60. package/dist/types/excalidraw/actions/actionStyles.d.ts +17 -4
  61. package/dist/types/excalidraw/actions/actionTextAutoResize.d.ts +1 -1
  62. package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +16 -3
  63. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +16 -3
  64. package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +16 -3
  65. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +16 -3
  66. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +16 -3
  67. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +16 -3
  68. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +17 -4
  69. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +16 -3
  70. package/dist/types/excalidraw/actions/colorTargets.d.ts +39 -0
  71. package/dist/types/excalidraw/actions/index.d.ts +1 -2
  72. package/dist/types/excalidraw/actions/manager.d.ts +1 -0
  73. package/dist/types/excalidraw/actions/shortcuts.d.ts +1 -1
  74. package/dist/types/excalidraw/actions/types.d.ts +5 -1
  75. package/dist/types/excalidraw/appState.d.ts +26 -5
  76. package/dist/types/excalidraw/components/Actions.d.ts +16 -10
  77. package/dist/types/excalidraw/components/App.arrowText.d.ts +104 -0
  78. package/dist/types/excalidraw/components/App.bucketFill.d.ts +48 -0
  79. package/dist/types/excalidraw/components/App.cursor.d.ts +38 -0
  80. package/dist/types/excalidraw/components/App.d.ts +468 -99
  81. package/dist/types/excalidraw/components/App.drawshape.d.ts +55 -0
  82. package/dist/types/excalidraw/components/App.duplicate.d.ts +51 -0
  83. package/dist/types/excalidraw/components/App.flowchart.d.ts +21 -0
  84. package/dist/types/excalidraw/components/App.pan.d.ts +54 -0
  85. package/dist/types/excalidraw/components/App.toolDrag.d.ts +63 -0
  86. package/dist/types/excalidraw/components/App.viewport.d.ts +73 -0
  87. package/dist/types/excalidraw/components/App.wheel.d.ts +26 -0
  88. package/dist/types/excalidraw/components/ColorPicker/ColorPicker.d.ts +8 -2
  89. package/dist/types/excalidraw/components/ColorPicker/CustomColorList.d.ts +3 -1
  90. package/dist/types/excalidraw/components/ColorPicker/Picker.d.ts +5 -1
  91. package/dist/types/excalidraw/components/ColorPicker/PickerColorList.d.ts +9 -2
  92. package/dist/types/excalidraw/components/ColorPicker/ShadeList.d.ts +4 -2
  93. package/dist/types/excalidraw/components/ColorPicker/TopPicks.d.ts +8 -1
  94. package/dist/types/excalidraw/components/ColorPicker/colorTopPicksDnD.d.ts +11 -0
  95. package/dist/types/excalidraw/components/ColorPicker/keyboardNavHandlers.d.ts +2 -1
  96. package/dist/types/excalidraw/components/FontPicker/FontPicker.d.ts +4 -1
  97. package/dist/types/excalidraw/components/FontPicker/FontPickerList.d.ts +6 -1
  98. package/dist/types/excalidraw/components/FontPicker/fontTopPicksDnD.d.ts +12 -0
  99. package/dist/types/excalidraw/components/IconButton.d.ts +48 -0
  100. package/dist/types/excalidraw/components/LaserPointerButton.d.ts +2 -4
  101. package/dist/types/excalidraw/components/LayerUI.d.ts +5 -2
  102. package/dist/types/excalidraw/components/LockButton.d.ts +3 -4
  103. package/dist/types/excalidraw/components/MagicButton.d.ts +0 -2
  104. package/dist/types/excalidraw/components/MobileMenu.d.ts +4 -4
  105. package/dist/types/excalidraw/components/MobileToolbar.d.ts +9 -0
  106. package/dist/types/excalidraw/components/PenModeButton.d.ts +2 -5
  107. package/dist/types/excalidraw/components/Popover.d.ts +1 -3
  108. package/dist/types/excalidraw/components/{ButtonIcon.d.ts → RadioButton.d.ts} +2 -5
  109. package/dist/types/excalidraw/components/ToolPopover.d.ts +3 -6
  110. package/dist/types/excalidraw/components/Toolbar.d.ts +11 -0
  111. package/dist/types/excalidraw/components/Tools.d.ts +151 -0
  112. package/dist/types/excalidraw/components/TopPicksDnD/TopPicksContextMenu.d.ts +14 -0
  113. package/dist/types/excalidraw/components/TopPicksDnD/TopPicksTip.d.ts +11 -0
  114. package/dist/types/excalidraw/components/TopPicksDnD/topPicksDnD.d.ts +58 -0
  115. package/dist/types/excalidraw/components/UserList.d.ts +3 -2
  116. package/dist/types/excalidraw/components/ViewportStatusFrame/ViewportStatusFrame.d.ts +11 -0
  117. package/dist/types/excalidraw/components/canvases/InteractiveCanvas.d.ts +2 -0
  118. package/dist/types/excalidraw/components/canvases/NewElementCanvas.d.ts +2 -0
  119. package/dist/types/excalidraw/components/footer/Footer.d.ts +3 -1
  120. package/dist/types/excalidraw/components/icons.d.ts +5 -1
  121. package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +2 -1
  122. package/dist/types/excalidraw/components/positionElementBesideCursor.d.ts +26 -0
  123. package/dist/types/excalidraw/components/shapeActionPredicates.d.ts +39 -0
  124. package/dist/types/excalidraw/data/blob.d.ts +36 -10
  125. package/dist/types/excalidraw/data/json.d.ts +18 -5
  126. package/dist/types/excalidraw/drawShapeTrail.d.ts +16 -0
  127. package/dist/types/excalidraw/fonts/Fonts.d.ts +3 -2
  128. package/dist/types/excalidraw/hooks/useTextEditorFocus.d.ts +5 -5
  129. package/dist/types/excalidraw/lasso/utils.d.ts +2 -0
  130. package/dist/types/excalidraw/renderOverrides.d.ts +9 -0
  131. package/dist/types/excalidraw/renderer/helpers.d.ts +25 -0
  132. package/dist/types/excalidraw/renderer/interactiveScene.d.ts +1 -1
  133. package/dist/types/excalidraw/scene/Renderer.d.ts +64 -2
  134. package/dist/types/excalidraw/scene/index.d.ts +1 -1
  135. package/dist/types/excalidraw/scene/types.d.ts +6 -1
  136. package/dist/types/excalidraw/types.d.ts +341 -21
  137. package/dist/types/excalidraw/viewport.d.ts +31 -66
  138. package/dist/types/laser-pointer/src/state.d.ts +1 -0
  139. package/dist/types/math/src/curve.d.ts +19 -12
  140. package/dist/types/math/src/index.d.ts +1 -0
  141. package/dist/types/math/src/pca.d.ts +79 -0
  142. package/dist/types/math/src/polygon.d.ts +25 -1
  143. package/dist/types/math/src/segment.d.ts +6 -0
  144. package/dist/types/utils/src/export.d.ts +1 -0
  145. package/dist/types/utils/src/shape.d.ts +2 -2
  146. package/package.json +2 -2
  147. package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +0 -173
  148. package/dist/types/excalidraw/components/FollowMode/FollowMode.d.ts +0 -10
  149. package/dist/types/excalidraw/components/HandButton.d.ts +0 -10
  150. package/dist/types/excalidraw/components/MobileToolBar.d.ts +0 -10
  151. package/dist/types/excalidraw/components/ToolButton.d.ts +0 -49
  152. package/dist/types/excalidraw/components/shapes.d.ts +0 -270
  153. package/dist/types/excalidraw/cursor.d.ts +0 -5
  154. package/dist/types/excalidraw/scene/zoom.d.ts +0 -12
package/dist/dev/index.js CHANGED
@@ -313,7 +313,7 @@ function curveIntersectLineSegment(c, l, opts) {
313
313
  }
314
314
  return [];
315
315
  }
316
- function curveClosestPoint(c, p, tolerance = 1e-3) {
316
+ function curveClosestParameter(c, p, tolerance = 1e-3) {
317
317
  const localMinimum = (min, max, f, e = tolerance) => {
318
318
  let m = min;
319
319
  let n = max;
@@ -330,7 +330,7 @@ function curveClosestPoint(c, p, tolerance = 1e-3) {
330
330
  };
331
331
  const maxSteps = 30;
332
332
  let closestStep = 0;
333
- for (let min = Infinity, step = 0; step < maxSteps; step++) {
333
+ for (let min = Infinity, step = 0; step <= maxSteps; step++) {
334
334
  const d = pointDistance(p, bezierEquation(c, step / maxSteps));
335
335
  if (d < min) {
336
336
  min = d;
@@ -339,22 +339,18 @@ function curveClosestPoint(c, p, tolerance = 1e-3) {
339
339
  }
340
340
  const t0 = Math.max((closestStep - 1) / maxSteps, 0);
341
341
  const t1 = Math.min((closestStep + 1) / maxSteps, 1);
342
- const solution = localMinimum(
342
+ const param = localMinimum(
343
343
  t0,
344
344
  t1,
345
345
  (t) => pointDistance(p, bezierEquation(c, t))
346
346
  );
347
- if (!solution) {
348
- return null;
349
- }
350
- return bezierEquation(c, solution);
347
+ return param ?? closestStep / maxSteps;
351
348
  }
352
- function curvePointDistance(c, p) {
353
- const closest = curveClosestPoint(c, p);
354
- if (!closest) {
355
- return 0;
356
- }
357
- return pointDistance(p, closest);
349
+ function curveClosestPoint(c, p, tolerance = 1e-3) {
350
+ return bezierEquation(c, curveClosestParameter(c, p, tolerance));
351
+ }
352
+ function curvePointDistance(c, p, tolerance = 1e-3) {
353
+ return pointDistance(p, curveClosestPoint(c, p, tolerance));
358
354
  }
359
355
  function isCurve(v) {
360
356
  return Array.isArray(v) && v.length === 4 && isPoint(v[0]) && isPoint(v[1]) && isPoint(v[2]) && isPoint(v[3]);
@@ -472,14 +468,13 @@ function curveLengthAtParameter(c, t) {
472
468
  }
473
469
  return z1 * sum;
474
470
  }
475
- function curvePointAtLength(c, percent) {
471
+ function curvePointAtLength(c, percent, totalLength = curveLength(c)) {
476
472
  if (percent <= 0) {
477
473
  return bezierEquation(c, 0);
478
474
  }
479
475
  if (percent >= 1) {
480
476
  return bezierEquation(c, 1);
481
477
  }
482
- const totalLength = curveLength(c);
483
478
  const targetLength = totalLength * percent;
484
479
  let tMin = 0;
485
480
  let tMax = 1;
@@ -528,6 +523,9 @@ var ellipseDistanceFromPoint = (p, ellipse2) => {
528
523
  vectorFromPoint(p),
529
524
  vectorScale(vectorFromPoint(center), -1)
530
525
  );
526
+ if (a === b) {
527
+ return Math.abs(Math.hypot(translatedPoint[0], translatedPoint[1]) - a);
528
+ }
531
529
  const px = Math.abs(translatedPoint[0]);
532
530
  const py = Math.abs(translatedPoint[1]);
533
531
  let tx = 0.707;
@@ -543,6 +541,9 @@ var ellipseDistanceFromPoint = (p, ellipse2) => {
543
541
  const qy = py - ey;
544
542
  const r = Math.hypot(ry, rx);
545
543
  const q = Math.hypot(qy, qx);
544
+ if (q === 0) {
545
+ break;
546
+ }
546
547
  tx = Math.min(1, Math.max(0, (qx * r / q + ex) / a));
547
548
  ty = Math.min(1, Math.max(0, (qy * r / q + ey) / b));
548
549
  const t = Math.hypot(ty, tx);
@@ -550,8 +551,8 @@ var ellipseDistanceFromPoint = (p, ellipse2) => {
550
551
  ty /= t;
551
552
  }
552
553
  const [minX, minY] = [
553
- a * tx * Math.sign(translatedPoint[0]),
554
- b * ty * Math.sign(translatedPoint[1])
554
+ a * tx * (translatedPoint[0] < 0 ? -1 : 1),
555
+ b * ty * (translatedPoint[1] < 0 ? -1 : 1)
555
556
  ];
556
557
  return pointDistance(pointFromVector(translatedPoint), pointFrom(minX, minY));
557
558
  };
@@ -638,93 +639,98 @@ function linesIntersectAt(a, b) {
638
639
  return null;
639
640
  }
640
641
 
641
- // src/segment.ts
642
- function lineSegment(a, b) {
643
- return [a, b];
644
- }
645
- var isLineSegment = (segment) => Array.isArray(segment) && segment.length === 2 && isPoint(segment[0]) && isPoint(segment[1]);
646
- var lineSegmentRotate = (l, angle, origin) => {
647
- return lineSegment(
648
- pointRotateRads(l[0], origin || pointCenter(l[0], l[1]), angle),
649
- pointRotateRads(l[1], origin || pointCenter(l[0], l[1]), angle)
650
- );
651
- };
652
- var segmentsIntersectAt = (a, b) => {
653
- const a0 = vectorFromPoint(a[0]);
654
- const a1 = vectorFromPoint(a[1]);
655
- const b0 = vectorFromPoint(b[0]);
656
- const b1 = vectorFromPoint(b[1]);
657
- const r = vectorSubtract(a1, a0);
658
- const s = vectorSubtract(b1, b0);
659
- const denominator = vectorCross(r, s);
660
- if (denominator === 0) {
661
- return null;
642
+ // src/pca.ts
643
+ function centroid(points) {
644
+ let cx = 0;
645
+ let cy = 0;
646
+ for (const [x, y] of points) {
647
+ cx += x;
648
+ cy += y;
662
649
  }
663
- const i = vectorSubtract(vectorFromPoint(b[0]), vectorFromPoint(a[0]));
664
- const u = vectorCross(i, r) / denominator;
665
- const t = vectorCross(i, s) / denominator;
666
- if (u === 0) {
667
- return null;
668
- }
669
- const p = vectorAdd(a0, vectorScale(r, t));
670
- if (t >= 0 && t < 1 && u >= 0 && u < 1) {
671
- return pointFromVector(p);
672
- }
673
- return null;
674
- };
675
- var pointOnLineSegment = (point, line2, threshold = PRECISION) => {
676
- const distance = distanceToLineSegment(point, line2);
677
- if (distance === 0) {
678
- return true;
650
+ return pointFrom(cx / points.length, cy / points.length);
651
+ }
652
+ function principalAxes(points) {
653
+ if (points.length < 2) {
654
+ console.error("Degenerate point set: at least two points are required");
679
655
  }
680
- return distance < threshold;
681
- };
682
- var distanceToLineSegment = (point, line2) => {
683
- const [x, y] = point;
684
- const [[x1, y1], [x2, y2]] = line2;
685
- const A = x - x1;
686
- const B = y - y1;
687
- const C = x2 - x1;
688
- const D = y2 - y1;
689
- const dot = A * C + B * D;
690
- const len_sq = C * C + D * D;
691
- let param = -1;
692
- if (len_sq !== 0) {
693
- param = dot / len_sq;
656
+ const c = centroid(points);
657
+ let m20 = 0;
658
+ let m02 = 0;
659
+ let m11 = 0;
660
+ for (const [x, y] of points) {
661
+ const dx = x - c[0];
662
+ const dy = y - c[1];
663
+ m20 += dx * dx;
664
+ m02 += dy * dy;
665
+ m11 += dx * dy;
694
666
  }
695
- let xx;
696
- let yy;
697
- if (param < 0) {
698
- xx = x1;
699
- yy = y1;
700
- } else if (param > 1) {
701
- xx = x2;
702
- yy = y2;
667
+ m20 /= points.length;
668
+ m02 /= points.length;
669
+ m11 /= points.length;
670
+ const trace = m20 + m02;
671
+ const diff = Math.hypot(m20 - m02, 2 * m11);
672
+ const majorVariance = (trace + diff) / 2;
673
+ const minorVariance = (trace - diff) / 2;
674
+ let major;
675
+ if (Math.abs(m11) > Number.EPSILON) {
676
+ major = vectorNormalize(vector(majorVariance - m02, m11));
703
677
  } else {
704
- xx = x1 + param * C;
705
- yy = y1 + param * D;
678
+ major = m20 >= m02 ? vector(1, 0) : vector(0, 1);
706
679
  }
707
- const dx = x - xx;
708
- const dy = y - yy;
709
- return Math.sqrt(dx * dx + dy * dy);
710
- };
711
- function lineSegmentIntersectionPoints(l, s, threshold) {
712
- const candidate = linesIntersectAt(line(l[0], l[1]), line(s[0], s[1]));
713
- if (!candidate || !pointOnLineSegment(candidate, s, threshold) || !pointOnLineSegment(candidate, l, threshold)) {
714
- return null;
680
+ return {
681
+ centroid: c,
682
+ major,
683
+ minor: vectorNormal(major),
684
+ majorVariance,
685
+ minorVariance
686
+ };
687
+ }
688
+ function principalCoords(points, axes, scale = 1) {
689
+ const { centroid: c, major, minor } = axes;
690
+ return points.map(([x, y]) => {
691
+ const dx = x - c[0];
692
+ const dy = y - c[1];
693
+ return [
694
+ (dx * major[0] + dy * major[1]) * scale,
695
+ (dx * minor[0] + dy * minor[1]) * scale
696
+ ];
697
+ });
698
+ }
699
+ function orientPrincipalAxes(points, axes) {
700
+ const u = principalCoords(points, axes).map(([uu]) => uu);
701
+ if (skewness(u) <= 0) {
702
+ return axes;
715
703
  }
716
- return candidate;
704
+ const major = vectorScale(axes.major, -1);
705
+ return { ...axes, major, minor: vectorNormal(major) };
717
706
  }
718
- function lineSegmentsDistance(s1, s2) {
719
- if (lineSegmentIntersectionPoints(s1, s2)) {
720
- return 0;
707
+ function elongation(axes) {
708
+ return axes.majorVariance > 0 ? axes.minorVariance / axes.majorVariance : 1;
709
+ }
710
+ function standardizedMoment(values, order) {
711
+ const n = values.length;
712
+ let mean = 0;
713
+ for (const v of values) {
714
+ mean += v;
721
715
  }
722
- return Math.min(
723
- distanceToLineSegment(s1[0], s2),
724
- distanceToLineSegment(s1[1], s2),
725
- distanceToLineSegment(s2[0], s1),
726
- distanceToLineSegment(s2[1], s1)
727
- );
716
+ mean /= n;
717
+ let variance = 0;
718
+ let moment = 0;
719
+ for (const v of values) {
720
+ const d = v - mean;
721
+ variance += d * d;
722
+ moment += d ** order;
723
+ }
724
+ variance /= n;
725
+ moment /= n;
726
+ const sigma = Math.sqrt(variance);
727
+ return sigma > Number.EPSILON ? moment / sigma ** order : 0;
728
+ }
729
+ function skewness(values) {
730
+ return standardizedMoment(values, 3);
731
+ }
732
+ function kurtosis(values) {
733
+ return standardizedMoment(values, 4);
728
734
  }
729
735
 
730
736
  // src/polygon.ts
@@ -770,21 +776,84 @@ var polygonIncludesPointNonZero = (point, polygon2) => {
770
776
  }
771
777
  return windingNumber !== 0;
772
778
  };
773
- var pointOnPolygon = (p, poly, threshold = PRECISION) => {
774
- let on = false;
775
- for (let i = 0, l = poly.length - 1; i < l; i++) {
776
- if (pointOnLineSegment(p, lineSegment(poly[i], poly[i + 1]), threshold)) {
777
- on = true;
778
- break;
779
- }
780
- }
781
- return on;
782
- };
783
779
  function polygonClose(polygon2) {
784
780
  return polygonIsClosed(polygon2) ? polygon2 : [...polygon2, polygon2[0]];
785
781
  }
786
- function polygonIsClosed(polygon2) {
787
- return pointsEqual(polygon2[0], polygon2[polygon2.length - 1]);
782
+ function polygonIsClosed(polygon2, tolerance = PRECISION) {
783
+ return pointsEqual(polygon2[0], polygon2[polygon2.length - 1], tolerance);
784
+ }
785
+ function polygonSignedArea(polygon2, tolerance = PRECISION) {
786
+ const pts = polygonIsClosed(polygon2, tolerance) ? polygon2.slice(0, -1) : polygon2;
787
+ let sum = 0;
788
+ for (let i = 0, j = pts.length - 1; i < pts.length; j = i++) {
789
+ sum += pts[j][0] * pts[i][1] - pts[i][0] * pts[j][1];
790
+ }
791
+ return sum / 2;
792
+ }
793
+ function polygonArea(polygon2, tolerance = PRECISION) {
794
+ return Math.abs(polygonSignedArea(polygon2, tolerance));
795
+ }
796
+ function convexHull(points) {
797
+ if (points.length < 3) {
798
+ return [...points];
799
+ }
800
+ const sorted = [...points].sort(
801
+ (a, b) => a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]
802
+ );
803
+ const cross = (o, a, b) => (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
804
+ const half = (pts) => {
805
+ const chain = [];
806
+ for (const p of pts) {
807
+ while (chain.length >= 2 && cross(chain[chain.length - 2], chain[chain.length - 1], p) <= 0) {
808
+ chain.pop();
809
+ }
810
+ chain.push(p);
811
+ }
812
+ chain.pop();
813
+ return chain;
814
+ };
815
+ const hull = [...half(sorted), ...half([...sorted].reverse())];
816
+ return hull.length >= 3 ? hull : [...points];
817
+ }
818
+ function simplifyConvexPolygon(polygon2, angleThreshold) {
819
+ if (polygon2.length < 3) {
820
+ return [...polygon2];
821
+ }
822
+ const turnAt = (i) => {
823
+ const prev = polygon2[(i - 1 + polygon2.length) % polygon2.length];
824
+ const curr = polygon2[i];
825
+ const next = polygon2[(i + 1) % polygon2.length];
826
+ const inAngle = Math.atan2(curr[1] - prev[1], curr[0] - prev[0]);
827
+ const outAngle = Math.atan2(next[1] - curr[1], next[0] - curr[0]);
828
+ return Math.abs(normalizeTurn(outAngle - inAngle));
829
+ };
830
+ let start = 0;
831
+ for (let i = 1; i < polygon2.length; i++) {
832
+ if (turnAt(i) > turnAt(start)) {
833
+ start = i;
834
+ }
835
+ }
836
+ const simplified = [];
837
+ let accumulated = 0;
838
+ for (let k = 0; k < polygon2.length; k++) {
839
+ const i = (start + k) % polygon2.length;
840
+ accumulated += turnAt(i);
841
+ if (accumulated >= angleThreshold) {
842
+ simplified.push(polygon2[i]);
843
+ accumulated = 0;
844
+ }
845
+ }
846
+ return simplified.length >= 3 ? simplified : [...polygon2];
847
+ }
848
+ function normalizeTurn(angle) {
849
+ let a = angle;
850
+ while (a > Math.PI) {
851
+ a -= 2 * Math.PI;
852
+ }
853
+ while (a < -Math.PI) {
854
+ a += 2 * Math.PI;
855
+ }
856
+ return a;
788
857
  }
789
858
 
790
859
  // src/range.ts
@@ -816,6 +885,91 @@ var rangeIncludesValue = (value, [min, max]) => {
816
885
  return value >= min && value <= max;
817
886
  };
818
887
 
888
+ // src/segment.ts
889
+ function lineSegment(a, b) {
890
+ return [a, b];
891
+ }
892
+ var isLineSegment = (segment) => Array.isArray(segment) && segment.length === 2 && isPoint(segment[0]) && isPoint(segment[1]);
893
+ var lineSegmentRotate = (l, angle, origin) => {
894
+ return lineSegment(
895
+ pointRotateRads(l[0], origin || pointCenter(l[0], l[1]), angle),
896
+ pointRotateRads(l[1], origin || pointCenter(l[0], l[1]), angle)
897
+ );
898
+ };
899
+ var segmentsIntersectAt = (a, b) => {
900
+ const a0 = vectorFromPoint(a[0]);
901
+ const a1 = vectorFromPoint(a[1]);
902
+ const b0 = vectorFromPoint(b[0]);
903
+ const b1 = vectorFromPoint(b[1]);
904
+ const r = vectorSubtract(a1, a0);
905
+ const s = vectorSubtract(b1, b0);
906
+ const denominator = vectorCross(r, s);
907
+ if (denominator === 0) {
908
+ return null;
909
+ }
910
+ const i = vectorSubtract(vectorFromPoint(b[0]), vectorFromPoint(a[0]));
911
+ const u = vectorCross(i, r) / denominator;
912
+ const t = vectorCross(i, s) / denominator;
913
+ if (u === 0) {
914
+ return null;
915
+ }
916
+ const p = vectorAdd(a0, vectorScale(r, t));
917
+ if (t >= 0 && t < 1 && u >= 0 && u < 1) {
918
+ return pointFromVector(p);
919
+ }
920
+ return null;
921
+ };
922
+ var pointOnLineSegment = (point, line2, threshold = PRECISION) => {
923
+ const distance = distanceToLineSegment(point, line2);
924
+ if (distance === 0) {
925
+ return true;
926
+ }
927
+ return distance < threshold;
928
+ };
929
+ var distanceToLineSegment = (point, line2) => {
930
+ return pointDistance(
931
+ point,
932
+ lineSegmentPointAt(line2, lineSegmentClosestParameter(point, line2))
933
+ );
934
+ };
935
+ function lineSegmentPointAt(line2, t) {
936
+ const [[x1, y1], [x2, y2]] = line2;
937
+ return pointFrom(x1 + t * (x2 - x1), y1 + t * (y2 - y1));
938
+ }
939
+ function lineSegmentIntersectionPoints(l, s, threshold) {
940
+ const candidate = linesIntersectAt(line(l[0], l[1]), line(s[0], s[1]));
941
+ if (!candidate || !pointOnLineSegment(candidate, s, threshold) || !pointOnLineSegment(candidate, l, threshold)) {
942
+ return null;
943
+ }
944
+ return candidate;
945
+ }
946
+ function lineSegmentsDistance(s1, s2) {
947
+ if (lineSegmentIntersectionPoints(s1, s2)) {
948
+ return 0;
949
+ }
950
+ return Math.min(
951
+ distanceToLineSegment(s1[0], s2),
952
+ distanceToLineSegment(s1[1], s2),
953
+ distanceToLineSegment(s2[0], s1),
954
+ distanceToLineSegment(s2[1], s1)
955
+ );
956
+ }
957
+ function lineSegmentClosestParameter(point, line2) {
958
+ const [x, y] = point;
959
+ const [[x1, y1], [x2, y2]] = line2;
960
+ const A = x - x1;
961
+ const B = y - y1;
962
+ const C = x2 - x1;
963
+ const D = y2 - y1;
964
+ const dot = A * C + B * D;
965
+ const len_sq = C * C + D * D;
966
+ let param = 0;
967
+ if (len_sq !== 0) {
968
+ param = dot / len_sq;
969
+ }
970
+ return Math.max(0, Math.min(1, param));
971
+ }
972
+
819
973
  // src/rectangle.ts
820
974
  function rectangle(topLeft, bottomRight) {
821
975
  return [topLeft, bottomRight];
@@ -852,10 +1006,13 @@ export {
852
1006
  average,
853
1007
  bezierEquation,
854
1008
  cartesian2Polar,
1009
+ centroid,
855
1010
  clamp,
1011
+ convexHull,
856
1012
  curve,
857
1013
  curveCatmullRomCubicApproxPoints,
858
1014
  curveCatmullRomQuadraticApproxPoints,
1015
+ curveClosestParameter,
859
1016
  curveClosestPoint,
860
1017
  curveIntersectLineSegment,
861
1018
  curveLength,
@@ -872,6 +1029,7 @@ export {
872
1029
  ellipseLineIntersectionPoints,
873
1030
  ellipseSegmentInterceptPoints,
874
1031
  ellipseTouchesPoint,
1032
+ elongation,
875
1033
  isCloseTo,
876
1034
  isCurve,
877
1035
  isFiniteNumber,
@@ -881,14 +1039,18 @@ export {
881
1039
  isRightAngleRads,
882
1040
  isValidPoint,
883
1041
  isVector,
1042
+ kurtosis,
884
1043
  line,
885
1044
  lineSegment,
1045
+ lineSegmentClosestParameter,
886
1046
  lineSegmentIntersectionPoints,
1047
+ lineSegmentPointAt,
887
1048
  lineSegmentRotate,
888
1049
  lineSegmentsDistance,
889
1050
  linesIntersectAt,
890
1051
  normalizeRadians,
891
1052
  offsetPointsForQuadraticBezier,
1053
+ orientPrincipalAxes,
892
1054
  pointCenter,
893
1055
  pointDistance,
894
1056
  pointDistanceSq,
@@ -897,16 +1059,20 @@ export {
897
1059
  pointFromPair,
898
1060
  pointFromVector,
899
1061
  pointOnLineSegment,
900
- pointOnPolygon,
901
1062
  pointRotateDegs,
902
1063
  pointRotateRads,
903
1064
  pointScaleFromOrigin,
904
1065
  pointTranslate,
905
1066
  pointsEqual,
906
1067
  polygon,
1068
+ polygonArea,
907
1069
  polygonFromPoints,
908
1070
  polygonIncludesPoint,
909
1071
  polygonIncludesPointNonZero,
1072
+ polygonIsClosed,
1073
+ polygonSignedArea,
1074
+ principalAxes,
1075
+ principalCoords,
910
1076
  radiansBetweenAngles,
911
1077
  radiansDifference,
912
1078
  radiansToDegrees,
@@ -922,6 +1088,9 @@ export {
922
1088
  round,
923
1089
  roundToStep,
924
1090
  segmentsIntersectAt,
1091
+ simplifyConvexPolygon,
1092
+ skewness,
1093
+ standardizedMoment,
925
1094
  triangleIncludesPoint,
926
1095
  vector,
927
1096
  vectorAdd,