给定两条曲线,想将其中一条曲线(蓝色曲线)平滑连接到另一条曲线(红色曲线),同时确保红色曲线保持不变。连接方向为从左下角向右上角。如下图所示:
目前,已经使用样条插值法获得了一条连接曲线(绿色曲线),但需要将绿色曲线从与红色曲线和蓝色曲线的交点处截断,并用截断后的蓝色曲线替换绿色曲线的最后一段。如下图所示:
解决方案
解决方案一
可以使用样条插值法来解决这个问题。样条插值法可以根据一组给定的数据点生成一条平滑的曲线。首先,将蓝色曲线和红色曲线的交点附近的数据点提取出来,然后使用样条插值法生成一条新的曲线,这条曲线将连接蓝色曲线和红色曲线。最后,将绿色曲线从与红色曲线和蓝色曲线的交点处截断,并用截断后的蓝色曲线替换绿色曲线的最后一段。
代码示例
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import spline
# Red line data
x1 = [0.01, 0.04, 0.08, 0.11, 0.15, 0.18, 0.22, 0.25, 0.29, 0.32, 0.35, 0.38, 0.41, 0.44, 0.46, 0.49, 0.51, 0.54, 0.56, 0.58]
y1 = [2.04, 2.14, 2.24, 2.34, 2.44, 2.54, 2.64, 2.74, 2.84, 2.94, 3.04, 3.14, 3.24, 3.34, 3.44, 3.54, 3.64, 3.74, 3.84, 3.94]
# Blue line data
x2 = [0.4634, 0.4497, 0.4375, 0.4268, 0.4175, 0.4095, 0.4027, 0.3971, 0.3925, 0.389, 0.3865, 0.3848, 0.384, 0.3839, 0.3845, 0.3857, 0.3874, 0.3896, 0.3922, 0.3951, 0.3982, 0.4016, 0.405, 0.4085, 0.412, 0.4154, 0.4186, 0.4215, 0.4242, 0.4265, 0.4283, 0.4297, 0.4304, 0.4305, 0.4298, 0.4284, 0.4261, 0.4228, 0.4185, 0.4132, 0.4067, 0.399, 0.39, 0.3796, 0.3679, 0.3546, 0.3397, 0.3232, 0.305, 0.285]
y2 = [1.0252, 1.0593, 1.0934, 1.1275, 1.1616, 1.1957, 1.2298, 1.2639, 1.298, 1.3321, 1.3662, 1.4003, 1.4344, 1.4685, 1.5026, 1.5367, 1.5708, 1.6049, 1.639, 1.6731, 1.7072, 1.7413, 1.7754, 1.8095, 1.8436, 1.8776, 1.9117, 1.9458, 1.9799, 2.014, 2.0481, 2.0822, 2.1163, 2.1504, 2.1845, 2.2186, 2.2527, 2.2868, 2.3209, 2.355, 2.3891, 2.4232, 2.4573, 2.4914, 2.5255, 2.5596, 2.5937, 2.6278, 2.6619, 2.696]
# Extract data points near the intersection
x3, y3 = [], []
for indx, y2_i in enumerate(y2):
if (y2[-1] - y2_i) <= 0.2:
y3.append(y2_i)
x3.append(x2[indx])
for indx, y1_i in enumerate(y1):
if 0. < (y1_i - y2[-1]) <= 0.4 and x1[indx] > x2[-1]:
y3.append(y1_i)
x3.append(x1[indx])
# Generate a new curve using spline interpolation
poli_order = 3
poli = np.polyfit(y3, x3, poli_order)
y_pol = np.linspace(min(y3), max(y3), 50)
p = np.poly1d(poli)
x_pol = [p(i) for i in y_pol]
# Plot the curves
plt.plot(x1, y1, 'r')
plt.plot(x2, y2, 'b')
plt.plot(x_pol, y_pol, 'g')
plt.scatter(x3, y3, c='k')
plt.show()
解决方案二
可以使用贝塞尔曲线来解决这个问题。贝塞尔曲线是一种常用的曲线拟合方法,可以根据一组给定的控制点生成一条平滑的曲线。贝塞尔曲线的优点是计算简单,并且可以生成非常平滑的曲线。
代码示例
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import splprep, splev
# Red line data
x1 = [0.01, 0.04, 0.08, 0.11, 0.15, 0.18, 0.22, 0.25, 0.29, 0.32, 0.35, 0.38, 0.41, 0.44, 0.46, 0.49, 0.51, 0.54, 0.56, 0.58]
y1 = [2.04, 2.14, 2.24, 2.34, 2.44, 2.54, 2.64, 2.74, 2.84, 2.94, 3.04, 3.14, 3.24, 3.34, 3.44, 3.54, 3.64, 3.74, 3.84, 3.94]
# Blue line data
x2 = [0.4634, 0.4497, 0.4375, 0.4268, 0.4175, 0.4095, 0.4027, 0.3971, 0.3