summaryrefslogtreecommitdiff
path: root/lib/stitches
diff options
context:
space:
mode:
authorGeorge Steel <george.steel@gmail.com>2022-12-26 20:13:48 -0500
committerGeorge Steel <george.steel@gmail.com>2022-12-26 20:13:48 -0500
commite28ea888a9604052d6d7b94c8e29e34b74242994 (patch)
treed9c20a8b56aca08791cde310e47a0a562c5ad97b /lib/stitches
parentb63f19b2d0747769c60c8a2a52489ee30fa02a07 (diff)
use random oracle for randomized satin columns and redo split stitches
Diffstat (limited to 'lib/stitches')
-rw-r--r--lib/stitches/__init__.py1
-rw-r--r--lib/stitches/ripple_stitch.py4
-rw-r--r--lib/stitches/running_stitch.py43
3 files changed, 42 insertions, 6 deletions
diff --git a/lib/stitches/__init__.py b/lib/stitches/__init__.py
index b0ff64fc..cfa05e51 100644
--- a/lib/stitches/__init__.py
+++ b/lib/stitches/__init__.py
@@ -6,7 +6,6 @@
from .auto_fill import auto_fill
from .fill import legacy_fill
from .guided_fill import guided_fill
-from .running_stitch import *
# Can't put this here because we get a circular import :(
# from .auto_satin import auto_satin
diff --git a/lib/stitches/ripple_stitch.py b/lib/stitches/ripple_stitch.py
index 6b7ce6ca..a66eff74 100644
--- a/lib/stitches/ripple_stitch.py
+++ b/lib/stitches/ripple_stitch.py
@@ -74,12 +74,12 @@ def _get_satin_ripple_helper_lines(stroke):
length = stroke.grid_size or stroke.running_stitch_length
# use satin column points for satin like build ripple stitches
- rail_points = SatinColumn(stroke.node).plot_points_on_rails(length)
+ rail_pairs = SatinColumn(stroke.node).plot_points_on_rails(length)
steps = _get_steps(stroke.get_line_count(), exponent=stroke.exponent, flip=stroke.flip_exponent)
helper_lines = []
- for point0, point1 in zip(*rail_points):
+ for point0, point1 in rail_pairs:
helper_lines.append([])
helper_line = LineString((point0, point1))
for step in steps:
diff --git a/lib/stitches/running_stitch.py b/lib/stitches/running_stitch.py
index 8c86eb7c..fd6d4572 100644
--- a/lib/stitches/running_stitch.py
+++ b/lib/stitches/running_stitch.py
@@ -6,11 +6,48 @@
import math
from copy import copy
-from shapely.geometry import LineString
+import numpy as np
+from shapely import geometry as shgeo
+from ..utils import prng
""" Utility functions to produce running stitches. """
+def split_segment_even_n(a, b, segments: int, jitter_sigma: float = 0.0, random_seed: str | None = None) -> list[shgeo.Point]:
+ if segments <= 1:
+ return []
+ line = shgeo.LineString((a, b))
+
+ splits = np.array(range(1, segments)) / segments
+ if random_seed is not None:
+ jitters = (prng.nUniformFloats(len(splits), random_seed) * 2) - 1
+ splits = splits + jitters * (jitter_sigma / segments)
+
+ # sort the splits in case a bad roll transposes any of them
+ return [line.interpolate(x, normalized=True) for x in sorted(splits)]
+
+
+def split_segment_even_dist(a, b, max_length: float, jitter_sigma: float = 0.0, random_seed: str | None = None) -> list[shgeo.Point]:
+ distance = shgeo.Point(a).distance(shgeo.Point(b))
+ segments = math.ceil(distance / max_length)
+ return split_segment_even_n(a, b, segments, jitter_sigma, random_seed)
+
+
+def split_segment_random_phase(a, b, length: float, length_sigma: float, random_seed: str) -> list[shgeo.Point]:
+ line = shgeo.LineString([a, b])
+ progress = length * prng.uniformFloats(random_seed, "phase")[0]
+ splits = [progress]
+ distance = line.length
+ if progress >= distance:
+ return []
+ for x in prng.iterUniformFloats(random_seed):
+ progress += length * (1 + length_sigma * (x - 0.5) * 2)
+ if progress >= distance:
+ break
+ splits.append(progress)
+ return [line.interpolate(x, normalized=False) for x in splits]
+
+
def running_stitch(points, stitch_length, tolerance):
"""Generate running stitch along a path.
@@ -28,7 +65,7 @@ def running_stitch(points, stitch_length, tolerance):
# simplify will remove as many points as possible while ensuring that the
# resulting path stays within the specified tolerance of the original path.
- path = LineString(points)
+ path = shgeo.LineString(points)
simplified = path.simplify(tolerance, preserve_topology=False)
# save the points that simplify picked and make sure we stitch them
@@ -45,7 +82,7 @@ def running_stitch(points, stitch_length, tolerance):
# Now split each section up evenly into stitches, each with a length no
# greater than the specified stitch_length.
- section_ls = LineString(section)
+ section_ls = shgeo.LineString(section)
section_length = section_ls.length
if section_length > stitch_length:
# a fractional stitch needs to be rounded up, which will make all