From 5c9f3276505a9cbe000842401cbf7dd132b48ccb Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Tue, 13 Apr 2021 20:32:16 -0400 Subject: [PATCH] Fix radius/diameter confusion in overlap search. Drill sizes are specified as hole diameter, but the nearest neighbour search is performed by distance. The overlap relation is documented as "when the centre of one hole is inside the other hole" which implies that we should be searching on hole radius. Presently the diameter is used, which is twice as far as expected. For holes that are the same size this is a minor technicality: such holes that are apart by less than the hole diameter do "overlap" in the drilled portion. But when a small hole is near a large hole they can be obviously disjoint yet slotifier can erroneously merge them. Adjust the search to half the diameter, plus some slop (5 tenths) so that holes exactly on the boundary are counted as overlapping. --- NEWS | 1 + src/slotifier.c | 7 +++++-- tests/simple.at | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index ef6df4b..c9b7e47 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,5 @@ Release 1.1a: + * Fix calculation error in overlap relation. * Various bug fixes and improvements. Release 1.1: diff --git a/src/slotifier.c b/src/slotifier.c index 0165931..b74a9ec 100644 --- a/src/slotifier.c +++ b/src/slotifier.c @@ -221,7 +221,7 @@ static int combine_holes(gerbv_image_t *drill, gerbv_net_t *hole, hole->aperture = -hole->aperture; for (i = 0; i < CVectorSize(group); i++) { - double xy[2], dia; + double xy[2], dia, r; CVectorGetElement(group, &hole, i); tool = drill->aperture[abs(hole->aperture)]; @@ -230,10 +230,13 @@ static int combine_holes(gerbv_image_t *drill, gerbv_net_t *hole, xy[0] = hole->start_x; xy[1] = hole->start_y; dia = tool->parameter[0]; + /* Half a mil slop to decisively include points on boundary. */ + r = dia/2 + 0.0005; + if (drill->aperture[biggest_tool]->parameter[0] < dia) biggest_tool = abs(hole->aperture); - if (CNearTreeFindInSphere(t, dia, 0, tmp, xy, 1) != 0) { + if (CNearTreeFindInSphere(t, r, 0, tmp, xy, 1) != 0) { /* We should always should find at least one hole! */ fprintf(stderr, _("%s: fatal error searching holes\n"), progname); diff --git a/tests/simple.at b/tests/simple.at index 1b6c588..8e28f6b 100644 --- a/tests/simple.at +++ b/tests/simple.at @@ -1,4 +1,4 @@ -# Copyright © 2018 Nick Bowler +# Copyright © 2018, 2021 Nick Bowler # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -53,3 +53,35 @@ M30 ]]) AT_CLEANUP + +AT_SETUP([non-overlapping holes]) + +AT_DATA([test.cnc], +[[M48 +INCH +T25C0.010 +T24C0.091 +% +T25 +X010433Y001181 +T24 +X010512Y002362 +X010512Y002047 +M30 +]]) + +AT_CHECK([slotifier test.cnc], [0], +[[M48 +INCH,TZ +T10C0.091 +T11C0.010 +% +T10 +X010512Y002362G85X010512Y002047 +T11 +X010433Y001181 +M30 + +]]) + +AT_CLEANUP -- 2.43.0