@tscircuit/schematic-trace-solver 0.0.63 → 0.0.65

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.js CHANGED
@@ -271,19 +271,19 @@ var doesPairCrossRestrictedCenterLines = (params) => {
271
271
  chipMap
272
272
  });
273
273
  if (restrictedCenterLines.size === 0) return false;
274
- const EPS10 = 1e-9;
274
+ const EPS11 = 1e-9;
275
275
  const crossesSegment = (a, b) => {
276
276
  for (const [, rcl] of restrictedCenterLines) {
277
277
  if (rcl.axes.has("x") && typeof rcl.x === "number") {
278
- if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS10) return true;
278
+ if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS11) return true;
279
279
  }
280
280
  if (rcl.axes.has("y") && typeof rcl.y === "number") {
281
- if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS10) return true;
281
+ if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS11) return true;
282
282
  }
283
283
  }
284
284
  return false;
285
285
  };
286
- if (Math.abs(p1.x - p2.x) < EPS10 || Math.abs(p1.y - p2.y) < EPS10) {
286
+ if (Math.abs(p1.x - p2.x) < EPS11 || Math.abs(p1.y - p2.y) < EPS11) {
287
287
  return crossesSegment({ x: p1.x, y: p1.y }, { x: p2.x, y: p2.y });
288
288
  }
289
289
  const elbowHV = { x: p2.x, y: p1.y };
@@ -850,8 +850,8 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
850
850
  if (!collision) {
851
851
  const first = path[0];
852
852
  const last = path[path.length - 1];
853
- const EPS10 = 1e-9;
854
- const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS10 && Math.abs(p.y - q.y) < EPS10;
853
+ const EPS11 = 1e-9;
854
+ const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS11 && Math.abs(p.y - q.y) < EPS11;
855
855
  if (samePoint(first, { x: PA.x, y: PA.y }) && samePoint(last, { x: PB.x, y: PB.y })) {
856
856
  this.solvedTracePath = path;
857
857
  this.solved = true;
@@ -1050,13 +1050,13 @@ var applyJogToTerminalSegment = ({
1050
1050
  segmentIndex: si,
1051
1051
  offset,
1052
1052
  JOG_SIZE,
1053
- EPS: EPS10 = 1e-6
1053
+ EPS: EPS11 = 1e-6
1054
1054
  }) => {
1055
1055
  if (si !== 0 && si !== pts.length - 2) return;
1056
1056
  const start = pts[si];
1057
1057
  const end = pts[si + 1];
1058
- const isVertical4 = Math.abs(start.x - end.x) < EPS10;
1059
- const isHorizontal3 = Math.abs(start.y - end.y) < EPS10;
1058
+ const isVertical4 = Math.abs(start.x - end.x) < EPS11;
1059
+ const isHorizontal3 = Math.abs(start.y - end.y) < EPS11;
1060
1060
  if (!isVertical4 && !isHorizontal3) return;
1061
1061
  const segDir = isVertical4 ? end.y > start.y ? 1 : -1 : end.x > start.x ? 1 : -1;
1062
1062
  if (si === 0) {
@@ -1103,15 +1103,18 @@ var applyJogToTerminalSegment = ({
1103
1103
  };
1104
1104
 
1105
1105
  // lib/solvers/TraceOverlapShiftSolver/TraceOverlapIssueSolver/TraceOverlapIssueSolver.ts
1106
+ var EPS4 = 1e-6;
1106
1107
  var TraceOverlapIssueSolver = class extends BaseSolver {
1107
1108
  overlappingTraceSegments;
1108
1109
  traceNetIslands;
1110
+ obstacleRects;
1109
1111
  SHIFT_DISTANCE = 0.1;
1110
1112
  correctedTraceMap = {};
1111
1113
  constructor(params) {
1112
1114
  super();
1113
1115
  this.overlappingTraceSegments = params.overlappingTraceSegments;
1114
1116
  this.traceNetIslands = params.traceNetIslands;
1117
+ this.obstacleRects = getObstacleRects(params.inputProblem);
1115
1118
  for (const { connNetId, pathsWithOverlap } of this.overlappingTraceSegments) {
1116
1119
  for (const {
1117
1120
  solvedTracePathIndex,
@@ -1123,13 +1126,15 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1123
1126
  }
1124
1127
  }
1125
1128
  _step() {
1126
- const EPS10 = 1e-6;
1127
- const offsets = this.overlappingTraceSegments.map((_, idx) => {
1129
+ const offsets = this.overlappingTraceSegments.map((group, idx) => {
1128
1130
  const n = Math.floor(idx / 2) + 1;
1129
1131
  const signed = idx % 2 === 0 ? -n : n;
1130
- return signed * this.SHIFT_DISTANCE;
1132
+ return this.getObstacleAwareOffset({
1133
+ group,
1134
+ offset: signed * this.SHIFT_DISTANCE
1135
+ });
1131
1136
  });
1132
- const eq = (a, b) => Math.abs(a - b) < EPS10;
1137
+ const eq = (a, b) => Math.abs(a - b) < EPS4;
1133
1138
  const samePoint = (p, q) => !!p && !!q && eq(p.x, q.x) && eq(p.y, q.y);
1134
1139
  this.overlappingTraceSegments.forEach((group, gidx) => {
1135
1140
  const offset = offsets[gidx];
@@ -1144,7 +1149,6 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1144
1149
  const original = this.traceNetIslands[group.connNetId][pathIdx];
1145
1150
  const current = this.correctedTraceMap[original.mspPairId] ?? original;
1146
1151
  const pts = current.tracePath.map((p) => ({ ...p }));
1147
- const segIdxs = Array.from(segIdxSet).sort((a, b) => a - b);
1148
1152
  const segIdxsRev = Array.from(segIdxSet).sort((a, b) => a - b).reverse();
1149
1153
  const JOG_SIZE = this.SHIFT_DISTANCE;
1150
1154
  for (const si of segIdxsRev) {
@@ -1155,13 +1159,13 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1155
1159
  segmentIndex: si,
1156
1160
  offset,
1157
1161
  JOG_SIZE,
1158
- EPS: EPS10
1162
+ EPS: EPS4
1159
1163
  });
1160
1164
  } else {
1161
1165
  const start = pts[si];
1162
1166
  const end = pts[si + 1];
1163
- const isVertical4 = Math.abs(start.x - end.x) < EPS10;
1164
- const isHorizontal3 = Math.abs(start.y - end.y) < EPS10;
1167
+ const isVertical4 = Math.abs(start.x - end.x) < EPS4;
1168
+ const isHorizontal3 = Math.abs(start.y - end.y) < EPS4;
1165
1169
  if (!isVertical4 && !isHorizontal3) continue;
1166
1170
  if (isVertical4) {
1167
1171
  start.x += offset;
@@ -1186,6 +1190,53 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1186
1190
  });
1187
1191
  this.solved = true;
1188
1192
  }
1193
+ getObstacleAwareOffset({
1194
+ group,
1195
+ offset
1196
+ }) {
1197
+ const blockingCollisions = this.getBlockingCollisions({ group, offset });
1198
+ if (blockingCollisions.length === 0) return offset;
1199
+ return blockingCollisions.flatMap(({ start, isVertical: isVertical4, obstacle }) => [
1200
+ (isVertical4 ? obstacle.minX - start.x : obstacle.minY - start.y) - this.SHIFT_DISTANCE,
1201
+ (isVertical4 ? obstacle.maxX - start.x : obstacle.maxY - start.y) + this.SHIFT_DISTANCE
1202
+ ]).filter(
1203
+ (candidateOffset) => this.getBlockingCollisions({ group, offset: candidateOffset }).length === 0
1204
+ ).sort((a, b) => Math.abs(a - offset) - Math.abs(b - offset))[0] ?? offset;
1205
+ }
1206
+ getBlockingCollisions({
1207
+ group,
1208
+ offset
1209
+ }) {
1210
+ const blockingCollisions = [];
1211
+ for (const {
1212
+ solvedTracePathIndex,
1213
+ traceSegmentIndex
1214
+ } of group.pathsWithOverlap) {
1215
+ const trace = this.traceNetIslands[group.connNetId][solvedTracePathIndex];
1216
+ const start = trace.tracePath[traceSegmentIndex];
1217
+ const end = trace.tracePath[traceSegmentIndex + 1];
1218
+ if (!start || !end) continue;
1219
+ const isVertical4 = Math.abs(start.x - end.x) < EPS4;
1220
+ const isHorizontal3 = Math.abs(start.y - end.y) < EPS4;
1221
+ if (!isVertical4 && !isHorizontal3) continue;
1222
+ const shiftedSegment = isVertical4 ? [
1223
+ { ...start, x: start.x + offset },
1224
+ { ...end, x: end.x + offset }
1225
+ ] : [
1226
+ { ...start, y: start.y + offset },
1227
+ { ...end, y: end.y + offset }
1228
+ ];
1229
+ const collision = findFirstCollision(shiftedSegment, this.obstacleRects);
1230
+ if (collision) {
1231
+ blockingCollisions.push({
1232
+ start,
1233
+ isVertical: isVertical4,
1234
+ obstacle: collision.rect
1235
+ });
1236
+ }
1237
+ }
1238
+ return blockingCollisions;
1239
+ }
1189
1240
  visualize() {
1190
1241
  const graphics = {
1191
1242
  lines: [],
@@ -1258,7 +1309,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1258
1309
  return islands;
1259
1310
  }
1260
1311
  findNextOverlapIssue() {
1261
- const EPS10 = 2e-3;
1312
+ const EPS11 = 2e-3;
1262
1313
  const netIds = Object.keys(this.traceNetIslands);
1263
1314
  for (let i = 0; i < netIds.length; i++) {
1264
1315
  for (let j = i + 1; j < netIds.length; j++) {
@@ -1276,7 +1327,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1276
1327
  const minB = Math.min(b1, b2);
1277
1328
  const maxB = Math.max(b1, b2);
1278
1329
  const overlap = Math.min(maxA, maxB) - Math.max(minA, minB);
1279
- return overlap > EPS10;
1330
+ return overlap > EPS11;
1280
1331
  };
1281
1332
  for (let pa = 0; pa < pathsA.length; pa++) {
1282
1333
  const pathA = pathsA[pa];
@@ -1284,8 +1335,8 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1284
1335
  for (let sa = 0; sa < ptsA.length - 1; sa++) {
1285
1336
  const a1 = ptsA[sa];
1286
1337
  const a2 = ptsA[sa + 1];
1287
- const aVert = Math.abs(a1.x - a2.x) < EPS10;
1288
- const aHorz = Math.abs(a1.y - a2.y) < EPS10;
1338
+ const aVert = Math.abs(a1.x - a2.x) < EPS11;
1339
+ const aHorz = Math.abs(a1.y - a2.y) < EPS11;
1289
1340
  if (!aVert && !aHorz) continue;
1290
1341
  for (let pb = 0; pb < pathsB.length; pb++) {
1291
1342
  const pathB = pathsB[pb];
@@ -1293,11 +1344,11 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1293
1344
  for (let sb = 0; sb < ptsB.length - 1; sb++) {
1294
1345
  const b1 = ptsB[sb];
1295
1346
  const b2 = ptsB[sb + 1];
1296
- const bVert = Math.abs(b1.x - b2.x) < EPS10;
1297
- const bHorz = Math.abs(b1.y - b2.y) < EPS10;
1347
+ const bVert = Math.abs(b1.x - b2.x) < EPS11;
1348
+ const bHorz = Math.abs(b1.y - b2.y) < EPS11;
1298
1349
  if (!bVert && !bHorz) continue;
1299
1350
  if (aVert && bVert) {
1300
- if (Math.abs(a1.x - b1.x) < EPS10) {
1351
+ if (Math.abs(a1.x - b1.x) < EPS11) {
1301
1352
  if (overlaps1D(a1.y, a2.y, b1.y, b2.y)) {
1302
1353
  const keyA = `${pa}:${sa}`;
1303
1354
  const keyB = `${pb}:${sb}`;
@@ -1318,7 +1369,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1318
1369
  }
1319
1370
  }
1320
1371
  } else if (aHorz && bHorz) {
1321
- if (Math.abs(a1.y - b1.y) < EPS10) {
1372
+ if (Math.abs(a1.y - b1.y) < EPS11) {
1322
1373
  if (overlaps1D(a1.x, a2.x, b1.x, b2.x)) {
1323
1374
  const keyA = `${pa}:${sa}`;
1324
1375
  const keyB = `${pb}:${sb}`;
@@ -1356,14 +1407,14 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1356
1407
  return null;
1357
1408
  }
1358
1409
  findNextDiagonalSegment() {
1359
- const EPS10 = 2e-3;
1410
+ const EPS11 = 2e-3;
1360
1411
  for (const mspPairId in this.correctedTraceMap) {
1361
1412
  const tracePath = this.correctedTraceMap[mspPairId].tracePath;
1362
1413
  for (let i = 0; i < tracePath.length - 1; i++) {
1363
1414
  const p1 = tracePath[i];
1364
1415
  const p2 = tracePath[i + 1];
1365
- const isHorizontal3 = Math.abs(p1.y - p2.y) < EPS10;
1366
- const isVertical4 = Math.abs(p1.x - p2.x) < EPS10;
1416
+ const isHorizontal3 = Math.abs(p1.y - p2.y) < EPS11;
1417
+ const isVertical4 = Math.abs(p1.x - p2.x) < EPS11;
1367
1418
  if (!isHorizontal3 && !isVertical4) {
1368
1419
  return { mspPairId, tracePath, i, p1, p2 };
1369
1420
  }
@@ -1377,13 +1428,13 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1377
1428
  return false;
1378
1429
  }
1379
1430
  const { mspPairId, tracePath, i, p1, p2 } = diagonalInfo;
1380
- const EPS10 = 2e-3;
1431
+ const EPS11 = 2e-3;
1381
1432
  const p0 = i > 0 ? tracePath[i - 1] : null;
1382
1433
  const p3 = i + 2 < tracePath.length ? tracePath[i + 2] : null;
1383
- const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS10 : false;
1384
- const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS10 : false;
1385
- const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS10 : false;
1386
- const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS10 : false;
1434
+ const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS11 : false;
1435
+ const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS11 : false;
1436
+ const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS11 : false;
1437
+ const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS11 : false;
1387
1438
  const elbow1 = { x: p1.x, y: p2.y };
1388
1439
  const elbow2 = { x: p2.x, y: p1.y };
1389
1440
  let score1 = 0;
@@ -1428,6 +1479,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1428
1479
  }
1429
1480
  const { overlappingTraceSegments } = overlapIssue;
1430
1481
  this.activeSubSolver = new TraceOverlapIssueSolver({
1482
+ inputProblem: this.inputProblem,
1431
1483
  overlappingTraceSegments,
1432
1484
  traceNetIslands: this.traceNetIslands
1433
1485
  });
@@ -1548,24 +1600,24 @@ function getRectBounds(center, w, h) {
1548
1600
  }
1549
1601
 
1550
1602
  // lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/collisions.ts
1551
- function segmentIntersectsRect2(p1, p2, rect, EPS10 = 1e-9) {
1552
- const isVert = Math.abs(p1.x - p2.x) < EPS10;
1553
- const isHorz = Math.abs(p1.y - p2.y) < EPS10;
1603
+ function segmentIntersectsRect2(p1, p2, rect, EPS11 = 1e-9) {
1604
+ const isVert = Math.abs(p1.x - p2.x) < EPS11;
1605
+ const isHorz = Math.abs(p1.y - p2.y) < EPS11;
1554
1606
  if (!isVert && !isHorz) return false;
1555
1607
  if (isVert) {
1556
1608
  const x = p1.x;
1557
- if (x < rect.minX - EPS10 || x > rect.maxX + EPS10) return false;
1609
+ if (x < rect.minX - EPS11 || x > rect.maxX + EPS11) return false;
1558
1610
  const segMinY = Math.min(p1.y, p2.y);
1559
1611
  const segMaxY = Math.max(p1.y, p2.y);
1560
1612
  const overlap = Math.min(segMaxY, rect.maxY) - Math.max(segMinY, rect.minY);
1561
- return overlap > EPS10;
1613
+ return overlap > EPS11;
1562
1614
  } else {
1563
1615
  const y = p1.y;
1564
- if (y < rect.minY - EPS10 || y > rect.maxY + EPS10) return false;
1616
+ if (y < rect.minY - EPS11 || y > rect.maxY + EPS11) return false;
1565
1617
  const segMinX = Math.min(p1.x, p2.x);
1566
1618
  const segMaxX = Math.max(p1.x, p2.x);
1567
1619
  const overlap = Math.min(segMaxX, rect.maxX) - Math.max(segMinX, rect.minX);
1568
- return overlap > EPS10;
1620
+ return overlap > EPS11;
1569
1621
  }
1570
1622
  }
1571
1623
  function rectIntersectsAnyTrace(bounds, inputTraceMap, hostPathId, hostSegIndex) {
@@ -1949,14 +2001,14 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
1949
2001
  };
1950
2002
  let bestCandidate = null;
1951
2003
  let bestScore = -Infinity;
1952
- const EPS10 = 1e-6;
2004
+ const EPS11 = 1e-6;
1953
2005
  for (const curr of tracesToScan) {
1954
2006
  const pts = curr.tracePath.slice();
1955
2007
  for (let si = 0; si < pts.length - 1; si++) {
1956
2008
  const a = pts[si];
1957
2009
  const b = pts[si + 1];
1958
- const isH = Math.abs(a.y - b.y) < EPS10;
1959
- const isV = Math.abs(a.x - b.x) < EPS10;
2010
+ const isH = Math.abs(a.y - b.y) < EPS11;
2011
+ const isV = Math.abs(a.x - b.x) < EPS11;
1960
2012
  if (!isH && !isV) continue;
1961
2013
  const segmentAllowed = isH ? ["y+", "y-"] : ["x+", "x-"];
1962
2014
  const candidateOrients = orientations.filter(
@@ -4172,8 +4224,8 @@ var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
4172
4224
  };
4173
4225
 
4174
4226
  // lib/solvers/TraceCleanupSolver/sub-solver/generateLShapeRerouteCandidates.ts
4175
- var EPS4 = 1e-6;
4176
- var isVertical2 = (a, b, eps = EPS4) => Math.abs(a.x - b.x) < eps;
4227
+ var EPS5 = 1e-6;
4228
+ var isVertical2 = (a, b, eps = EPS5) => Math.abs(a.x - b.x) < eps;
4177
4229
  var generateLShapeRerouteCandidates = ({
4178
4230
  lShape,
4179
4231
  rectangle,
@@ -4186,7 +4238,7 @@ var generateLShapeRerouteCandidates = ({
4186
4238
  let c2;
4187
4239
  let i1_padded = interactionPoint1;
4188
4240
  let i2_padded = interactionPoint2;
4189
- if (Math.abs(p2.x - x) < EPS4 && Math.abs(p2.y - (y + height)) < EPS4) {
4241
+ if (Math.abs(p2.x - x) < EPS5 && Math.abs(p2.y - (y + height)) < EPS5) {
4190
4242
  c2 = { x: x + width + padding, y: y - padding };
4191
4243
  if (isVertical2(p1, p2)) {
4192
4244
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
@@ -4198,7 +4250,7 @@ var generateLShapeRerouteCandidates = ({
4198
4250
  } else {
4199
4251
  i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
4200
4252
  }
4201
- } else if (Math.abs(p2.x - (x + width)) < EPS4 && Math.abs(p2.y - (y + height)) < EPS4) {
4253
+ } else if (Math.abs(p2.x - (x + width)) < EPS5 && Math.abs(p2.y - (y + height)) < EPS5) {
4202
4254
  c2 = { x: x - padding, y: y - padding };
4203
4255
  if (isVertical2(p1, p2)) {
4204
4256
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
@@ -4210,7 +4262,7 @@ var generateLShapeRerouteCandidates = ({
4210
4262
  } else {
4211
4263
  i2_padded = { x: interactionPoint2.x - padding, y: interactionPoint2.y };
4212
4264
  }
4213
- } else if (Math.abs(p2.x - x) < EPS4 && Math.abs(p2.y - y) < EPS4) {
4265
+ } else if (Math.abs(p2.x - x) < EPS5 && Math.abs(p2.y - y) < EPS5) {
4214
4266
  c2 = { x: x + width + padding, y: y + height + padding };
4215
4267
  if (isVertical2(p1, p2)) {
4216
4268
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
@@ -4222,7 +4274,7 @@ var generateLShapeRerouteCandidates = ({
4222
4274
  } else {
4223
4275
  i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
4224
4276
  }
4225
- } else if (Math.abs(p2.x - (x + width)) < EPS4 && Math.abs(p2.y - y) < EPS4) {
4277
+ } else if (Math.abs(p2.x - (x + width)) < EPS5 && Math.abs(p2.y - y) < EPS5) {
4226
4278
  c2 = { x: x - padding, y: y + height + padding };
4227
4279
  if (isVertical2(p1, p2)) {
4228
4280
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
@@ -4667,9 +4719,9 @@ var UntangleTraceSubsolver = class extends BaseSolver {
4667
4719
  };
4668
4720
 
4669
4721
  // lib/solvers/TraceCleanupSolver/is4PointRectangle.ts
4670
- var EPS5 = 1e-6;
4671
- var sameX = (a, b) => Math.abs(a.x - b.x) <= EPS5;
4672
- var sameY = (a, b) => Math.abs(a.y - b.y) <= EPS5;
4722
+ var EPS6 = 1e-6;
4723
+ var sameX = (a, b) => Math.abs(a.x - b.x) <= EPS6;
4724
+ var sameY = (a, b) => Math.abs(a.y - b.y) <= EPS6;
4673
4725
  var is4PointRectangle = (path) => {
4674
4726
  if (path.length !== 4) return false;
4675
4727
  const [p0, p1, p2, p3] = path;
@@ -4803,7 +4855,7 @@ var TraceCleanupSolver = class extends BaseSolver {
4803
4855
  };
4804
4856
 
4805
4857
  // lib/solvers/Example28Solver/types.ts
4806
- var EPS6 = 1e-9;
4858
+ var EPS7 = 1e-9;
4807
4859
 
4808
4860
  // lib/solvers/Example28Solver/geometry.ts
4809
4861
  var getPathKey = (path) => path.map((point) => `${point.x},${point.y}`).join(";");
@@ -4815,10 +4867,10 @@ var getPathLength = (path) => {
4815
4867
  return length;
4816
4868
  };
4817
4869
  var getDistance = (a, b) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
4818
- var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS6 || Math.abs(start.y - end.y) < EPS6;
4819
- var getSegmentOrientation = (start, end) => Math.abs(start.y - end.y) < EPS6 ? "horizontal" : "vertical";
4870
+ var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS7 || Math.abs(start.y - end.y) < EPS7;
4871
+ var getSegmentOrientation = (start, end) => Math.abs(start.y - end.y) < EPS7 ? "horizontal" : "vertical";
4820
4872
  var projectPointToSegment = (point, start, end) => {
4821
- if (Math.abs(start.x - end.x) < EPS6) {
4873
+ if (Math.abs(start.x - end.x) < EPS7) {
4822
4874
  return {
4823
4875
  x: start.x,
4824
4876
  y: Math.min(
@@ -4827,7 +4879,7 @@ var projectPointToSegment = (point, start, end) => {
4827
4879
  )
4828
4880
  };
4829
4881
  }
4830
- if (Math.abs(start.y - end.y) < EPS6) {
4882
+ if (Math.abs(start.y - end.y) < EPS7) {
4831
4883
  return {
4832
4884
  x: Math.min(
4833
4885
  Math.max(point.x, Math.min(start.x, end.x)),
@@ -4870,9 +4922,9 @@ var findSegmentContainingPoint = (path, point) => {
4870
4922
  };
4871
4923
  var isPointWithinSegmentPrimaryRange = (point, segment) => {
4872
4924
  if (segment.orientation === "horizontal") {
4873
- return point.x >= Math.min(segment.start.x, segment.end.x) - EPS6 && point.x <= Math.max(segment.start.x, segment.end.x) + EPS6;
4925
+ return point.x >= Math.min(segment.start.x, segment.end.x) - EPS7 && point.x <= Math.max(segment.start.x, segment.end.x) + EPS7;
4874
4926
  }
4875
- return point.y >= Math.min(segment.start.y, segment.end.y) - EPS6 && point.y <= Math.max(segment.start.y, segment.end.y) + EPS6;
4927
+ return point.y >= Math.min(segment.start.y, segment.end.y) - EPS7 && point.y <= Math.max(segment.start.y, segment.end.y) + EPS7;
4876
4928
  };
4877
4929
  var findPreferredReroutedSegment = (path, originalSegmentIndex, originalSegmentCount, orientation, anchorPoint) => {
4878
4930
  const matchingSegments = getSegments(path).filter(
@@ -4900,18 +4952,18 @@ var projectPointToPath = (point, path) => {
4900
4952
  return bestPoint;
4901
4953
  };
4902
4954
  var segmentsIntersect = (a1, a2, b1, b2) => {
4903
- const aVertical = Math.abs(a1.x - a2.x) < EPS6;
4904
- const bVertical = Math.abs(b1.x - b2.x) < EPS6;
4905
- const between = (value, p1, p2) => value >= Math.min(p1, p2) - EPS6 && value <= Math.max(p1, p2) + EPS6;
4955
+ const aVertical = Math.abs(a1.x - a2.x) < EPS7;
4956
+ const bVertical = Math.abs(b1.x - b2.x) < EPS7;
4957
+ const between = (value, p1, p2) => value >= Math.min(p1, p2) - EPS7 && value <= Math.max(p1, p2) + EPS7;
4906
4958
  if (aVertical && bVertical) {
4907
- if (Math.abs(a1.x - b1.x) > EPS6) return false;
4959
+ if (Math.abs(a1.x - b1.x) > EPS7) return false;
4908
4960
  const overlap = Math.min(Math.max(a1.y, a2.y), Math.max(b1.y, b2.y)) - Math.max(Math.min(a1.y, a2.y), Math.min(b1.y, b2.y));
4909
- return overlap > EPS6;
4961
+ return overlap > EPS7;
4910
4962
  }
4911
4963
  if (!aVertical && !bVertical) {
4912
- if (Math.abs(a1.y - b1.y) > EPS6) return false;
4964
+ if (Math.abs(a1.y - b1.y) > EPS7) return false;
4913
4965
  const overlap = Math.min(Math.max(a1.x, a2.x), Math.max(b1.x, b2.x)) - Math.max(Math.min(a1.x, a2.x), Math.min(b1.x, b2.x));
4914
- return overlap > EPS6;
4966
+ return overlap > EPS7;
4915
4967
  }
4916
4968
  const verticalA = aVertical ? a1 : b1;
4917
4969
  const verticalB = aVertical ? a2 : b2;
@@ -4943,13 +4995,13 @@ var isPathCollidingWithChipInterior = (path, chipObstacles) => {
4943
4995
  return false;
4944
4996
  };
4945
4997
  var segmentRunsAlongRectBoundary = (start, end, rect) => {
4946
- const isVertical4 = Math.abs(start.x - end.x) < EPS6;
4947
- const isHorizontal3 = Math.abs(start.y - end.y) < EPS6;
4998
+ const isVertical4 = Math.abs(start.x - end.x) < EPS7;
4999
+ const isHorizontal3 = Math.abs(start.y - end.y) < EPS7;
4948
5000
  if (isVertical4) {
4949
- return Math.abs(start.x - rect.minX) < EPS6 || Math.abs(start.x - rect.maxX) < EPS6;
5001
+ return Math.abs(start.x - rect.minX) < EPS7 || Math.abs(start.x - rect.maxX) < EPS7;
4950
5002
  }
4951
5003
  if (isHorizontal3) {
4952
- return Math.abs(start.y - rect.minY) < EPS6 || Math.abs(start.y - rect.maxY) < EPS6;
5004
+ return Math.abs(start.y - rect.minY) < EPS7 || Math.abs(start.y - rect.maxY) < EPS7;
4953
5005
  }
4954
5006
  return false;
4955
5007
  };
@@ -5573,16 +5625,16 @@ var Example28Solver = class extends BaseSolver {
5573
5625
  // lib/solvers/AvailableNetOrientationSolver/constants.ts
5574
5626
  var LABEL_SEARCH_STEP = 0.05;
5575
5627
  var WICK_CLEARANCE = 1e-3;
5576
- var EPS7 = 1e-9;
5577
- var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS7;
5628
+ var EPS8 = 1e-9;
5629
+ var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS8;
5578
5630
  var CANDIDATE_SELECTED_COLOR2 = "blue";
5579
5631
  var CANDIDATE_REJECTED_COLOR2 = "red";
5580
5632
 
5581
5633
  // lib/solvers/AvailableNetOrientationSolver/geometry.ts
5582
5634
  var isYOrientation = (orientation) => orientation === "y+" || orientation === "y-";
5583
5635
  var isXOrientation = (orientation) => orientation === "x+" || orientation === "x-";
5584
- var rectsOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS7 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS7;
5585
- var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS7;
5636
+ var rectsOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS8 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS8;
5637
+ var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS8;
5586
5638
  var traceCrossesBoundsInterior = (bounds, traceMap) => {
5587
5639
  for (const trace of Object.values(traceMap)) {
5588
5640
  const points = trace.tracePath;
@@ -5605,7 +5657,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
5605
5657
  return false;
5606
5658
  }
5607
5659
  if (sameX2(p1, p2)) {
5608
- if (p1.x <= interiorBounds.minX + EPS7 || p1.x >= interiorBounds.maxX - EPS7) {
5660
+ if (p1.x <= interiorBounds.minX + EPS8 || p1.x >= interiorBounds.maxX - EPS8) {
5609
5661
  return false;
5610
5662
  }
5611
5663
  return rangesOverlap(
@@ -5616,7 +5668,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
5616
5668
  );
5617
5669
  }
5618
5670
  if (sameY2(p1, p2)) {
5619
- if (p1.y <= interiorBounds.minY + EPS7 || p1.y >= interiorBounds.maxY - EPS7) {
5671
+ if (p1.y <= interiorBounds.minY + EPS8 || p1.y >= interiorBounds.maxY - EPS8) {
5620
5672
  return false;
5621
5673
  }
5622
5674
  return rangesOverlap(
@@ -5636,6 +5688,14 @@ var tracePathCrossesAnyBounds = (tracePath, bounds) => {
5636
5688
  }
5637
5689
  return false;
5638
5690
  };
5691
+ var tracePathIntersectsBounds = (tracePath, bounds) => {
5692
+ for (let i = 0; i < tracePath.length - 1; i++) {
5693
+ if (segmentIntersectsRect2(tracePath[i], tracePath[i + 1], bounds)) {
5694
+ return true;
5695
+ }
5696
+ }
5697
+ return false;
5698
+ };
5639
5699
  var tracePathCrossesAnyTrace = (tracePath, traceMap) => {
5640
5700
  for (const trace of Object.values(traceMap)) {
5641
5701
  const points = trace.tracePath;
@@ -5656,10 +5716,10 @@ var tracePathCrossesAnyTrace = (tracePath, traceMap) => {
5656
5716
  };
5657
5717
  var segmentsStrictlyCross = (a1, a2, b1, b2) => {
5658
5718
  if (sameX2(a1, a2) && sameY2(b1, b2)) {
5659
- return a1.x > Math.min(b1.x, b2.x) + EPS7 && a1.x < Math.max(b1.x, b2.x) - EPS7 && b1.y > Math.min(a1.y, a2.y) + EPS7 && b1.y < Math.max(a1.y, a2.y) - EPS7;
5719
+ return a1.x > Math.min(b1.x, b2.x) + EPS8 && a1.x < Math.max(b1.x, b2.x) - EPS8 && b1.y > Math.min(a1.y, a2.y) + EPS8 && b1.y < Math.max(a1.y, a2.y) - EPS8;
5660
5720
  }
5661
5721
  if (sameY2(a1, a2) && sameX2(b1, b2)) {
5662
- return b1.x > Math.min(a1.x, a2.x) + EPS7 && b1.x < Math.max(a1.x, a2.x) - EPS7 && a1.y > Math.min(b1.y, b2.y) + EPS7 && a1.y < Math.max(b1.y, b2.y) - EPS7;
5722
+ return b1.x > Math.min(a1.x, a2.x) + EPS8 && b1.x < Math.max(a1.x, a2.x) - EPS8 && a1.y > Math.min(b1.y, b2.y) + EPS8 && a1.y < Math.max(b1.y, b2.y) - EPS8;
5663
5723
  }
5664
5724
  return false;
5665
5725
  };
@@ -5691,8 +5751,8 @@ var simplifyOrthogonalPath = (path) => {
5691
5751
  return simplified;
5692
5752
  };
5693
5753
  var pointsEqual = (a, b) => sameX2(a, b) && sameY2(a, b);
5694
- var sameX2 = (a, b) => Math.abs(a.x - b.x) <= EPS7;
5695
- var sameY2 = (a, b) => Math.abs(a.y - b.y) <= EPS7;
5754
+ var sameX2 = (a, b) => Math.abs(a.x - b.x) <= EPS8;
5755
+ var sameY2 = (a, b) => Math.abs(a.y - b.y) <= EPS8;
5696
5756
  var getMaxSearchDistance = (inputProblem) => {
5697
5757
  const maxChipWidth = Math.max(
5698
5758
  ...inputProblem.chips.map((chip) => chip.width),
@@ -5900,28 +5960,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
5900
5960
  this.addConnectorTrace(label, candidate, labelIndex);
5901
5961
  }
5902
5962
  addConnectorTrace(label, candidate, labelIndex) {
5903
- let tracePath;
5904
- if (candidate.phase === "lateral-shift") {
5905
- const orientDir = dir(candidate.orientation);
5906
- const kickedSource = {
5907
- x: label.anchorPoint.x - orientDir.x * LABEL_SEARCH_STEP,
5908
- y: label.anchorPoint.y - orientDir.y * LABEL_SEARCH_STEP
5909
- };
5910
- tracePath = simplifyOrthogonalPath([
5911
- label.anchorPoint,
5912
- ...getConnectorTracePath(
5913
- kickedSource,
5914
- candidate.anchorPoint,
5915
- candidate.orientation
5916
- )
5917
- ]);
5918
- } else {
5919
- tracePath = getConnectorTracePath(
5920
- label.anchorPoint,
5921
- candidate.anchorPoint,
5922
- candidate.orientation
5923
- );
5924
- }
5963
+ const tracePath = this.getCandidateConnectorTrace(label, candidate);
5925
5964
  if (tracePath.length < 2) return;
5926
5965
  const mspPairId = `available-net-orientation-${labelIndex}-${label.netId ?? label.globalConnNetId}`;
5927
5966
  const connectorTrace = {
@@ -6001,7 +6040,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6001
6040
  );
6002
6041
  const maxSearchDistance = this.getSearchDistanceLimit(label, orientation);
6003
6042
  const maxOutwardDistance = outwardDirection.x === 0 && outwardDirection.y === 0 ? 0 : this.maxSearchDistance;
6004
- for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS7; outwardDistance += LABEL_SEARCH_STEP) {
6043
+ for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS8; outwardDistance += LABEL_SEARCH_STEP) {
6005
6044
  const baseAnchor = {
6006
6045
  x: initialBaseAnchor.x + outwardDirection.x * outwardDistance,
6007
6046
  y: initialBaseAnchor.y + outwardDirection.y * outwardDistance
@@ -6074,7 +6113,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6074
6113
  outwardDistance,
6075
6114
  phase = "shift"
6076
6115
  } = params;
6077
- for (let distance3 = LABEL_SEARCH_STEP; distance3 <= maxSearchDistance + EPS7; distance3 += LABEL_SEARCH_STEP) {
6116
+ for (let distance3 = LABEL_SEARCH_STEP; distance3 <= maxSearchDistance + EPS8; distance3 += LABEL_SEARCH_STEP) {
6078
6117
  const anchorPoint = {
6079
6118
  x: baseAnchor.x + direction.x * distance3,
6080
6119
  y: baseAnchor.y + direction.y * distance3
@@ -6104,9 +6143,36 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6104
6143
  distance: distance3,
6105
6144
  outwardDistance,
6106
6145
  selected: false,
6107
- status: this.getCandidateStatus(candidate, label, labelIndex)
6146
+ status: this.getCandidateStatus({
6147
+ candidate,
6148
+ label,
6149
+ labelIndex,
6150
+ phase
6151
+ })
6108
6152
  };
6109
6153
  }
6154
+ getCandidateConnectorTrace(label, candidate) {
6155
+ if (candidate.phase === "lateral-shift") {
6156
+ const orientDir = dir(candidate.orientation);
6157
+ const kickedSource = {
6158
+ x: label.anchorPoint.x - orientDir.x * LABEL_SEARCH_STEP,
6159
+ y: label.anchorPoint.y - orientDir.y * LABEL_SEARCH_STEP
6160
+ };
6161
+ return simplifyOrthogonalPath([
6162
+ label.anchorPoint,
6163
+ ...getConnectorTracePath(
6164
+ kickedSource,
6165
+ candidate.anchorPoint,
6166
+ candidate.orientation
6167
+ )
6168
+ ]);
6169
+ }
6170
+ return getConnectorTracePath(
6171
+ label.anchorPoint,
6172
+ candidate.anchorPoint,
6173
+ candidate.orientation
6174
+ );
6175
+ }
6110
6176
  getSearchStartAnchor(label, orientation) {
6111
6177
  const anchorPoint = this.getWickOffsetAnchor(label.anchorPoint, orientation);
6112
6178
  const { width, height } = getDimsForOrientation({
@@ -6226,17 +6292,18 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6226
6292
  (nc) => nc.pinIds.some((pid) => label.pinIds.includes(pid))
6227
6293
  )?.netLabelHeight;
6228
6294
  }
6229
- getCandidateStatus(candidate, label, labelIndex) {
6295
+ getCandidateStatus(params) {
6296
+ const { candidate, label, labelIndex, phase } = params;
6230
6297
  const boundsStatus = this.getBoundsStatus(
6231
6298
  getRectBounds(candidate.center, candidate.width, candidate.height),
6232
6299
  labelIndex
6233
6300
  );
6234
6301
  if (boundsStatus !== "valid") return boundsStatus;
6235
- const connectorTrace = getConnectorTracePath(
6236
- label.anchorPoint,
6237
- candidate.anchorPoint,
6238
- candidate.orientation
6239
- );
6302
+ const connectorTrace = this.getCandidateConnectorTrace(label, {
6303
+ anchorPoint: candidate.anchorPoint,
6304
+ orientation: candidate.orientation,
6305
+ phase
6306
+ });
6240
6307
  if (tracePathCrossesAnyTrace(connectorTrace, this.traceMap)) {
6241
6308
  return "trace-collision";
6242
6309
  }
@@ -6248,7 +6315,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6248
6315
  for (let i = 0; i < this.outputNetLabelPlacements.length; i++) {
6249
6316
  if (i === labelIndex) continue;
6250
6317
  const otherLabel = this.outputNetLabelPlacements[i];
6251
- if (tracePathCrossesAnyBounds(
6318
+ if (tracePathIntersectsBounds(
6252
6319
  connectorTrace,
6253
6320
  getRectBounds(otherLabel.center, otherLabel.width, otherLabel.height)
6254
6321
  )) {
@@ -6284,8 +6351,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6284
6351
  sharesChipBoundary(bounds) {
6285
6352
  for (const chip of this.chipObstacleSpatialIndex.chips) {
6286
6353
  const chipBounds = chip.bounds;
6287
- const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS7 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS7;
6288
- const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS7 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS7;
6354
+ const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS8 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS8;
6355
+ const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS8 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS8;
6289
6356
  if (adjacentToVerticalSide && rangesOverlap(
6290
6357
  bounds.minY,
6291
6358
  bounds.maxY,
@@ -6333,7 +6400,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6333
6400
  let nearestDistance = Number.POSITIVE_INFINITY;
6334
6401
  for (const chip of this.chipObstacleSpatialIndex.chips) {
6335
6402
  const bounds = chip.bounds;
6336
- if (point.x < bounds.minX - EPS7 || point.x > bounds.maxX + EPS7 || point.y < bounds.minY - EPS7 || point.y > bounds.maxY + EPS7) {
6403
+ if (point.x < bounds.minX - EPS8 || point.x > bounds.maxX + EPS8 || point.y < bounds.minY - EPS8 || point.y > bounds.maxY + EPS8) {
6337
6404
  continue;
6338
6405
  }
6339
6406
  for (const [side, distance3] of getSideDistances(point, bounds)) {
@@ -6350,8 +6417,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6350
6417
  let nearestDistanceSq = Number.POSITIVE_INFINITY;
6351
6418
  for (const chip of this.chipObstacleSpatialIndex.chips) {
6352
6419
  const bounds = chip.bounds;
6353
- const dx = point.x < bounds.minX - EPS7 ? bounds.minX - point.x : point.x > bounds.maxX + EPS7 ? point.x - bounds.maxX : 0;
6354
- const dy = point.y < bounds.minY - EPS7 ? bounds.minY - point.y : point.y > bounds.maxY + EPS7 ? point.y - bounds.maxY : 0;
6420
+ const dx = point.x < bounds.minX - EPS8 ? bounds.minX - point.x : point.x > bounds.maxX + EPS8 ? point.x - bounds.maxX : 0;
6421
+ const dy = point.y < bounds.minY - EPS8 ? bounds.minY - point.y : point.y > bounds.maxY + EPS8 ? point.y - bounds.maxY : 0;
6355
6422
  if (dx === 0 && dy === 0) continue;
6356
6423
  const distanceSq = dx ** 2 + dy ** 2;
6357
6424
  if (distanceSq >= nearestDistanceSq) continue;
@@ -6390,9 +6457,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6390
6457
  };
6391
6458
 
6392
6459
  // lib/solvers/VccNetLabelCornerPlacementSolver/geometry.ts
6393
- var EPS8 = 1e-6;
6460
+ var EPS9 = 1e-6;
6394
6461
  var isTraceLine = (trace) => getUniquePinCount(trace.pinIds) >= 2;
6395
- var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS8 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS8;
6462
+ var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS9 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS9;
6396
6463
  var getTraceCorners = (path) => {
6397
6464
  const corners = [];
6398
6465
  for (let i = 1; i < path.length - 1; i++) {
@@ -6416,11 +6483,11 @@ var getUniquePinCount = (pinIds) => new Set(pinIds).size;
6416
6483
  var isTraceCorner = (a, b, c) => getSegmentOrientation2(a, b) !== getSegmentOrientation2(b, c);
6417
6484
  var isPointOnSegment = (point, start, end) => {
6418
6485
  if (getSegmentOrientation2(start, end) === "horizontal") {
6419
- return Math.abs(point.y - start.y) <= EPS8 && point.x >= Math.min(start.x, end.x) - EPS8 && point.x <= Math.max(start.x, end.x) + EPS8;
6486
+ return Math.abs(point.y - start.y) <= EPS9 && point.x >= Math.min(start.x, end.x) - EPS9 && point.x <= Math.max(start.x, end.x) + EPS9;
6420
6487
  }
6421
- return Math.abs(point.x - start.x) <= EPS8 && point.y >= Math.min(start.y, end.y) - EPS8 && point.y <= Math.max(start.y, end.y) + EPS8;
6488
+ return Math.abs(point.x - start.x) <= EPS9 && point.y >= Math.min(start.y, end.y) - EPS9 && point.y <= Math.max(start.y, end.y) + EPS9;
6422
6489
  };
6423
- var getSegmentOrientation2 = (a, b) => Math.abs(a.y - b.y) <= EPS8 ? "horizontal" : "vertical";
6490
+ var getSegmentOrientation2 = (a, b) => Math.abs(a.y - b.y) <= EPS9 ? "horizontal" : "vertical";
6424
6491
 
6425
6492
  // lib/solvers/VccNetLabelCornerPlacementSolver/visualize.ts
6426
6493
  var CANDIDATE_SELECTED_COLOR3 = "blue";
@@ -6698,11 +6765,11 @@ var VccNetLabelCornerPlacementSolver = class extends BaseSolver {
6698
6765
  };
6699
6766
 
6700
6767
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/geometry.ts
6701
- var EPS9 = 1e-6;
6768
+ var EPS10 = 1e-6;
6702
6769
  var TRACE_BOUNDARY_TOLERANCE2 = 1e-6;
6703
6770
  var getLabelBounds = (label) => getRectBounds(label.center, label.width, label.height);
6704
- var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS9 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS9;
6705
- var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -EPS9 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) >= -EPS9;
6771
+ var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS10 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS10;
6772
+ var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -EPS10 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) >= -EPS10;
6706
6773
  var traceCrossesBoundsInterior2 = (bounds, traces) => {
6707
6774
  for (const trace of traces) {
6708
6775
  const points = trace.tracePath;
@@ -6748,7 +6815,7 @@ var getPointAtTraceDistance = (trace, distance3) => {
6748
6815
  const end = trace.tracePath[i + 1];
6749
6816
  const segmentLength = getManhattanDistance(start, end);
6750
6817
  const nextDistance = pathDistance + segmentLength;
6751
- if (distance3 <= nextDistance + EPS9) {
6818
+ if (distance3 <= nextDistance + EPS10) {
6752
6819
  const offset = Math.max(
6753
6820
  0,
6754
6821
  Math.min(segmentLength, distance3 - pathDistance)
@@ -6787,7 +6854,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
6787
6854
  return false;
6788
6855
  }
6789
6856
  if (isVertical3(start, end)) {
6790
- if (start.x <= interior.minX + EPS9 || start.x >= interior.maxX - EPS9) {
6857
+ if (start.x <= interior.minX + EPS10 || start.x >= interior.maxX - EPS10) {
6791
6858
  return false;
6792
6859
  }
6793
6860
  return rangesOverlap2(
@@ -6798,7 +6865,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
6798
6865
  );
6799
6866
  }
6800
6867
  if (isHorizontal2(start, end)) {
6801
- if (start.y <= interior.minY + EPS9 || start.y >= interior.maxY - EPS9) {
6868
+ if (start.y <= interior.minY + EPS10 || start.y >= interior.maxY - EPS10) {
6802
6869
  return false;
6803
6870
  }
6804
6871
  return rangesOverlap2(
@@ -6812,10 +6879,10 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
6812
6879
  };
6813
6880
  var isPointOnSegment2 = (point, start, end) => {
6814
6881
  if (isHorizontal2(start, end)) {
6815
- return Math.abs(point.y - start.y) <= EPS9 && point.x >= Math.min(start.x, end.x) - EPS9 && point.x <= Math.max(start.x, end.x) + EPS9;
6882
+ return Math.abs(point.y - start.y) <= EPS10 && point.x >= Math.min(start.x, end.x) - EPS10 && point.x <= Math.max(start.x, end.x) + EPS10;
6816
6883
  }
6817
6884
  if (isVertical3(start, end)) {
6818
- return Math.abs(point.x - start.x) <= EPS9 && point.y >= Math.min(start.y, end.y) - EPS9 && point.y <= Math.max(start.y, end.y) + EPS9;
6885
+ return Math.abs(point.x - start.x) <= EPS10 && point.y >= Math.min(start.y, end.y) - EPS10 && point.y <= Math.max(start.y, end.y) + EPS10;
6819
6886
  }
6820
6887
  return false;
6821
6888
  };
@@ -6823,9 +6890,9 @@ var getSegmentDirection = (start, end) => ({
6823
6890
  x: isVertical3(start, end) ? 0 : Math.sign(end.x - start.x),
6824
6891
  y: isHorizontal2(start, end) ? 0 : Math.sign(end.y - start.y)
6825
6892
  });
6826
- var isHorizontal2 = (start, end) => Math.abs(start.y - end.y) <= EPS9;
6827
- var isVertical3 = (start, end) => Math.abs(start.x - end.x) <= EPS9;
6828
- var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS9;
6893
+ var isHorizontal2 = (start, end) => Math.abs(start.y - end.y) <= EPS10;
6894
+ var isVertical3 = (start, end) => Math.abs(start.x - end.x) <= EPS10;
6895
+ var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS10;
6829
6896
  var getUniquePinCount2 = (pinIds) => new Set(pinIds).size;
6830
6897
 
6831
6898
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/candidates.ts
@@ -6882,7 +6949,7 @@ var getCandidateDistances = (traceLength, vertexDistances) => {
6882
6949
  for (const distance3 of vertexDistances) {
6883
6950
  distances.add(roundDistance(distance3));
6884
6951
  }
6885
- return [...distances].filter((distance3) => distance3 >= -EPS9 && distance3 <= traceLength + EPS9).sort((a, b) => a - b);
6952
+ return [...distances].filter((distance3) => distance3 >= -EPS10 && distance3 <= traceLength + EPS10).sort((a, b) => a - b);
6886
6953
  };
6887
6954
  var getOrientationsForPoint = (params) => {
6888
6955
  const { inputProblem, label, point, orientationConstraint } = params;
@@ -6991,13 +7058,13 @@ var getOutwardOrientationOptions = (point, chipBounds) => {
6991
7058
  };
6992
7059
  var getOutwardAxisOption = (params) => {
6993
7060
  const { value, min, max, center, positiveOrientation, negativeOrientation } = params;
6994
- if (value > max + EPS9) {
7061
+ if (value > max + EPS10) {
6995
7062
  return {
6996
7063
  orientation: positiveOrientation,
6997
7064
  outwardScore: 1 + value - max
6998
7065
  };
6999
7066
  }
7000
- if (value < min - EPS9) {
7067
+ if (value < min - EPS10) {
7001
7068
  return {
7002
7069
  orientation: negativeOrientation,
7003
7070
  outwardScore: 1 + min - value
@@ -7008,7 +7075,7 @@ var getOutwardAxisOption = (params) => {
7008
7075
  outwardScore: getNormalizedCenterDistance(value, center, max - min)
7009
7076
  };
7010
7077
  };
7011
- var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS9, span / 2);
7078
+ var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS10, span / 2);
7012
7079
  var ALL_ORIENTATIONS = ["x+", "x-", "y+", "y-"];
7013
7080
  var getFlippedOrientation = (orientation) => {
7014
7081
  switch (orientation) {
@@ -7103,7 +7170,7 @@ var normalizeFacingDirection = (value) => {
7103
7170
  var dedupeStrings = (values) => [
7104
7171
  ...new Set(values.filter((value) => value !== void 0))
7105
7172
  ];
7106
- var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS9 && Math.abs(point.y - label.anchorPoint.y) <= EPS9 && orientation === label.orientation;
7173
+ var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS10 && Math.abs(point.y - label.anchorPoint.y) <= EPS10 && orientation === label.orientation;
7107
7174
 
7108
7175
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/visualize.ts
7109
7176
  var CANDIDATE_SELECTED_COLOR4 = "blue";
@@ -7491,16 +7558,14 @@ function buildMergedObstacleLabel(seedLabel, allLabels) {
7491
7558
  height: h
7492
7559
  };
7493
7560
  }
7494
- function detectInnerTraceLabelOverlaps(traces, labels) {
7561
+ function detectTraceLabelOverlaps(traces, labels) {
7495
7562
  const overlaps = [];
7496
7563
  for (const trace of traces) {
7497
7564
  for (const label of labels) {
7498
7565
  if (trace.globalConnNetId === label.globalConnNetId) continue;
7499
7566
  const bounds = getRectBounds(label.center, label.width, label.height);
7500
7567
  const path = trace.tracePath;
7501
- const innerStart = 1;
7502
- const innerEnd = path.length - 2;
7503
- for (let i = innerStart; i < innerEnd; i++) {
7568
+ for (let i = 0; i < path.length - 1; i++) {
7504
7569
  if (segmentIntersectsRect2(path[i], path[i + 1], bounds)) {
7505
7570
  overlaps.push({ trace, label });
7506
7571
  break;
@@ -7566,7 +7631,7 @@ var NetLabelTraceCollisionSolver = class extends BaseSolver {
7566
7631
  }
7567
7632
  return;
7568
7633
  }
7569
- const overlaps = detectInnerTraceLabelOverlaps(
7634
+ const overlaps = detectTraceLabelOverlaps(
7570
7635
  this.outputTraces,
7571
7636
  this.outputNetLabelPlacements
7572
7637
  );