kopia lustrzana https://github.com/inkstitch/inkstitch
61 wiersze
1.9 KiB
Python
61 wiersze
1.9 KiB
Python
import numpy as np
|
|
|
|
from ..stitches.running_stitch import stitch_curve_evenly
|
|
from .geometry import Point, coordinate_list_to_point_list
|
|
|
|
|
|
def _remove_duplicate_coordinates(coords_array):
|
|
"""Remove consecutive duplicate points from an array.
|
|
|
|
Arguments:
|
|
coords_array -- numpy.array
|
|
|
|
Returns:
|
|
a numpy.array of coordinates, minus consecutive duplicates
|
|
"""
|
|
|
|
differences = np.diff(coords_array, axis=0)
|
|
zero_differences = np.isclose(differences, 0)
|
|
keepers = np.r_[True, np.any(zero_differences == False, axis=1)] # noqa: E712
|
|
|
|
return coords_array[keepers]
|
|
|
|
|
|
def smooth_path(path, smoothness=1.0, iterations=5):
|
|
"""Smooth a path of coordinates.
|
|
|
|
Arguments:
|
|
path -- an iterable of coordinate tuples or Points
|
|
smoothness -- float, how much smoothing to apply. Bigger numbers
|
|
smooth more.
|
|
|
|
Returns:
|
|
A list of Points.
|
|
"""
|
|
points = coordinate_list_to_point_list(path)
|
|
if smoothness == 0:
|
|
return points
|
|
|
|
# Smoothing seems to look nicer if the line segments in the path are mostly
|
|
# similar in length. If we have some especially long segments, then the
|
|
# smoothed path sometimes diverges more from the original path as the
|
|
# spline curve struggles to fit the path. This can be especially bad at
|
|
# the start and end.
|
|
#
|
|
# Fortunately, we can convert the path to segments that are mostly the same
|
|
# length by using the running stitch algorithm.
|
|
points = stitch_curve_evenly(points, smoothness * 5, smoothness * 2)
|
|
points = np.array(points)
|
|
for _ in range(iterations):
|
|
ll = points.repeat(2, axis=0)
|
|
r = np.empty_like(ll)
|
|
if len(r) == 0:
|
|
continue
|
|
r[0] = ll[0]
|
|
r[2::2] = ll[1:-1:2]
|
|
r[1:-1:2] = ll[2::2]
|
|
r[-1] = ll[-1]
|
|
points = ll * 0.75 + r * 0.25
|
|
|
|
return [Point(*coord) for coord in points]
|