下面的源代码应该找到两条曲线之间的交点。
但是,该函数无法检测交点。
我该如何修复它?
using MathNet.Numerics.Interpolation;
using System.Collections.Generic;
using System.Linq;
public static Vec2 FindIntersectionOfTwoCurves(List<double> xList1, List<double> yList1,
List<double> xList2, List<double> yList2)
{
if (xList1 == null || yList1 == null || xList2 == null || yList2 == null ||
xList1.Count != yList1.Count || xList2.Count != yList2.Count)
return null;
IInterpolation interpolation1 = Interpolate.Linear(xList1, yList1);
IInterpolation interpolation2 = Interpolate.Linear(xList2, yList2);
double lowerBound = Math.Max(xList1.Min(), xList2.Min());
double upperBound = Math.Min(xList1.Max(), xList2.Max());
double step = (upperBound - lowerBound) / 1000; // adjust the step size as needed
for (double x = lowerBound; x <= upperBound; x += step)
{
double y1 = interpolation1.Interpolate(x);
double y2 = interpolation2.Interpolate(x);
if (Math.Abs(y1 - y2) < 1e-7)
{
return new Vec2(x, y1);
}
}
return null;
}
public class Vec2
{
public double X { get; set; }
public double Y { get; set; }
public Vec2(double x, double y)
{
X = x;
Y = y;
}
}
由于您试图找到两条曲线与非连续一阶导数的交点,因此您应该使用二分法。
一个快速编写的C#实现如下,二分查找的实现来自这里,如果是线性间隔的,二分查找可以用更简单的线性插值代替
X
。这个小小的改变可以解决你的问题。不要注意
Math.Abs(y1 - y2)
小于某个 epsilon(例如1e-7
)。相反,请注意 的符号y1 - y2
发生变化,以便它与之前的迭代不同。这就是所谓的寻找零交叉点。例如: