Python实现移除两条平移抛物线相交段生成双底形态
移除平移抛物线相交区段生成双底模式的实现方法
问题背景
- 现有x、y轴取值范围均归一化到0~1的基础抛物线,形态如下:

- 沿x轴平移基础抛物线得到第二条曲线,直接全量拼接两条曲线的效果如下,存在交叉重叠区段:

- 目标效果为移除相交区段,得到连续的双底(double bottoms)模式图形:

当前实现代码如下:
import numpy as np import matplotlib.pyplot as plt def get_parabol(start=-1, end=1, steps=100, normalized=True): x = np.linspace(start, end, steps) y = x**2 if normalized: x = np.array(x) x = (x - x.min())/(x.max() - x.min()) y = np.array(y) y = (y - y.min())/(y.max() - y.min()) return x, y def curve_after(x, y, x_ratio=1/3, y_ratio=1/2, normalized=False): x = x*x_ratio + x.max() - x[0]*x_ratio y = y*y_ratio + y.max() - y.max()*y_ratio if normalized: x = np.array(x) x = (x - x.min())/(x.max() - x.min()) y = np.array(y) y = (y - y.min())/(y.max() - y.min()) return x, y def concat_arrays(*arr, axis=0, normalized=True): arr = np.concatenate([*arr], axis=axis).tolist() if normalized: arr = np.array(arr) arr = (arr - arr.min())/(arr.max() - arr.min()) return arr x, y = get_parabol() new_x, new_y = curve_after(x, y, x_ratio=1, y_ratio=1, normalized=False) new_x = np.add(x, 0.5) # new_y = np.add(y, 0.2) xx = concat_arrays(x, new_x, normalized=True) yy = concat_arrays(y, new_y, normalized=True) # plt.plot(x, y, '-') plt.plot(xx, yy, '--')
需求场景为模式分析研究,需要通过数学函数稳定生成各类标准模式图案。
实现方案
核心逻辑
不要直接全量拼接两条曲线的所有采样点,先找到两条抛物线的交点作为裁剪分界点,仅保留每条曲线在交点外侧的非重叠区段,拼接后统一做0~1归一化,即可得到无交叉的连续双底曲线。
具体步骤:
- 生成基础归一化抛物线,按设定偏移量生成x轴平移后的第二条抛物线
- 在覆盖两条曲线全范围的公共采样轴上,通过插值计算两条曲线的y值,通过y值差的过零点定位交点位置
- 裁剪曲线:基础抛物线保留交点左侧的采样点,平移后的抛物线保留交点右侧的采样点
- 拼接两段保留的点集,统一归一化到0~1区间后即可绘图
可运行代码
import numpy as np import matplotlib.pyplot as plt def get_parabol(start=-1, end=1, steps=100, normalized=True): x = np.linspace(start, end, steps) y = x**2 if normalized: x = np.array(x) x = (x - x.min())/(x.max() - x.min()) y = np.array(y) y = (y - y.min())/(y.max() - y.min()) return x, y # 生成基础抛物线与平移抛物线 x, y = get_parabol() x_shift = 0.5 # 可调整该值修改双底间距 y_shift = 0 # 可调整该值修改两个底的高度差 new_x = x + x_shift new_y = y + y_shift # 定位两条曲线的交点 x_common = np.linspace( min(x.min(), new_x.min()), max(x.max(), new_x.max()), 1000 ) y1_interp = np.interp(x_common, x, y, left=np.nan, right=np.nan) y2_interp = np.interp(x_common, new_x, new_y, left=np.nan, right=np.nan) cross_idx = np.where(np.diff(np.sign(y1_interp - y2_interp)))[0][0] cross_x = x_common[cross_idx] # 裁剪非重叠区段 x_keep1 = x[x < cross_x] y_keep1 = y[x < cross_x] x_keep2 = new_x[new_x > cross_x] y_keep2 = new_y[new_x > cross_x] # 拼接并归一化到0-1范围 xx = np.concatenate([x_keep1, x_keep2]) yy = np.concatenate([y_keep1, y_keep2]) xx = (xx - xx.min()) / (xx.max() - xx.min()) yy = (yy - yy.min()) / (yy.max() - yy.min()) # 绘制结果 plt.plot(xx, yy, '--') plt.xlim(0, 1) plt.ylim(0, 1) plt.show()
扩展说明
该交点裁剪逻辑不绑定抛物线函数,调整曲线类型、平移量、y轴偏移/缩放比例时都可以直接复用,适合批量生成不同参数的双底、双顶类模式图案,满足模式分析的数据集生成需求。
内容的提问来源于stack exchange,提问作者William Le
相关产品推荐
相关产品推荐

