@tscircuit/schematic-trace-solver 0.0.114 → 0.0.115

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.
package/dist/index.d.ts CHANGED
@@ -146,17 +146,11 @@ type RectPadding = {
146
146
  maxY?: number;
147
147
  };
148
148
 
149
- type RectBounds = {
150
- minX: number;
151
- minY: number;
152
- maxX: number;
153
- maxY: number;
154
- };
155
- type ChipObstacleRect = RectBounds & {
149
+ type ChipObstacleRect = Bounds & {
156
150
  kind: "chip";
157
151
  chipId: string;
158
152
  };
159
- type TextBoxObstacleRect = RectBounds & {
153
+ type TextBoxObstacleRect = Bounds & {
160
154
  kind: "text_box";
161
155
  textBox: NonNullable<InputProblem["textBoxes"]>[number];
162
156
  };
package/dist/index.js CHANGED
@@ -1116,6 +1116,9 @@ var generateInternalSegmentCollisionDetours = ({
1116
1116
  ]).filter(hasOnlyNonzeroOrthogonalSegments);
1117
1117
  };
1118
1118
 
1119
+ // lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/rect.ts
1120
+ import { boundsDistance } from "@tscircuit/math-utils";
1121
+
1119
1122
  // lib/solvers/GuidelinesSolver/getInputChipBounds.ts
1120
1123
  function getInputChipBounds(chip) {
1121
1124
  const halfWidth = chip.width / 2;
@@ -1129,6 +1132,7 @@ function getInputChipBounds(chip) {
1129
1132
  }
1130
1133
 
1131
1134
  // lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/rect.ts
1135
+ var MIN_ROUTABLE_OBSTACLE_GAP = 0.05;
1132
1136
  var isTextBoxObstacle = (obstacle) => obstacle.kind === "text_box";
1133
1137
  var chipToRect = (chip) => {
1134
1138
  const b = getInputChipBounds(chip);
@@ -1137,7 +1141,17 @@ var chipToRect = (chip) => {
1137
1141
  var getObstacleRects = (problem, opts = {}) => {
1138
1142
  const chipRects = problem.chips.map(chipToRect);
1139
1143
  const textBoxRects = (problem.textBoxes ?? []).map((textBox) => {
1140
- const b = getTextBoxBounds(textBox, opts.textBoxPadding);
1144
+ const textBounds = getTextBoxBounds(textBox, opts.textBoxPadding);
1145
+ const attachedChipBounds = chipRects.find(
1146
+ (chip) => chip.chipId === textBox.chipId
1147
+ );
1148
+ const gap = attachedChipBounds ? boundsDistance(textBounds, attachedChipBounds) : Number.POSITIVE_INFINITY;
1149
+ const b = attachedChipBounds && gap > 0 && gap < MIN_ROUTABLE_OBSTACLE_GAP ? {
1150
+ minX: Math.min(textBounds.minX, attachedChipBounds.maxX),
1151
+ maxX: Math.max(textBounds.maxX, attachedChipBounds.minX),
1152
+ minY: Math.min(textBounds.minY, attachedChipBounds.maxY),
1153
+ maxY: Math.max(textBounds.maxY, attachedChipBounds.minY)
1154
+ } : textBounds;
1141
1155
  return {
1142
1156
  kind: "text_box",
1143
1157
  textBox,
@@ -1207,9 +1221,9 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
1207
1221
  this.textObstacles = new Set(this.obstacles.filter(isTextBoxObstacle));
1208
1222
  const endpointChipIds = new Set(this.pins.map((pin) => pin.chipId));
1209
1223
  this.endpointTextObstacles = new Set(
1210
- endpointChipIds.size > 1 ? this.obstacles.filter(isTextBoxObstacle).filter(
1224
+ this.obstacles.filter(isTextBoxObstacle).filter(
1211
1225
  (obstacle) => obstacle.textBox.chipId !== void 0 && endpointChipIds.has(obstacle.textBox.chipId)
1212
- ) : []
1226
+ )
1213
1227
  );
1214
1228
  const [pin1, pin2] = this.pins;
1215
1229
  const directShortPath = calculateDirectShortPath(pin1, pin2);
@@ -123,16 +123,16 @@ export class SchematicTraceSingleLineSolver2 extends BaseSolver {
123
123
  })
124
124
  this.textObstacles = new Set(this.obstacles.filter(isTextBoxObstacle))
125
125
  const endpointChipIds = new Set(this.pins.map((pin) => pin.chipId))
126
+ // Same-chip routes also need these obstacles so they can escape around
127
+ // attached text after a narrow chip-to-text channel is closed.
126
128
  this.endpointTextObstacles = new Set(
127
- endpointChipIds.size > 1
128
- ? this.obstacles
129
- .filter(isTextBoxObstacle)
130
- .filter(
131
- (obstacle) =>
132
- obstacle.textBox.chipId !== undefined &&
133
- endpointChipIds.has(obstacle.textBox.chipId),
134
- )
135
- : [],
129
+ this.obstacles
130
+ .filter(isTextBoxObstacle)
131
+ .filter(
132
+ (obstacle) =>
133
+ obstacle.textBox.chipId !== undefined &&
134
+ endpointChipIds.has(obstacle.textBox.chipId),
135
+ ),
136
136
  )
137
137
 
138
138
  const [pin1, pin2] = this.pins
@@ -1,20 +1,21 @@
1
+ import { boundsDistance, type Bounds } from "@tscircuit/math-utils"
1
2
  import { getInputChipBounds } from "lib/solvers/GuidelinesSolver/getInputChipBounds"
2
3
  import type { InputChip, InputProblem } from "lib/types/InputProblem"
3
4
  import { getTextBoxBounds, type RectPadding } from "lib/utils/textBoxBounds"
4
5
 
5
- export type RectBounds = {
6
- minX: number
7
- minY: number
8
- maxX: number
9
- maxY: number
10
- }
6
+ // Component text is normally placed 0.04 units from its chip. A trace
7
+ // centerline can fit mathematically, but its rendered stroke cannot usefully
8
+ // occupy that channel.
9
+ const MIN_ROUTABLE_OBSTACLE_GAP = 0.05
10
+
11
+ export type { Bounds as RectBounds } from "@tscircuit/math-utils"
11
12
 
12
- export type ChipObstacleRect = RectBounds & {
13
+ export type ChipObstacleRect = Bounds & {
13
14
  kind: "chip"
14
15
  chipId: string
15
16
  }
16
17
 
17
- export type TextBoxObstacleRect = RectBounds & {
18
+ export type TextBoxObstacleRect = Bounds & {
18
19
  kind: "text_box"
19
20
  textBox: NonNullable<InputProblem["textBoxes"]>[number]
20
21
  }
@@ -36,7 +37,22 @@ export const getObstacleRects = (
36
37
  ): ObstacleRect[] => {
37
38
  const chipRects = problem.chips.map(chipToRect)
38
39
  const textBoxRects = (problem.textBoxes ?? []).map((textBox) => {
39
- const b = getTextBoxBounds(textBox, opts.textBoxPadding)
40
+ const textBounds = getTextBoxBounds(textBox, opts.textBoxPadding)
41
+ const attachedChipBounds = chipRects.find(
42
+ (chip) => chip.chipId === textBox.chipId,
43
+ )
44
+ const gap = attachedChipBounds
45
+ ? boundsDistance(textBounds, attachedChipBounds)
46
+ : Number.POSITIVE_INFINITY
47
+ const b =
48
+ attachedChipBounds && gap > 0 && gap < MIN_ROUTABLE_OBSTACLE_GAP
49
+ ? {
50
+ minX: Math.min(textBounds.minX, attachedChipBounds.maxX),
51
+ maxX: Math.max(textBounds.maxX, attachedChipBounds.minX),
52
+ minY: Math.min(textBounds.minY, attachedChipBounds.maxY),
53
+ maxY: Math.max(textBounds.maxY, attachedChipBounds.minY),
54
+ }
55
+ : textBounds
40
56
  return {
41
57
  kind: "text_box" as const,
42
58
  textBox,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/schematic-trace-solver",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.114",
4
+ "version": "0.0.115",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "start": "cosmos",
@@ -13,7 +13,7 @@
13
13
  "devDependencies": {
14
14
  "@biomejs/biome": "^2.2.2",
15
15
  "@react-hook/resize-observer": "^2.0.2",
16
- "@tscircuit/math-utils": "^0.0.19",
16
+ "@tscircuit/math-utils": "^0.0.36",
17
17
  "@types/bun": "^1.2.21",
18
18
  "bun-match-svg": "^0.0.13",
19
19
  "calculate-elbow": "^0.0.12",