點在面內的算法

放射線算法,就是把一個點向任意方向發射(本程序是向下),如果跟這個面有奇數個交點,證明點在面裏面,若是偶數個,則是在外面(包括0), 

struct TabPoint 
    { 
        private double x; 
        public double X 
        { 
            get { return x; } 
            set { x = value; } 
        } 
        private double y; 
        public double Y 
        { 
            get { return y; } 
            set { y = value; } 
        } 
    } 
    struct Polygon 
    { 
        public ArrayList pointsArray; 
        private double minx; 
        public double MinX 
        { 
            get { return minx; } 
            set { minx = value; } 
        } 
        private double miny; 
        public double MinY 
        { 
            get { return miny; } 
            set { miny = value; } 
        } 
        private double maxx; 
        public double MaxX 
        { 
            get { return maxx; } 
            set { maxx = value; } 
        } 
        private double maxy; 
        public double MaxY 
        { 
            get { return maxy; } 
            set { maxy = value; } 
        } 
    } 
    class Analyse 
    { 
        private readonly double dis = 0.0000000001;  
        //返回值:true點在面內  false點在面外 
        public bool JudgeMeetPoint(TabPoint tpt, ArrayList polygonPtArray) 
        { 
            int MeetPointNum = 0; 
            int PolygonPtSize = polygonPtArray.Count; 
            for (int k = 1; k < PolygonPtSize; k++) 
            { 
                TabPoint pt1 = (TabPoint)polygonPtArray[k - 1]; 
                TabPoint pt2 = (TabPoint)polygonPtArray[k]; 
                if (((tpt.X <= pt1.X && tpt.X >= pt2.X) || 
                    (tpt.X >= pt1.X && tpt.X <= pt2.X)) & 
                     (tpt.Y >= pt1.Y || tpt.Y >= pt2.Y) & 
                     (pt1.X != pt2.X && pt1.Y != pt2.Y)) 
                { 
                    //判斷點是否在線上 
                    if (JudgePtInLine(pt1, pt2, tpt)) 
                    { 
                        return true; 
                    } 
                    //處理特殊情況,交點是端點的情況 
                    double temp; 
                    //temp相當於被除數(斜率的分母) 
                    temp = pt1.X - pt2.X; 
                    if (temp >= -dis && temp <= dis) 
                    { 
                        //處理交點情況 
                        double dx = tpt.X - pt1.X; 
                        if (dx >= -dis && dx <= dis) 
                        { 
                            int[] indexs = new int[2]; 
                            indexs[0] = 0; 
                            indexs[1] = 0; 
                            GetNotSame(polygonPtArray, k, ref indexs); 
                            TabPoint linePt1, linePt2; 
                            linePt1 = (TabPoint)polygonPtArray[indexs[0]]; 
                            linePt2 = (TabPoint)polygonPtArray[indexs[1]]; 
                            if (k > indexs[0]) 
                            { 
                                break; 
                            } 
                            else 
                            { 
                                k = indexs[0] + 1; 
                            } 
                            if (tpt.Y > pt1.Y && ((tpt.X >= linePt1.X && tpt.X <= linePt2.X) || 
                                (tpt.X >= linePt2.X && tpt.X <= linePt1.X))) 
                                MeetPointNum++; 
                        } 
                    } 
                    else 
                    { 
                        double kk, bb; 
                        double MeetPtY, MeetPtX; 
                        kk = (pt1.Y - pt2.Y) / (pt1.X - pt2.X); 
                        bb = pt1.Y - kk * pt1.X; 
                        MeetPtY = kk * tpt.X + bb; 
                        MeetPtX = tpt.X; 
                        //處理特殊情況,交點是端點的情況 
                        double dx, dy, dx2, dy2; 
                        dx = MeetPtX - pt1.X; 
                        dy = MeetPtY - pt1.Y; 
                        dx2 = MeetPtX - pt2.X; 
                        dy2 = MeetPtY - pt2.Y; 
                        if ((dx >= -dis && dx <= dis && dy >= -dis 
                            && dy <= dis)) 
                        { 
                            TabPoint pt3; 
                            if (k == 1) 
                            { 
                                pt3 = (TabPoint)polygonPtArray[PolygonPtSize - 2]; 
                            } 
                            else 
                            { 
                                pt3 = (TabPoint)polygonPtArray[k - 2]; 
                            } 
                            //提取交點的上下兩點分別在垂線的兩側 
                            if (tpt.Y > MeetPtY && ((MeetPtX >= pt3.Y && MeetPtX <= pt2.X) || 
                                (MeetPtX >= pt2.X && MeetPtX <= pt3.X))) 
                                MeetPointNum++; 
                        } 
                        else if (!(dx2 >= -dis && dx2 <= dis && dy2 >= -dis 
                                    && dy2 <= dis)) 
                        { 
                            if (tpt.Y > MeetPtY) 
                                MeetPointNum++; 
                        } 
                    } 
                } 
            } 
            if (MeetPointNum % 2 == 1) 
                return true; 
            else 
                return false; 
        } 
        //判斷點是否在線上 
        private bool JudgePtInLine(TabPoint tpt1, TabPoint tpt2, TabPoint tpt) 
        { 
            double dx1 = GetDistance(tpt1, tpt2); 
            double dx2 = GetDistance(tpt, tpt1); 
            double dx3 = GetDistance(tpt, tpt2); 
            double dx = dx3 + dx2 - dx1; 
            if (dx >= -0.0000000001 && dx <= 0.0000000001) 
            { 
                return true; 
            } 
            return false; 
        } 
        //求取兩點之間的距離 
        private double GetDistance(TabPoint tpt1, TabPoint tpt2) 
        { 
            double x = tpt1.X - tpt2.X; 
            if (x <= 0) 
            { 
                x = -x; 
            } 
            double y = tpt1.Y - tpt2.Y; 
            if (y <= 0) 
            { 
                y = -y; 
            } 
            return System.Math.Sqrt(x * x + y * y); 
        } 
        //在鏈表中獲取x軸不相同的點 
        private void GetNotSame(ArrayList pointArray, int index, ref int[] indexs) 
        { 
            indexs[0] = indexs[1] = -1; 
            int size = pointArray.Count; 
            TabPoint buftpt, tpt; 
            tpt = (TabPoint)pointArray[index]; 
            for (int i = index; i < size; i++) 
            { 
                buftpt = (TabPoint)pointArray; 
                if (buftpt.X != tpt.X) 
                { 
                    indexs[0] = i; 
                    break; 
                } 
            } 
            if (indexs[0] == -1) 
            { 
                for (int i = 0; i < size; i++) 
                { 
                    buftpt = (TabPoint)pointArray; 
                    if (buftpt.X != tpt.X) 
                    { 
                        indexs[0] = i; 
                        break; 
                    } 
                } 
            } 

            for (int j = index; j >= 0; j--) 
            { 
                buftpt = (TabPoint)pointArray[j]; 
                if (buftpt.X != tpt.X) 
                { 
                    indexs[1] = j; 
                    break; 
                } 
            } 
            if (indexs[1] == -1) 
            { 
                for (int j = size - 1; j >= 0; j--) 
                { 
                    buftpt = (TabPoint)pointArray[j]; 
                    if (buftpt.X != tpt.X) 
                    { 
                        indexs[1] = j; 
                        break; 
                    } 
                } 
            } 
        } 
        public bool JudgeInRect(TabPoint minPt,TabPoint maxPt,TabPoint pt) 
        { 
            if (pt.X >= minPt.X && pt.X <= maxPt.X && pt.Y >= minPt.Y && pt.Y <= maxPt.Y) 
            { 
                return true; 
            } 
            else 
            { 
                return false; 
            } 
        } 
    }

發佈了12 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章