summaryrefslogtreecommitdiff
path: root/lib/stitches/running_stitch.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stitches/running_stitch.py')
-rw-r--r--lib/stitches/running_stitch.py47
1 files changed, 34 insertions, 13 deletions
diff --git a/lib/stitches/running_stitch.py b/lib/stitches/running_stitch.py
index 8b8add7e..058ee565 100644
--- a/lib/stitches/running_stitch.py
+++ b/lib/stitches/running_stitch.py
@@ -210,11 +210,12 @@ def take_stitch(start: Point, points: typing.Sequence[Point], idx: int, stitch_l
return points[-1], None
-def stitch_curve_evenly(points: typing.Sequence[Point], stitch_length: float, tolerance: float) -> typing.List[Point]:
+def stitch_curve_evenly(points: typing.Sequence[Point], stitch_length: typing.List[float], tolerance: float, stitch_length_pos: int = 0) -> \
+ typing.Tuple[typing.List[Point], int]:
# Will split a straight line into even-length stitches while still handling curves correctly.
# Includes end point but not start point.
if len(points) < 2:
- return []
+ return [], stitch_length_pos
distLeft = [0] * len(points)
for j in reversed(range(0, len(points) - 1)):
distLeft[j] = distLeft[j + 1] + points[j].distance(points[j+1])
@@ -225,26 +226,33 @@ def stitch_curve_evenly(points: typing.Sequence[Point], stitch_length: float, to
while i is not None and i < len(points):
d = last.distance(points[i]) + distLeft[i]
if d == 0:
- return stitches
- stitch_len = d / math.ceil(d / stitch_length) + 0.000001 # correction for rounding error
+ return stitches, stitch_length_pos
+ stitch_len = d / math.ceil(d / stitch_length[stitch_length_pos]) + 0.000001 # correction for rounding error
stitch, newidx = take_stitch(last, points, i, stitch_len, tolerance)
i = newidx
if stitch is not None:
stitches.append(stitch)
last = stitch
- return stitches
+ stitch_length_pos += 1
+ if stitch_length_pos > len(stitch_length) - 1:
+ stitch_length_pos = 0
+ return stitches, stitch_length_pos
+
+
+def stitch_curve_randomly(
+ points: typing.Sequence[Point],
+ stitch_length: typing.List[float], tolerance: float, stitch_length_sigma: float,
+ random_seed: str, stitch_length_pos: int = 0) -> typing.Tuple[typing.List[Point], int]:
+ min_stitch_length = max(0, stitch_length[stitch_length_pos] * (1 - stitch_length_sigma))
+ max_stitch_length = stitch_length[stitch_length_pos] * (1 + stitch_length_sigma)
-def stitch_curve_randomly(points: typing.Sequence[Point], stitch_length: float, tolerance: float, stitch_length_sigma: float, random_seed: str) ->\
- typing.List[Point]:
- min_stitch_length = max(0, stitch_length * (1 - stitch_length_sigma))
- max_stitch_length = stitch_length * (1 + stitch_length_sigma)
# Will split a straight line into stitches of random length within the range.
# Attempts to randomize phase so that the distribution of outputs does not depend on direction.
# Includes end point but not start point.
if len(points) < 2:
- return []
+ return [], stitch_length_pos
i: typing.Optional[int] = 1
last = points[0]
@@ -252,6 +260,13 @@ def stitch_curve_randomly(points: typing.Sequence[Point], stitch_length: float,
stitches = []
rand_iter = iter(prng.iter_uniform_floats(random_seed))
while i is not None and i < len(points):
+ if len(stitch_length) > 1:
+ min_stitch_length = max(0, stitch_length[stitch_length_pos] * (1 - stitch_length_sigma))
+ max_stitch_length = stitch_length[stitch_length_pos] * (1 + stitch_length_sigma)
+ stitch_length_pos += 1
+ if stitch_length_pos > len(stitch_length) - 1:
+ stitch_length_pos = 0
+
r = next(rand_iter)
# If the last stitch was shortened due to tolerance (or this is the first stitch),
# reduce the lower length limit to randomize the phase. This prevents moiré and asymmetry.
@@ -263,7 +278,7 @@ def stitch_curve_randomly(points: typing.Sequence[Point], stitch_length: float,
stitches.append(stitch)
last_shortened = min(last.distance(stitch) / stitch_len, 1.0)
last = stitch
- return stitches
+ return stitches, stitch_length_pos
def path_to_curves(points: typing.List[Point], min_len: float):
@@ -309,10 +324,12 @@ def even_running_stitch(points, stitch_length, tolerance):
if not points:
return
stitches = [points[0]]
+ last_stitch_length_pos = 0
for curve in path_to_curves(points, 2 * tolerance):
# segments longer than twice the tolerance will usually be forced by it, so set that as the minimum for corner detection
check_stop_flag()
- stitches.extend(stitch_curve_evenly(curve, stitch_length, tolerance))
+ stitched_curve, last_stitch_length_pos = stitch_curve_evenly(curve, stitch_length, tolerance, last_stitch_length_pos)
+ stitches.extend(stitched_curve)
return stitches
@@ -323,10 +340,14 @@ def random_running_stitch(points, stitch_length, tolerance, stitch_length_sigma,
if not points:
return
stitches = [points[0]]
+ last_stitch_length_pos = 0
for i, curve in enumerate(path_to_curves(points, 2 * tolerance)):
# segments longer than twice the tolerance will usually be forced by it, so set that as the minimum for corner detection
check_stop_flag()
- stitches.extend(stitch_curve_randomly(curve, stitch_length, tolerance, stitch_length_sigma, prng.join_args(random_seed, i)))
+ stitched_curve, last_stitch_length_pos = stitch_curve_randomly(
+ curve, stitch_length, tolerance, stitch_length_sigma, prng.join_args(random_seed, i), last_stitch_length_pos
+ )
+ stitches.extend(stitched_curve)
return stitches