将 3d 坐标拟合成抛物线

Fit 3d coordinates into a parabola

我想通过将球的 3d 坐标拟合成抛物线来预测球的轨迹。下面是我的代码。但是我得到的不是抛物线,而是一条直线。如果您对此有任何线索,请告诉我。谢谢!

# draw scatter coordiante 
fig = plt.figure()
ax = plt.axes(projection = '3d')
x_list = []
y_list = []
z_list = []
for x in rm_list:
    x_list.append(x[0][0])
    y_list.append(x[0][1])
    z_list.append(x[0][2])
x = np.array(x_list)
y = np.array(y_list)
z = np.array(z_list)
ax.scatter(x, y, z)

# curve fit
def func(x, a, b, c, d):
    return a * x[0]**2 + b * x[1]**2 + c * x[0] * x[1] + d

data = np.column_stack([x_list, y_list, z_list])
popt, _ = curve_fit(func, data[:,:2].T, ydata=data[:,2])
a, b, c, d = popt
print('y= %.5f * x ^ 2 + %.5f * y ^ 2 + %.5f * x * y + %.5f' %(a, b, c, d))
x1 = np.linspace(0.3, 0.4, 100)
y1 = np.linspace(0.02, 0.06, 100)
z1 = a * x1 ** 2 + b * y1 ** 2 + c * x1 * y1 + d
ax.plot(x1, y1, z1, color='green')

plt.show()

更新 1 将函数更改为 ax^2 + by^2 + cxy + dx + ey + f 后,我得到了一条抛物线但不适合坐标。

您拥有基础时间戳数据可以使拟合过程更容易:

import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
from numpy.polynomial import Polynomial

# test data generation with some noise
# here read in your data
np.random.seed(123)
n = 40
x_param = [ 1, 21, -1]
y_param = [12, -3,  0]
z_param = [-3,  0, -2]
px = Polynomial(x_param)
py = Polynomial(y_param)
pz = Polynomial(z_param)
t = np.random.choice(np.linspace (-3000, 2000, 1000)/500, n)
x = px(t) + np.random.random(n)
y = py(t) + np.random.random(n)
z = pz(t) + np.random.random(n)


# here start the real calculations 
# draw scatter coordinates of raw data
fig = plt.figure()
ax = plt.axes(projection = '3d')
ax.scatter(x, y, z, label="raw data")

# curve fit function
def func(t, x2, x1, x0, y2, y1, y0, z2, z1, z0):
    Px=Polynomial([x2, x1, x0])
    Py=Polynomial([y2, y1, y0])
    Pz=Polynomial([z2, z1, z0])
    return np.concatenate([Px(t), Py(t), Pz(t)])


# curve fit
# start values are not necessary for this example 
# but make it your rule to always provide start values for curve_fit 
start_vals = [ 1, 10,  1, 
              10,  1,  1, 
              -1, -1, -1]
xyz = np.concatenate([x, y, z])
popt, _ = curve_fit(func, t, xyz, p0=start_vals)
print(popt)
#[ 1.58003630e+00  2.10059868e+01 -1.00401965e+00  
#  1.25895591e+01 -2.97374035e+00 -3.23358241e-03 
# -2.44293562e+00  3.96407428e-02 -1.99671092e+00]

# regularly spaced fit data
t_fit = np.linspace(min(t), max(t), 100)
xyz_fit = func(t_fit, *popt).reshape(3, -1)    
ax.plot(xyz_fit[0, :], xyz_fit[1, :], xyz_fit[2, :], color="green", label="fitted data")

ax.legend()
plt.show()

示例输出: