码迷,mamicode.com
首页 > 其他好文 > 详细

线性差值法结构类(面向对象的方式)

时间:2018-06-29 01:20:33      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:gen   ast   class   sele   name   length   generic   ati   HERE   

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication7
{
    public enum PointState
    {
        Inner = 0,//定义域的点
        Mid = 1,//未超出定义域的点
        LeftOuter = 2,//超出左侧
        RightOuter = 3//超出右侧
    }
    public class Point
    {
        public Point Left;
        public Point Right;
        public double x { get; set; }
        public double y { get; set; }

        public PointState state { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            double[] xarr = new double[] { 7 }; //{ 7, 9, 5, 13, 11 ,14,  15, 16,17,18,19,20,21,22,23,24,25,26,27,28};

            double[] yarr = new double[] { 4 }; //{ 4, 9, 10, 12, 15, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 };
            //求解的点
            double[] x1arr = new double[] { 1, 2, 3, 4, 6, 8, 11, 13, 14, 16, 17 };
            double[] y1arr;
            var pointDictionary = LineDifferenceMethod(xarr, yarr, x1arr, out y1arr, true);
            Console.Read();
        }
        /// <summary>
        /// 线性差值法
        /// </summary>
        /// <param name="xarr">原始数据x轴</param>
        /// <param name="yarr">原始数据y轴</param>
        /// <param name="x1arr">求解的x轴的点的数组</param>
        /// <param name="extension">边缘点是否使用斜率延伸</param>
        /// <returns></returns>
        public static Dictionary<double, Point> LineDifferenceMethod(double[] xarr, double[] yarr, double[] x1arr, out double[] y1arr, bool extension = false)
        {
            List<Point> points = new List<Point>();
            List<double> xarrcopy = xarr.OrderBy(x => x).ToList();
            for (int i = 0; i < xarr.Length; i++)
            {
                Point p = new Point();
                p.x = xarr[i];
                p.y = yarr[i];
                p.state = PointState.Inner;
                points.Add(p);
            }
            if (points.Count == 1)
            {
                for (int i = 0; i < x1arr.Length; i++)
                {
                    Point p = new Point();
                    p.x = x1arr[i];
                    p.y = yarr[0];
                    if (p.x != xarr[0])
                    {
                        if (p.x < xarr[0])
                        {
                            p.state = PointState.LeftOuter;
                        }
                        else if (p.x > xarr[0])
                        {
                            p.state = PointState.RightOuter;
                        }
                        points.Add(p);
                    }

                }
                y1arr = points.ToDictionary(p => p.x).Select(p => p.Value.y).ToArray();
                return points.ToDictionary(p => p.x);
            }

            Point firstPoint = points.OrderBy(p => p.x).ToArray().FirstOrDefault();
            Point lastPoint = points.OrderBy(p => p.x).ToArray().LastOrDefault();
            Dictionary<double, Point> pointDict = points.ToDictionary(p => p.x);
            for (int i = 0; i < x1arr.Length; i++)
            {
                Point p = new Point();
                double qx = x1arr[i];
                p.x = qx;
                p.y = 0;
                if (qx < xarrcopy[0])
                {
                    p.state = PointState.LeftOuter;

                }
                else if (qx > xarrcopy[xarrcopy.Count - 1])
                {
                    p.state = PointState.RightOuter;
                }
                else if (pointDict.ContainsKey(qx))
                {
                    //内部点不用求了
                    p = pointDict[qx];
                    continue;
                }
                else
                {
                    p.state = PointState.Mid;
                }
                points.Add(p);

            }
            points = points.OrderBy(p => p.x).ToList();

            for (int i = 0; i < points.Count; i++)
            {

                Point p = points[i];
                if (i == 0)
                {
                    p.Left = null;
                    if (points.Count > 1)
                    {
                        p.Right = points[i + 1];
                    }
                    else
                    {
                        p.Right = null;
                    }

                }
                else if (i == points.Count - 1)
                {
                    p.Right = null;
                    if (points.Count > 1)
                    {
                        p.Left = points[i - 1];
                    }
                    else
                    {
                        p.Right = null;
                    }
                }
                else if (i > 0 && i < points.Count - 1)
                {
                    p.Left = points[i - 1];
                    p.Right = points[i + 1];
                }

            }
            foreach (var item in points)
            {
                if (item.state == PointState.Mid)
                {
                    var right = item.Right;
                    var left = item.Left;
                    AdjustLeftRight(ref right, ref left, item);

                }
                else if (item.state == PointState.LeftOuter)
                {

                    if (!extension)
                    {
                        item.y = firstPoint.y;
                    }
                    else
                    {
                        var right = firstPoint.Right;
                        var left = firstPoint;
                        AdjustLeftRight(ref right, ref left, item);



                    }
                }
                else if (item.state == PointState.RightOuter)
                {
                    if (!extension)
                    {
                        item.y = lastPoint.y;
                    }
                    else
                    {
                        var right = lastPoint;
                        var left = lastPoint.Left;
                        AdjustLeftRight(ref right, ref left, item);


                    }
                }
            }
            pointDict = points.ToDictionary(p => p.x);
            y1arr = pointDict.Where(p => x1arr.Contains(p.Key)).Select(x => x.Value.y).ToArray();
            return pointDict;

        }

        private static void AdjustLeftRight(ref Point right, ref Point left, Point item)
        {
            while (right.state != PointState.Inner)
            {
                right = right.Right;
            }
            while (left.state != PointState.Inner)
            {
                left = left.Left;
            }
            double k = (right.y - left.y) / (right.x - left.x);//斜率
            item.y = left.y + k * (item.x - left.x);
        }
    }
}

 

线性差值法结构类(面向对象的方式)

标签:gen   ast   class   sele   name   length   generic   ati   HERE   

原文地址:https://www.cnblogs.com/kexb/p/9241474.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!