@tscircuit/math-utils 0.0.12 → 0.0.14

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.
@@ -0,0 +1,36 @@
1
+ import {
2
+ distance
3
+ } from "./chunk-CHQOCSFB.js";
4
+ import {
5
+ clamp
6
+ } from "./chunk-MHHTZHOJ.js";
7
+
8
+ // src/point-distance.ts
9
+ function pointToBoxDistance(p, box) {
10
+ const halfWidth = box.width / 2;
11
+ const halfHeight = box.height / 2;
12
+ const minX = box.center.x - halfWidth;
13
+ const maxX = box.center.x + halfWidth;
14
+ const minY = box.center.y - halfHeight;
15
+ const maxY = box.center.y + halfHeight;
16
+ if (p.x >= minX && p.x <= maxX && p.y >= minY && p.y <= maxY) {
17
+ return 0;
18
+ }
19
+ const closestX = clamp(p.x, minX, maxX);
20
+ const closestY = clamp(p.y, minY, maxY);
21
+ return distance(p, { x: closestX, y: closestY });
22
+ }
23
+ function pointToBoundsDistance(p, bounds) {
24
+ if (p.x >= bounds.minX && p.x <= bounds.maxX && p.y >= bounds.minY && p.y <= bounds.maxY) {
25
+ return 0;
26
+ }
27
+ const closestX = clamp(p.x, bounds.minX, bounds.maxX);
28
+ const closestY = clamp(p.y, bounds.minY, bounds.maxY);
29
+ return distance(p, { x: closestX, y: closestY });
30
+ }
31
+
32
+ export {
33
+ pointToBoxDistance,
34
+ pointToBoundsDistance
35
+ };
36
+ //# sourceMappingURL=chunk-46MP2ZSF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/point-distance.ts"],"sourcesContent":["import type { Point, Bounds } from \"./common\"\nimport { distance } from \"./line-intersections\"\nimport { clamp } from \"./nearest-box\"\nimport type { Box } from \"./nearest-box\"\n\n/**\n * Returns the minimum distance from a point to a box.\n * If the point is inside the box, the distance is 0.\n */\nexport function pointToBoxDistance(p: Point, box: Box): number {\n const halfWidth = box.width / 2\n const halfHeight = box.height / 2\n const minX = box.center.x - halfWidth\n const maxX = box.center.x + halfWidth\n const minY = box.center.y - halfHeight\n const maxY = box.center.y + halfHeight\n\n // Check if the point is inside the box\n if (p.x >= minX && p.x <= maxX && p.y >= minY && p.y <= maxY) {\n return 0\n }\n\n // Find the closest point on the box boundary\n const closestX = clamp(p.x, minX, maxX)\n const closestY = clamp(p.y, minY, maxY)\n\n // Calculate the distance to the closest point\n return distance(p, { x: closestX, y: closestY })\n}\n\n/**\n * Returns the minimum distance from a point to a bounds rectangle.\n * If the point is inside the bounds, the distance is 0.\n */\nexport function pointToBoundsDistance(p: Point, bounds: Bounds): number {\n // Check if the point is inside the bounds\n if (\n p.x >= bounds.minX &&\n p.x <= bounds.maxX &&\n p.y >= bounds.minY &&\n p.y <= bounds.maxY\n ) {\n return 0\n }\n\n // Find the closest point on the bounds boundary\n const closestX = clamp(p.x, bounds.minX, bounds.maxX)\n const closestY = clamp(p.y, bounds.minY, bounds.maxY)\n\n // Calculate the distance to the closest point\n return distance(p, { x: closestX, y: closestY })\n}\n"],"mappings":";;;;;;;;AASO,SAAS,mBAAmB,GAAU,KAAkB;AAC7D,QAAM,YAAY,IAAI,QAAQ;AAC9B,QAAM,aAAa,IAAI,SAAS;AAChC,QAAM,OAAO,IAAI,OAAO,IAAI;AAC5B,QAAM,OAAO,IAAI,OAAO,IAAI;AAC5B,QAAM,OAAO,IAAI,OAAO,IAAI;AAC5B,QAAM,OAAO,IAAI,OAAO,IAAI;AAG5B,MAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM;AAC5D,WAAO;AAAA,EACT;AAGA,QAAM,WAAW,MAAM,EAAE,GAAG,MAAM,IAAI;AACtC,QAAM,WAAW,MAAM,EAAE,GAAG,MAAM,IAAI;AAGtC,SAAO,SAAS,GAAG,EAAE,GAAG,UAAU,GAAG,SAAS,CAAC;AACjD;AAMO,SAAS,sBAAsB,GAAU,QAAwB;AAEtE,MACE,EAAE,KAAK,OAAO,QACd,EAAE,KAAK,OAAO,QACd,EAAE,KAAK,OAAO,QACd,EAAE,KAAK,OAAO,MACd;AACA,WAAO;AAAA,EACT;AAGA,QAAM,WAAW,MAAM,EAAE,GAAG,OAAO,MAAM,OAAO,IAAI;AACpD,QAAM,WAAW,MAAM,EAAE,GAAG,OAAO,MAAM,OAAO,IAAI;AAGpD,SAAO,SAAS,GAAG,EAAE,GAAG,UAAU,GAAG,SAAS,CAAC;AACjD;","names":[]}
@@ -72,10 +72,27 @@ function segmentToBoxMinDistance(a, b, box) {
72
72
  };
73
73
  return segmentToBoundsMinDistance(a, b, bounds);
74
74
  }
75
+ function segmentToCircleMinDistance(a, b, circle) {
76
+ const circleCenter = { x: circle.x, y: circle.y };
77
+ if (a.x === b.x && a.y === b.y) {
78
+ return Math.max(0, distance(a, circleCenter) - circle.radius);
79
+ }
80
+ const ab = { x: b.x - a.x, y: b.y - a.y };
81
+ const ac = { x: circleCenter.x - a.x, y: circleCenter.y - a.y };
82
+ const abLengthSq = ab.x * ab.x + ab.y * ab.y;
83
+ const t = Math.max(0, Math.min(1, (ab.x * ac.x + ab.y * ac.y) / abLengthSq));
84
+ const closestPoint = {
85
+ x: a.x + t * ab.x,
86
+ y: a.y + t * ab.y
87
+ };
88
+ const distToCenter = distance(closestPoint, circleCenter);
89
+ return Math.max(0, distToCenter - circle.radius);
90
+ }
75
91
 
76
92
  export {
77
93
  segmentToSegmentMinDistance,
78
94
  segmentToBoundsMinDistance,
79
- segmentToBoxMinDistance
95
+ segmentToBoxMinDistance,
96
+ segmentToCircleMinDistance
80
97
  };
