summaryrefslogtreecommitdiff
path: root/lib/stitches/running_stitch.py
diff options
context:
space:
mode:
authorLex Neva <lexelby@users.noreply.github.com>2018-05-19 14:41:50 -0400
committerGitHub <noreply@github.com>2018-05-19 14:41:50 -0400
commit9dadd836e2f09b0216f7b40c782e2b55bcc90dee (patch)
tree128b6f13ea682a8e5a033370ab2e13388801f100 /lib/stitches/running_stitch.py
parentba7288d8fcd62678bd17d8fab01d0d488d9e21e8 (diff)
parent6fe417cd64090f028c0d07b799620eb94637bf33 (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.py66
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