@excalidraw/math 0.18.0-2a82821 → 0.18.0-2b1c2a9

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 (160) hide show
  1. package/dist/dev/index.js +270 -107
  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 +19 -0
  5. package/dist/types/common/src/constants.d.ts +3 -0
  6. package/dist/types/common/src/keys.d.ts +2 -0
  7. package/dist/types/common/src/points.d.ts +1 -1
  8. package/dist/types/common/src/utils.d.ts +1 -43
  9. package/dist/types/element/src/Scene.d.ts +1 -1
  10. package/dist/types/element/src/align.d.ts +2 -2
  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 +17 -8
  14. package/dist/types/element/src/bounds.d.ts +5 -9
  15. package/dist/types/element/src/bucketFill.d.ts +110 -0
  16. package/dist/types/element/src/collision.d.ts +1 -1
  17. package/dist/types/element/src/comparisons.d.ts +4 -4
  18. package/dist/types/element/src/convertToShape.d.ts +23 -0
  19. package/dist/types/element/src/distribute.d.ts +2 -2
  20. package/dist/types/element/src/dragElements.d.ts +27 -0
  21. package/dist/types/element/src/duplicate.d.ts +3 -3
  22. package/dist/types/element/src/embeddable.d.ts +2 -2
  23. package/dist/types/element/src/flowchart.d.ts +7 -7
  24. package/dist/types/element/src/fractionalIndex.d.ts +2 -2
  25. package/dist/types/element/src/frame.d.ts +4 -4
  26. package/dist/types/element/src/groups.d.ts +9 -9
  27. package/dist/types/element/src/index.d.ts +4 -1
  28. package/dist/types/element/src/linearElementEditor.d.ts +27 -10
  29. package/dist/types/element/src/newElement.d.ts +14 -0
  30. package/dist/types/element/src/renderElement.d.ts +0 -3
  31. package/dist/types/element/src/resizeElements.d.ts +2 -2
  32. package/dist/types/element/src/selection.d.ts +5 -5
  33. package/dist/types/element/src/shape.d.ts +12 -0
  34. package/dist/types/element/src/sortElements.d.ts +10 -0
  35. package/dist/types/element/src/textElement.d.ts +13 -9
  36. package/dist/types/element/src/transform.d.ts +2 -2
  37. package/dist/types/element/src/typeChecks.d.ts +25 -25
  38. package/dist/types/element/src/types.d.ts +9 -1
  39. package/dist/types/element/src/utils.d.ts +7 -3
  40. package/dist/types/element/src/zindex.d.ts +2 -2
  41. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +36 -12
  42. package/dist/types/excalidraw/actions/actionAlign.d.ts +6 -6
  43. package/dist/types/excalidraw/actions/actionBoundText.d.ts +24 -8
  44. package/dist/types/excalidraw/actions/actionCanvas.d.ts +146 -931
  45. package/dist/types/excalidraw/actions/actionClipboard.d.ts +24 -8
  46. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +12 -4
  47. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +38 -13
  48. package/dist/types/excalidraw/actions/actionDeselect.d.ts +9 -4
  49. package/dist/types/excalidraw/actions/actionDistribute.d.ts +2 -3
  50. package/dist/types/excalidraw/actions/actionElementLink.d.ts +12 -4
  51. package/dist/types/excalidraw/actions/actionElementLock.d.ts +25 -9
  52. package/dist/types/excalidraw/actions/actionExport.d.ts +26 -10
  53. package/dist/types/excalidraw/actions/actionFinalize.d.ts +1 -0
  54. package/dist/types/excalidraw/actions/actionFrame.d.ts +48 -197
  55. package/dist/types/excalidraw/actions/actionGroup.d.ts +39 -23
  56. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +16 -6
  57. package/dist/types/excalidraw/actions/actionLink.d.ts +13 -5
  58. package/dist/types/excalidraw/actions/actionMenu.d.ts +12 -4
  59. package/dist/types/excalidraw/actions/actionProperties.d.ts +43 -24
  60. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +17 -9
  61. package/dist/types/excalidraw/actions/actionStyles.d.ts +12 -4
  62. package/dist/types/excalidraw/actions/actionTextAutoResize.d.ts +1 -1
  63. package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +13 -5
  64. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +16 -9
  65. package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +13 -5
  66. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +13 -5
  67. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +16 -9
  68. package/dist/types/excalidraw/actions/actionToggleShapeSwitch.d.ts +1 -1
  69. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +13 -5
  70. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +14 -6
  71. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +13 -5
  72. package/dist/types/excalidraw/actions/index.d.ts +1 -2
  73. package/dist/types/excalidraw/actions/manager.d.ts +1 -0
  74. package/dist/types/excalidraw/actions/shortcuts.d.ts +1 -1
  75. package/dist/types/excalidraw/actions/types.d.ts +8 -4
  76. package/dist/types/excalidraw/appState.d.ts +9 -4
  77. package/dist/types/excalidraw/components/Actions.d.ts +17 -12
  78. package/dist/types/excalidraw/components/App.arrowText.d.ts +104 -0
  79. package/dist/types/excalidraw/components/App.bucketFill.d.ts +48 -0
  80. package/dist/types/excalidraw/components/App.cursor.d.ts +38 -0
  81. package/dist/types/excalidraw/components/App.d.ts +372 -67
  82. package/dist/types/excalidraw/components/App.drawshape.d.ts +55 -0
  83. package/dist/types/excalidraw/components/App.flowchart.d.ts +21 -0
  84. package/dist/types/excalidraw/components/App.viewport.d.ts +73 -0
  85. package/dist/types/excalidraw/components/ColorPicker/ColorPicker.d.ts +9 -3
  86. package/dist/types/excalidraw/components/ColorPicker/CustomColorList.d.ts +3 -1
  87. package/dist/types/excalidraw/components/ColorPicker/Picker.d.ts +3 -1
  88. package/dist/types/excalidraw/components/ColorPicker/PickerColorList.d.ts +9 -2
  89. package/dist/types/excalidraw/components/ColorPicker/ShadeList.d.ts +4 -2
  90. package/dist/types/excalidraw/components/ColorPicker/TopPicks.d.ts +8 -1
  91. package/dist/types/excalidraw/components/ColorPicker/keyboardNavHandlers.d.ts +2 -1
  92. package/dist/types/excalidraw/components/ColorPicker/topPicksDnD.d.ts +31 -0
  93. package/dist/types/excalidraw/components/ConvertElementTypePopup.d.ts +1 -1
  94. package/dist/types/excalidraw/components/CursorHint.d.ts +46 -0
  95. package/dist/types/excalidraw/components/{ToolButton.d.ts → IconButton.d.ts} +16 -19
  96. package/dist/types/excalidraw/components/Island.d.ts +7 -0
  97. package/dist/types/excalidraw/components/LaserPointerButton.d.ts +2 -4
  98. package/dist/types/excalidraw/components/LayerUI.d.ts +5 -2
  99. package/dist/types/excalidraw/components/LockButton.d.ts +3 -4
  100. package/dist/types/excalidraw/components/MagicButton.d.ts +0 -2
  101. package/dist/types/excalidraw/components/MobileMenu.d.ts +4 -4
  102. package/dist/types/excalidraw/components/MobileToolbar.d.ts +9 -0
  103. package/dist/types/excalidraw/components/PenModeButton.d.ts +2 -5
  104. package/dist/types/excalidraw/components/Popover.d.ts +1 -3
  105. package/dist/types/excalidraw/components/{ButtonIcon.d.ts → RadioButton.d.ts} +2 -5
  106. package/dist/types/excalidraw/components/Stats/Angle.d.ts +2 -2
  107. package/dist/types/excalidraw/components/Stats/Dimension.d.ts +2 -2
  108. package/dist/types/excalidraw/components/Stats/DragInput.d.ts +2 -2
  109. package/dist/types/excalidraw/components/Stats/MultiAngle.d.ts +2 -2
  110. package/dist/types/excalidraw/components/Stats/MultiDimension.d.ts +2 -2
  111. package/dist/types/excalidraw/components/Stats/MultiPosition.d.ts +2 -2
  112. package/dist/types/excalidraw/components/Stats/Position.d.ts +3 -3
  113. package/dist/types/excalidraw/components/Stats/utils.d.ts +1 -1
  114. package/dist/types/excalidraw/components/ToolPopover.d.ts +3 -6
  115. package/dist/types/excalidraw/components/Toolbar.d.ts +11 -0
  116. package/dist/types/excalidraw/components/Tools.d.ts +146 -0
  117. package/dist/types/excalidraw/components/UserList.d.ts +3 -2
  118. package/dist/types/excalidraw/components/ViewportStatusFrame/ViewportStatusFrame.d.ts +11 -0
  119. package/dist/types/excalidraw/components/canvases/InteractiveCanvas.d.ts +2 -0
  120. package/dist/types/excalidraw/components/footer/Footer.d.ts +3 -1
  121. package/dist/types/excalidraw/components/hyperlink/helpers.d.ts +2 -2
  122. package/dist/types/excalidraw/components/icons.d.ts +4 -1
  123. package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +1 -1
  124. package/dist/types/excalidraw/components/positionElementBesideCursor.d.ts +26 -0
  125. package/dist/types/excalidraw/components/shapeActionPredicates.d.ts +39 -0
  126. package/dist/types/excalidraw/data/blob.d.ts +28 -12
  127. package/dist/types/excalidraw/data/index.d.ts +4 -4
  128. package/dist/types/excalidraw/data/json.d.ts +20 -12
  129. package/dist/types/excalidraw/drawShapeTrail.d.ts +16 -0
  130. package/dist/types/excalidraw/fonts/Fonts.d.ts +3 -2
  131. package/dist/types/excalidraw/hooks/useAppStateValue.d.ts +29 -0
  132. package/dist/types/excalidraw/hooks/useTextEditorFocus.d.ts +5 -5
  133. package/dist/types/excalidraw/lasso/utils.d.ts +2 -0
  134. package/dist/types/excalidraw/renderer/animation.d.ts +1 -0
  135. package/dist/types/excalidraw/renderer/helpers.d.ts +7 -0
  136. package/dist/types/excalidraw/renderer/interactiveScene.d.ts +1 -3
  137. package/dist/types/excalidraw/scene/Renderer.d.ts +12 -11
  138. package/dist/types/excalidraw/scene/export.d.ts +3 -3
  139. package/dist/types/excalidraw/scene/index.d.ts +1 -1
  140. package/dist/types/excalidraw/scene/types.d.ts +4 -3
  141. package/dist/types/excalidraw/snapping.d.ts +7 -7
  142. package/dist/types/excalidraw/types.d.ts +410 -20
  143. package/dist/types/excalidraw/viewport.d.ts +275 -0
  144. package/dist/types/excalidraw/wysiwyg/textWysiwyg.d.ts +2 -3
  145. package/dist/types/laser-pointer/src/state.d.ts +1 -0
  146. package/dist/types/math/src/curve.d.ts +19 -12
  147. package/dist/types/math/src/index.d.ts +1 -0
  148. package/dist/types/math/src/pca.d.ts +79 -0
  149. package/dist/types/math/src/polygon.d.ts +25 -1
  150. package/dist/types/math/src/segment.d.ts +6 -0
  151. package/dist/types/utils/src/export.d.ts +3 -3
  152. package/package.json +2 -2
  153. package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +0 -172
  154. package/dist/types/excalidraw/components/FollowMode/FollowMode.d.ts +0 -10
  155. package/dist/types/excalidraw/components/HandButton.d.ts +0 -10
  156. package/dist/types/excalidraw/components/MobileToolBar.d.ts +0 -10
  157. package/dist/types/excalidraw/components/shapes.d.ts +0 -270
  158. package/dist/types/excalidraw/cursor.d.ts +0 -5
  159. package/dist/types/excalidraw/scene/scroll.d.ts +0 -18
  160. 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;
@@ -638,93 +633,98 @@ function linesIntersectAt(a, b) {
638
633
  return null;
639
634
  }
640
635
 
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;
662
- }
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;
636
+ // src/pca.ts
637
+ function centroid(points) {
638
+ let cx = 0;
639
+ let cy = 0;
640
+ for (const [x, y] of points) {
641
+ cx += x;
642
+ cy += y;
668
643
  }
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;
644
+ return pointFrom(cx / points.length, cy / points.length);
645
+ }
646
+ function principalAxes(points) {
647
+ if (points.length < 2) {
648
+ console.error("Degenerate point set: at least two points are required");
679
649
  }
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;
650
+ const c = centroid(points);
651
+ let m20 = 0;
652
+ let m02 = 0;
653
+ let m11 = 0;
654
+ for (const [x, y] of points) {
655
+ const dx = x - c[0];
656
+ const dy = y - c[1];
657
+ m20 += dx * dx;
658
+ m02 += dy * dy;
659
+ m11 += dx * dy;
694
660
  }
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;
661
+ m20 /= points.length;
662
+ m02 /= points.length;
663
+ m11 /= points.length;
664
+ const trace = m20 + m02;
665
+ const diff = Math.hypot(m20 - m02, 2 * m11);
666
+ const majorVariance = (trace + diff) / 2;
667
+ const minorVariance = (trace - diff) / 2;
668
+ let major;
669
+ if (Math.abs(m11) > Number.EPSILON) {
670
+ major = vectorNormalize(vector(majorVariance - m02, m11));
703
671
  } else {
704
- xx = x1 + param * C;
705
- yy = y1 + param * D;
672
+ major = m20 >= m02 ? vector(1, 0) : vector(0, 1);
706
673
  }
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;
674
+ return {
675
+ centroid: c,
676
+ major,
677
+ minor: vectorNormal(major),
678
+ majorVariance,
679
+ minorVariance
680
+ };
681
+ }
682
+ function principalCoords(points, axes, scale = 1) {
683
+ const { centroid: c, major, minor } = axes;
684
+ return points.map(([x, y]) => {
685
+ const dx = x - c[0];
686
+ const dy = y - c[1];
687
+ return [
688
+ (dx * major[0] + dy * major[1]) * scale,
689
+ (dx * minor[0] + dy * minor[1]) * scale
690
+ ];
691
+ });
692
+ }
693
+ function orientPrincipalAxes(points, axes) {
694
+ const u = principalCoords(points, axes).map(([uu]) => uu);
695
+ if (skewness(u) <= 0) {
696
+ return axes;
715
697
  }
716
- return candidate;
698
+ const major = vectorScale(axes.major, -1);
699
+ return { ...axes, major, minor: vectorNormal(major) };
717
700
  }
718
- function lineSegmentsDistance(s1, s2) {
719
- if (lineSegmentIntersectionPoints(s1, s2)) {
720
- return 0;
701
+ function elongation(axes) {
702
+ return axes.majorVariance > 0 ? axes.minorVariance / axes.majorVariance : 1;
703
+ }
704
+ function standardizedMoment(values, order) {
705
+ const n = values.length;
706
+ let mean = 0;
707
+ for (const v of values) {
708
+ mean += v;
721
709
  }
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
- );
710
+ mean /= n;
711
+ let variance = 0;
712
+ let moment = 0;
713
+ for (const v of values) {
714
+ const d = v - mean;
715
+ variance += d * d;
716
+ moment += d ** order;
717
+ }
718
+ variance /= n;
719
+ moment /= n;
720
+ const sigma = Math.sqrt(variance);
721
+ return sigma > Number.EPSILON ? moment / sigma ** order : 0;
722
+ }
723
+ function skewness(values) {
724
+ return standardizedMoment(values, 3);
725
+ }
726
+ function kurtosis(values) {
727
+ return standardizedMoment(values, 4);
728
728
  }
729
729
 
730
730
  // src/polygon.ts
@@ -770,21 +770,84 @@ var polygonIncludesPointNonZero = (point, polygon2) => {
770
770
  }
771
771
  return windingNumber !== 0;
772
772
  };
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
773
  function polygonClose(polygon2) {
784
774
  return polygonIsClosed(polygon2) ? polygon2 : [...polygon2, polygon2[0]];
785
775
  }
