从鼠标坐标构建平滑曲线

时间:2016-07-06 23:09:02

标签: python curve points smooth

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

以身作则: - 在X ms之后,我可以得到这些(x,y)坐标:(0,0),(3,1),(5,4),(6,7) - 在2 * X ms后我可以得到:(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()

结果还可以: smooth curve

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

smooth_curve2

编辑:发现了一些有趣的线索:

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()

有很多要点时效果很好: splines

但是当不到5分时(这就是我喜欢的)不太好: enter image description here

0 个答案:

没有答案