import numpy as np
def dx(dis, k):
return np.sqrt(dis / (k**2 + 1.))
def dy(dis, k):
return k * dx(dis, k)
def parallel_curve(xs, ys, ks, dis=1.):
""" 由于对称性, 会返回两条平行曲线上的点
:param xs: ndarray, 原始曲线上点的x值 [shape:(N,)]
:param xs: ndarray, 原始曲线上点的y值 [shape:(N,)]
:param ks: ndarray, 原始曲线上点的斜率 [shape:(N,)]
:param dis: float, 曲线间的距离
:return: ndarray, pxs [shape:(2, N)], pys [shape:(2, N)]
"""
g = np.sign(ks)
g[g == 0] = 1
ms = -1. / (ks + 1e-20)
pxs = np.vstack((xs + dx(dis ** 2, ms) * g, xs - dx(dis ** 2, ms) * g))
pys = np.vstack((ys + dy(dis ** 2, ms) * g, ys - dy(dis ** 2, ms) * g))
return pxs, pys
Example:
x = np.arange(-20, 20, 1)
curve = np.poly1d([0.005, 0.02, -1, 2]) # 可以通过定义或拟合点来找到函数表达式
der = np.polyder(curve)
y = curve(x)
ks = der(x)
ps = parallel_curve(x, y, ks, dis=1.5)
plt.figure(figsize=(17, 12))
plt.plot(x, y, color='crimson', marker='o', linewidth=1.5)
plt.plot(ps[0][0], ps[1][0], color='teal', marker='o', linewidth=1.5)
plt.plot(ps[0][1], ps[1][1], color='mediumpurple', marker='o', linewidth=1.5)
plt.grid()
plt.axis("equal")
plt.xlabel('x', {'fontsize': 'x-large'})
plt.ylabel('y', {'fontsize': 'x-large'})
plt.legend(('original curve', 'parallel curve 1', 'parallel curve 2'), loc=2)
plt.title('distance=1.5', {'fontsize': 'x-large'})
plt.show()