Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从鼠标坐标构建平滑曲线_Python_Curve_Points_Smooth - Fatal编程技术网

Python 从鼠标坐标构建平滑曲线

Python 从鼠标坐标构建平滑曲线,python,curve,points,smooth,Python,Curve,Points,Smooth,在我正在进行的一个项目中,我每X毫秒获取一次鼠标坐标。我想画出这些坐标之间最可能的路径 举例来说: -在X ms之后,我可以得到这些(X,y)坐标:(0,0),(3,1),(5,4),(6,7) -在2*X毫秒后,我可以得到:(0,0),(3,1),(5,4),(6,7),(8,5),(11,-7) -等等 我想一步一步地在这些点之间画一条路径,一旦我画了一条路径,我就不能改变它(我迫不及待地要用所有的坐标来画这条线) 我开始考虑一个解决方案,通过计算多项式拟合在一对坐标之间画线: import

在我正在进行的一个项目中,我每X毫秒获取一次鼠标坐标。我想画出这些坐标之间最可能的路径

举例来说: -在X ms之后,我可以得到这些(X,y)坐标:(0,0),(3,1),(5,4),(6,7) -在2*X毫秒后,我可以得到:(0,0),(3,1),(5,4),(6,7),(8,5),(11,-7) -等等

我想一步一步地在这些点之间画一条路径,一旦我画了一条路径,我就不能改变它(我迫不及待地要用所有的坐标来画这条线)

我开始考虑一个解决方案,通过计算多项式拟合在一对坐标之间画线:

import numpy as np
import matplotlib.pyplot as plt

def construct_path(points):
    x = points[:,0]
    y = points[:,1]

    (x_new,y_new) = ([],[])
    for i in range(0,len(x) - 2):
        (x_tmp, y_tmp) =  get_new_points(x[i:(i+3)], y[i:(i+3)], (i+3) == len(x))
        (x_new,y_new) = (x_new + x_tmp.tolist(), y_new + y_tmp.tolist())
        previous_points = [x_tmp,y_tmp]

    return (x_new, y_new)

def get_new_points(x,y, end):
    x = np.array(x)
    y = np.array(y)

    # calculate polynomial
    z = np.polyfit(x, y, 2)
    f = np.poly1d(z)

    # calculate new x's and y's

    if not end:
        x_new = np.linspace(x[0], x[1], 11)
    else:
        x_new = np.linspace(x[0], x[1], 10, endpoint=False).tolist() + np.linspace(x[1], x[2], 11).tolist()
        x_new = np.array(x_new)
    y_new = f(x_new)

    print(x_new, y_new)
    return (x_new, y_new)


points = np.array([(0, 0), (3, 1), (5, 4), (6, 7), (8, 5), (11, -7) ])

x = points[:,0]
y = points[:,1]
(x_new, y_new) = construct_path(points)

plt.plot(x,y,'o',np.array(x_new),np.array(y_new))
plt.xlim([-2, 12])
plt.ylim([-10, 10])
plt.show()
结果还可以:

但当点具有接近的x或y(例如:(0,0)、(3,1)、(5.8,4)、(6,7)、(8,5)、(11,-7))时,它不起作用

编辑:找到了一些有趣的线索:

from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate

def range_spline(x,y):
    t = np.arange(x.shape[0], dtype=float)
    t /= t[-1]
    nt = np.linspace(0, 1, 100)
    new_x = scipy.interpolate.spline(t, x, nt)
    new_y = scipy.interpolate.spline(t, y, nt)
    return (new_x,new_y)

def dist_spline(x,y):
    t = np.zeros(x.shape)
    t[1:] = np.sqrt((x[1:] - x[:-1])**2 + (y[1:] - y[:-1])**2)
    t = np.cumsum(t)
    t /= t[-1]
    nt = np.linspace(0, 1, 100)
    new_x = scipy.interpolate.spline(t, x, nt)
    new_y = scipy.interpolate.spline(t, y, nt)
    return (new_x, new_y)

x = np.array([ 0,  3,  6,  6,  8,  11, 8, 6, 6])
y = np.array([ 0,  1,  4,  7,  5,  -7, -10, -10, -5])
#x = np.array([ 0, 2, 4])
#y = np.array([ 0, 2, 0])


(x1, y1) = range_spline(x,y)
(x2,y2) = dist_spline(x,y)

plt.plot(x,y, 'o')
plt.plot(x1, y1, label='range_spline')
plt.plot(x2, y2, label='dist_spline')

plt.legend(loc='best')
plt.show()
当有许多要点时,它工作得很好:

但当分数低于5分时(这是我想要的):

您可以尝试一些分段单调插值方法,如<代码>插值器在插值数据中保持单调性,并且如果数据不平滑,则不会超调。使用样条曲线而不是多项式拟合将使您受益,因为样条曲线也将匹配截面之间边界处的导数。我比较了不同的样条线方法(包括pchip),我认为这里可以使用相同的方法。