lixiaojun
2023-11-02 cee1c6bf2c5c03c0beadcc9c8f720b03589f83a3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
namespace Yw.Curve
{
    public static class CurvePoint_Extensions
    {
 
        /// <summary>
        /// 计算总长度
        /// </summary>
        public static double CalcuTotalLength(this List<CurvePoint> ptList)
        {
            if (ptList == null || ptList.Count < 1)
            {
                return default;
            }
            double length = 0;
            for (int i = 1; i < ptList.Count; i++)
            {
                length += ptList[i].Distance(ptList[i - 1]);
            }
            return length;
        }
 
        /// <summary>
        /// 获取Y最小的点
        /// </summary>
        public static CurvePoint GetPointByMinY(this List<CurvePoint> ptList)
        {
            if (ptList == null || ptList.Count < 1)
            {
                return default;
            }
            return ptList.OrderBy(x => x.Y).FirstOrDefault();
        }
 
        /// <summary>
        /// 获取Y最大的点
        /// </summary>
        public static CurvePoint GetPointByMaxY(this List<CurvePoint> ptList)
        {
            if (ptList == null || !ptList.Any())
            {
                return default;
            }
            return ptList.OrderBy(x => x.Y).LastOrDefault();
        }
 
        /// <summary>
        /// 获取Y最小的点索引
        /// </summary>
        public static int GetPointIndexByMinY(this List<CurvePoint> ptList)
        {
            var pt = GetPointByMinY(ptList);
            return ptList.IndexOf(pt);
        }
 
        /// <summary>
        /// 获取Y最大的点索引
        /// </summary>
        public static int GetPointIndexByMaxY(this List<CurvePoint> ptList)
        {
            var pt = GetPointByMaxY(ptList);
            return ptList.IndexOf(pt);
        }
 
        /// <summary>
        /// 根据X 获取点索引
        /// </summary>
        public static int GetPointIndexByX(this List<CurvePoint> ptList, double x)
        {
            if (ptList == null || !ptList.Any())
            {
                return -1;
            }
            int index = 0;
            foreach (var pt in ptList)
            {
                if (Math.Abs(pt.X - x) < 0.0001)
                {
                    return index;
                }
                index++;
            }
            return -1;
        }
 
        /// <summary>
        /// 获取X方向距离最小的点
        /// </summary>
        public static CurvePoint GetClosestPointByX(this List<CurvePoint> ptList, double x)
        {
            if (ptList == null || ptList.Count < 1)
            {
                return default;
            }
            var pt = ptList.OrderBy(t => Math.Abs(t.X - x)).FirstOrDefault();
            return pt;
        }
 
        /// <summary>
        /// 获取X方向距离最小的点索引
        /// </summary>
        public static int GetClosestPointIndexByX(this List<CurvePoint> ptList, double x)
        {
            var pt = GetClosestPointByX(ptList, x);
            return ptList.IndexOf(pt);
        }
 
        /// <summary>
        /// 获得X值的坐标位置,可能有多个点(是线形插值,不是曲线上的点)
        /// </summary>
        public static List<double> GetInterPointY(this List<CurvePoint> ptList, double x)
        {
            if (ptList == null || ptList.Count < 1)
            {
                return default;
            }
            var list = ptList.ToList();
            var equalPoints = new List<double>();
            int num = ptList.Count;
            for (int i = 0; i < num - 1; i++)//少一个点
            {
                if ((x >= list[i].X && x <= list[i + 1].X) || (x <= list[i].X && x >= list[i + 1].X))
                {//直线插值
                    double y;
                    if (Math.Abs(list[i].X - list[i + 1].X) < 0.01)
                        y = (list[i].Y + list[i + 1].Y) * 0.5;
                    else
                        y = list[i].Y + (list[i + 1].Y - list[i].Y) * (x - list[i].X) / (list[i + 1].X - list[i].X);
 
                    equalPoints.Add(y);
                }
            }
            return equalPoints;
        }
 
        /// <summary>
        /// ptList 是一个多边形,判断点是否在多边形里
        /// 原理是 通过p做一个+X方向的射线, 偶数个交点 就是在外部,奇数个就是在内部
        /// </summary>
        public static bool IsInPolygon(this IEnumerable<CurvePoint> ptList, CurvePoint p, bool isClosed = true)
        {
            if (ptList == null || ptList.Count() < 1)
                return default;
            var list = ptList.ToList();
            int crossNum = 0;
 
            for (int i = 0; i < list.Count() - 1; i++)
            {
                if (p.IsIntersectLineLeft(list[i], list[i + 1]))
                {
                    crossNum++;
                }
            }
 
            if (isClosed)
            {
                if (p.IsIntersectLineLeft(list[list.Count - 1], list[0]))
                {
                    crossNum++;
                }
            }
 
            if ((crossNum % 2) == 0)
                return false;
            else
                return true;
        }
 
 
 
    }
}