81
- //# sourceMappingURL=chunk-OMVVSGKD.js.map
98
+ //# sourceMappingURL=chunk-K7F26NYD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/segment-distance.ts"],"sourcesContent":["import type { Point } from \"./common\"\nimport {\n distance,\n doSegmentsIntersect,\n pointToSegmentDistance,\n} from \"./line-intersections\"\nimport { clamp } from \"./nearest-box\"\n\n/**\n * Returns the minimum distance between two line segments.\n */\nexport function segmentToSegmentMinDistance(\n a: Point,\n b: Point,\n u: Point,\n v: Point,\n): number {\n // Handle degenerate cases: segments of zero length\n if (a.x === b.x && a.y === b.y) {\n return pointToSegmentDistance(a, u, v)\n }\n if (u.x === v.x && u.y === v.y) {\n return pointToSegmentDistance(u, a, b)\n }\n\n // Check if segments intersect\n if (doSegmentsIntersect(a, b, u, v)) {\n return 0\n }\n\n // Compute the minimum distance between the segments\n const distances = [\n pointToSegmentDistance(a, u, v),\n pointToSegmentDistance(b, u, v),\n pointToSegmentDistance(u, a, b),\n pointToSegmentDistance(v, a, b),\n ]\n\n return Math.min(...distances)\n}\n\n/**\n * Returns the minimum distance from a line segment to a bounding box.\n */\nexport function segmentToBoundsMinDistance(\n a: Point,\n b: Point,\n bounds: { minX: number; minY: number; maxX: number; maxY: number },\n): number {\n // Check if segment intersects with the bounds\n // Create the four edges of the bounds\n const topLeft = { x: bounds.minX, y: bounds.minY }\n const topRight = { x: bounds.maxX, y: bounds.minY }\n const bottomLeft = { x: bounds.minX, y: bounds.maxY }\n const bottomRight = { x: bounds.maxX, y: bounds.maxY }\n\n // Check if segment intersects with any of the bounds edges\n if (\n doSegmentsIntersect(a, b, topLeft, topRight) ||\n doSegmentsIntersect(a, b, topRight, bottomRight) ||\n doSegmentsIntersect(a, b, bottomRight, bottomLeft) ||\n doSegmentsIntersect(a, b, bottomLeft, topLeft)\n ) {\n return 0\n }\n\n // Check if segment is entirely inside the bounds\n if (\n a.x >= bounds.minX &&\n a.x <= bounds.maxX &&\n a.y >= bounds.minY &&\n a.y <= bounds.maxY &&\n b.x >= bounds.minX &&\n b.x <= bounds.maxX &&\n b.y >= bounds.minY &&\n b.y <= bounds.maxY\n ) {\n return 0\n }\n\n // If not intersecting, calculate the minimum distance\n const distances = [\n pointToSegmentDistance(topLeft, a, b),\n pointToSegmentDistance(topRight, a, b),\n pointToSegmentDistance(bottomLeft, a, b),\n pointToSegmentDistance(bottomRight, a, b),\n ]\n\n // If one of the segment endpoints is inside the bounds, we need to consider its distance to the bounds as 0\n if (\n a.x >= bounds.minX &&\n a.x <= bounds.maxX &&\n a.y >= bounds.minY &&\n a.y <= bounds.maxY\n ) {\n return 0\n }\n\n if (\n b.x >= bounds.minX &&\n b.x <= bounds.maxX &&\n b.y >= bounds.minY &&\n b.y <= bounds.maxY\n ) {\n return 0\n }\n\n // Calculate distances from segment endpoints to bounds if outside\n if (\n a.x < bounds.minX ||\n a.x > bounds.maxX ||\n a.y < bounds.minY ||\n a.y > bounds.maxY\n ) {\n const closestX = clamp(a.x, bounds.minX, bounds.maxX)\n const closestY = clamp(a.y, bounds.minY, bounds.maxY)\n distances.push(distance(a, { x: closestX, y: closestY }))\n }\n\n if (\n b.x < bounds.minX ||\n b.x > bounds.maxX ||\n b.y < bounds.minY ||\n b.y > bounds.maxY\n ) {\n const closestX = clamp(b.x, bounds.minX, bounds.maxX)\n const closestY = clamp(b.y, bounds.minY, bounds.maxY)\n distances.push(distance(b, { x: closestX, y: closestY }))\n }\n\n return Math.min(...distances)\n}\n\n/**\n * Returns the minimum distance from a line segment to a box.\n */\nexport function segmentToBoxMinDistance(\n a: Point,\n b: Point,\n box: { center: Point; width: number; height: number },\n): number {\n const halfWidth = box.width / 2\n const halfHeight = box.height / 2\n const bounds = {\n minX: box.center.x - halfWidth,\n maxX: box.center.x + halfWidth,\n minY: box.center.y - halfHeight,\n maxY: box.center.y + halfHeight,\n }\n\n return segmentToBoundsMinDistance(a, b, bounds)\n}\n\n/**\n * Returns the minimum distance from a line segment to a circle.\n */\nexport function segmentToCircleMinDistance(\n a: Point,\n b: Point,\n circle: { x: number; y: number; radius: number },\n): number {\n // Calculate the distance from the circle center to the line segment\n const circleCenter = { x: circle.x, y: circle.y }\n\n // Handle degenerate case: segment of zero length (point to circle)\n if (a.x === b.x && a.y === b.y) {\n return Math.max(0, distance(a, circleCenter) - circle.radius)\n }\n\n // Vector from a to b\n const ab = { x: b.x - a.x, y: b.y - a.y }\n // Vector from a to circle center\n const ac = { x: circleCenter.x - a.x, y: circleCenter.y - a.y }\n\n // Length of segment ab squared\n const abLengthSq = ab.x * ab.x + ab.y * ab.y\n\n // Calculate projection of ac onto ab, normalized by the length of ab\n const t = Math.max(0, Math.min(1, (ab.x * ac.x + ab.y * ac.y) / abLengthSq))\n\n // Find the closest point on the segment to the circle center\n const closestPoint = {\n x: a.x + t * ab.x,\n y: a.y + t * ab.y,\n }\n\n // Calculate distance from closest point to circle center\n const distToCenter = distance(closestPoint, circleCenter)\n\n // Return the distance to the circle (subtract radius from distance to center)\n return Math.max(0, distToCenter - circle.radius)\n}\n"],"mappings":"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","names":[]}
package/dist/common.d.ts CHANGED
@@ -2,5 +2,11 @@ type Point = {
2
2
  x: number;
3
3
  y: number;
4
4
  };
