O código-fonte abaixo deve encontrar uma interseção entre duas curvas.
No entanto, a função não consegue detectar o ponto de intersecção.
Como posso consertar isso?
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;
}
}
como você está tentando encontrar uma interseção de duas curvas com uma primeira derivada não contínua, você deve usar o método Bisection .
uma implementação C# escrita rapidamente é a seguinte, a implementação da pesquisa binária é daqui , a pesquisa binária pode ser substituída por uma interpolação linear mais simples se
X
for linearmente espaçada.Esta pequena mudança pode resolver seu problema. Não espere que
Math.Abs(y1 - y2)
seja menor que algum épsilon (por exemplo1e-7
). Em vez disso, observe o sinal dey1 - y2
mudança para que seja diferente da iteração anterior. Isso é chamado de procurar um cruzamento zero .Por exemplo: