1 // Copyright 2000 softSurfer, 2012 Dan Sunday 2 // This code may be freely used and modified for any purpose 3 // providing that this copyright notice is included with it. 4 // SoftSurfer makes no warranty for this code, and cannot be held 5 // liable for any real or imagined damage resulting from its use. 6 // Users of this code must verify correctness for their application. 7 // a Point is defined by its coordinates {int x, y;} 8 //=================================================================== 9 // isLeft(): tests if a point is Left|On|Right of an infinite line. 10 判断P2点在直线上(P0,P1) 11 // Input: three points P0, P1, and P2 12 // Return: >0 for P2 left of the line through P0 and P1 13 // =0 for P2 on the line 14 // <0 for P2 right of the line 15 // See: Algorithm 1 "Area of Triangles and Polygons" 16 inline int isLeft( Point P0, Point P1, Point P2 ) 17 { 18 return ( (P1.x - P0.x) * (P2.y - P0.y) 19 - (P2.x - P0.x) * (P1.y - P0.y) ); 20 } 21 //=================================================================== 22 射线法判断点在多边形内 23 // cn_PnPoly(): crossing number test for a point in a polygon 24 // Input: P = a point, 25 // V[] = vertex points of a polygon V[n+1] with V[n]=V[0] 26 // Return: 0 = outside, 1 = inside 27 // This code is patterned after [Franklin, 2000] 28 int cn_PnPoly( Point P, Point* V, int n ) 29 { 30 int cn = 0; // the crossing number counter 31 32 // loop through all edges of the polygon 33 for (int i=0; i<n; i++) { // edge from V[i] to V[i+1] 34 if (((V[i].y <= P.y) && (V[i+1].y > P.y)) // an upward crossing 35 || ((V[i].y > P.y) && (V[i+1].y <= P.y))) { // a downward crossing 36 // compute the actual edge-ray intersect x-coordinate 37 float vt = (float)(P.y - V[i].y) / (V[i+1].y - V[i].y); 38 if (P.x < V[i].x + vt * (V[i+1].x - V[i].x)) // P.x < intersect 39 ++cn; // a valid crossing of y=P.y right of P.x 40 } 41 } 42 return (cn&1); // 0 if even (out), and 1 if odd (in) 43 44 } 45 //=================================================================== 46 47 // wn_PnPoly(): winding number test for a point in a polygon 48 // Input: P = a point, 49 // V[] = vertex points of a polygon V[n+1] with V[n]=V[0] 50 // Return: wn = the winding number (=0 only when P is outside) 51 int wn_PnPoly( Point P, Point* V, int n ) 52 { 53 int wn = 0; // the winding number counter 54 55 // loop through all edges of the polygon 56 for (int i=0; i<n; i++) { // edge from V[i] to V[i+1] 57 if (V[i].y <= P.y) { // start y <= P.y 58 if (V[i+1].y > P.y) // an upward crossing 59 if (isLeft( V[i], V[i+1], P) > 0) // P left of edge 60 ++wn; // have a valid up intersect 61 } 62 else { // start y > P.y (no test needed) 63 if (V[i+1].y <= P.y) // a downward crossing 64 if (isLeft( V[i], V[i+1], P) < 0) // P right of edge 65 --wn; // have a valid down intersect 66 } 67 } 68 return wn; 69 } 70 //===================================================================