786
- function polygonIsClosed(polygon2) {
787
- return pointsEqual(polygon2[0], polygon2[polygon2.length - 1]);
776
+ function polygonIsClosed(polygon2, tolerance = PRECISION) {
777
+ return pointsEqual(polygon2[0], polygon2[polygon2.length - 1], tolerance);
778
+ }
779
+ function polygonSignedArea(polygon2, tolerance = PRECISION) {
780
+ const pts = polygonIsClosed(polygon2, tolerance) ? polygon2.slice(0, -1) : polygon2;
781
+ let sum = 0;
782
+ for (let i = 0, j = pts.length - 1; i < pts.length; j = i++) {
783
+ sum += pts[j][0] * pts[i][1] - pts[i][0] * pts[j][1];
784
+ }
785
+ return sum / 2;
786
+ }
787
+ function polygonArea(polygon2, tolerance = PRECISION) {
788
+ return Math.abs(polygonSignedArea(polygon2, tolerance));
789
+ }
790
+ function convexHull(points) {
791
+ if (points.length < 3) {
792
+ return [...points];
793
+ }
794
+ const sorted = [...points].sort(
795
+ (a, b) => a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]
796
+ );
797
+ const cross = (o, a, b) => (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
798
+ const half = (pts) => {
799
+ const chain = [];
800
+ for (const p of pts) {
801
+ while (chain.length >= 2 && cross(chain[chain.length - 2], chain[chain.length - 1], p) <= 0) {
802
+ chain.pop();
803
+ }
804
+ chain.push(p);
805
+ }
806
+ chain.pop();
807
+ return chain;
808
+ };
809
+ const hull = [...half(sorted), ...half([...sorted].reverse())];
810
+ return hull.length >= 3 ? hull : [...points];
811
+ }
812
+ function simplifyConvexPolygon(polygon2, angleThreshold) {
813
+ if (polygon2.length < 3) {
814
+ return [...polygon2];
815
+ }
816
+ const turnAt = (i) => {
817
+ const prev = polygon2[(i - 1 + polygon2.length) % polygon2.length];
818
+ const curr = polygon2[i];
819
+ const next = polygon2[(i + 1) % polygon2.length];
820
+ const inAngle = Math.atan2(curr[1] - prev[1], curr[0] - prev[0]);
821
+ const outAngle = Math.atan2(next[1] - curr[1], next[0] - curr[0]);
822
+ return Math.abs(normalizeTurn(outAngle - inAngle));
823
+ };
824
+ let start = 0;
825
+ for (let i = 1; i < polygon2.length; i++) {
826
+ if (turnAt(i) > turnAt(start)) {
827
+ start = i;
828
+ }
829
+ }
830
+ const simplified = [];
831
+ let accumulated = 0;
832
+ for (let k = 0; k < polygon2.length; k++) {
833
+ const i = (start + k) % polygon2.length;
834
+ accumulated += turnAt(i);
835
+ if (accumulated >= angleThreshold) {
836
+ simplified.push(polygon2[i]);
837
+ accumulated = 0;
838
+ }
839
+ }
840
+ return simplified.length >= 3 ? simplified : [...polygon2];
841
+ }
842
+ function normalizeTurn(angle) {
843
+ let a = angle;
844
+ while (a > Math.PI) {
845
+ a -= 2 * Math.PI;
846
+ }
847
+ while (a < -Math.PI) {
848
+ a += 2 * Math.PI;
849
+ }
850
+ return a;
788
851
  }
789
852
 
790
853
  // src/range.ts
@@ -816,6 +879,91 @@ var rangeIncludesValue = (value, [min, max]) => {
816
879
  return value >= min && value <= max;
817
880
  };
818
881
 
882
+ // src/segment.ts
883
+ function lineSegment(a, b) {
884
+ return [a, b];
885
+ }
886
+ var isLineSegment = (segment) => Array.isArray(segment) && segment.length === 2 && isPoint(segment[0]) && isPoint(segment[1]);
887
+ var lineSegmentRotate = (l, angle, origin) => {
888
+ return lineSegment(
889
+ pointRotateRads(l[0], origin || pointCenter(l[0], l[1]), angle),
890
+ pointRotateRads(l[1], origin || pointCenter(l[0], l[1]), angle)
891
+ );
892
+ };
893
+ var segmentsIntersectAt = (a, b) => {
894
+ const a0 = vectorFromPoint(a[0]);
895
+ const a1 = vectorFromPoint(a[1]);
896
+ const b0 = vectorFromPoint(b[0]);
897
+ const b1 = vectorFromPoint(b[1]);
898
+ const r = vectorSubtract(a1, a0);
899
+ const s = vectorSubtract(b1, b0);
900
+ const denominator = vectorCross(r, s);
901
+ if (denominator === 0) {
902
+ return null;
903
+ }
904
+ const i = vectorSubtract(vectorFromPoint(b[0]), vectorFromPoint(a[0]));
905
+ const u = vectorCross(i, r) / denominator;
906
+ const t = vectorCross(i, s) / denominator;
907
+ if (u === 0) {
908
+ return null;
909
+ }
910
+ const p = vectorAdd(a0, vectorScale(r, t));
911
+ if (t >= 0 && t < 1 && u >= 0 && u < 1) {
912
+ return pointFromVector(p);
913
+ }
914
+ return null;
915
+ };
916
+ var pointOnLineSegment = (point, line2, threshold = PRECISION) => {
917
+ const distance = distanceToLineSegment(point, line2);
918
+ if (distance === 0) {
919
+ return true;
920
+ }
921
+ return distance < threshold;
922
+ };
923
+ var distanceToLineSegment = (point, line2) => {
924
+ return pointDistance(
925
+ point,
926
+ lineSegmentPointAt(line2, lineSegmentClosestParameter(point, line2))
927
+ );
928
+ };
929
+ function lineSegmentPointAt(line2, t) {
930
+ const [[x1, y1], [x2, y2]] = line2;
931
+ return pointFrom(x1 + t * (x2 - x1), y1 + t * (y2 - y1));
932
+ }
933
+ function lineSegmentIntersectionPoints(l, s, threshold) {
934
+ const candidate = linesIntersectAt(line(l[0], l[1]), line(s[0], s[1]));
935
+ if (!candidate || !pointOnLineSegment(candidate, s, threshold) || !pointOnLineSegment(candidate, l, threshold)) {
936
+ return null;
937
+ }
938
+ return candidate;
939
+ }
940
+ function lineSegmentsDistance(s1, s2) {
941
+ if (lineSegmentIntersectionPoints(s1, s2)) {
942
+ return 0;
943
+ }
944
+ return Math.min(
945
+ distanceToLineSegment(s1[0], s2),
946
+ distanceToLineSegment(s1[1], s2),
947
+ distanceToLineSegment(s2[0], s1),
948
+ distanceToLineSegment(s2[1], s1)
949
+ );
950
+ }
951
+ function lineSegmentClosestParameter(point, line2) {
952
+ const [x, y] = point;
953
+ const [[x1, y1], [x2, y2]] = line2;
954
+ const A = x - x1;
955
+ const B = y - y1;
956
+ const C = x2 - x1;
957
+ const D = y2 - y1;
958
+ const dot = A * C + B * D;
959
+ const len_sq = C * C + D * D;
960
+ let param = 0;
961
+ if (len_sq !== 0) {
962
+ param = dot / len_sq;
963
+ }
964
+ return Math.max(0, Math.min(1, param));
965
+ }
966
+
819
967
  // src/rectangle.ts
820
968
  function rectangle(topLeft, bottomRight) {
821
969
  return [topLeft, bottomRight];
@@ -852,10 +1000,13 @@ export {
852
1000
  average,
853
1001
  bezierEquation,
854
1002
  cartesian2Polar,
1003
+ centroid,
855
1004
  clamp,
1005
+ convexHull,
856
1006
  curve,
857
1007
  curveCatmullRomCubicApproxPoints,
858
1008
  curveCatmullRomQuadraticApproxPoints,
1009
+ curveClosestParameter,
859
1010
  curveClosestPoint,
860
1011
  curveIntersectLineSegment,
861
1012
  curveLength,
@@ -872,6 +1023,7 @@ export {
872
1023
  ellipseLineIntersectionPoints,
873
1024
  ellipseSegmentInterceptPoints,
874
1025
  ellipseTouchesPoint,
1026
+ elongation,
875
1027
  isCloseTo,
876
1028
  isCurve,
877
1029
  isFiniteNumber,
@@ -881,14 +1033,18 @@ export {
881
1033
  isRightAngleRads,
882
1034
  isValidPoint,
883
1035
  isVector,
1036
+ kurtosis,
884
1037
  line,
885
1038
  lineSegment,
1039
+ lineSegmentClosestParameter,
886
1040
  lineSegmentIntersectionPoints,
1041
+ lineSegmentPointAt,
887
1042
  lineSegmentRotate,
888
1043
  lineSegmentsDistance,
889
1044
  linesIntersectAt,
890
1045
  normalizeRadians,
891
1046
  offsetPointsForQuadraticBezier,
1047
+ orientPrincipalAxes,
892
1048
  pointCenter,
893
1049
  pointDistance,
894
1050
  pointDistanceSq,
@@ -897,16 +1053,20 @@ export {
897
1053
  pointFromPair,
898
1054
  pointFromVector,
899
1055
  pointOnLineSegment,
900
- pointOnPolygon,
901
1056
  pointRotateDegs,
902
1057
  pointRotateRads,
903
1058
  pointScaleFromOrigin,
904
1059
  pointTranslate,
905
1060
  pointsEqual,
906
1061
  polygon,
1062
+ polygonArea,
907
1063
  polygonFromPoints,
908
1064
  polygonIncludesPoint,
909
1065
  polygonIncludesPointNonZero,
1066
+ polygonIsClosed,
1067
+ polygonSignedArea,
1068
+ principalAxes,
1069
+ principalCoords,
910
1070
  radiansBetweenAngles,
911
1071
  radiansDifference,
912
1072
  radiansToDegrees,
@@ -922,6 +1082,9 @@ export {
922
1082
  round,
923
1083
  roundToStep,
924
1084
  segmentsIntersectAt,
1085
+ simplifyConvexPolygon,
1086
+ skewness,
1087
+ standardizedMoment,
925
1088
  triangleIncludesPoint,
926
1089
  vector,
927
1090
  vectorAdd,