#define max(x,y) ((x) > (y) ? (x) : (y)) #define min(x,y) ((x) < (y) ? (x) : (y)) #define ERROR 0.00000001 /* ZERO approximation * #define INSIDE 1 #define OUTSIDE 2 #define INTERSECT 3 /* position of point with respect to polygon. retruns INSIDE, OUTSIDE or INTERSECT cannot handle situations such that described in "Algorithms", R. Sedgewick, pp. 355 */ /* points: number of polygon's vertices point: array which holds the coordinates of the polygon's vertices p: the point we try to determine if it is inside, outside or on the polygon. struct POINT { float x,y; }; struct LINE_SEGMENT { struct POINT *p1, *p2; }; */ int point_to_polygon(p, point, points) POINT *p, *point; int points; { int i, active; POINT r, p1, p2, *pptr; LINE_SEGMENT horiz, line_seg; float x1, x2, y1, y2; float active_xs[MAXPOINTS]; p1.x = 0; p1.y = p->y; p2.x = MAXNUMBER; p2.y = p->y; horiz.p1 = &p1; horiz.p2 = &p2; active = 0; pptr = point; for (i = 0; i < points - 1; i++) { y1 = min(pptr->y, (pptr + 1)->y); y2 = max(pptr->y, (pptr + 1)->y); if (y1 < p->y && p->y <= y2) { line_seg.p1 = pptr; line_seg.p2 = pptr + 1; intersection(&horiz, &line_seg, &r); /* finds intersection point */ active++; active_xs[active - 1] = r.x; } pptr++; } if (active > 1) { sort(active_xs, active); /* sorts active_xs, active: array size */ for (i = 0; i < active - 1 ; i++) if (i%2 == 0) { x1 = min(active_xs[i], active_xs[i + 1]); x2 = max(active_xs[i], active_xs[i + 1]); if (ZERO(x1 - p->x) || ZERO(x2 - p->x)) return(INTERSECT); if ( (x1 < p->x) && (p->x < x2) ) return(INSIDE); } } return(OUTSIDE); } /* returns in p the intersection of two line segments. if parallel returns 0 else returns 1 */ int intersection(line_seg1, line_seg2, p) LINE_SEGMENT *line_seg1, *line_seg2; POINT *p; { register float x1,y1, x2,y2, x3,y3, x4,y4; register float A1, B1, C1, A2, B2, C2; x1 = (*line_seg1).p1->x; y1 = (*line_seg1).p1->y; x2 = (*line_seg1).p2->x; y2 = (*line_seg1).p2->y; x3 = (*line_seg2).p1->x; y3 = (*line_seg2).p1->y; x4 = (*line_seg2).p2->x; y4 = (*line_seg2).p2->y; if (ZERO(x1 - x2)) { A1 = 1; B1 = 0; C1 = -x1; } else { A1 = (y2 - y1)/(x2 - x1); B1 = -1; C1 = y1 - A1*x1; } if (ZERO(x3 - x4)) { A2 = 1; B2 = 0; C2 = -x3; } else { A2 = (y4 - y3)/(x4 - x3); B2 = -1; C2 = y3 - A2*x3; } if (ZERO(A1*B2 - B1*A2)) return(0); /* lines parallel */ else { (*p).x = (-C1*B2 + C2*B1)/(A1*B2 - A2*B1); (*p).y = (-C2*A1 + C1*A2)/(A1*B2 - A2*B1); return(1) } } /* ZERO approximation */ int ZERO(number) float number; { if (fabs((double)number) < ERROR) return(1); else return(0); }