From d95ddbb6b9f86c37b7bb4e5dae9a74f6194a5282 Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Thu, 16 Apr 2026 19:39:42 -0700 Subject: [PATCH] [Arc] return clearer errors when working with an invalid arclength --- masque/shapes/arc.py | 12 ++++++++++-- masque/test/test_shape_advanced.py | 6 ++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/masque/shapes/arc.py b/masque/shapes/arc.py index 2adfe10..00c5714 100644 --- a/masque/shapes/arc.py +++ b/masque/shapes/arc.py @@ -231,6 +231,8 @@ class Arc(PositionableImpl, Shape): if (num_vertices is None) and (max_arclen is None): raise PatternError('Max number of points and arclength left unspecified' + ' (default was also overridden)') + if max_arclen is not None and (numpy.isnan(max_arclen) or max_arclen <= 0): + raise PatternError('Max arclength must be positive and not NaN') r0, r1 = self.radii @@ -257,13 +259,19 @@ class Arc(PositionableImpl, Shape): return arc_lengths, tt wh = self.width / 2.0 + arclen_limits: list[float] = [] + if max_arclen is not None: + arclen_limits.append(max_arclen) if num_vertices is not None: n_pts = numpy.ceil(max(self.radii + wh) / min(self.radii) * num_vertices * 100).astype(int) perimeter_inner = get_arclens(n_pts, *a_ranges[0], dr=-wh)[0].sum() perimeter_outer = get_arclens(n_pts, *a_ranges[1], dr= wh)[0].sum() implied_arclen = (perimeter_outer + perimeter_inner + self.width * 2) / num_vertices - max_arclen = min(implied_arclen, max_arclen if max_arclen is not None else numpy.inf) - assert max_arclen is not None + if not (numpy.isnan(implied_arclen) or implied_arclen <= 0): + arclen_limits.append(implied_arclen) + if not arclen_limits: + raise PatternError('Arc polygonization could not determine a valid max_arclen') + max_arclen = min(arclen_limits) def get_thetas(inner: bool) -> NDArray[numpy.float64]: """ Figure out the parameter values at which we should place vertices to meet the arclength constraint""" diff --git a/masque/test/test_shape_advanced.py b/masque/test/test_shape_advanced.py index 350e8f0..689df2a 100644 --- a/masque/test/test_shape_advanced.py +++ b/masque/test/test_shape_advanced.py @@ -122,6 +122,12 @@ def test_curve_polygonizers_clamp_large_max_arclen() -> None: assert len(polys[0].vertices) >= 3 +def test_arc_polygonization_rejects_nan_implied_arclen() -> None: + arc = Arc(radii=(10, 20), angles=(0, numpy.nan), width=2) + with pytest.raises(PatternError, match='valid max_arclen'): + arc.to_polygons(num_vertices=24) + + def test_ellipse_integer_radii_scale_cleanly() -> None: ellipse = Ellipse(radii=(10, 20)) ellipse.scale_by(0.5)