Bug Description
The pointOnSegment() function in src/parsers/altium/connectivity.ts uses axis-aligned bounding-box containment instead of a true point-on-line-segment test. This causes false connectivity between wires that have overlapping bounding boxes but don't physically intersect, merging nets that should be electrically separate.
Reproduction
Design: Altium multi-sheet project with a Si8663ED-B-IS digital isolator (U9, 16-pin SOIC). This is a galvanic isolator with two independent power domains:
- Side A (pins 1–8): VDD1 =
+3V3_SOM, GND1 = SOM_GND
- Side B (pins 9–16): VDD2 =
+3V3_PD, GND2 = +3V3_PD_GND
Expected: Pin 1 on +3V3_SOM, pin 16 on +3V3_PD (two separate nets).
Actual: Both pin 1 and pin 16 reported as +3V3_SOM. The +3V3_PD connection on pin 16 is lost.
Verified against: Altium's own netlist export (Protel .NET format) confirms pin 16 is in the +3V3_PD net block, not +3V3_SOM.
Root Cause
In connectivity.ts, the spatial connectivity algorithm uses pointOnSegment() to determine if a pin endpoint touches a wire:
const pointOnSegment = (point: Coordinate, segment: LineSegment): boolean => {
const [p1, p2] = segment;
const [px, py] = point;
const minX = Math.min(p1[0], p2[0]);
const maxX = Math.max(p1[0], p2[0]);
const minY = Math.min(p1[1], p2[1]);
const maxY = Math.max(p1[1], p2[1]);
return px >= minX && px <= maxX && py >= minY && py <= maxY;
};
This returns true for any point inside the bounding box of a wire segment, even if the point is not on the line itself. For orthogonal wires this is fine (the bounding box degenerates to the line), but when two separate wires on different nets have overlapping bounding boxes, the Union-Find algorithm falsely merges them.
Once merged, assignNetName() picks the first power port name encountered (+3V3_SOM), silently overwriting the correct assignment for pin 16 (+3V3_PD).
Impact
This is a silent correctness bug — no error or warning is produced. For safety-critical designs (this was found on a quench protection system for superconducting magnets), incorrect net assignments on isolation barriers can mask dangerous design errors or create false alarms during review.
Suggested Fix
Add a cross-product collinearity check before the bounding-box test:
const pointOnSegment = (point: Coordinate, segment: LineSegment): boolean => {
const [p1, p2] = segment;
const [px, py] = point;
// Check collinearity via cross product
const cross = (p2[0] - p1[0]) * (py - p1[1]) - (p2[1] - p1[1]) * (px - p1[0]);
if (Math.abs(cross) > 1) return false; // tolerance for integer coordinate rounding
// Then check bounding box containment
const minX = Math.min(p1[0], p2[0]);
const maxX = Math.max(p1[0], p2[0]);
const minY = Math.min(p1[1], p2[1]);
const maxY = Math.max(p1[1], p2[1]);
return px >= minX && px <= maxX && py >= minY && py <= maxY;
};
Environment
- universal-netlist MCP server (current version as of 2026-03-19)
- Altium Designer project (.PrjPcb) with multi-sheet .SchDoc schematics
- Component: Si8663ED-B-IS (16-pin digital isolator, two power domains)
Bug Description
The
pointOnSegment()function insrc/parsers/altium/connectivity.tsuses axis-aligned bounding-box containment instead of a true point-on-line-segment test. This causes false connectivity between wires that have overlapping bounding boxes but don't physically intersect, merging nets that should be electrically separate.Reproduction
Design: Altium multi-sheet project with a Si8663ED-B-IS digital isolator (U9, 16-pin SOIC). This is a galvanic isolator with two independent power domains:
+3V3_SOM, GND1 =SOM_GND+3V3_PD, GND2 =+3V3_PD_GNDExpected: Pin 1 on
+3V3_SOM, pin 16 on+3V3_PD(two separate nets).Actual: Both pin 1 and pin 16 reported as
+3V3_SOM. The+3V3_PDconnection on pin 16 is lost.Verified against: Altium's own netlist export (Protel .NET format) confirms pin 16 is in the
+3V3_PDnet block, not+3V3_SOM.Root Cause
In
connectivity.ts, the spatial connectivity algorithm usespointOnSegment()to determine if a pin endpoint touches a wire:This returns
truefor any point inside the bounding box of a wire segment, even if the point is not on the line itself. For orthogonal wires this is fine (the bounding box degenerates to the line), but when two separate wires on different nets have overlapping bounding boxes, the Union-Find algorithm falsely merges them.Once merged,
assignNetName()picks the first power port name encountered (+3V3_SOM), silently overwriting the correct assignment for pin 16 (+3V3_PD).Impact
This is a silent correctness bug — no error or warning is produced. For safety-critical designs (this was found on a quench protection system for superconducting magnets), incorrect net assignments on isolation barriers can mask dangerous design errors or create false alarms during review.
Suggested Fix
Add a cross-product collinearity check before the bounding-box test:
Environment