SGU 124 判点在多边形内外边界

来源:互联网 发布:全知之眼手稿 编辑:程序博客网 时间:2024/04/30 07:53

模板题。

原理:先判点是不是在线段上。然后从这个点任意做一条射线,若与奇数条边相交,则该点在圆内,否则该点在圆外,注意遇到多边形的两条边的交点,算相交一次。

我们可以定义线段为左闭右开区间,这样可以避免重复计算。

这题比较特殊,dotOnSeg这个函数也特殊化了,不过point_in_polygon这个没有特殊化,只要改一下dotOnSeg就可以解决这类问题了。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;struct point {int x, y;void in() {scanf("%d%d", &x, &y);}}l[20004], r[20004], o;int n;bool dotOnSeg(point o, point s, point e) {if(s.x == o.x && e.x == o.x && o.y >= min(s.y, e.y) && o.y <= max(s.y, e.y)) return 1;if(s.y == o.y && e.y == o.y && o.x >= min(s.x, e.x) && o.x <= max(s.x, e.x)) return 1;return 0;}int cross(point o, point a, point b) {    return (a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x);}int point_in_polygon() {// 点是否在多边形内, 2边上,1内部,0外部int i, t;point a, b;for (i=0; i < n; i++) {if ( dotOnSeg(o, l[i], r[i]) )return 2;}t = 0;for (i=0; i < n; i++) {a = l[i]; b = r[i];if ( a.y > b.y ) {point tmp = a; a = b; b = tmp;}if ( cross(o, a, b) < 0 && a.y <= o.y && o.y < b.y )t++;}return t&1;}int main() {int i, j;scanf("%d", &n);for(i = 0; i < n; i++) l[i].in(), r[i].in();o.in();int g = point_in_polygon();if(g == 1) puts("INSIDE");else if(g == 2) puts("BORDER");else puts("OUTSIDE");return 0;}


原创粉丝点击