detect——point_in_polygon

/******************实现功能:判断平面任一点是否在指定多边形内********************/

  1 #include <string>
  2 #include <vector>
  3 #include <math.h>
  4 #include <iostream>
  5 #include <fstream>
  6 #include <sstream>
  7 
  8 using namespace std;
  9 
 10 typedef struct { int x, y; } Point;
 11 
 12 //算法说明   file:///D:/ddb/相机标定/Point_In_Polygon.pdf
 13 // a Point is defined by its coordinates {int x, y;}
 14 //===================================================================
 15 
 16 // isLeft(): tests if a point is Left|On|Right of an infinite line.
 17 //    Input:  three points P0, P1, and P2
 18 //    Return: >0 for P2 left of the line through P0 and P1
 19 //            =0 for P2  on the line
 20 //            <0 for P2  right of the line
 21 //    See: Algorithm 1 "Area of Triangles and Polygons"
 22 
 23 inline int
 24 isLeft(Point P0, Point P1, Point P2)
 25 {
 26     return ((P1.x - P0.x) * (P2.y - P0.y)
 27         - (P2.x - P0.x) * (P1.y - P0.y));
 28 }
 29 
 30 //==================================================================
 31 // cn_PnPoly(): crossing number test for a point in a polygon
 32 //      Input:   P = a point,
 33 //               V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
 34 //      Return:  0 = outside, 1 = inside
 35 // This code is patterned after [Franklin, 2000]
 36 int
 37 cn_PnPoly(Point P, Point* V, int n)
 38 {
 39     int    cn = 0;    // the  crossing number counter
 40 
 41                       // loop through all edges of the polygon
 42     for (int i = 0; i < n; i++)
 43     {    
 44         // edge from V[i]  to V[i+1]
 45         if (((V[i].y <= P.y) && (V[i + 1].y > P.y))||((V[i].y > P.y) && (V[i + 1].y <= P.y)))  // an upward crossing
 46         { 
 47             // a downward crossing
 48             // compute  the actual edge-ray intersect x-coordinate
 49             float vt = (float)(P.y - V[i].y) / (V[i + 1].y - V[i].y);
 50             if (P.x < V[i].x + vt * (V[i + 1].x - V[i].x))                // P.x < intersect
 51                 ++cn;            // a valid crossing of y=P.y right of P.x
 52         }
 53     }
 54     return (cn & 1);    // 0 if even (out), and 1 if  odd (in)
 55 }
 56 
 57 // wn_PnPoly(): winding number test for a point in a polygon
 58 //      Input:   P = a point,
 59 //               V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
 60 //      Return:  wn = the winding number (=0 only when P is outside)
 61 int
 62 wn_PnPoly(Point P, Point* V, int n)
 63 {
 64     int    wn = 0;            // the  winding number counter
 65     // loop through all edges of the polygon
 66     for (int i = 0; i<n; i++) 
 67     {                    
 68         // edge from V[i] to  V[i+1]
 69         if (V[i].y <= P.y) 
 70         {         
 71             // start y <= P.y
 72             if (V[i + 1].y  > P.y)      // an upward crossing
 73                 if (isLeft(V[i], V[i + 1], P) > 0)  // P left of  edge
 74                     ++wn;            // have  a valid up intersect
 75         }
 76         else 
 77         {                        // start y > P.y (no test needed)
 78             if (V[i + 1].y <= P.y)     // a downward crossing
 79                 if (isLeft(V[i], V[i + 1], P) < 0)  // P right of  edge
 80                     --wn;            // have  a valid down intersect
 81         }
 82     }
 83     return wn;
 84 }
 85 
 86 
 87 int
 88 wn_PnPoly_ddb(Point& P, const std::vector<Point>& V)      // std::vector<Point>& V = vertex points of a polygon V[n + 1] with V[n] = V[0] ,  注意多一个点首尾相同
 89 {
 90     int wn = 0;            // the  winding number counter
 91     int n = V.size() - 1;                    // loop through all edges of the polygon
 92     for (int i = 0; i<n; i++)
 93     {
 94         // edge from V[i] to  V[i+1]
 95         if (V[i].y <= P.y)
 96         {
 97             // start y <= P.y
 98             if (V[i + 1].y  > P.y)      // an upward crossing
 99                 if (isLeft(V[i], V[i + 1], P) > 0)  // P left of  edge
100                     ++wn;            // have  a valid up intersect
101         }
102         else
103         {                        // start y > P.y (no test needed)
104             if (V[i + 1].y <= P.y)     // a downward crossing
105                 if (isLeft(V[i], V[i + 1], P) < 0)  // P right of  edge
106                     --wn;            // have  a valid down intersect
107         }
108     }
109     return wn;
110 }
111 
112 void
113 readImageROIpolygen(const std::string& path, std::vector<Point>& pointVec, int i)
114 {
115     char name[60];
116     string filename;
117     Point p2d;
118 
119     int length = sprintf(name, "%d%s", i + 1, "_ROI.txt");
120     filename = path + "/" + name;
121     ifstream infile(filename);
122 
123     string Fline;
124     if (infile) // 有该文件  
125     {
126         while (getline(infile, Fline)) // Fline中不包括每行的换行符  
127         {
128             //cout << Fline << endl;
129             string buf;
130             stringstream ss(Fline);  // 字符流ss 
131             vector<string> tokens;  // vector
132 
133             // 按照逗号分隔 
134             while (getline(ss, buf, ','))
135             {
136                 tokens.push_back(buf);
137             }
138 
139             ////stringstream  按空格分开字符输入 
140             //while (ss >> buf)        
141             //{
142             //    tokens.push_back(buf);
143             //}
144 
145             if (tokens.size()<1)
146             {
147                 continue;
148             }
149             else if (tokens.size() == 2)
150             {
151                 int j = 0;
152                 p2d.x = atof(tokens[j].c_str());   //根据字段顺序做修改   对应图像 u v
153                 j++;
154                 p2d.y = atof(tokens[j].c_str());
155                 pointVec.push_back(p2d);
156             }
157         }
158         pointVec.push_back(pointVec[0]);
159         //std::cout << i << endl;
160     }
161     else // 没有该文件  
162     {
163         cout << "error::  no such file" << endl;
164     }
165     infile.close();
166     
167 }
168 
169 /**************** Test ****************/
170 void 
171 main()
172 {
173     Point detectPoint;
174     detectPoint.x = 2653; //1363, 1260   //2896,2276   //2653,390
175     detectPoint.y = 390;
176     std::string path="矫正后图像";
177 
178     std::vector<Point> pointVec;
179     readImageROIpolygen(path, pointVec,0);
180     if (pointVec.size()==0)
181     {
182         cout << "no ROI!!!" << endl;
183         return;    
184     }
185 
186     if (wn_PnPoly_ddb(detectPoint, pointVec) == 0)
187     {
188         cout << "detectPoint outside ImageROIpolygen!!!!" << endl;
189     }
190     else
191     {
192         cout << "detectPoint in ImageROIpolygen!!!!" << endl;
193     }
194     
195     system("pause");
196 }
原文地址:https://www.cnblogs.com/lovebay/p/9529530.html