diff options
| author | Lex Neva <lexelby@users.noreply.github.com> | 2018-05-19 14:41:50 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-05-19 14:41:50 -0400 |
| commit | 9dadd836e2f09b0216f7b40c782e2b55bcc90dee (patch) | |
| tree | 128b6f13ea682a8e5a033370ab2e13388801f100 /lib/stitches/running_stitch.py | |
| parent | ba7288d8fcd62678bd17d8fab01d0d488d9e21e8 (diff) | |
| parent | 6fe417cd64090f028c0d07b799620eb94637bf33 (diff) | |
Merge pull request #163 from lexelby/lexelby-single-extension
single code entry point
Diffstat (limited to 'lib/stitches/running_stitch.py')
| -rw-r--r-- | lib/stitches/running_stitch.py | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/lib/stitches/running_stitch.py b/lib/stitches/running_stitch.py new file mode 100644 index 00000000..81124339 --- /dev/null +++ b/lib/stitches/running_stitch.py @@ -0,0 +1,66 @@ +""" Utility functions to produce running stitches. """ + + +def running_stitch(points, stitch_length): + """Generate running stitch along a path. + + Given a path and a stitch length, walk along the path in increments of the + stitch length. If sharp corners are encountered, an extra stitch will be + added at the corner to avoid rounding the corner. The starting and ending + point are always stitched. + + The path is described by a set of line segments, each connected to the next. + The line segments are described by a sequence of points. + """ + + if len(points) < 2: + return [] + + output = [points[0]] + segment_start = points[0] + last_segment_direction = None + + # This tracks the distance we've travelled along the current segment so + # far. Each time we make a stitch, we add the stitch_length to this + # value. If we fall off the end of the current segment, we carry over + # the remainder to the next segment. + distance = 0.0 + + for segment_end in points[1:]: + segment = segment_end - segment_start + segment_length = segment.length() + + if segment_length == 0: + continue + + segment_direction = segment.unit() + + # corner detection + if last_segment_direction: + cos_angle_between = segment_direction * last_segment_direction + + # This checks whether the corner is sharper than 45 degrees. + if cos_angle_between < 0.5: + # Only add the corner point if it's more than 0.1mm away to + # avoid a double-stitch. + if (segment_start - output[-1]).length() > 0.1: + # add a stitch at the corner + output.append(segment_start) + + # next stitch needs to be stitch_length along this segment + distance = stitch_length + + while distance < segment_length: + output.append(segment_start + distance * segment_direction) + distance += stitch_length + + # prepare for the next segment + segment_start = segment_end + last_segment_direction = segment_direction + distance -= segment_length + + # stitch the last point unless we're already almos there + if (segment_start - points[-1]).length() > 0.1: + output.append(segment_start) + + return output |
