diff --git a/src/parsers/altium/connectivity.ts b/src/parsers/altium/connectivity.ts index d27d4c2..14853a3 100644 --- a/src/parsers/altium/connectivity.ts +++ b/src/parsers/altium/connectivity.ts @@ -180,6 +180,13 @@ const pointOnSegment = (point: Coordinate, segment: LineSegment): boolean => { const [p1, p2] = segment; const [px, py] = point; + // Cross product collinearity check: perpendicular distance must be within tolerance. + // Altium coordinates (10000 units/mil) can have small rounding errors (~2 units), + // so we use tolerance of 2 units (0.0002 mil). Squared form avoids sqrt. + const cross = (p2[0] - p1[0]) * (py - p1[1]) - (p2[1] - p1[1]) * (px - p1[0]); + const segLenSq = (p2[0] - p1[0]) ** 2 + (p2[1] - p1[1]) ** 2; + if (segLenSq > 0 && cross * cross > 4 * segLenSq) return false; + const minX = Math.min(p1[0], p2[0]); const maxX = Math.max(p1[0], p2[0]); const minY = Math.min(p1[1], p2[1]); diff --git a/src/parsers/altium/index.test.ts b/src/parsers/altium/index.test.ts index 468add0..55b5c7c 100644 --- a/src/parsers/altium/index.test.ts +++ b/src/parsers/altium/index.test.ts @@ -323,6 +323,28 @@ describe("Connectivity", () => { expect(isConnected(wireA, wireB)).toBe(false); }); + it("should detect disconnected wires with overlapping bounding boxes", () => { + const wireA: AltiumRecord = { + index: 0, + RECORD: RECORD_TYPES.WIRE, + coords: [ + [0, 0], + [100, 100], + ], + }; + + const wireB: AltiumRecord = { + index: 1, + RECORD: RECORD_TYPES.WIRE, + coords: [ + [100, 0], + [0, 100], + ], + }; + + expect(isConnected(wireA, wireB)).toBe(false); + }); + it("should detect pin connected to wire", () => { const wire: AltiumRecord = { index: 0, diff --git a/src/parsers/altium/index.ts b/src/parsers/altium/index.ts index eaf0665..629ad67 100644 --- a/src/parsers/altium/index.ts +++ b/src/parsers/altium/index.ts @@ -333,11 +333,17 @@ export const extractComponents = (schematic: AltiumSchematic): ComponentDetails } const component: ComponentDetails[string] = { - mpn, - description: extractedDescription, pins, }; + if (mpn !== undefined) { + component.mpn = mpn; + } + + if (extractedDescription !== undefined) { + component.description = extractedDescription; + } + if (comment !== undefined) { component.comment = comment; }