diff --git a/bun.lockb b/bun.lockb
index 924052a..b42bd2e 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/lib/sch/svg-object-fns/create-svg-objects-from-sch-trace.ts b/lib/sch/svg-object-fns/create-svg-objects-from-sch-trace.ts
index b530f54..8b4eb16 100644
--- a/lib/sch/svg-object-fns/create-svg-objects-from-sch-trace.ts
+++ b/lib/sch/svg-object-fns/create-svg-objects-from-sch-trace.ts
@@ -14,34 +14,53 @@ export function createSchematicTrace(
let path = ""
// Process all edges
- edges.forEach((edge: any, index: number) => {
- // Get the points, applying trace offset
- const fromPoint = {
- x: edge.from.x ?? edge.from.center?.x,
- y: edge.from.y ?? edge.from.center?.y,
- }
- const toPoint = {
- x: edge.to.x ?? edge.to.center?.x,
- y: edge.to.y ?? edge.to.center?.y,
- }
+ for (let edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
+ const edge = edges[edgeIndex]!
// Transform the points using the matrix
- const [transformedFromX, transformedFromY] = applyToPoint(transform, [
- fromPoint.x,
- fromPoint.y,
+ const [screenFromX, screenFromY] = applyToPoint(transform, [
+ edge.from.x,
+ edge.from.y,
])
- const [transformedToX, transformedToY] = applyToPoint(transform, [
- toPoint.x,
- toPoint.y,
+ const [screenToX, screenToY] = applyToPoint(transform, [
+ edge.to.x,
+ edge.to.y,
])
- // Build the path string
- if (index === 0) {
- path += `M ${transformedFromX} ${transformedFromY} L ${transformedToX} ${transformedToY}`
+ if (edge.is_crossing) {
+ // For crossing traces, create a small arc/hop
+ const midX = (screenFromX + screenToX) / 2
+ const midY = (screenFromY + screenToY) / 2
+
+ // Calculate perpendicular offset for the arc
+ const dx = screenToX - screenFromX
+ const dy = screenToY - screenFromY
+ const len = Math.sqrt(dx * dx + dy * dy)
+ const hopHeight = len * 0.7
+
+ // Perpendicular vector
+ const perpX = (-dy / len) * hopHeight
+ const perpY = (dx / len) * hopHeight
+
+ // Control point for the quadratic curve
+ const controlX = midX + perpX
+ const controlY = midY - Math.abs(perpY)
+
+ // Build the path string with a quadratic curve for the hop
+ if (edgeIndex === 0) {
+ path += `M ${screenFromX} ${screenFromY} Q ${controlX} ${controlY} ${screenToX} ${screenToY}`
+ } else {
+ path += ` Q ${controlX} ${controlY} ${screenToX} ${screenToY}`
+ }
+ }
+
+ // Regular straight line for non-crossing traces
+ if (edgeIndex === 0) {
+ path += `M ${screenFromX} ${screenFromY} L ${screenToX} ${screenToY}`
} else {
- path += ` L ${transformedToX} ${transformedToY}`
+ path += ` L ${screenToX} ${screenToY}`
}
- })
+ }
// Only create SVG object if we have a valid path
return path
diff --git a/package.json b/package.json
index 115a995..5ef9b8c 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,7 @@
"@storybook/react": "^8.2.5",
"@storybook/react-vite": "^8.2.5",
"@storybook/test": "^8.2.5",
- "@tscircuit/core": "^0.0.153",
+ "@tscircuit/core": "^0.0.155",
"@tscircuit/plop": "^0.0.10",
"@types/bun": "^1.1.9",
"bun-match-svg": "^0.0.6",
@@ -41,7 +41,7 @@
"vite-tsconfig-paths": "^5.0.1"
},
"peerDependencies": {
- "circuit-json": "^0.0.95"
+ "circuit-json": "^0.0.97"
},
"dependencies": {
"@tscircuit/footprinter": "^0.0.57",
diff --git a/tests/sch/__snapshots__/trace-overlap.snap.svg b/tests/sch/__snapshots__/trace-overlap.snap.svg
new file mode 100644
index 0000000..010945f
--- /dev/null
+++ b/tests/sch/__snapshots__/trace-overlap.snap.svg
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/tests/sch/trace-overlap.test.tsx b/tests/sch/trace-overlap.test.tsx
new file mode 100644
index 0000000..a038866
--- /dev/null
+++ b/tests/sch/trace-overlap.test.tsx
@@ -0,0 +1,34 @@
+import { test, expect } from "bun:test"
+import { convertCircuitJsonToSchematicSvg } from "lib"
+import { getTestFixture } from "tests/fixtures/get-test-fixture"
+
+test("schematic trace overlap", () => {
+ const { project } = getTestFixture()
+
+ project.add(
+
+
+
+
+
+
+
+ ,
+ )
+
+ expect(
+ convertCircuitJsonToSchematicSvg(project.getCircuitJson()),
+ ).toMatchSvgSnapshot(import.meta.path)
+})