[Arc] return clearer errors when working with an invalid arclength
This commit is contained in:
parent
bdc4dfdd06
commit
d95ddbb6b9
2 changed files with 16 additions and 2 deletions
|
|
@ -231,6 +231,8 @@ class Arc(PositionableImpl, Shape):
|
||||||
if (num_vertices is None) and (max_arclen is None):
|
if (num_vertices is None) and (max_arclen is None):
|
||||||
raise PatternError('Max number of points and arclength left unspecified'
|
raise PatternError('Max number of points and arclength left unspecified'
|
||||||
+ ' (default was also overridden)')
|
+ ' (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
|
r0, r1 = self.radii
|
||||||
|
|
||||||
|
|
@ -257,13 +259,19 @@ class Arc(PositionableImpl, Shape):
|
||||||
return arc_lengths, tt
|
return arc_lengths, tt
|
||||||
|
|
||||||
wh = self.width / 2.0
|
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:
|
if num_vertices is not None:
|
||||||
n_pts = numpy.ceil(max(self.radii + wh) / min(self.radii) * num_vertices * 100).astype(int)
|
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_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()
|
perimeter_outer = get_arclens(n_pts, *a_ranges[1], dr= wh)[0].sum()
|
||||||
implied_arclen = (perimeter_outer + perimeter_inner + self.width * 2) / num_vertices
|
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)
|
if not (numpy.isnan(implied_arclen) or implied_arclen <= 0):
|
||||||
assert max_arclen is not None
|
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]:
|
def get_thetas(inner: bool) -> NDArray[numpy.float64]:
|
||||||
""" Figure out the parameter values at which we should place vertices to meet the arclength constraint"""
|
""" Figure out the parameter values at which we should place vertices to meet the arclength constraint"""
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,12 @@ def test_curve_polygonizers_clamp_large_max_arclen() -> None:
|
||||||
assert len(polys[0].vertices) >= 3
|
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:
|
def test_ellipse_integer_radii_scale_cleanly() -> None:
|
||||||
ellipse = Ellipse(radii=(10, 20))
|
ellipse = Ellipse(radii=(10, 20))
|
||||||
ellipse.scale_by(0.5)
|
ellipse.scale_by(0.5)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue