lixiaojun
2023-11-24 bd2c0ed221e235420c7fdffefa1cdfa085529a0a
Yw.CurveBase.Core/7-fit/FitHelper.cs
@@ -160,5 +160,103 @@
            }
        }
        #region 获得X值
        /// <summary>
        /// 获取线性插值X(可能有多个点)
        /// </summary>
        public static List<CurvePoint> GetInterPointX(List<CurvePoint> pts, double y)
        {
            if (pts == null || pts.Count < 2)
            {
                return default;
            }
            var list = new List<CurvePoint>();
            for (int i = 0; i < pts.Count - 1; i++)
            {
                if ((y >= pts[i].Y && y <= pts[i + 1].Y) || (y <= pts[i].Y && y >= pts[i + 1].Y))
                {//直线插值
                    double x;
                    if (Math.Abs(pts[i].Y - pts[i + 1].Y) < 0.01)
                        x = (pts[i].X + pts[i + 1].X) * 0.5;
                    else
                        x = pts[i].X + (pts[i + 1].X - pts[i].X) * (y - pts[i].Y) / (pts[i + 1].Y - pts[i].Y);
                    list.Add(new CurvePoint(x, y));
                }
            }
            return list;
        }
        /// <summary>
        /// 获取线性插值X(可能有多个点)(允许延长)
        /// </summary>
        public static List<CurvePoint> GetInterPointXByExtend(List<CurvePoint> pts, double y)
        {
            if (pts == null || pts.Count < 2)
            {
                return default;
            }
            //在范围内
            var minY = pts.Min(x => x.Y);
            var maxY = pts.Max(x => x.Y);
            if (y >= minY && y <= maxY)
            {
                return GetInterPointX(pts, y);
            }
            var list = new List<CurvePoint>();
            //判断是否在前面的延长部分
            double x_start = CurveLineHelper.GetXbyY(pts[0].X, pts[0].Y, pts[1].X, pts[1].Y, y);
            if (x_start <= pts[0].X)
            {
                if (x_start > 0 && x_start > pts[0].X * 0.9)//放一点余量
                {
                    list.Add(new CurvePoint(x_start, y));
                }
            }
            //判断是否在后面的延长部分:U型曲线 是前后都有
            double x_end = CurveLineHelper.GetXbyY(pts[pts.Count - 2].X, pts[pts.Count - 2].Y, pts[pts.Count - 1].X, pts[pts.Count - 1].Y, y);
            if (x_end >= pts[pts.Count - 1].X && x_end < pts[pts.Count - 1].X * 1.1)//放一点余量
            {
                list.Add(new CurvePoint(x_end, y));
            }
            return list;
        }
        /// <summary>
        /// 获取线性插值X(可能有多个点)
        /// </summary>
        public static List<CurvePoint> GetInterPointX(CurveExpress express, double y, int pointNumber = 20, double extendRatio = 1.0)
        {
            if (express == null)
            {
                return default;
            }
            var pts = express.GetFitPointsByXRange(express.Min, express.Max * extendRatio, pointNumber);
            return GetInterPointX(pts, y);
        }
        /// <summary>
        /// 获取线性插值X(可能有多个点)(允许延长)
        /// </summary>
        public static List<CurvePoint> GetInterPointXByExtend(CurveExpress express, double y, int pointNumber = 20, double extendRatio = 1.2)
        {
            if (express == null)
            {
                return default;
            }
            var pts = express.GetFitPointsByXRange(express.Min, express.Max * extendRatio, pointNumber);
            return GetInterPointXByExtend(pts, y);
        }
        #endregion 获得X值
    }
}