5
+ type Bounds = {
6
+ minX: number;
7
+ minY: number;
8
+ maxX: number;
9
+ maxY: number;
10
+ };
5
11
 
6
- export type { Point };
12
+ export type { Bounds, Point };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { distance, doSegmentsIntersect, doesLineIntersectLine, onSegment, orientation, pointToSegmentDistance } from './line-intersections.js';
2
2
  export { Box, BoxSet, GridCell, clamp, computeDistanceBetweenBoxes, findNearestPointsBetweenBoxSets, getBoundingBox } from './nearest-box.js';
3
- export { Point } from './common.js';
3
+ export { Bounds, Point } from './common.js';
4
4
  export { getUnitVectorFromDirection, getUnitVectorFromPointAToB } from './get-unit-vector.js';
5
5
  export { GridCellPositions, GridOptions, grid } from './grid.js';
6
- export { segmentToBoundsMinDistance, segmentToBoxMinDistance, segmentToSegmentMinDistance } from './segment-distance.js';
6
+ export { segmentToBoundsMinDistance, segmentToBoxMinDistance, segmentToCircleMinDistance, segmentToSegmentMinDistance } from './segment-distance.js';
7
+ export { pointToBoundsDistance, pointToBoxDistance } from './point-distance.js';
package/dist/index.js CHANGED
@@ -6,11 +6,16 @@ import {
6
6
  import {
7
7
  grid
8
8
  } from "./chunk-U45EKA3R.js";
9
+ import {
10
+ pointToBoundsDistance,
11
+ pointToBoxDistance
12
+ } from "./chunk-46MP2ZSF.js";
9
13
  import {
10
14
  segmentToBoundsMinDistance,
11
15
  segmentToBoxMinDistance,
16
+ segmentToCircleMinDistance,
12
17
  segmentToSegmentMinDistance
13
- } from "./chunk-OMVVSGKD.js";
18
+ } from "./chunk-K7F26NYD.js";
14
19
  import {
15
20
  distance,
16
21
  doSegmentsIntersect,
@@ -38,9 +43,12 @@ export {
38
43
  grid,
39
44
  onSegment,
40
45
  orientation,
46
+ pointToBoundsDistance,
47
+ pointToBoxDistance,
41
48
  pointToSegmentDistance,
42
49
  segmentToBoundsMinDistance,
43
50
  segmentToBoxMinDistance,
51
+ segmentToCircleMinDistance,
44
52
  segmentToSegmentMinDistance
45
53
  };
46
54
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,15 @@
1
+ import { Point, Bounds } from './common.js';
2
+ import { Box } from './nearest-box.js';
3
+
4
+ /**
5
+ * Returns the minimum distance from a point to a box.
6
+ * If the point is inside the box, the distance is 0.
7
+ */
8
+ declare function pointToBoxDistance(p: Point, box: Box): number;
9
+ /**
10
+ * Returns the minimum distance from a point to a bounds rectangle.
11
+ * If the point is inside the bounds, the distance is 0.
12
+ */
13
+ declare function pointToBoundsDistance(p: Point, bounds: Bounds): number;
14
+
15
+ export { pointToBoundsDistance, pointToBoxDistance };
@@ -0,0 +1,11 @@
1
+ import {
2
+ pointToBoundsDistance,
3
+ pointToBoxDistance
4
+ } from "./chunk-46MP2ZSF.js";
5
+ import "./chunk-CHQOCSFB.js";
6
+ import "./chunk-MHHTZHOJ.js";
7
+ export {
8
+ pointToBoundsDistance,
9
+ pointToBoxDistance
10
+ };
11
+ //# sourceMappingURL=point-distance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -21,5 +21,13 @@ declare function segmentToBoxMinDistance(a: Point, b: Point, box: {
21
21
  width: number;
22
22
  height: number;
23
23
  }): number;
