Fix ArcPoly primitive approximate_arcs

This commit is contained in:
jaseg 2026-03-08 14:38:13 +01:00
parent 97513df5d9
commit e19dec20b6
2 changed files with 22 additions and 3 deletions

View file

@ -121,14 +121,14 @@ class ArcPoly(GraphicPrimitive):
def approximate_arcs(self, max_error=1e-2, clip_max_error=True):
outline = []
for p1, p2, (clockwise, center) in self.segments():
for (x1, y1), (x2, y2), (clockwise, (cx, cy)) in self.segments:
if clockwise is None:
outline.append(p1)
outline.append((x1, y1))
else:
outline.extend(approximate_arc(cx, cy, x1, y1, x2, y2, clockwise,
max_error=max_error, clip_max_error=clip_max_error))
outline.pop() # remove arc end point
return type(self)(outline)
return type(self)(outline, polarity_dark=self.polarity_dark)
def bounding_box(self):
bbox = (None, None), (None, None)

View file

@ -53,15 +53,21 @@ def object_test(tmpfile, img_support, epsilon=1e-4):
# test primitive to_arc_poly
arc_poly_gbr = GerberFile()
arc_poly_approx_gbr = GerberFile()
for obj in gbr.objects:
for primitive in obj.to_primitives(MM):
poly = primitive.to_arc_poly()
region = Region.from_arc_poly(poly)
arc_poly_gbr.objects.append(region)
# Regression test for gitlab issue #17
assert primitive.polarity_dark == poly.polarity_dark
assert region.polarity_dark == poly.polarity_dark
# Test for arc poly arc approximation, and regression test for gitlab issue #16
region = Region.from_arc_poly(poly.approximate_arcs())
arc_poly_approx_gbr.objects.append(region)
arc_poly_svg = tmpfile('ArcPoly SVG Output', '.svg')
with open(arc_poly_svg, 'w') as f:
f.write(str(arc_poly_gbr.to_svg(force_bounds=bounds, arg_unit='inch', fg='black', bg='white')))
@ -69,6 +75,14 @@ def object_test(tmpfile, img_support, epsilon=1e-4):
arc_poly_png = tmpfile('ArcPoly conversion render', '.png')
img_support.svg_to_png(arc_poly_svg, arc_poly_png, dpi=300, bg='white')
# Arc approximation test
arc_poly_approx_svg = tmpfile('ArcPoly Approximation SVG Output', '.svg')
with open(arc_poly_approx_svg, 'w') as f:
f.write(str(arc_poly_approx_gbr.to_svg(force_bounds=bounds, arg_unit='inch', fg='black', bg='white')))
arc_poly_approx_png = tmpfile('ArcPoly Approximation conversion render', '.png')
img_support.svg_to_png(arc_poly_approx_svg, arc_poly_approx_png, dpi=300, bg='white')
# Reference export via gerber through GerbV
out_gbr = tmpfile('GBR Output', '.gbr')
gbr.save(out_gbr)
@ -96,6 +110,11 @@ def object_test(tmpfile, img_support, epsilon=1e-4):
assert mean < epsilon
assert hist[3:].sum() < epsilon*hist.size
mean, _max, hist = img_support.image_difference(out_png, arc_poly_approx_png, diff_out=tmpfile('ArcPoly Approximation Difference', '.png'))
assert hist[9] < 1
assert mean < epsilon
assert hist[3:].sum() < epsilon*hist.size
@pytest.mark.parametrize('angle_deg', [0, 5, -5, 10, -10, 15, -15, 30, -30, 45, -45, 60, -60, 75, -75, 90, -90, 120, -120, 180, 153, 155, 157])
def test_line(angle_deg, tmpfile, img_support):
with object_test(tmpfile, img_support) as gbr: