现在的位置: 首页 > 综合 > 正文

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

2014年07月19日 ⁄ 综合 ⁄ 共 993字 ⁄ 字号 评论关闭

模板题。

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

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

这题比较特殊,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;
}

抱歉!评论已关闭.