imrishabh18/rp2040-motor-controller
This circuit incorporates a USB-C Power Delivery (PD) interface with a CH224K controller, a WJ500V-5.08-04P motor output connector, multiple power conditioning components including capacitors, resistors, diodes, and an RP2040 microcontroller, to manage motor control, signal routing, and power management for a USB-powered stepper motor system.
- Version
- 1.0.14
- License
- unset
- Stars
- 0
tests/helpers/routedViaOverlapsPad.ts
import type { PcbSmtPad, PcbVia } from "circuit-json"
const distanceToSegment = (
point: { x: number; y: number },
start: { x: number; y: number },
end: { x: number; y: number },
) => {
const dx = end.x - start.x
const dy = end.y - start.y
const lengthSquared = dx * dx + dy * dy
const t =
lengthSquared <= 1e-12
? 0
: Math.max(
0,
Math.min(
1,
((point.x - start.x) * dx + (point.y - start.y) * dy) /
lengthSquared,
),
)
return Math.hypot(
point.x - (start.x + dx * t),
point.y - (start.y + dy * t),
)
}
const pointInPolygon = (
point: { x: number; y: number },
polygon: Array<{ x: number; y: number }>,
) => {
let inside = false
for (
let index = 0, prior = polygon.length - 1;
index < polygon.length;
prior = index++
) {
const currentPoint = polygon[index]!
const priorPoint = polygon[prior]!
if (
currentPoint.y > point.y !== priorPoint.y > point.y &&
point.x <
((priorPoint.x - currentPoint.x) * (point.y - currentPoint.y)) /
(priorPoint.y - currentPoint.y) +
currentPoint.x
) {
inside = !inside
}
}
return inside
}
export const routedViaOverlapsPad = (via: PcbVia, pad: PcbSmtPad) => {
if (!via.layers.includes(pad.layer)) return false
const viaRadius = via.outer_diameter / 2
if (pad.shape === "polygon") {
if (pointInPolygon({ x: via.x, y: via.y }, pad.points)) return true
return pad.points.some(
(start, index) =>
distanceToSegment(
{ x: via.x, y: via.y },
start,
pad.points[(index + 1) % pad.points.length]!,
) < viaRadius,
)
}
const rotation =
pad.shape === "rotated_rect" || pad.shape === "rotated_pill"
? (-pad.ccw_rotation * Math.PI) / 180
: 0
const translated = { x: via.x - pad.x, y: via.y - pad.y }
const localPoint = {
x:
translated.x * Math.cos(rotation) -
translated.y * Math.sin(rotation),
y:
translated.x * Math.sin(rotation) +
translated.y * Math.cos(rotation),
}
if (pad.shape === "circle") {
return Math.hypot(localPoint.x, localPoint.y) < pad.radius + viaRadius
}
if (pad.shape === "pill" || pad.shape === "rotated_pill") {
const horizontal = pad.width >= pad.height
const radius = Math.min(pad.width, pad.height) / 2
const halfSegment = Math.abs(pad.width - pad.height) / 2
return (
distanceToSegment(
localPoint,
horizontal
? { x: -halfSegment, y: 0 }
: { x: 0, y: -halfSegment },
horizontal
? { x: halfSegment, y: 0 }
: { x: 0, y: halfSegment },
) <
radius + viaRadius
)
}
const dx = Math.max(Math.abs(localPoint.x) - pad.width / 2, 0)
const dy = Math.max(Math.abs(localPoint.y) - pad.height / 2, 0)
return Math.hypot(dx, dy) < viaRadius
}