diff options
| author | George Steel <george.steel@gmail.com> | 2022-12-26 20:13:48 -0500 |
|---|---|---|
| committer | George Steel <george.steel@gmail.com> | 2022-12-26 20:13:48 -0500 |
| commit | e28ea888a9604052d6d7b94c8e29e34b74242994 (patch) | |
| tree | d9c20a8b56aca08791cde310e47a0a562c5ad97b /lib/stitches | |
| parent | b63f19b2d0747769c60c8a2a52489ee30fa02a07 (diff) | |
use random oracle for randomized satin columns and redo split stitches
Diffstat (limited to 'lib/stitches')
| -rw-r--r-- | lib/stitches/__init__.py | 1 | ||||
| -rw-r--r-- | lib/stitches/ripple_stitch.py | 4 | ||||
| -rw-r--r-- | lib/stitches/running_stitch.py | 43 |
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 |
