如何在Python中为多条多项式曲线拟合凸包?
寻找覆盖多条多项式曲线的凸包的Python实现
我有若干已知表达式的多项式曲线,组合效果如图所示,需要找到能覆盖所有曲线的凸包(类似图中蓝色曲线),想知道Python有没有相关实现函数。
以下是各曲线的函数表达式:
y = 0.00867 * x + -0.00001 * x^2 + 0.00000* x^3+ 24.08735 y = 0.00314 * x + -0.00000 * x^2 + 25.50681 y = 0.00092 * x + -0.00000 * x^2 + 28.09722 y = 0.00480 * x + -0.00000 * x^2 + 30.29156 y = 0.00255 * x + -0.00000 * x^2 + 36.37911
解决方案
你需要的其实是上包络线(逐点取所有曲线在对应x处的最大值,连接后形成的曲线),而非传统的点集凸包。Python可以通过numpy和matplotlib轻松实现,步骤如下:
- 定义多项式函数:将每个表达式转换为可计算的多项式对象,使用
numpy.poly1d(注意系数按高次到低次排列)。 - 生成采样点:确定x的取值区间,生成足够多的采样点以捕捉曲线细节。
- 计算上包络线:对每个x点,计算所有曲线的y值并取最大值,得到包络线的y值。
- 可视化验证:绘制原始曲线和包络线,确认覆盖效果。
示例代码
import numpy as np import matplotlib.pyplot as plt # 转换所有多项式为numpy可计算的对象(系数从高次到低次排列) polynomials = [ np.poly1d([-0.00001, 0.00867, 24.08735]), # 对应第一条曲线 np.poly1d([0, 0.00314, 25.50681]), # 对应第二条曲线 np.poly1d([0, 0.00092, 28.09722]), # 对应第三条曲线 np.poly1d([0, 0.00480, 30.29156]), # 对应第四条曲线 np.poly1d([0, 0.00255, 36.37911]) # 对应第五条曲线 ] # 设置x的取值范围(根据实际需求调整区间和采样点数量) x = np.linspace(0, 1000, 1000) # 计算每个x点对应的所有曲线y值,取最大值得到上包络线 y_envelope = np.max([poly(x) for poly in polynomials], axis=0) # 绘制结果 plt.figure(figsize=(10, 6)) # 绘制原始曲线 for idx, poly in enumerate(polynomials): plt.plot(x, poly(x), alpha=0.6, label=f"曲线{idx+1}") # 绘制上包络线 plt.plot(x, y_envelope, color='blue', linewidth=2, label='覆盖所有曲线的上包络线') plt.xlabel('x') plt.ylabel('y') plt.title('多项式曲线及上包络线') plt.legend() plt.show()
补充说明
如果确实需要传统的点集凸包(将所有曲线上的采样点合并后计算凸包),可以使用scipy.spatial.ConvexHull:
from scipy.spatial import ConvexHull # 采样所有曲线上的点 all_points = [] for poly in polynomials: y = poly(x) all_points.extend(np.column_stack((x, y))) all_points = np.array(all_points) # 计算凸包 hull = ConvexHull(all_points) # 绘制凸包 plt.figure(figsize=(10,6)) plt.plot(all_points[:,0], all_points[:,1], 'o', alpha=0.3) for simplex in hull.simplices: plt.plot(all_points[simplex, 0], all_points[simplex, 1], 'blue') plt.show()
但这种方法生成的凸包会包含曲线下方的区域,对于“覆盖所有曲线”的需求,上包络线是更精准的选择。
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

