c#版点在面内算法

 

 

 

点在面算法,就是放射线算法,原理很简单,就是把一个点向任意方向发射(本程序是向下),如果跟这个面有奇数个交点,证明点在面里面,若是偶数个,则是在外面(包括0),算法主要是优化效率。本人水平有限,算法中肯定有不足之处,请大家海涵!

主要函数如下。

1.   struct TabPoint
2.    {
3.        private double x;
4.        public double X
5.        {
6.            get { return x; }
7.            set { x = value; }
8.        }
9.
10.        private double y;
11.        public double Y
12.        {
13.            get { return y; }
14.            set { y = value; }
15.        }
16.    }
17.
18.    struct Polygon
19.    {
20.        public ArrayList pointsArray;
21.        private double minx;
22.        public double MinX
23.        {
24.            get { return minx; }
25.            set { minx = value; }
26.        }
27.
28.        private double miny;
29.        public double MinY
30.        {
31.            get { return miny; }
32.            set { miny = value; }
33.        }
34.
35.        private double maxx;
36.        public double MaxX
37.        {
38.            get { return maxx; }
39.            set { maxx = value; }
40.        }
41.
42.        private double maxy;
43.        public double MaxY
44.        {
45.            get { return maxy; }
46.            set { maxy = value; }
47.        }
48.    }
49.
50.    class Analyse
51.    {
52.        private readonly double dis = 0.0000000001; 
53.
54.        //返回值:true点在面内  false点在面外 
55.        public bool JudgeMeetPoint(TabPoint tpt, ArrayList polygonPtArray)
56.        {
57.
58.            int MeetPointNum = 0;
59.
60.            int PolygonPtSize = polygonPtArray.Count;
61.            for (int k = 1; k < PolygonPtSize; k++)
62.            {
63.                TabPoint pt1 = (TabPoint)polygonPtArray[k - 1];
64.                TabPoint pt2 = (TabPoint)polygonPtArray[k];
65.
66.                if (((tpt.X <= pt1.X && tpt.X >= pt2.X) ||
67.                    (tpt.X >= pt1.X && tpt.X <= pt2.X)) &
68.                     (tpt.Y >= pt1.Y || tpt.Y >= pt2.Y) &
69.                     (pt1.X != pt2.X && pt1.Y != pt2.Y))
70.                {
71.                    //判断点是否在线上 
72.                    if (JudgePtInLine(pt1, pt2, tpt))
73.                    {
74.                        return true;
75.                    }
76.
77.                    //处理特殊情况,交点是端点的情况 
78.                    double temp;
79.                    //temp相当于被除数(斜率的分母)
80.                    temp = pt1.X - pt2.X;
81.                    if (temp >= -dis && temp <= dis)
82.                    {
83.                        //处理交点情况 
84.                        double dx = tpt.X - pt1.X;
85.                        if (dx >= -dis && dx <= dis)
86.                        {
87.                            int[] indexs = new int[2];
88.                            indexs[0] = 0;
89.                            indexs[1] = 0;
90.                            GetNotSame(polygonPtArray, k, ref indexs);
91.                            TabPoint linePt1, linePt2;
92.                            linePt1 = (TabPoint)polygonPtArray[indexs[0]];
93.                            linePt2 = (TabPoint)polygonPtArray[indexs[1]];
94.                            if (k > indexs[0])
95.                            {
96.                                break;
97.                            }
98.                            else
99.                            {
100.                                k = indexs[0] + 1;
101.                            }
102.                            if (tpt.Y > pt1.Y && ((tpt.X >= linePt1.X && tpt.X <= linePt2.X) ||
103.                                (tpt.X >= linePt2.X && tpt.X <= linePt1.X)))
104.                                MeetPointNum++;
105.                        }
106.                    }
107.                    else
108.                    {
109.                        double kk, bb;
110.                        double MeetPtY, MeetPtX;
111.                        kk = (pt1.Y - pt2.Y) / (pt1.X - pt2.X);
112.                        bb = pt1.Y - kk * pt1.X;
113.                        MeetPtY = kk * tpt.X + bb;
114.                        MeetPtX = tpt.X;
115.                        //处理特殊情况,交点是端点的情况 
116.                        double dx, dy, dx2, dy2;
117.                        dx = MeetPtX - pt1.X;
118.                        dy = MeetPtY - pt1.Y;
119.                        dx2 = MeetPtX - pt2.X;
120.                        dy2 = MeetPtY - pt2.Y;
121.                        if ((dx >= -dis && dx <= dis && dy >= -dis
122.                            && dy <= dis))
123.                        {
124.                            TabPoint pt3;
125.                            if (k == 1)
126.                            {
127.                                pt3 = (TabPoint)polygonPtArray[PolygonPtSize - 2];
128.                            }
129.                            else
130.                            {
131.                                pt3 = (TabPoint)polygonPtArray[k - 2];
132.                            }
133.                            //提取交点的上下两点分别在垂线的两侧 
134.                            if (tpt.Y > MeetPtY && ((MeetPtX >= pt3.Y && MeetPtX <= pt2.X) ||
135.                                (MeetPtX >= pt2.X && MeetPtX <= pt3.X)))
136.                                MeetPointNum++;
137.                        }
138.                        else if (!(dx2 >= -dis && dx2 <= dis && dy2 >= -dis
139.                                    && dy2 <= dis))
140.                        {
141.                            if (tpt.Y > MeetPtY)
142.                                MeetPointNum++;
143.                        }
144.                    }
145.                }
146.            }
147.
148.            if (MeetPointNum % 2 == 1)
149.                return true;
150.            else
151.                return false;
152.        }
153.        //判断点是否在线上 
154.        private bool JudgePtInLine(TabPoint tpt1, TabPoint tpt2, TabPoint tpt)
155.        {
156.            double dx1 = GetDistance(tpt1, tpt2);
157.            double dx2 = GetDistance(tpt, tpt1);
158.            double dx3 = GetDistance(tpt, tpt2);
159.            double dx = dx3 + dx2 - dx1;
160.
161.            if (dx >= -0.0000000001 && dx <= 0.0000000001)
162.            {
163.                return true;
164.            }
165.            return false;
166.        }
167.        //求取两点之间的距离 
168.        private double GetDistance(TabPoint tpt1, TabPoint tpt2)
169.        {
170.            double x = tpt1.X - tpt2.X;
171.            if (x <= 0)
172.            {
173.                x = -x;
174.            }
175.            double y = tpt1.Y - tpt2.Y;
176.            if (y <= 0)
177.            {
178.                y = -y;
179.            }
180.
181.            return System.Math.Sqrt(x * x + y * y);
182.        }
183.        //在链表中获取x轴不相同的点 
184.        private void GetNotSame(ArrayList pointArray, int index, ref int[] indexs)
185.        {
186.            indexs[0] = indexs[1] = -1;
187.            int size = pointArray.Count;
188.            TabPoint buftpt, tpt;
189.            tpt = (TabPoint)pointArray[index];
190.
191.            for (int i = index; i < size; i++)
192.            {
193.                buftpt = (TabPoint)pointArray[i];
194.                if (buftpt.X != tpt.X)
195.                {
196.                    indexs[0] = i;
197.                    break;
198.                }
199.            }
200.
201.            if (indexs[0] == -1)
202.            {
203.                for (int i = 0; i < size; i++)
204.                {
205.                    buftpt = (TabPoint)pointArray[i];
206.                    if (buftpt.X != tpt.X)
207.                    {
208.                        indexs[0] = i;
209.                        break;
210.                    }
211.                }
212.            }
213.
214.
215.            for (int j = index; j >= 0; j--)
216.            {
217.                buftpt = (TabPoint)pointArray[j];
218.                if (buftpt.X != tpt.X)
219.                {
220.                    indexs[1] = j;
221.                    break;
222.                }
223.            }
224.            if (indexs[1] == -1)
225.            {
226.                for (int j = size - 1; j >= 0; j--)
227.                {
228.                    buftpt = (TabPoint)pointArray[j];
229.                    if (buftpt.X != tpt.X)
230.                    {
231.                        indexs[1] = j;
232.                        break;
233.                    }
234.                }
235.            }
236.        }
237.
238.        public bool JudgeInRect(TabPoint minPt,TabPoint maxPt,TabPoint pt)
239.        {
240.            if (pt.X >= minPt.X && pt.X <= maxPt.X && pt.Y >= minPt.Y && pt.Y <= maxPt.Y)
241.            {
242.                return true;
243.            }
244.            else
245.            {
246.                return false;
247.            }
248.        }

 

 

 

 

 

你可能感兴趣的:(c#版点在面内算法)