summaryrefslogtreecommitdiff
path: root/lib/stitches/running_stitch.py
diff options
context:
space:
mode:
authorLex Neva <github.com@lexneva.name>2018-05-01 20:37:51 -0400
committerLex Neva <github.com@lexneva.name>2018-05-01 20:37:51 -0400
commit1b31806423c8fec4040fed6d1009db016860b763 (patch)
tree71ccac169471e76685a7fa0b9910f64555dc73a7 /lib/stitches/running_stitch.py
parent5b7f14d092456a941dbd189e61ed38d9b16d388b (diff)
rename inkstitch/ to lib/
You can't have a module and a package named the same thing. PyInstaller wants to import the main script as if it were a module, and this doesn't work unless there's no directory of the same name with a __init__.py in it.
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