Skip to content

Commit 2ad2be4

Browse files
Funkenjaegerqu1ck
authored andcommitted
Support arc tracks
Closes #230
1 parent e47db71 commit 2ad2be4

File tree

2 files changed

+84
-15
lines changed

2 files changed

+84
-15
lines changed

InteractiveHtmlBom/ecad/schema/genericjsonpcbdata_v1.schema

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -506,17 +506,39 @@
506506
},
507507
"Track": {
508508
"type": "object",
509-
"additionalProperties": false,
510-
"properties": {
511-
"start": { "$ref": "#/definitions/Coordinates" },
512-
"end": { "$ref": "#/definitions/Coordinates" },
513-
"width": { "type": "number" },
514-
"net": { "type": "string" }
515-
},
516-
"required": [
517-
"start",
518-
"end",
519-
"width"
509+
"oneOf":[
510+
{
511+
"additionalProperties": false,
512+
"properties": {
513+
"start": { "$ref": "#/definitions/Coordinates" },
514+
"end": { "$ref": "#/definitions/Coordinates" },
515+
"width": { "type": "number" },
516+
"net": { "type": "string" }
517+
},
518+
"required": [
519+
"start",
520+
"end",
521+
"width"
522+
]
523+
},
524+
{
525+
"additionalProperties": false,
526+
"properties": {
527+
"center": { "$ref": "#/definitions/Coordinates" },
528+
"startangle": { "type": "number" },
529+
"endangle": { "type": "number" },
530+
"radius": { "type": "number" },
531+
"width": { "type": "number" },
532+
"net": { "type": "string" }
533+
},
534+
"required": [
535+
"center",
536+
"startangle",
537+
"endangle",
538+
"radius",
539+
"width"
540+
]
541+
}
520542
]
521543
},
522544
"Zones": {

InteractiveHtmlBom/web/render.js

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,16 @@ function drawTracks(canvas, layer, color, highlight) {
384384
if (highlight && highlightedNet != track.net) continue;
385385
ctx.lineWidth = track.width;
386386
ctx.beginPath();
387-
ctx.moveTo(...track.start);
388-
ctx.lineTo(...track.end);
387+
if ('radius' in track) {
388+
ctx.arc(
389+
...track.center,
390+
track.radius,
391+
deg2rad(track.startangle),
392+
deg2rad(track.endangle));
393+
} else {
394+
ctx.moveTo(...track.start);
395+
ctx.lineTo(...track.end);
396+
}
389397
ctx.stroke();
390398
}
391399
}
@@ -632,6 +640,39 @@ function pointWithinDistanceToSegment(x, y, x1, y1, x2, y2, d) {
632640
return dx * dx + dy * dy <= d * d;
633641
}
634642

643+
function modulo(n, mod) {
644+
return ((n % mod) + mod ) % mod;
645+
}
646+
647+
function pointWithinDistanceToArc(x, y, xc, yc, radius, startangle, endangle, d) {
648+
var dx = x - xc;
649+
var dy = y - yc;
650+
var r_sq = dx * dx + dy * dy;
651+
var rmin = Math.max(0, radius-d);
652+
var rmax = radius + d;
653+
654+
if (r_sq < rmin * rmin || r_sq > rmax * rmax)
655+
return false;
656+
657+
var angle1 = modulo(deg2rad(startangle), 2 * Math.PI);
658+
var dx1 = xc + radius * Math.cos(angle1) - x;
659+
var dy1 = yc + radius * Math.sin(angle1) - y;
660+
if (dx1 * dx1 + dy1 * dy1 <= d * d)
661+
return true;
662+
663+
var angle2 = modulo(deg2rad(endangle), 2 * Math.PI);
664+
var dx2 = xc + radius * Math.cos(angle2) - x;
665+
var dy2 = yc + radius * Math.sin(angle2) - y;
666+
if (dx2 * dx2 + dy2 * dy2 <= d * d)
667+
return true;
668+
669+
var angle = modulo(Math.atan2(dy, dx), 2 * Math.PI);
670+
if (angle1 > angle2)
671+
return (angle >= angle2 || angle <= angle1);
672+
else
673+
return (angle >= angle1 && angle <= angle2);
674+
}
675+
635676
function pointWithinPad(x, y, pad) {
636677
var v = [x - pad.pos[0], y - pad.pos[1]];
637678
v = rotateVector(v, -pad.angle);
@@ -646,8 +687,14 @@ function netHitScan(layer, x, y) {
646687
// Check track segments
647688
if (settings.renderTracks && pcbdata.tracks) {
648689
for(var track of pcbdata.tracks[layer]) {
649-
if (pointWithinDistanceToSegment(x, y, ...track.start, ...track.end, track.width / 2)) {
650-
return track.net;
690+
if ('radius' in track) {
691+
if (pointWithinDistanceToArc(x, y, ...track.center, track.radius, track.startangle, track.endangle, track.width / 2)) {
692+
return track.net;
693+
}
694+
} else {
695+
if (pointWithinDistanceToSegment(x, y, ...track.start, ...track.end, track.width / 2)) {
696+
return track.net;
697+
}
651698
}
652699
}
653700
}

0 commit comments

Comments
 (0)