FZU1120 A Pilot in Danger! 判断点是否在多边形中
2010-10-13 11:53
274 查看
判断点是否在多边形中:
判断点P是否在多边形中是计算几何中一个非常基本但是十分重要的算法。以点P为端点,向左方作射线L,由于多边形是有界的,所以射线L的左端一定在多边形外,考虑沿着L从无穷远处开始自左向右移动,遇到和多边形的第一个交点的时候,进入到了多边形的内部,遇到第二个交点的时候,离开了多边形,……所以很容易看出当L和多边形的交点数目C是奇数的时候,P在多边形内,是偶数的话P在多边形外。
但是有些特殊情况要加以考虑。如图下图(a)(b)(c)(d)所示。在图(a)中,L和多边形的顶点相交,这时候交点只能计算一个;在图(b)中,L和多边形顶点的交点不应被计算;在图(c)和(d) 中,L和多边形的一条边重合,这条边应该被忽略不计。如果L和多边形的一条边重合,这条边应该被忽略不计。
代码
判断点P是否在多边形中是计算几何中一个非常基本但是十分重要的算法。以点P为端点,向左方作射线L,由于多边形是有界的,所以射线L的左端一定在多边形外,考虑沿着L从无穷远处开始自左向右移动,遇到和多边形的第一个交点的时候,进入到了多边形的内部,遇到第二个交点的时候,离开了多边形,……所以很容易看出当L和多边形的交点数目C是奇数的时候,P在多边形内,是偶数的话P在多边形外。
但是有些特殊情况要加以考虑。如图下图(a)(b)(c)(d)所示。在图(a)中,L和多边形的顶点相交,这时候交点只能计算一个;在图(b)中,L和多边形顶点的交点不应被计算;在图(c)和(d) 中,L和多边形的一条边重合,这条边应该被忽略不计。如果L和多边形的一条边重合,这条边应该被忽略不计。
代码
#include <stdio.h> #include <stdlib.h> #include <math.h> #define MaxNode 50 #define INF 999999999 int flag[50050]; typedef struct TPoint { double x; double y; } TPoiont; typedef struct TSegment { TPoint p1; TPoint p2; } TSegment; typedef struct TPolygon { TPoint point[MaxNode]; int n; } TPolygon; double multi(TPoint p1, TPoint p2, TPoint p0) { //求矢量[p0, p1], [p0, p2]的叉积 //p0是顶点 return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y); //若结果等于0,则这三点共线 //若结果大于0,则p0p2在p0p1的逆时针方向 //若结果小于0,则p0p2在p0p1的顺时针方向 } double max(double x, double y) { //比较两个数的大小,返回大的数 if (x > y) return x; else return y; } double min(double x, double y) { //比较两个数的大小,返回小的数 if (x < y) return x; else return y; } bool Intersect(TSegment L1, TSegment L2) { //线段l1与l2相交而且不在端点上时,返回true //判断线段是否相交 //1.快速排斥试验判断以两条线段为对角线的两个矩形是否相交 TPoint s1 = L1.p1; TPoint e1 = L1.p2; TPoint s2 = L2.p1; TPoint e2 = L2.p2; //2.跨立试验 if ((max(s1.x, e1.x) > min(s2.x, e2.x)) && (max(s2.x, e2.x) > min(s1.x, e1.x)) && (max(s1.y, e1.y) > min(s2.y, e2.y)) && (max(s2.y, e2.y) > min(s1.y, e1.y)) && (multi(s2, e1, s1) * multi(e1, e2, s1) > 0) && (multi(s1, e2, s2) * multi(e2, e1, s2) > 0) ) return true; return false; } bool Online(TSegment L, TPoint p) {//p在L上(不在端点)时返回true //1.在L所在的直线上 2.在L为对角线的矩形中 double dx, dy, dx1, dy1; dx = L.p2.x - L.p1.x; dy = L.p2.y - L.p1.y; dx1 = p.x - L.p1.x; dy1 = p.y - L.p1.y; if (dx * dy1 - dy * dx1 != 0) return false; //叉积 if (dx1 * (dx1 - dx) < 0 || dy1 * (dy1 - dy) < 0) return true; return false; } bool same1(TSegment L, TPoint p1, TPoint p2) { //判断p1, p2是否在L的同侧 if (multi(p1, L.p2, L.p1) * multi(L.p2, p2, L.p1) < 0) return true; return false; } bool Inside(TPoint q, TPolygon polygon) { int c, i; TSegment L1, L2; c = 0; L1.p1 = q; L1.p2 = q; L1.p2.x = INF; /*(1)相交1.p[i]和p[i+1]在L的两侧2.p[i]和p[i+2]在L的同侧 * 3.p[u]和p[i+3]在L的同侧或异侧*/ for (i = 1; i <= polygon.n; i++) { L2.p1 = polygon.point[i]; L2.p2 = polygon.point[i + 1]; if (Intersect(L1, L2)) { c++; continue; } if (!Online(L1, polygon.point[i + 1])) continue; if (!Online(L1, polygon.point[i + 2]) && !same1(L1, polygon.point[i], polygon.point[i + 2])) { c++; continue; } if (Online(L1, polygon.point[i + 2]) && !same1(L1, polygon.point[i], polygon.point[i + 3])) c++; } if (c % 2 == 0) return false; else return true; } int main() { int i, test, k; int primp, primq; TPoint p; p.x = 0; p.y = 0; test = 1; TPolygon polygon; while (scanf("%d", &polygon.n) != EOF && polygon.n) { printf("Pilot %d\n", test++); for (i = 1; i <= polygon.n; i++) { scanf("%lf%lf", &polygon.point[i].x, &polygon.point[i].y); } scanf("%d%d", &primp, &primq); if (Inside(p, polygon)) { printf("The pilot is in danger!\n"); k = (primp - 1) * (primq - 1) / 2; printf("The secret number is %d.\n", k); } else printf("The pilot is safe.\n"); printf("\n"); } return 0; }
相关文章推荐
- FZU1120 A Pilot in Danger! [计算几何+数论]
- FZUACM Problem 1120 A Pilot in Danger!
- FZUACM Problem 1120 A Pilot in Danger!
- A Round Peg in a Ground Hole(判断是否是凸包,点是否在凸包内,圆与多边形的关系)
- poj 1584 A Round Peg in a Ground Hole(判断凸多边形+圆是否在凸多边形内)
- POJ 1584: A Round Peg in a Ground Hole 射线法判断点是否在多边形内 点与直线距离 判断多边形是否为凸多边形
- POJ1584 A Round Peg in a Ground Hole 判断多边形是否为凸多边形,判断凸多边形是否在圆内
- POJ1584 A Round Peg in a Ground Hole 判断多边形是否为凸多边形,判断凸多边形是否在圆内
- POJ 1584 A Round Peg in a Ground Hole(判断凸多边形,判断圆是否在凸多边形内)
- POJ 1584:A Round Peg in a Ground Hole _判断点是否在多边形内(5种方法)
- FZU 2035 Axial symmetry(判断多边形是否对称)
- poj 1584 A Round Peg in a Ground Hole 判断多边形是否为凸多边形 + 圆心是否在凸多边形内 + 圆是否在凸多边形内部
- 判断一个点是否在矩形内PtInRegion-解决PtInRect不能正确判断不同形式TRent的情况
- 判断点是否在多边形中
- 判断一个点是否在一个多边形内部
- 判断点是否在多边形内
- 判断点是否在多边形内
- Dancing Stars on Me---hdu5533(判断是否为正多边形)
- JS判断坐标点是否在给定的多边形内
- 如何判断一个指定的经纬度点是否落在一个多边形内