Untitled
unknown
python
2 years ago
2.5 kB
6
Indexable
import numpy as np import matplotlib.pyplot as plt from matplotlib.path import Path from matplotlib.patches import PathPatch def linear_interpolation(p1, p2, t): return tuple(a + t * (b - a) for a, b in zip(p1, p2)) def normalize_vector(v): return v / np.linalg.norm(v) def absolute_padding(p1, p2, padding): direction = normalize_vector(np.array(p2) - np.array(p1)) return tuple(np.array(p1) + padding * direction) def interpolate_points(ax, x, y, pad, open=False, absolute_pad=False, **kwargs): verts = [] codes = [] points = list(zip(x, y)) n = len(points) for i, (prev_pt, curr_pt, next_pt) in enumerate(zip(points[-1:] + points[:-1], points, points[1:] + points[:1])): if i == 0: if open: codes.append(Path.MOVETO) verts.append(curr_pt) else: if absolute_pad: smoothed_pt = absolute_padding(curr_pt, prev_pt, pad) else: smoothed_pt = linear_interpolation(prev_pt, curr_pt, 1 - pad) codes.append(Path.MOVETO) verts.append(smoothed_pt) else: if absolute_pad: if open and i == n - 1: smoothed_pt = curr_pt else: smoothed_pt = absolute_padding(curr_pt, prev_pt, pad) else: if open and i == n - 1: smoothed_pt = curr_pt else: smoothed_pt = linear_interpolation(prev_pt, curr_pt, 1 - pad) codes.append(Path.LINETO) verts.append(smoothed_pt) if not open or i < n - 1: if absolute_pad: smoothed_pt = absolute_padding(curr_pt, next_pt, pad) else: smoothed_pt = linear_interpolation(curr_pt, next_pt, pad) codes.extend([Path.CURVE3, Path.CURVE3]) verts.extend([curr_pt, smoothed_pt]) if not open: codes.append(Path.LINETO) verts.append(verts[0]) rounded_path = Path(verts, codes) rounded_patch = PathPatch(rounded_path, **kwargs) ax.add_patch(rounded_patch) fig, ax = plt.subplots(dpi=220, figsize=(1.5, 1.5)) x = np.array([0.25, 0.25, 0.75, 0.75]) y = np.array([0, 1, 1, 0]) ax.plot(x, y, 'o:', 'k', mfc='r', zorder=2) ax.set_xlim(-0.5, 1.5) ax.set_ylim(-0.5, 1.5) interpolate_points(ax, x, y, 0.25, open=True, absolute_pad=True, facecolor='red', edgecolor='k', alpha=1/3) plt.show()
Editor is loading...