@tscircuit/schematic-trace-solver 0.0.132 → 0.0.134
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 +265 -134
- package/lib/solvers/AvailableNetOrientationSolver/AvailableNetOrientationSolver.ts +12 -6
- package/lib/solvers/AvailableNetOrientationSolver/orderRoutedLabelsBeforeOverlappingPortLabels.ts +47 -0
- package/lib/solvers/LongDistancePairSolver/LongDistancePairSolver.ts +140 -6
- package/package.json +1 -1
- package/tests/repros/__snapshots__/repro-type-c-vbus-led-ground-label.snap.svg +66 -0
- package/tests/repros/__snapshots__/repro-usb-power-vbus-label-detour.snap.svg +3 -3
- package/tests/repros/repro-type-c-vbus-led-ground-label.test.ts +149 -0
- package/tests/repros/repro-usb-power-vbus-label-detour.test.ts +20 -1
package/dist/index.js
CHANGED
|
@@ -325,19 +325,19 @@ var doesPairCrossRestrictedCenterLines = (params) => {
|
|
|
325
325
|
chipMap
|
|
326
326
|
});
|
|
327
327
|
if (restrictedCenterLines.size === 0) return false;
|
|
328
|
-
const
|
|
328
|
+
const EPS14 = 1e-9;
|
|
329
329
|
const crossesSegment = (a, b) => {
|
|
330
330
|
for (const [, rcl] of restrictedCenterLines) {
|
|
331
331
|
if (rcl.axes.has("x") && typeof rcl.x === "number") {
|
|
332
|
-
if ((a.x - rcl.x) * (b.x - rcl.x) < -
|
|
332
|
+
if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS14) return true;
|
|
333
333
|
}
|
|
334
334
|
if (rcl.axes.has("y") && typeof rcl.y === "number") {
|
|
335
|
-
if ((a.y - rcl.y) * (b.y - rcl.y) < -
|
|
335
|
+
if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS14) return true;
|
|
336
336
|
}
|
|
337
337
|
}
|
|
338
338
|
return false;
|
|
339
339
|
};
|
|
340
|
-
if (Math.abs(p1.x - p2.x) <
|
|
340
|
+
if (Math.abs(p1.x - p2.x) < EPS14 || Math.abs(p1.y - p2.y) < EPS14) {
|
|
341
341
|
return crossesSegment({ x: p1.x, y: p1.y }, { x: p2.x, y: p2.y });
|
|
342
342
|
}
|
|
343
343
|
const elbowHV = { x: p2.x, y: p1.y };
|
|
@@ -1424,8 +1424,8 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
|
|
|
1424
1424
|
if (!collision) {
|
|
1425
1425
|
const first = path[0];
|
|
1426
1426
|
const last = path[path.length - 1];
|
|
1427
|
-
const
|
|
1428
|
-
const samePoint = (p, q) => Math.abs(p.x - q.x) <
|
|
1427
|
+
const EPS14 = 1e-9;
|
|
1428
|
+
const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS14 && Math.abs(p.y - q.y) < EPS14;
|
|
1429
1429
|
if (samePoint(first, { x: PA.x, y: PA.y }) && samePoint(last, { x: PB.x, y: PB.y })) {
|
|
1430
1430
|
this.solvedTracePath = path;
|
|
1431
1431
|
this.solved = true;
|
|
@@ -1709,13 +1709,13 @@ var applyJogToTerminalSegment = ({
|
|
|
1709
1709
|
segmentIndex: si,
|
|
1710
1710
|
offset,
|
|
1711
1711
|
JOG_SIZE,
|
|
1712
|
-
EPS:
|
|
1712
|
+
EPS: EPS14 = 1e-6
|
|
1713
1713
|
}) => {
|
|
1714
1714
|
if (si !== 0 && si !== pts.length - 2) return;
|
|
1715
1715
|
const start = pts[si];
|
|
1716
1716
|
const end = pts[si + 1];
|
|
1717
|
-
const isVertical5 = Math.abs(start.x - end.x) <
|
|
1718
|
-
const isHorizontal4 = Math.abs(start.y - end.y) <
|
|
1717
|
+
const isVertical5 = Math.abs(start.x - end.x) < EPS14;
|
|
1718
|
+
const isHorizontal4 = Math.abs(start.y - end.y) < EPS14;
|
|
1719
1719
|
if (!isVertical5 && !isHorizontal4) return;
|
|
1720
1720
|
const segDir = isVertical5 ? end.y > start.y ? 1 : -1 : end.x > start.x ? 1 : -1;
|
|
1721
1721
|
if (pts.length === 2) {
|
|
@@ -2144,7 +2144,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2144
2144
|
return islands;
|
|
2145
2145
|
}
|
|
2146
2146
|
findNextOverlapIssue() {
|
|
2147
|
-
const
|
|
2147
|
+
const EPS14 = 2e-3;
|
|
2148
2148
|
const netIds = Object.keys(this.traceNetIslands);
|
|
2149
2149
|
for (let i = 0; i < netIds.length; i++) {
|
|
2150
2150
|
for (let j = i + 1; j < netIds.length; j++) {
|
|
@@ -2171,7 +2171,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2171
2171
|
segmentBIndex,
|
|
2172
2172
|
rangeOverlap
|
|
2173
2173
|
}) => {
|
|
2174
|
-
if (rangeOverlap >
|
|
2174
|
+
if (rangeOverlap > EPS14) {
|
|
2175
2175
|
const keyA = `${pathAIndex}:${segmentAIndex}`;
|
|
2176
2176
|
const keyB = `${pathBIndex}:${segmentBIndex}`;
|
|
2177
2177
|
if (!seenA.has(keyA)) {
|
|
@@ -2190,7 +2190,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2190
2190
|
}
|
|
2191
2191
|
return;
|
|
2192
2192
|
}
|
|
2193
|
-
if (rangeOverlap < -
|
|
2193
|
+
if (rangeOverlap < -EPS14) return;
|
|
2194
2194
|
const pathA = pathsA[pathAIndex].tracePath;
|
|
2195
2195
|
const pathB = pathsB[pathBIndex].tracePath;
|
|
2196
2196
|
const segmentAStart = pathA[segmentAIndex];
|
|
@@ -2213,8 +2213,8 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2213
2213
|
for (let sa = 0; sa < ptsA.length - 1; sa++) {
|
|
2214
2214
|
const a1 = ptsA[sa];
|
|
2215
2215
|
const a2 = ptsA[sa + 1];
|
|
2216
|
-
const aVert = Math.abs(a1.x - a2.x) <
|
|
2217
|
-
const aHorz = Math.abs(a1.y - a2.y) <
|
|
2216
|
+
const aVert = Math.abs(a1.x - a2.x) < EPS14;
|
|
2217
|
+
const aHorz = Math.abs(a1.y - a2.y) < EPS14;
|
|
2218
2218
|
if (!aVert && !aHorz) continue;
|
|
2219
2219
|
for (let pb = 0; pb < pathsB.length; pb++) {
|
|
2220
2220
|
const pathB = pathsB[pb];
|
|
@@ -2225,11 +2225,11 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2225
2225
|
for (let sb = 0; sb < ptsB.length - 1; sb++) {
|
|
2226
2226
|
const b1 = ptsB[sb];
|
|
2227
2227
|
const b2 = ptsB[sb + 1];
|
|
2228
|
-
const bVert = Math.abs(b1.x - b2.x) <
|
|
2229
|
-
const bHorz = Math.abs(b1.y - b2.y) <
|
|
2228
|
+
const bVert = Math.abs(b1.x - b2.x) < EPS14;
|
|
2229
|
+
const bHorz = Math.abs(b1.y - b2.y) < EPS14;
|
|
2230
2230
|
if (!bVert && !bHorz) continue;
|
|
2231
2231
|
if (aVert && bVert) {
|
|
2232
|
-
if (Math.abs(a1.x - b1.x) <
|
|
2232
|
+
if (Math.abs(a1.x - b1.x) < EPS14) {
|
|
2233
2233
|
recordCollinearInteraction({
|
|
2234
2234
|
pathAIndex: pa,
|
|
2235
2235
|
segmentAIndex: sa,
|
|
@@ -2239,7 +2239,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2239
2239
|
});
|
|
2240
2240
|
}
|
|
2241
2241
|
} else if (aHorz && bHorz) {
|
|
2242
|
-
if (Math.abs(a1.y - b1.y) <
|
|
2242
|
+
if (Math.abs(a1.y - b1.y) < EPS14) {
|
|
2243
2243
|
recordCollinearInteraction({
|
|
2244
2244
|
pathAIndex: pa,
|
|
2245
2245
|
segmentAIndex: sa,
|
|
@@ -2295,14 +2295,14 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2295
2295
|
return null;
|
|
2296
2296
|
}
|
|
2297
2297
|
findNextDiagonalSegment() {
|
|
2298
|
-
const
|
|
2298
|
+
const EPS14 = 2e-3;
|
|
2299
2299
|
for (const mspPairId in this.correctedTraceMap) {
|
|
2300
2300
|
const tracePath = this.correctedTraceMap[mspPairId].tracePath;
|
|
2301
2301
|
for (let i = 0; i < tracePath.length - 1; i++) {
|
|
2302
2302
|
const p1 = tracePath[i];
|
|
2303
2303
|
const p2 = tracePath[i + 1];
|
|
2304
|
-
const isHorizontal4 = Math.abs(p1.y - p2.y) <
|
|
2305
|
-
const isVertical5 = Math.abs(p1.x - p2.x) <
|
|
2304
|
+
const isHorizontal4 = Math.abs(p1.y - p2.y) < EPS14;
|
|
2305
|
+
const isVertical5 = Math.abs(p1.x - p2.x) < EPS14;
|
|
2306
2306
|
if (!isHorizontal4 && !isVertical5) {
|
|
2307
2307
|
return { mspPairId, tracePath, i, p1, p2 };
|
|
2308
2308
|
}
|
|
@@ -2316,13 +2316,13 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2316
2316
|
return false;
|
|
2317
2317
|
}
|
|
2318
2318
|
const { mspPairId, tracePath, i, p1, p2 } = diagonalInfo;
|
|
2319
|
-
const
|
|
2319
|
+
const EPS14 = 2e-3;
|
|
2320
2320
|
const p0 = i > 0 ? tracePath[i - 1] : null;
|
|
2321
2321
|
const p3 = i + 2 < tracePath.length ? tracePath[i + 2] : null;
|
|
2322
|
-
const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) <
|
|
2323
|
-
const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) <
|
|
2324
|
-
const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) <
|
|
2325
|
-
const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) <
|
|
2322
|
+
const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS14 : false;
|
|
2323
|
+
const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS14 : false;
|
|
2324
|
+
const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS14 : false;
|
|
2325
|
+
const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS14 : false;
|
|
2326
2326
|
const elbow1 = { x: p1.x, y: p2.y };
|
|
2327
2327
|
const elbow2 = { x: p2.x, y: p1.y };
|
|
2328
2328
|
let score1 = 0;
|
|
@@ -2450,24 +2450,24 @@ var ChipObstacleSpatialIndex = class {
|
|
|
2450
2450
|
};
|
|
2451
2451
|
|
|
2452
2452
|
// lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/collisions.ts
|
|
2453
|
-
function segmentIntersectsRect2(p1, p2, rect,
|
|
2454
|
-
const isVert = Math.abs(p1.x - p2.x) <
|
|
2455
|
-
const isHorz = Math.abs(p1.y - p2.y) <
|
|
2453
|
+
function segmentIntersectsRect2(p1, p2, rect, EPS14 = 1e-9) {
|
|
2454
|
+
const isVert = Math.abs(p1.x - p2.x) < EPS14;
|
|
2455
|
+
const isHorz = Math.abs(p1.y - p2.y) < EPS14;
|
|
2456
2456
|
if (!isVert && !isHorz) return false;
|
|
2457
2457
|
if (isVert) {
|
|
2458
2458
|
const x = p1.x;
|
|
2459
|
-
if (x < rect.minX -
|
|
2459
|
+
if (x < rect.minX - EPS14 || x > rect.maxX + EPS14) return false;
|
|
2460
2460
|
const segMinY = Math.min(p1.y, p2.y);
|
|
2461
2461
|
const segMaxY = Math.max(p1.y, p2.y);
|
|
2462
2462
|
const overlap = Math.min(segMaxY, rect.maxY) - Math.max(segMinY, rect.minY);
|
|
2463
|
-
return overlap >
|
|
2463
|
+
return overlap > EPS14;
|
|
2464
2464
|
} else {
|
|
2465
2465
|
const y = p1.y;
|
|
2466
|
-
if (y < rect.minY -
|
|
2466
|
+
if (y < rect.minY - EPS14 || y > rect.maxY + EPS14) return false;
|
|
2467
2467
|
const segMinX = Math.min(p1.x, p2.x);
|
|
2468
2468
|
const segMaxX = Math.max(p1.x, p2.x);
|
|
2469
2469
|
const overlap = Math.min(segMaxX, rect.maxX) - Math.max(segMinX, rect.minX);
|
|
2470
|
-
return overlap >
|
|
2470
|
+
return overlap > EPS14;
|
|
2471
2471
|
}
|
|
2472
2472
|
}
|
|
2473
2473
|
function rectIntersectsAnyTrace(bounds, inputTraceMap, hostPathId, hostSegIndex) {
|
|
@@ -2864,14 +2864,14 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
|
|
|
2864
2864
|
};
|
|
2865
2865
|
let bestCandidate = null;
|
|
2866
2866
|
let bestScore = -Infinity;
|
|
2867
|
-
const
|
|
2867
|
+
const EPS14 = 1e-6;
|
|
2868
2868
|
for (const curr of tracesToScan) {
|
|
2869
2869
|
const pts = curr.tracePath.slice();
|
|
2870
2870
|
for (let si = 0; si < pts.length - 1; si++) {
|
|
2871
2871
|
const a = pts[si];
|
|
2872
2872
|
const b = pts[si + 1];
|
|
2873
|
-
const isH = Math.abs(a.y - b.y) <
|
|
2874
|
-
const isV = Math.abs(a.x - b.x) <
|
|
2873
|
+
const isH = Math.abs(a.y - b.y) < EPS14;
|
|
2874
|
+
const isV = Math.abs(a.x - b.x) < EPS14;
|
|
2875
2875
|
if (!isH && !isV) continue;
|
|
2876
2876
|
const segmentAllowed = isH ? ["y+", "y-"] : ["x+", "x-"];
|
|
2877
2877
|
const candidateOrients = orientations.filter(
|
|
@@ -4619,6 +4619,81 @@ var distance3 = (p1, p2) => {
|
|
|
4619
4619
|
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
|
|
4620
4620
|
};
|
|
4621
4621
|
var manhattanDistance = (p1, p2) => Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y);
|
|
4622
|
+
var EPS6 = 1e-9;
|
|
4623
|
+
var between = (value, first, second) => value >= Math.min(first, second) - EPS6 && value <= Math.max(first, second) + EPS6;
|
|
4624
|
+
var getAxisAlignedIntersection = (firstStart, firstEnd, secondStart, secondEnd) => {
|
|
4625
|
+
const firstIsHorizontal = Math.abs(firstStart.y - firstEnd.y) <= EPS6;
|
|
4626
|
+
const firstIsVertical = Math.abs(firstStart.x - firstEnd.x) <= EPS6;
|
|
4627
|
+
const secondIsHorizontal = Math.abs(secondStart.y - secondEnd.y) <= EPS6;
|
|
4628
|
+
const secondIsVertical = Math.abs(secondStart.x - secondEnd.x) <= EPS6;
|
|
4629
|
+
if (firstIsHorizontal && secondIsVertical) {
|
|
4630
|
+
const point = { x: secondStart.x, y: firstStart.y };
|
|
4631
|
+
return between(point.x, firstStart.x, firstEnd.x) && between(point.y, secondStart.y, secondEnd.y) ? point : null;
|
|
4632
|
+
}
|
|
4633
|
+
if (firstIsVertical && secondIsHorizontal) {
|
|
4634
|
+
const point = { x: firstStart.x, y: secondStart.y };
|
|
4635
|
+
return between(point.y, firstStart.y, firstEnd.y) && between(point.x, secondStart.x, secondEnd.x) ? point : null;
|
|
4636
|
+
}
|
|
4637
|
+
if (firstIsHorizontal && secondIsHorizontal && Math.abs(firstStart.y - secondStart.y) <= EPS6) {
|
|
4638
|
+
const overlapMin = Math.max(
|
|
4639
|
+
Math.min(firstStart.x, firstEnd.x),
|
|
4640
|
+
Math.min(secondStart.x, secondEnd.x)
|
|
4641
|
+
);
|
|
4642
|
+
const overlapMax = Math.min(
|
|
4643
|
+
Math.max(firstStart.x, firstEnd.x),
|
|
4644
|
+
Math.max(secondStart.x, secondEnd.x)
|
|
4645
|
+
);
|
|
4646
|
+
if (overlapMin > overlapMax + EPS6) return null;
|
|
4647
|
+
return {
|
|
4648
|
+
x: Math.max(overlapMin, Math.min(firstStart.x, overlapMax)),
|
|
4649
|
+
y: firstStart.y
|
|
4650
|
+
};
|
|
4651
|
+
}
|
|
4652
|
+
if (firstIsVertical && secondIsVertical && Math.abs(firstStart.x - secondStart.x) <= EPS6) {
|
|
4653
|
+
const overlapMin = Math.max(
|
|
4654
|
+
Math.min(firstStart.y, firstEnd.y),
|
|
4655
|
+
Math.min(secondStart.y, secondEnd.y)
|
|
4656
|
+
);
|
|
4657
|
+
const overlapMax = Math.min(
|
|
4658
|
+
Math.max(firstStart.y, firstEnd.y),
|
|
4659
|
+
Math.max(secondStart.y, secondEnd.y)
|
|
4660
|
+
);
|
|
4661
|
+
if (overlapMin > overlapMax + EPS6) return null;
|
|
4662
|
+
return {
|
|
4663
|
+
x: firstStart.x,
|
|
4664
|
+
y: Math.max(overlapMin, Math.min(firstStart.y, overlapMax))
|
|
4665
|
+
};
|
|
4666
|
+
}
|
|
4667
|
+
return null;
|
|
4668
|
+
};
|
|
4669
|
+
var clipPathAtFirstIntersection = (tracePath, existingTraces) => {
|
|
4670
|
+
for (let pathIndex = 0; pathIndex < tracePath.length - 1; pathIndex++) {
|
|
4671
|
+
const pathStart = tracePath[pathIndex];
|
|
4672
|
+
const pathEnd = tracePath[pathIndex + 1];
|
|
4673
|
+
const intersections = existingTraces.flatMap(
|
|
4674
|
+
(trace) => trace.tracePath.slice(0, -1).flatMap((traceStart, traceIndex) => {
|
|
4675
|
+
const intersection2 = getAxisAlignedIntersection(
|
|
4676
|
+
pathStart,
|
|
4677
|
+
pathEnd,
|
|
4678
|
+
traceStart,
|
|
4679
|
+
trace.tracePath[traceIndex + 1]
|
|
4680
|
+
);
|
|
4681
|
+
return intersection2 ? [intersection2] : [];
|
|
4682
|
+
})
|
|
4683
|
+
);
|
|
4684
|
+
intersections.sort(
|
|
4685
|
+
(first, second) => distance3(pathStart, first) - distance3(pathStart, second)
|
|
4686
|
+
);
|
|
4687
|
+
const intersection = intersections[0];
|
|
4688
|
+
if (!intersection) continue;
|
|
4689
|
+
const clippedPath = tracePath.slice(0, pathIndex + 1);
|
|
4690
|
+
if (distance3(clippedPath.at(-1), intersection) > EPS6) {
|
|
4691
|
+
clippedPath.push(intersection);
|
|
4692
|
+
}
|
|
4693
|
+
return clippedPath;
|
|
4694
|
+
}
|
|
4695
|
+
return null;
|
|
4696
|
+
};
|
|
4622
4697
|
var LongDistancePairSolver = class extends BaseSolver {
|
|
4623
4698
|
constructor(params) {
|
|
4624
4699
|
super();
|
|
@@ -4733,20 +4808,36 @@ var LongDistancePairSolver = class extends BaseSolver {
|
|
|
4733
4808
|
} else if (this.subSolver?.solved) {
|
|
4734
4809
|
const newTracePath = this.subSolver.solvedTracePath;
|
|
4735
4810
|
if (newTracePath && this.currentCandidatePair) {
|
|
4811
|
+
const [p1, p2] = this.currentCandidatePair;
|
|
4812
|
+
const globalConnNetId = this.netConnMap.getNetConnectedToId(p1.pinId);
|
|
4813
|
+
const sameNetTraces = this.allSolvedTraces.filter(
|
|
4814
|
+
(trace) => trace.globalConnNetId === globalConnNetId
|
|
4815
|
+
);
|
|
4816
|
+
const inputNetConnection = this.inputProblem.netConnections.find(
|
|
4817
|
+
(connection) => connection.pinIds.length === 3 && connection.pinIds.includes(p1.pinId) && connection.pinIds.includes(p2.pinId)
|
|
4818
|
+
);
|
|
4819
|
+
const sourceChip = this.chipMap[p1.chipId];
|
|
4820
|
+
const targetRailTrace = sameNetTraces.find(
|
|
4821
|
+
(trace) => trace.pinIds.includes(p2.pinId) && trace.pins.every((pin) => pin.chipId === p2.chipId)
|
|
4822
|
+
);
|
|
4823
|
+
const canJoinThreePinNet = inputNetConnection !== void 0 && sourceChip?.pins.length === 2 && targetRailTrace !== void 0;
|
|
4824
|
+
const junctionTracePath = canJoinThreePinNet ? clipPathAtFirstIntersection(newTracePath, sameNetTraces) : null;
|
|
4825
|
+
const acceptedTracePath = junctionTracePath ?? newTracePath;
|
|
4826
|
+
const tracesToCheck = junctionTracePath ? this.allSolvedTraces.filter(
|
|
4827
|
+
(trace) => trace.globalConnNetId !== globalConnNetId
|
|
4828
|
+
) : this.allSolvedTraces;
|
|
4736
4829
|
const isTraceClear = !doesTraceOverlapWithExistingTraces(
|
|
4737
|
-
|
|
4738
|
-
|
|
4830
|
+
acceptedTracePath,
|
|
4831
|
+
tracesToCheck
|
|
4739
4832
|
);
|
|
4740
4833
|
if (isTraceClear) {
|
|
4741
|
-
const [p1, p2] = this.currentCandidatePair;
|
|
4742
|
-
const globalConnNetId = this.netConnMap.getNetConnectedToId(p1.pinId);
|
|
4743
4834
|
const mspPairId = `${p1.pinId}-${p2.pinId}`;
|
|
4744
4835
|
const newSolvedTrace = {
|
|
4745
4836
|
mspPairId,
|
|
4746
4837
|
dcConnNetId: globalConnNetId,
|
|
4747
4838
|
globalConnNetId,
|
|
4748
4839
|
pins: [p1, p2],
|
|
4749
|
-
tracePath:
|
|
4840
|
+
tracePath: acceptedTracePath,
|
|
4750
4841
|
mspConnectionPairIds: [mspPairId],
|
|
4751
4842
|
pinIds: [p1.pinId, p2.pinId]
|
|
4752
4843
|
};
|
|
@@ -5525,9 +5616,9 @@ var moveRailSegments = (trace, segments, coordinate) => {
|
|
|
5525
5616
|
};
|
|
5526
5617
|
|
|
5527
5618
|
// lib/solvers/RailNetLabelCornerPlacementSolver/geometry.ts
|
|
5528
|
-
var
|
|
5619
|
+
var EPS7 = 1e-6;
|
|
5529
5620
|
var isTraceLine = (trace) => getUniquePinCount(trace.pinIds) >= 2;
|
|
5530
|
-
var rectsOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >
|
|
5621
|
+
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;
|
|
5531
5622
|
var getTraceCorners = (path) => {
|
|
5532
5623
|
const corners = [];
|
|
5533
5624
|
for (let i = 1; i < path.length - 1; i++) {
|
|
@@ -5551,11 +5642,11 @@ var getUniquePinCount = (pinIds) => new Set(pinIds).size;
|
|
|
5551
5642
|
var isTraceCorner = (a, b, c) => getSegmentOrientation(a, b) !== getSegmentOrientation(b, c);
|
|
5552
5643
|
var isPointOnSegment = (point, start, end) => {
|
|
5553
5644
|
if (getSegmentOrientation(start, end) === "horizontal") {
|
|
5554
|
-
return Math.abs(point.y - start.y) <=
|
|
5645
|
+
return Math.abs(point.y - start.y) <= EPS7 && point.x >= Math.min(start.x, end.x) - EPS7 && point.x <= Math.max(start.x, end.x) + EPS7;
|
|
5555
5646
|
}
|
|
5556
|
-
return Math.abs(point.x - start.x) <=
|
|
5647
|
+
return Math.abs(point.x - start.x) <= EPS7 && point.y >= Math.min(start.y, end.y) - EPS7 && point.y <= Math.max(start.y, end.y) + EPS7;
|
|
5557
5648
|
};
|
|
5558
|
-
var getSegmentOrientation = (a, b) => Math.abs(a.y - b.y) <=
|
|
5649
|
+
var getSegmentOrientation = (a, b) => Math.abs(a.y - b.y) <= EPS7 ? "horizontal" : "vertical";
|
|
5559
5650
|
|
|
5560
5651
|
// lib/solvers/TraceCleanupSolver/sameNetRailAlignment/preservesLabelAnchors.ts
|
|
5561
5652
|
var getAnchoredTraceIds = (label, traces) => new Set(
|
|
@@ -5571,17 +5662,17 @@ var preservesLabelAnchors = (labels, before, after) => labels.every((label) => {
|
|
|
5571
5662
|
});
|
|
5572
5663
|
|
|
5573
5664
|
// lib/solvers/Example28Solver/types.ts
|
|
5574
|
-
var
|
|
5665
|
+
var EPS8 = 1e-9;
|
|
5575
5666
|
|
|
5576
5667
|
// lib/solvers/Example28Solver/segmentRunsAlongRectBoundary.ts
|
|
5577
5668
|
var segmentRunsAlongRectBoundary = (start, end, rect) => {
|
|
5578
|
-
const isVertical5 = Math.abs(start.x - end.x) <
|
|
5579
|
-
const isHorizontal4 = Math.abs(start.y - end.y) <
|
|
5669
|
+
const isVertical5 = Math.abs(start.x - end.x) < EPS8;
|
|
5670
|
+
const isHorizontal4 = Math.abs(start.y - end.y) < EPS8;
|
|
5580
5671
|
if (isVertical5) {
|
|
5581
|
-
return Math.abs(start.x - rect.minX) <
|
|
5672
|
+
return Math.abs(start.x - rect.minX) < EPS8 || Math.abs(start.x - rect.maxX) < EPS8;
|
|
5582
5673
|
}
|
|
5583
5674
|
if (isHorizontal4) {
|
|
5584
|
-
return Math.abs(start.y - rect.minY) <
|
|
5675
|
+
return Math.abs(start.y - rect.minY) < EPS8 || Math.abs(start.y - rect.maxY) < EPS8;
|
|
5585
5676
|
}
|
|
5586
5677
|
return false;
|
|
5587
5678
|
};
|
|
@@ -5596,10 +5687,10 @@ var getPathLength2 = (path) => {
|
|
|
5596
5687
|
return length;
|
|
5597
5688
|
};
|
|
5598
5689
|
var getDistance2 = (a, b) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
|
|
5599
|
-
var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) <
|
|
5600
|
-
var getSegmentOrientation2 = (start, end) => Math.abs(start.y - end.y) <
|
|
5690
|
+
var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS8 || Math.abs(start.y - end.y) < EPS8;
|
|
5691
|
+
var getSegmentOrientation2 = (start, end) => Math.abs(start.y - end.y) < EPS8 ? "horizontal" : "vertical";
|
|
5601
5692
|
var projectPointToSegment = (point, start, end) => {
|
|
5602
|
-
if (Math.abs(start.x - end.x) <
|
|
5693
|
+
if (Math.abs(start.x - end.x) < EPS8) {
|
|
5603
5694
|
return {
|
|
5604
5695
|
x: start.x,
|
|
5605
5696
|
y: Math.min(
|
|
@@ -5608,7 +5699,7 @@ var projectPointToSegment = (point, start, end) => {
|
|
|
5608
5699
|
)
|
|
5609
5700
|
};
|
|
5610
5701
|
}
|
|
5611
|
-
if (Math.abs(start.y - end.y) <
|
|
5702
|
+
if (Math.abs(start.y - end.y) < EPS8) {
|
|
5612
5703
|
return {
|
|
5613
5704
|
x: Math.min(
|
|
5614
5705
|
Math.max(point.x, Math.min(start.x, end.x)),
|
|
@@ -5651,9 +5742,9 @@ var findSegmentContainingPoint = (path, point) => {
|
|
|
5651
5742
|
};
|
|
5652
5743
|
var isPointWithinSegmentPrimaryRange = (point, segment) => {
|
|
5653
5744
|
if (segment.orientation === "horizontal") {
|
|
5654
|
-
return point.x >= Math.min(segment.start.x, segment.end.x) -
|
|
5745
|
+
return point.x >= Math.min(segment.start.x, segment.end.x) - EPS8 && point.x <= Math.max(segment.start.x, segment.end.x) + EPS8;
|
|
5655
5746
|
}
|
|
5656
|
-
return point.y >= Math.min(segment.start.y, segment.end.y) -
|
|
5747
|
+
return point.y >= Math.min(segment.start.y, segment.end.y) - EPS8 && point.y <= Math.max(segment.start.y, segment.end.y) + EPS8;
|
|
5657
5748
|
};
|
|
5658
5749
|
var findPreferredReroutedSegment = (path, originalSegmentIndex, originalSegmentCount, orientation, anchorPoint) => {
|
|
5659
5750
|
const matchingSegments = getSegments(path).filter(
|
|
@@ -5681,24 +5772,24 @@ var projectPointToPath = (point, path) => {
|
|
|
5681
5772
|
return bestPoint;
|
|
5682
5773
|
};
|
|
5683
5774
|
var segmentsIntersect = (a1, a2, b1, b2) => {
|
|
5684
|
-
const aVertical = Math.abs(a1.x - a2.x) <
|
|
5685
|
-
const bVertical = Math.abs(b1.x - b2.x) <
|
|
5686
|
-
const
|
|
5775
|
+
const aVertical = Math.abs(a1.x - a2.x) < EPS8;
|
|
5776
|
+
const bVertical = Math.abs(b1.x - b2.x) < EPS8;
|
|
5777
|
+
const between2 = (value, p1, p2) => value >= Math.min(p1, p2) - EPS8 && value <= Math.max(p1, p2) + EPS8;
|
|
5687
5778
|
if (aVertical && bVertical) {
|
|
5688
|
-
if (Math.abs(a1.x - b1.x) >
|
|
5779
|
+
if (Math.abs(a1.x - b1.x) > EPS8) return false;
|
|
5689
5780
|
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));
|
|
5690
|
-
return overlap >
|
|
5781
|
+
return overlap > EPS8;
|
|
5691
5782
|
}
|
|
5692
5783
|
if (!aVertical && !bVertical) {
|
|
5693
|
-
if (Math.abs(a1.y - b1.y) >
|
|
5784
|
+
if (Math.abs(a1.y - b1.y) > EPS8) return false;
|
|
5694
5785
|
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));
|
|
5695
|
-
return overlap >
|
|
5786
|
+
return overlap > EPS8;
|
|
5696
5787
|
}
|
|
5697
5788
|
const verticalA = aVertical ? a1 : b1;
|
|
5698
5789
|
const verticalB = aVertical ? a2 : b2;
|
|
5699
5790
|
const horizontalA = aVertical ? b1 : a1;
|
|
5700
5791
|
const horizontalB = aVertical ? b2 : a2;
|
|
5701
|
-
return
|
|
5792
|
+
return between2(verticalA.x, horizontalA.x, horizontalB.x) && between2(horizontalA.y, verticalA.y, verticalB.y);
|
|
5702
5793
|
};
|
|
5703
5794
|
var countPathIntersections = (pathA, pathB) => {
|
|
5704
5795
|
let count = 0;
|
|
@@ -6068,7 +6159,7 @@ var getTraceObstacles = (allTraces, excludeTraceId) => {
|
|
|
6068
6159
|
|
|
6069
6160
|
// lib/solvers/TraceCleanupSolver/sub-solver/findIntersectionsWithObstacles.ts
|
|
6070
6161
|
import { getSegmentIntersection } from "@tscircuit/math-utils/line-intersections";
|
|
6071
|
-
var
|
|
6162
|
+
var EPS9 = 1e-6;
|
|
6072
6163
|
var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
|
|
6073
6164
|
const intersections = [];
|
|
6074
6165
|
for (const obstacle of obstacles) {
|
|
@@ -6087,17 +6178,17 @@ var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
|
|
|
6087
6178
|
}
|
|
6088
6179
|
return intersections;
|
|
6089
6180
|
};
|
|
6090
|
-
var isSamePoint = (first, second) => Math.abs(first.x - second.x) <
|
|
6181
|
+
var isSamePoint = (first, second) => Math.abs(first.x - second.x) < EPS9 && Math.abs(first.y - second.y) < EPS9;
|
|
6091
6182
|
var findPerpendicularPathCrossings = (path, otherPath) => {
|
|
6092
6183
|
const crossings = [];
|
|
6093
6184
|
for (let pathSegmentIndex = 1; pathSegmentIndex < path.length - 2; pathSegmentIndex++) {
|
|
6094
6185
|
const start = path[pathSegmentIndex];
|
|
6095
6186
|
const end = path[pathSegmentIndex + 1];
|
|
6096
|
-
const isVertical5 = Math.abs(start.x - end.x) <
|
|
6187
|
+
const isVertical5 = Math.abs(start.x - end.x) < EPS9;
|
|
6097
6188
|
for (let otherPathSegmentIndex = 1; otherPathSegmentIndex < otherPath.length - 2; otherPathSegmentIndex++) {
|
|
6098
6189
|
const otherStart = otherPath[otherPathSegmentIndex];
|
|
6099
6190
|
const otherEnd = otherPath[otherPathSegmentIndex + 1];
|
|
6100
|
-
const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) <
|
|
6191
|
+
const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) < EPS9;
|
|
6101
6192
|
if (isVertical5 === otherIsVertical) continue;
|
|
6102
6193
|
const intersection = getSegmentIntersection(
|
|
6103
6194
|
start,
|
|
@@ -6117,8 +6208,8 @@ var findPerpendicularPathCrossings = (path, otherPath) => {
|
|
|
6117
6208
|
};
|
|
6118
6209
|
|
|
6119
6210
|
// lib/solvers/TraceCleanupSolver/sub-solver/generateLShapeRerouteCandidates.ts
|
|
6120
|
-
var
|
|
6121
|
-
var isVertical3 = (a, b, eps =
|
|
6211
|
+
var EPS10 = 1e-6;
|
|
6212
|
+
var isVertical3 = (a, b, eps = EPS10) => Math.abs(a.x - b.x) < eps;
|
|
6122
6213
|
var generateLShapeRerouteCandidates = ({
|
|
6123
6214
|
lShape,
|
|
6124
6215
|
rectangle,
|
|
@@ -6131,7 +6222,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
6131
6222
|
let c2;
|
|
6132
6223
|
let i1_padded = interactionPoint1;
|
|
6133
6224
|
let i2_padded = interactionPoint2;
|
|
6134
|
-
if (Math.abs(p2.x - x) <
|
|
6225
|
+
if (Math.abs(p2.x - x) < EPS10 && Math.abs(p2.y - (y + height)) < EPS10) {
|
|
6135
6226
|
c2 = { x: x + width + padding, y: y - padding };
|
|
6136
6227
|
if (isVertical3(p1, p2)) {
|
|
6137
6228
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
|
|
@@ -6143,7 +6234,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
6143
6234
|
} else {
|
|
6144
6235
|
i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
|
|
6145
6236
|
}
|
|
6146
|
-
} else if (Math.abs(p2.x - (x + width)) <
|
|
6237
|
+
} else if (Math.abs(p2.x - (x + width)) < EPS10 && Math.abs(p2.y - (y + height)) < EPS10) {
|
|
6147
6238
|
c2 = { x: x - padding, y: y - padding };
|
|
6148
6239
|
if (isVertical3(p1, p2)) {
|
|
6149
6240
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
|
|
@@ -6155,7 +6246,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
6155
6246
|
} else {
|
|
6156
6247
|
i2_padded = { x: interactionPoint2.x - padding, y: interactionPoint2.y };
|
|
6157
6248
|
}
|
|
6158
|
-
} else if (Math.abs(p2.x - x) <
|
|
6249
|
+
} else if (Math.abs(p2.x - x) < EPS10 && Math.abs(p2.y - y) < EPS10) {
|
|
6159
6250
|
c2 = { x: x + width + padding, y: y + height + padding };
|
|
6160
6251
|
if (isVertical3(p1, p2)) {
|
|
6161
6252
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
|
|
@@ -6167,7 +6258,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
6167
6258
|
} else {
|
|
6168
6259
|
i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
|
|
6169
6260
|
}
|
|
6170
|
-
} else if (Math.abs(p2.x - (x + width)) <
|
|
6261
|
+
} else if (Math.abs(p2.x - (x + width)) < EPS10 && Math.abs(p2.y - y) < EPS10) {
|
|
6171
6262
|
c2 = { x: x - padding, y: y + height + padding };
|
|
6172
6263
|
if (isVertical3(p1, p2)) {
|
|
6173
6264
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
|
|
@@ -6195,7 +6286,7 @@ var generatePerpendicularTraceDetours = ({
|
|
|
6195
6286
|
const buildDetours = (path, index) => {
|
|
6196
6287
|
const start = path[index];
|
|
6197
6288
|
const end = path[index + 1];
|
|
6198
|
-
const movingAxis = Math.abs(start.x - end.x) <
|
|
6289
|
+
const movingAxis = Math.abs(start.x - end.x) < EPS10 ? "y" : "x";
|
|
6199
6290
|
const detourAxis = movingAxis === "x" ? "y" : "x";
|
|
6200
6291
|
const gate = obstacleStart[movingAxis] + Math.sign(start[movingAxis] - obstacleStart[movingAxis]) * clearance;
|
|
6201
6292
|
const obstacleRange = [obstacleStart[detourAxis], obstacleEnd[detourAxis]];
|
|
@@ -6793,9 +6884,9 @@ var UntangleTraceSubsolver = class extends BaseSolver {
|
|
|
6793
6884
|
};
|
|
6794
6885
|
|
|
6795
6886
|
// lib/solvers/TraceCleanupSolver/is4PointRectangle.ts
|
|
6796
|
-
var
|
|
6797
|
-
var sameX = (a, b) => Math.abs(a.x - b.x) <=
|
|
6798
|
-
var sameY = (a, b) => Math.abs(a.y - b.y) <=
|
|
6887
|
+
var EPS11 = 1e-6;
|
|
6888
|
+
var sameX = (a, b) => Math.abs(a.x - b.x) <= EPS11;
|
|
6889
|
+
var sameY = (a, b) => Math.abs(a.y - b.y) <= EPS11;
|
|
6799
6890
|
var is4PointRectangle = (path) => {
|
|
6800
6891
|
if (path.length !== 4) return false;
|
|
6801
6892
|
const [p0, p1, p2, p3] = path;
|
|
@@ -7070,7 +7161,7 @@ var doesPathRunAlongChipBoundary = (path, chipObstacles) => {
|
|
|
7070
7161
|
const end = path[i + 1];
|
|
7071
7162
|
for (const obstacle of chipObstacles) {
|
|
7072
7163
|
if (!segmentRunsAlongRectBoundary(start, end, obstacle)) continue;
|
|
7073
|
-
if (getSegmentOverlapWithRectSpan(start, end, obstacle) >
|
|
7164
|
+
if (getSegmentOverlapWithRectSpan(start, end, obstacle) > EPS8) {
|
|
7074
7165
|
return true;
|
|
7075
7166
|
}
|
|
7076
7167
|
}
|
|
@@ -7085,13 +7176,13 @@ var getChipBoundaryOverlap = (path, chipObstacles) => {
|
|
|
7085
7176
|
for (const obstacle of chipObstacles) {
|
|
7086
7177
|
if (!segmentRunsAlongRectBoundary(start, end, obstacle)) continue;
|
|
7087
7178
|
const overlap = getSegmentOverlapWithRectSpan(start, end, obstacle);
|
|
7088
|
-
if (overlap >
|
|
7179
|
+
if (overlap > EPS8) total += overlap;
|
|
7089
7180
|
}
|
|
7090
7181
|
}
|
|
7091
7182
|
return total;
|
|
7092
7183
|
};
|
|
7093
7184
|
var getSegmentOverlapWithRectSpan = (start, end, rect) => {
|
|
7094
|
-
const isVertical5 = Math.abs(start.x - end.x) <
|
|
7185
|
+
const isVertical5 = Math.abs(start.x - end.x) < EPS8;
|
|
7095
7186
|
if (isVertical5) {
|
|
7096
7187
|
return Math.min(Math.max(start.y, end.y), rect.maxY) - Math.max(Math.min(start.y, end.y), rect.minY);
|
|
7097
7188
|
}
|
|
@@ -7855,16 +7946,16 @@ var createPortOnlyLabelConnectorTrace = ({
|
|
|
7855
7946
|
// lib/solvers/AvailableNetOrientationSolver/constants.ts
|
|
7856
7947
|
var LABEL_SEARCH_STEP = 0.05;
|
|
7857
7948
|
var WICK_CLEARANCE = 1e-3;
|
|
7858
|
-
var
|
|
7859
|
-
var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE +
|
|
7949
|
+
var EPS12 = 1e-9;
|
|
7950
|
+
var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS12;
|
|
7860
7951
|
var CANDIDATE_SELECTED_COLOR2 = "blue";
|
|
7861
7952
|
var CANDIDATE_REJECTED_COLOR2 = "red";
|
|
7862
7953
|
|
|
7863
7954
|
// lib/solvers/AvailableNetOrientationSolver/geometry.ts
|
|
7864
7955
|
var isYOrientation = (orientation) => orientation === "y+" || orientation === "y-";
|
|
7865
7956
|
var isXOrientation = (orientation) => orientation === "x+" || orientation === "x-";
|
|
7866
|
-
var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >
|
|
7867
|
-
var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) >
|
|
7957
|
+
var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS12 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS12;
|
|
7958
|
+
var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS12;
|
|
7868
7959
|
var traceCrossesBoundsInterior = (bounds, traceMap) => {
|
|
7869
7960
|
for (const trace of Object.values(traceMap)) {
|
|
7870
7961
|
const points = trace.tracePath;
|
|
@@ -7887,7 +7978,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
|
|
|
7887
7978
|
return false;
|
|
7888
7979
|
}
|
|
7889
7980
|
if (sameX2(p1, p2)) {
|
|
7890
|
-
if (p1.x <= interiorBounds.minX +
|
|
7981
|
+
if (p1.x <= interiorBounds.minX + EPS12 || p1.x >= interiorBounds.maxX - EPS12) {
|
|
7891
7982
|
return false;
|
|
7892
7983
|
}
|
|
7893
7984
|
return rangesOverlap(
|
|
@@ -7898,7 +7989,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
|
|
|
7898
7989
|
);
|
|
7899
7990
|
}
|
|
7900
7991
|
if (sameY2(p1, p2)) {
|
|
7901
|
-
if (p1.y <= interiorBounds.minY +
|
|
7992
|
+
if (p1.y <= interiorBounds.minY + EPS12 || p1.y >= interiorBounds.maxY - EPS12) {
|
|
7902
7993
|
return false;
|
|
7903
7994
|
}
|
|
7904
7995
|
return rangesOverlap(
|
|
@@ -7954,8 +8045,8 @@ var simplifyOrthogonalPath = (path) => {
|
|
|
7954
8045
|
return simplified;
|
|
7955
8046
|
};
|
|
7956
8047
|
var pointsEqual2 = (a, b) => sameX2(a, b) && sameY2(a, b);
|
|
7957
|
-
var sameX2 = (a, b) => Math.abs(a.x - b.x) <=
|
|
7958
|
-
var sameY2 = (a, b) => Math.abs(a.y - b.y) <=
|
|
8048
|
+
var sameX2 = (a, b) => Math.abs(a.x - b.x) <= EPS12;
|
|
8049
|
+
var sameY2 = (a, b) => Math.abs(a.y - b.y) <= EPS12;
|
|
7959
8050
|
var getMaxSearchDistance = (inputProblem) => {
|
|
7960
8051
|
const maxChipWidth = Math.max(
|
|
7961
8052
|
...inputProblem.chips.map((chip) => chip.width),
|
|
@@ -7964,6 +8055,42 @@ var getMaxSearchDistance = (inputProblem) => {
|
|
|
7964
8055
|
return maxChipWidth * 3;
|
|
7965
8056
|
};
|
|
7966
8057
|
|
|
8058
|
+
// lib/solvers/AvailableNetOrientationSolver/orderRoutedLabelsBeforeOverlappingPortLabels.ts
|
|
8059
|
+
var isPortOnlyLabel = (label) => label.mspConnectionPairIds.length === 0;
|
|
8060
|
+
var orderRoutedLabelsBeforeOverlappingPortLabels = ({
|
|
8061
|
+
labelIndices,
|
|
8062
|
+
netLabelPlacements
|
|
8063
|
+
}) => {
|
|
8064
|
+
const orderedLabelIndices = [...labelIndices];
|
|
8065
|
+
for (const routedLabelIndex of labelIndices) {
|
|
8066
|
+
const routedLabel = netLabelPlacements[routedLabelIndex];
|
|
8067
|
+
if (isPortOnlyLabel(routedLabel)) continue;
|
|
8068
|
+
const routedBounds = getRectBounds(
|
|
8069
|
+
routedLabel.center,
|
|
8070
|
+
routedLabel.width,
|
|
8071
|
+
routedLabel.height
|
|
8072
|
+
);
|
|
8073
|
+
const blockingPosition = orderedLabelIndices.findIndex((labelIndex) => {
|
|
8074
|
+
const portOnlyLabel = netLabelPlacements[labelIndex];
|
|
8075
|
+
if (!isPortOnlyLabel(portOnlyLabel)) return false;
|
|
8076
|
+
if (portOnlyLabel.globalConnNetId === routedLabel.globalConnNetId) {
|
|
8077
|
+
return false;
|
|
8078
|
+
}
|
|
8079
|
+
const portOnlyBounds = getRectBounds(
|
|
8080
|
+
portOnlyLabel.center,
|
|
8081
|
+
portOnlyLabel.width,
|
|
8082
|
+
portOnlyLabel.height
|
|
8083
|
+
);
|
|
8084
|
+
return rectsOverlap2(routedBounds, portOnlyBounds);
|
|
8085
|
+
});
|
|
8086
|
+
const routedPosition = orderedLabelIndices.indexOf(routedLabelIndex);
|
|
8087
|
+
if (blockingPosition === -1 || blockingPosition > routedPosition) continue;
|
|
8088
|
+
orderedLabelIndices.splice(routedPosition, 1);
|
|
8089
|
+
orderedLabelIndices.splice(blockingPosition, 0, routedLabelIndex);
|
|
8090
|
+
}
|
|
8091
|
+
return orderedLabelIndices;
|
|
8092
|
+
};
|
|
8093
|
+
|
|
7967
8094
|
// lib/solvers/AvailableNetOrientationSolver/visualize.ts
|
|
7968
8095
|
var visualizeAvailableNetOrientationSolver = (params) => {
|
|
7969
8096
|
const graphics = visualizeInputProblem(params.inputProblem);
|
|
@@ -8114,12 +8241,16 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8114
8241
|
}
|
|
8115
8242
|
}
|
|
8116
8243
|
this.sortCrowdedTopBankByPin(indices);
|
|
8117
|
-
const
|
|
8244
|
+
const orderedIndices = orderRoutedLabelsBeforeOverlappingPortLabels({
|
|
8245
|
+
labelIndices: indices,
|
|
8246
|
+
netLabelPlacements: this.outputNetLabelPlacements
|
|
8247
|
+
});
|
|
8248
|
+
const blockedStandaloneLabelIndex = orderedIndices.find((index) => {
|
|
8118
8249
|
const label = this.outputNetLabelPlacements[index];
|
|
8119
8250
|
const orientations = this.getAvailableOrientations(label);
|
|
8120
8251
|
return this.isPortOnlyLabel(label) && this.isStandaloneSinglePinNetLabel(label) && orientations.length === 1 && isYOrientation(orientations[0]) && this.labelIntersectsDifferentNetTrace(label);
|
|
8121
8252
|
});
|
|
8122
|
-
if (blockedStandaloneLabelIndex === void 0) return
|
|
8253
|
+
if (blockedStandaloneLabelIndex === void 0) return orderedIndices;
|
|
8123
8254
|
this.blockedStandaloneLabelIndex = blockedStandaloneLabelIndex;
|
|
8124
8255
|
this.blockedStandaloneLabelTargetAnchorX = null;
|
|
8125
8256
|
const blockedLabel = this.outputNetLabelPlacements[blockedStandaloneLabelIndex];
|
|
@@ -8127,8 +8258,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8127
8258
|
const chipSide = this.getChipSideForPoint(blockedLabel.anchorPoint);
|
|
8128
8259
|
const affectedSlots = [];
|
|
8129
8260
|
const labelsToOrder = [];
|
|
8130
|
-
for (let slot = 0; slot <
|
|
8131
|
-
const index =
|
|
8261
|
+
for (let slot = 0; slot < orderedIndices.length; slot++) {
|
|
8262
|
+
const index = orderedIndices[slot];
|
|
8132
8263
|
const label = this.outputNetLabelPlacements[index];
|
|
8133
8264
|
const orientations = this.getAvailableOrientations(label);
|
|
8134
8265
|
if (this.getChipSideForPoint(label.anchorPoint) === chipSide && orientations.length === 1 && orientations[0] === requiredOrientation) {
|
|
@@ -8158,9 +8289,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8158
8289
|
).x;
|
|
8159
8290
|
}
|
|
8160
8291
|
for (let i = 0; i < affectedSlots.length; i++) {
|
|
8161
|
-
|
|
8292
|
+
orderedIndices[affectedSlots[i]] = labelsToOrder[i];
|
|
8162
8293
|
}
|
|
8163
|
-
return
|
|
8294
|
+
return orderedIndices;
|
|
8164
8295
|
}
|
|
8165
8296
|
sortCrowdedTopBankByPin(indices) {
|
|
8166
8297
|
const slotsByChip = /* @__PURE__ */ new Map();
|
|
@@ -8371,7 +8502,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8371
8502
|
index,
|
|
8372
8503
|
pin: this.pinMap[otherLabel.pinIds[0]]
|
|
8373
8504
|
})).filter(
|
|
8374
|
-
({ index, pin: otherPin }) => this.crowdedPortOnlyLabelIndices.has(index) && otherPin?.chipId === pin.chipId && otherPin.x > pin.x +
|
|
8505
|
+
({ index, pin: otherPin }) => this.crowdedPortOnlyLabelIndices.has(index) && otherPin?.chipId === pin.chipId && otherPin.x > pin.x + EPS12
|
|
8375
8506
|
).sort((a, b) => a.pin.x - b.pin.x)[0]?.pin;
|
|
8376
8507
|
if (orientation === "y-" && nextPinToRight) return null;
|
|
8377
8508
|
const anchorX = orientation === "y-" ? Math.max(
|
|
@@ -8404,7 +8535,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8404
8535
|
const centeredAnchorY = hasUpFacingStack ? (lowestUpFacingLabelY + highestUpFacingLabelY) / 2 : stackedAnchorY;
|
|
8405
8536
|
const anchorYs = orientation === "y-" ? [centeredAnchorY, stackedAnchorY] : [stackedAnchorY];
|
|
8406
8537
|
for (const anchorY of anchorYs) {
|
|
8407
|
-
if (anchorY - label.anchorPoint.y > this.maxSearchDistance +
|
|
8538
|
+
if (anchorY - label.anchorPoint.y > this.maxSearchDistance + EPS12) {
|
|
8408
8539
|
continue;
|
|
8409
8540
|
}
|
|
8410
8541
|
const candidate = this.createCandidate(
|
|
@@ -8433,11 +8564,11 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8433
8564
|
if (trace.globalConnNetId !== label.globalConnNetId) return false;
|
|
8434
8565
|
const path = trace.tracePath;
|
|
8435
8566
|
return path.some((point, pointIndex) => {
|
|
8436
|
-
if (Math.abs(point.x - label.anchorPoint.x) >
|
|
8567
|
+
if (Math.abs(point.x - label.anchorPoint.x) > EPS12 || Math.abs(point.y - label.anchorPoint.y) > EPS12) {
|
|
8437
8568
|
return false;
|
|
8438
8569
|
}
|
|
8439
8570
|
return [path[pointIndex - 1], path[pointIndex + 1]].some(
|
|
8440
|
-
(neighbor) => neighbor && Math.abs(neighbor.x - point.x) <=
|
|
8571
|
+
(neighbor) => neighbor && Math.abs(neighbor.x - point.x) <= EPS12 && (neighbor.y - point.y) * direction.y > EPS12
|
|
8441
8572
|
);
|
|
8442
8573
|
});
|
|
8443
8574
|
});
|
|
@@ -8527,7 +8658,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8527
8658
|
orientation
|
|
8528
8659
|
);
|
|
8529
8660
|
if (outwardDirection.x === 0 && outwardDirection.y === 0) continue;
|
|
8530
|
-
for (let distance5 = LABEL_SEARCH_STEP; distance5 <= this.maxSearchDistance +
|
|
8661
|
+
for (let distance5 = LABEL_SEARCH_STEP; distance5 <= this.maxSearchDistance + EPS12; distance5 += LABEL_SEARCH_STEP) {
|
|
8531
8662
|
const anchorPoint = {
|
|
8532
8663
|
x: connectorSource.x + outwardDirection.x * distance5,
|
|
8533
8664
|
y: connectorSource.y + outwardDirection.y * distance5
|
|
@@ -8582,7 +8713,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8582
8713
|
);
|
|
8583
8714
|
const maxSearchDistance = this.getSearchDistanceLimit(label, orientation);
|
|
8584
8715
|
const maxOutwardDistance = outwardDirection.x === 0 && outwardDirection.y === 0 ? 0 : this.maxSearchDistance;
|
|
8585
|
-
for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance +
|
|
8716
|
+
for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS12; outwardDistance += LABEL_SEARCH_STEP) {
|
|
8586
8717
|
const baseAnchor = {
|
|
8587
8718
|
x: initialBaseAnchor.x + outwardDirection.x * outwardDistance,
|
|
8588
8719
|
y: initialBaseAnchor.y + outwardDirection.y * outwardDistance
|
|
@@ -8656,7 +8787,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8656
8787
|
phase = "shift",
|
|
8657
8788
|
stopOnTraceCollision = true
|
|
8658
8789
|
} = params;
|
|
8659
|
-
for (let distance5 = LABEL_SEARCH_STEP; distance5 <= maxSearchDistance +
|
|
8790
|
+
for (let distance5 = LABEL_SEARCH_STEP; distance5 <= maxSearchDistance + EPS12; distance5 += LABEL_SEARCH_STEP) {
|
|
8660
8791
|
const anchorPoint = {
|
|
8661
8792
|
x: baseAnchor.x + direction.x * distance5,
|
|
8662
8793
|
y: baseAnchor.y + direction.y * distance5
|
|
@@ -8962,9 +9093,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8962
9093
|
const { anchorPoint, orientation } = candidate;
|
|
8963
9094
|
const chipBounds = chip.bounds;
|
|
8964
9095
|
if (isYOrientation(orientation)) {
|
|
8965
|
-
return anchorPoint.x < chipBounds.minX -
|
|
9096
|
+
return anchorPoint.x < chipBounds.minX - EPS12 || anchorPoint.x > chipBounds.maxX + EPS12;
|
|
8966
9097
|
}
|
|
8967
|
-
return anchorPoint.y < chipBounds.minY -
|
|
9098
|
+
return anchorPoint.y < chipBounds.minY - EPS12 || anchorPoint.y > chipBounds.maxY + EPS12;
|
|
8968
9099
|
});
|
|
8969
9100
|
}
|
|
8970
9101
|
getBoundsStatus(candidateBoundsCheck) {
|
|
@@ -9065,8 +9196,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9065
9196
|
if (!chip) return null;
|
|
9066
9197
|
const sides = new Set(
|
|
9067
9198
|
pins.map((pin) => {
|
|
9068
|
-
if (Math.abs(pin.x - chip.bounds.minX) <=
|
|
9069
|
-
if (Math.abs(pin.x - chip.bounds.maxX) <=
|
|
9199
|
+
if (Math.abs(pin.x - chip.bounds.minX) <= EPS12) return "left";
|
|
9200
|
+
if (Math.abs(pin.x - chip.bounds.maxX) <= EPS12) return "right";
|
|
9070
9201
|
return null;
|
|
9071
9202
|
})
|
|
9072
9203
|
);
|
|
@@ -9099,8 +9230,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9099
9230
|
sharesChipBoundary(bounds) {
|
|
9100
9231
|
for (const chip of this.chipObstacleSpatialIndex.chips) {
|
|
9101
9232
|
const chipBounds = chip.bounds;
|
|
9102
|
-
const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE +
|
|
9103
|
-
const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE +
|
|
9233
|
+
const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS12 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS12;
|
|
9234
|
+
const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS12 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS12;
|
|
9104
9235
|
if (adjacentToVerticalSide && rangesOverlap(
|
|
9105
9236
|
bounds.minY,
|
|
9106
9237
|
bounds.maxY,
|
|
@@ -9162,7 +9293,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9162
9293
|
let nearestDistance = Number.POSITIVE_INFINITY;
|
|
9163
9294
|
for (const chip of this.chipObstacleSpatialIndex.chips) {
|
|
9164
9295
|
const bounds = chip.bounds;
|
|
9165
|
-
if (point.x < bounds.minX -
|
|
9296
|
+
if (point.x < bounds.minX - EPS12 || point.x > bounds.maxX + EPS12 || point.y < bounds.minY - EPS12 || point.y > bounds.maxY + EPS12) {
|
|
9166
9297
|
continue;
|
|
9167
9298
|
}
|
|
9168
9299
|
for (const [side, distance5] of getSideDistances(point, bounds)) {
|
|
@@ -9179,8 +9310,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9179
9310
|
let nearestDistanceSq = Number.POSITIVE_INFINITY;
|
|
9180
9311
|
for (const chip of this.chipObstacleSpatialIndex.chips) {
|
|
9181
9312
|
const bounds = chip.bounds;
|
|
9182
|
-
const dx = point.x < bounds.minX -
|
|
9183
|
-
const dy = point.y < bounds.minY -
|
|
9313
|
+
const dx = point.x < bounds.minX - EPS12 ? bounds.minX - point.x : point.x > bounds.maxX + EPS12 ? point.x - bounds.maxX : 0;
|
|
9314
|
+
const dy = point.y < bounds.minY - EPS12 ? bounds.minY - point.y : point.y > bounds.maxY + EPS12 ? point.y - bounds.maxY : 0;
|
|
9184
9315
|
if (dx === 0 && dy === 0) continue;
|
|
9185
9316
|
const distanceSq = dx ** 2 + dy ** 2;
|
|
9186
9317
|
if (distanceSq >= nearestDistanceSq) continue;
|
|
@@ -9496,7 +9627,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
9496
9627
|
for (const anchorPoint of getTraceCorners(path)) {
|
|
9497
9628
|
const cornerIndex = path.indexOf(anchorPoint);
|
|
9498
9629
|
const anchorAlignedToPin = pins.some(
|
|
9499
|
-
(pin) => Math.abs(pin.x - anchorPoint.x) <=
|
|
9630
|
+
(pin) => Math.abs(pin.x - anchorPoint.x) <= EPS7
|
|
9500
9631
|
);
|
|
9501
9632
|
const pinAligned = anchorAlignedToPin || allowRailAlignedFallback && this.isPinAlignedCorner(path, cornerIndex);
|
|
9502
9633
|
if (!pinAligned) continue;
|
|
@@ -9536,12 +9667,12 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
9536
9667
|
return traceCrossesBoundsInterior(bounds, otherNetTraceMap);
|
|
9537
9668
|
}
|
|
9538
9669
|
pointsEqual(a, b) {
|
|
9539
|
-
return Math.abs(a.x - b.x) <=
|
|
9670
|
+
return Math.abs(a.x - b.x) <= EPS7 && Math.abs(a.y - b.y) <= EPS7;
|
|
9540
9671
|
}
|
|
9541
9672
|
getVerticalSegmentPointIndices(path, cornerIndex) {
|
|
9542
9673
|
const corner = path[cornerIndex];
|
|
9543
|
-
const previousIsVertical = Math.abs(path[cornerIndex - 1].x - corner.x) <=
|
|
9544
|
-
const nextIsVertical = Math.abs(path[cornerIndex + 1].x - corner.x) <=
|
|
9674
|
+
const previousIsVertical = Math.abs(path[cornerIndex - 1].x - corner.x) <= EPS7;
|
|
9675
|
+
const nextIsVertical = Math.abs(path[cornerIndex + 1].x - corner.x) <= EPS7;
|
|
9545
9676
|
if (previousIsVertical === nextIsVertical) return null;
|
|
9546
9677
|
const indices = previousIsVertical ? [cornerIndex - 1, cornerIndex] : [cornerIndex, cornerIndex + 1];
|
|
9547
9678
|
return indices;
|
|
@@ -9591,7 +9722,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
9591
9722
|
const end = otherTrace.tracePath[i + 1];
|
|
9592
9723
|
if (!segmentCrossesBoundsInterior(start, end, labelBounds)) continue;
|
|
9593
9724
|
const halfLabelWidth = label.width / 2;
|
|
9594
|
-
if (Math.abs(start.x - end.x) <=
|
|
9725
|
+
if (Math.abs(start.x - end.x) <= EPS7) {
|
|
9595
9726
|
shiftedCoordinates.add(
|
|
9596
9727
|
start.x - halfLabelWidth - LABEL_TRACE_CLEARANCE3
|
|
9597
9728
|
);
|
|
@@ -9609,7 +9740,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
9609
9740
|
}
|
|
9610
9741
|
}
|
|
9611
9742
|
return [...shiftedCoordinates].flatMap((x) => {
|
|
9612
|
-
if (Math.abs(x - corner.x) <=
|
|
9743
|
+
if (Math.abs(x - corner.x) <= EPS7) return [];
|
|
9613
9744
|
const reroutedTracePath = simplifyPath(
|
|
9614
9745
|
path.map(
|
|
9615
9746
|
(point, pointIndex) => verticalPointIndices.includes(pointIndex) ? { ...point, x } : point
|
|
@@ -9740,11 +9871,11 @@ var getOrientationConstraint = (inputProblem, label) => {
|
|
|
9740
9871
|
};
|
|
9741
9872
|
|
|
9742
9873
|
// lib/solvers/TraceAnchoredNetLabelOverlapSolver/geometry.ts
|
|
9743
|
-
var
|
|
9874
|
+
var EPS13 = 1e-6;
|
|
9744
9875
|
var TRACE_BOUNDARY_TOLERANCE2 = 1e-6;
|
|
9745
9876
|
var getLabelBounds = (label) => getRectBounds(label.center, label.width, label.height);
|
|
9746
|
-
var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >
|
|
9747
|
-
var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -
|
|
9877
|
+
var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS13 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS13;
|
|
9878
|
+
var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -EPS13 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) >= -EPS13;
|
|
9748
9879
|
var traceCrossesBoundsInterior2 = (bounds, traces) => {
|
|
9749
9880
|
for (const trace of traces) {
|
|
9750
9881
|
const points = trace.tracePath;
|
|
@@ -9790,7 +9921,7 @@ var getPointAtTraceDistance = (trace, distance5) => {
|
|
|
9790
9921
|
const end = trace.tracePath[i + 1];
|
|
9791
9922
|
const segmentLength = getManhattanDistance(start, end);
|
|
9792
9923
|
const nextDistance = pathDistance + segmentLength;
|
|
9793
|
-
if (distance5 <= nextDistance +
|
|
9924
|
+
if (distance5 <= nextDistance + EPS13) {
|
|
9794
9925
|
const offset = Math.max(
|
|
9795
9926
|
0,
|
|
9796
9927
|
Math.min(segmentLength, distance5 - pathDistance)
|
|
@@ -9829,7 +9960,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
|
|
|
9829
9960
|
return false;
|
|
9830
9961
|
}
|
|
9831
9962
|
if (isVertical4(start, end)) {
|
|
9832
|
-
if (start.x <= interior.minX +
|
|
9963
|
+
if (start.x <= interior.minX + EPS13 || start.x >= interior.maxX - EPS13) {
|
|
9833
9964
|
return false;
|
|
9834
9965
|
}
|
|
9835
9966
|
return rangesOverlap2(
|
|
@@ -9840,7 +9971,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
|
|
|
9840
9971
|
);
|
|
9841
9972
|
}
|
|
9842
9973
|
if (isHorizontal3(start, end)) {
|
|
9843
|
-
if (start.y <= interior.minY +
|
|
9974
|
+
if (start.y <= interior.minY + EPS13 || start.y >= interior.maxY - EPS13) {
|
|
9844
9975
|
return false;
|
|
9845
9976
|
}
|
|
9846
9977
|
return rangesOverlap2(
|
|
@@ -9854,10 +9985,10 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
|
|
|
9854
9985
|
};
|
|
9855
9986
|
var isPointOnSegment2 = (point, start, end) => {
|
|
9856
9987
|
if (isHorizontal3(start, end)) {
|
|
9857
|
-
return Math.abs(point.y - start.y) <=
|
|
9988
|
+
return Math.abs(point.y - start.y) <= EPS13 && point.x >= Math.min(start.x, end.x) - EPS13 && point.x <= Math.max(start.x, end.x) + EPS13;
|
|
9858
9989
|
}
|
|
9859
9990
|
if (isVertical4(start, end)) {
|
|
9860
|
-
return Math.abs(point.x - start.x) <=
|
|
9991
|
+
return Math.abs(point.x - start.x) <= EPS13 && point.y >= Math.min(start.y, end.y) - EPS13 && point.y <= Math.max(start.y, end.y) + EPS13;
|
|
9861
9992
|
}
|
|
9862
9993
|
return false;
|
|
9863
9994
|
};
|
|
@@ -9865,9 +9996,9 @@ var getSegmentDirection = (start, end) => ({
|
|
|
9865
9996
|
x: isVertical4(start, end) ? 0 : Math.sign(end.x - start.x),
|
|
9866
9997
|
y: isHorizontal3(start, end) ? 0 : Math.sign(end.y - start.y)
|
|
9867
9998
|
});
|
|
9868
|
-
var isHorizontal3 = (start, end) => Math.abs(start.y - end.y) <=
|
|
9869
|
-
var isVertical4 = (start, end) => Math.abs(start.x - end.x) <=
|
|
9870
|
-
var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) >
|
|
9999
|
+
var isHorizontal3 = (start, end) => Math.abs(start.y - end.y) <= EPS13;
|
|
10000
|
+
var isVertical4 = (start, end) => Math.abs(start.x - end.x) <= EPS13;
|
|
10001
|
+
var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS13;
|
|
9871
10002
|
var getUniquePinCount2 = (pinIds) => new Set(pinIds).size;
|
|
9872
10003
|
|
|
9873
10004
|
// lib/solvers/TraceAnchoredNetLabelOverlapSolver/candidates.ts
|
|
@@ -9924,7 +10055,7 @@ var getCandidateDistances = (traceLength, vertexDistances) => {
|
|
|
9924
10055
|
for (const distance5 of vertexDistances) {
|
|
9925
10056
|
distances.add(roundDistance(distance5));
|
|
9926
10057
|
}
|
|
9927
|
-
return [...distances].filter((distance5) => distance5 >= -
|
|
10058
|
+
return [...distances].filter((distance5) => distance5 >= -EPS13 && distance5 <= traceLength + EPS13).sort((a, b) => a - b);
|
|
9928
10059
|
};
|
|
9929
10060
|
var getOrientationsForPoint = (params) => {
|
|
9930
10061
|
const { inputProblem, label, point, orientationConstraint } = params;
|
|
@@ -10013,13 +10144,13 @@ var getOutwardOrientationOptions = (point, chipBounds) => {
|
|
|
10013
10144
|
};
|
|
10014
10145
|
var getOutwardAxisOption = (params) => {
|
|
10015
10146
|
const { value, min, max, center, positiveOrientation, negativeOrientation } = params;
|
|
10016
|
-
if (value > max +
|
|
10147
|
+
if (value > max + EPS13) {
|
|
10017
10148
|
return {
|
|
10018
10149
|
orientation: positiveOrientation,
|
|
10019
10150
|
outwardScore: 1 + value - max
|
|
10020
10151
|
};
|
|
10021
10152
|
}
|
|
10022
|
-
if (value < min -
|
|
10153
|
+
if (value < min - EPS13) {
|
|
10023
10154
|
return {
|
|
10024
10155
|
orientation: negativeOrientation,
|
|
10025
10156
|
outwardScore: 1 + min - value
|
|
@@ -10030,7 +10161,7 @@ var getOutwardAxisOption = (params) => {
|
|
|
10030
10161
|
outwardScore: getNormalizedCenterDistance(value, center, max - min)
|
|
10031
10162
|
};
|
|
10032
10163
|
};
|
|
10033
|
-
var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(
|
|
10164
|
+
var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS13, span / 2);
|
|
10034
10165
|
var ALL_ORIENTATIONS = ["x+", "x-", "y+", "y-"];
|
|
10035
10166
|
var getFlippedOrientation = (orientation) => {
|
|
10036
10167
|
switch (orientation) {
|
|
@@ -10103,7 +10234,7 @@ var getNetLabelHeight = (inputProblem, label) => {
|
|
|
10103
10234
|
)?.netLabelHeight;
|
|
10104
10235
|
};
|
|
10105
10236
|
var roundDistance = (distance5) => Number(distance5.toFixed(6));
|
|
10106
|
-
var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <=
|
|
10237
|
+
var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS13 && Math.abs(point.y - label.anchorPoint.y) <= EPS13 && orientation === label.orientation;
|
|
10107
10238
|
|
|
10108
10239
|
// lib/solvers/TraceAnchoredNetLabelOverlapSolver/visualize.ts
|
|
10109
10240
|
var CANDIDATE_SELECTED_COLOR4 = "blue";
|