24
+ /**
25
+ * Returns the minimum distance from a line segment to a circle.
26
+ */
27
+ declare function segmentToCircleMinDistance(a: Point, b: Point, circle: {
28
+ x: number;
29
+ y: number;
30
+ radius: number;
31
+ }): number;
24
32
 
25
- export { segmentToBoundsMinDistance, segmentToBoxMinDistance, segmentToSegmentMinDistance };
33
+ export { segmentToBoundsMinDistance, segmentToBoxMinDistance, segmentToCircleMinDistance, segmentToSegmentMinDistance };
@@ -1,13 +1,15 @@
1
1
  import {
2
2
  segmentToBoundsMinDistance,
3
3
  segmentToBoxMinDistance,
4
+ segmentToCircleMinDistance,
4
5
  segmentToSegmentMinDistance
5
- } from "./chunk-OMVVSGKD.js";
6
+ } from "./chunk-K7F26NYD.js";
6
7
  import "./chunk-CHQOCSFB.js";
7
8
  import "./chunk-MHHTZHOJ.js";
8
9
  export {
9
10
  segmentToBoundsMinDistance,
10
11
  segmentToBoxMinDistance,
12
+ segmentToCircleMinDistance,
11
13
  segmentToSegmentMinDistance
12
14
  };
13
15
  //# sourceMappingURL=segment-distance.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/math-utils",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.12",
4
+ "version": "0.0.14",
5
5
  "type": "module",
6
6
  "module": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/segment-distance.ts"],"sourcesContent":["import type { Point } from \"./common\"\nimport {\n distance,\n doSegmentsIntersect,\n pointToSegmentDistance,\n} from \"./line-intersections\"\nimport { clamp } from \"./nearest-box\"\n\n/**\n * Returns the minimum distance between two line segments.\n */\nexport function segmentToSegmentMinDistance(\n a: Point,\n b: Point,\n u: Point,\n v: Point,\n): number {\n // Handle degenerate cases: segments of zero length\n if (a.x === b.x && a.y === b.y) {\n return pointToSegmentDistance(a, u, v)\n }\n if (u.x === v.x && u.y === v.y) {\n return pointToSegmentDistance(u, a, b)\n }\n\n // Check if segments intersect\n if (doSegmentsIntersect(a, b, u, v)) {\n return 0\n }\n\n // Compute the minimum distance between the segments\n const distances = [\n pointToSegmentDistance(a, u, v),\n pointToSegmentDistance(b, u, v),\n pointToSegmentDistance(u, a, b),\n pointToSegmentDistance(v, a, b),\n ]\n\n return Math.min(...distances)\n}\n\n/**\n * Returns the minimum distance from a line segment to a bounding box.\n */\nexport function segmentToBoundsMinDistance(\n a: Point,\n b: Point,\n bounds: { minX: number; minY: number; maxX: number; maxY: number },\n): number {\n // Check if segment intersects with the bounds\n // Create the four edges of the bounds\n const topLeft = { x: bounds.minX, y: bounds.minY }\n const topRight = { x: bounds.maxX, y: bounds.minY }\n const bottomLeft = { x: bounds.minX, y: bounds.maxY }\n const bottomRight = { x: bounds.maxX, y: bounds.maxY }\n\n // Check if segment intersects with any of the bounds edges\n if (\n doSegmentsIntersect(a, b, topLeft, topRight) ||\n doSegmentsIntersect(a, b, topRight, bottomRight) ||\n doSegmentsIntersect(a, b, bottomRight, bottomLeft) ||\n doSegmentsIntersect(a, b, bottomLeft, topLeft)\n ) {\n return 0\n }\n\n // Check if segment is entirely inside the bounds\n if (\n a.x >= bounds.minX &&\n a.x <= bounds.maxX &&\n a.y >= bounds.minY &&\n a.y <= bounds.maxY &&\n b.x >= bounds.minX &&\n b.x <= bounds.maxX &&\n b.y >= bounds.minY &&\n b.y <= bounds.maxY\n ) {\n return 0\n }\n\n // If not intersecting, calculate the minimum distance\n const distances = [\n pointToSegmentDistance(topLeft, a, b),\n pointToSegmentDistance(topRight, a, b),\n pointToSegmentDistance(bottomLeft, a, b),\n pointToSegmentDistance(bottomRight, a, b),\n ]\n\n // If one of the segment endpoints is inside the bounds, we need to consider its distance to the bounds as 0\n if (\n a.x >= bounds.minX &&\n a.x <= bounds.maxX &&\n a.y >= bounds.minY &&\n a.y <= bounds.maxY\n ) {\n return 0\n }\n\n if (\n b.x >= bounds.minX &&\n b.x <= bounds.maxX &&\n b.y >= bounds.minY &&\n b.y <= bounds.maxY\n ) {\n return 0\n }\n\n // Calculate distances from segment endpoints to bounds if outside\n if (\n a.x < bounds.minX ||\n a.x > bounds.maxX ||\n a.y < bounds.minY ||\n a.y > bounds.maxY\n ) {\n const closestX = clamp(a.x, bounds.minX, bounds.maxX)\n const closestY = clamp(a.y, bounds.minY, bounds.maxY)\n distances.push(distance(a, { x: closestX, y: closestY }))\n }\n\n if (\n b.x < bounds.minX ||\n b.x > bounds.maxX ||\n b.y < bounds.minY ||\n b.y > bounds.maxY\n ) {\n const closestX = clamp(b.x, bounds.minX, bounds.maxX)\n const closestY = clamp(b.y, bounds.minY, bounds.maxY)\n distances.push(distance(b, { x: closestX, y: closestY }))\n }\n\n return Math.min(...distances)\n}\n\n/**\n * Returns the minimum distance from a line segment to a box.\n */\nexport function segmentToBoxMinDistance(\n a: Point,\n b: Point,\n box: { center: Point; width: number; height: number },\n): number {\n const halfWidth = box.width / 2\n const halfHeight = box.height / 2\n const bounds = {\n minX: box.center.x - halfWidth,\n maxX: box.center.x + halfWidth,\n minY: box.center.y - halfHeight,\n maxY: box.center.y + halfHeight,\n }\n\n return segmentToBoundsMinDistance(a, b, bounds)\n}\n"],"mappings":"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","names":[]}