Skip to content

Commit

Permalink
refactor BSpline.divide() method
Browse files Browse the repository at this point in the history
  • Loading branch information
mozman committed Jan 18, 2025
1 parent 9c06811 commit 2183a69
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 13 deletions.
21 changes: 13 additions & 8 deletions src/ezdxf/math/bspline.py
Original file line number Diff line number Diff line change
Expand Up @@ -1997,23 +1997,28 @@ def param_at(self, distance: float) -> float:
t2 = next_point.param
return float(t1 + (t2 - t1) * (offset / next_point.distance))

def divide(self, count: int) -> Iterator[float]:
def divide(self, count: int) -> list[float]:
"""Returns the interpolated B-spline parameters for dividing the curve into
`count` segments of equal length.
The first (0.0) and last parameter (max_t) are included e.g. dividing a B-spline
by 2 yields 3 parameters [0.0, t, max_t], parameter t divides the B-spline into
2 parts of equal length.
The method yields only the dividing parameters, the first (0.0) and last parameter
(max_t) are not included e.g. dividing a B-spline by 3 yields two parameters
[t1, t2] that divides the B-spline into 3 parts of equal length.
"""
if count < 1:
raise ValueError(f"invalid count: {count}")
total_length: float = self.length
seg_length = total_length / count
offset = 0.0
while offset <= total_length:
yield self.param_at(offset)
offset += seg_length
distance = seg_length
max_t = self._spline.max_t
result: list[float] = []
while distance < total_length:
t = self.param_at(distance)
if not math.isclose(max_t, t):
result.append(t)
distance += seg_length
return result

def _measure_spline(self, segments: int) -> None:
spline = self._spline
Expand Down
10 changes: 5 additions & 5 deletions tests/test_06_math/test_628_bspline_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,10 @@ def test_distance_out_of_range(self, spline):

def test_divide(self, spline):
mtool = spline.measure(100)
params = list(mtool.divide(7))
assert len(params) == 8
assert params[0] == 0.0
assert params[-1] == spline.max_t
params = mtool.divide(7)
assert len(params) == 6
assert params[0] != 0.0
assert params[-1] != spline.max_t

def test_extents(self, spline):
mtool = spline.measure()
Expand All @@ -221,7 +221,7 @@ def test_extents(self, spline):

def test_split_spline():
spline = BSpline(CONTROL_POINTS)
_, mid_t, _ = spline.measure().divide(2)
mid_t = spline.measure().divide(2)[0]
sp1, sp2 = spline.split(mid_t)
l1 = sp1.measure().length
l2 = sp2.measure().length
Expand Down

0 comments on commit 2183a69

Please sign in to comment.