boj 35 Video Surveillance 半平面交求多边形的核
2013-05-22 15:35
337 查看
//============================================================================ // Name : 35.cpp // Author : wly // Version : // Copyright : Your copyright notice // Description : Video Surveillance // Algorithm : 求多边形的核 // 计算几何,半平面交求多边形的核 // http://blog.csdn.net/accry/article/details/6070621 // 半平面交找核思想: // 对多边形的每一条边,这条边所在的直线都可以将平面分成两块,求一条边划分的半平面与之前得出的多边形的交, // 得出的多边形再与下一条边的半平面求交,依次类推,最后得到的多边形就是原多边形的核 //============================================================================ #include <stdio.h> #include <stdlib.h> #include <cmath> #include <algorithm> using namespace std; const double MAX = 100000000; const double pi = acos(-1.0); const double eps = 1e-8; int cCnt, curCnt, n; //点结构 struct Point { double x, y; Point(double ix, double iy) : x(ix), y(iy) { } Point() { } void input() { scanf("%lf%lf", &x, &y); } } points[110], p[110], q[110]; //将两点确定的直线量化 inline void getline(Point x, Point y, double &a, double &b, double &c) { a = y.y - x.y; b = x.x - y.x; c = y.x * x.y - x.x * y.y; } int sig(double k) { return (k < -eps) ? -1 : (k > eps); } //x点y点的连线与量化后的直线求交点 void interect(Point x, Point y, double a, double b, double c) { double u = fabs(a * x.x + b * x.y + c); double v = fabs(a * y.x + b * y.y + c); q[++curCnt].x = (x.x * v + y.x * u) / (u + v); q[curCnt].y = (x.y * v + y.y * u) / (u + v); } //利用半平面切割 void cut(double a, double b, double c) { curCnt = 0; int i; for (i = 1; i <= cCnt; i++) //遍历所有顶点是否能观察到该边 { if (sig(a * p[i].x + b * p[i].y + c) >= 0)//因为线段是顺时针给出的,如果是逆时针就是<=0 { q[++curCnt] = p[i]; //若是则存储 } else { if (sig(a * p[i - 1].x + b * p[i - 1].y + c) > 0)//逆时针就是<0 interect(p[i - 1], p[i], a, b, c); if (sig(a * p[i + 1].x + b * p[i + 1].y + c) > 0)//逆时针就是<0 interect(p[i + 1], p[i], a, b, c); } } //最后的p数组存放半平面的点集合 for (i = 1; i <= curCnt; i++) p[i] = q[i]; p[curCnt + 1] = p[1], p[0] = p[curCnt]; cCnt = curCnt; } //半平面交初始化 inline void initial() { for (int i = 1; i <= n; ++i) p[i] = points[i]; points[n + 1] = points[1]; p[n + 1] = p[1]; p[0] = p ; cCnt = n; } //输入 inline void init() { for (int i = 1; i <= n; i++) points[i].input(); } //获得多边形的核,结果存在p数组中,如果没有结果,p数组长度为0 inline void solve() { initial(); for (int i = 1; i <= n; ++i) { double a, b, c; getline(points[i], points[i + 1], a, b, c); cut(a, b, c); } //多边形核的面积 /*double area = 0; for (int i = 1; i <= curCnt; ++i) area += p[i].x * p[i + 1].y - p[i + 1].x * p[i].y; area = fabs(area / 2.0);*/ } int main() { int tc = 1; while (scanf("%d", &n), n) { init(); solve(); printf("Floor #%d\n", tc++); if (!cCnt) puts("Surveillance is impossible.");//这里如果有一个点,或者一条线段都可以,所以判断m是不是等于0就行了,不用判断面积 else puts("Surveillance is possible."); printf("\n"); } return 0; }
相关文章推荐
- 半平面交,求解多边形内核
- bzoj 2618: [Cqoi2006]凸多边形 [半平面交]
- POJ-1279 Art Gallery(求多边形内核面积,半平面交)
- POJ 3335 半平面交与多边形的核
- POJ 1279 Art Gallery(半平面交求多边形核的面积)
- [置顶] 半平面交,求解多边形内核
- poj 3384 Feng Shui - 多边形的边内退一段距离后求半平面交,然后求最远点对
- POJ 3384 Feng Shui (半平面交求多边形内两个圆最大面积)
- POJ3130 How I Mathematician Wonder What You Are! 半平面交判多边形是否有核
- [bzoj2618][半平面交][Cqoi2006]凸多边形
- POJ 1474 多边形的核(半平面交)
- 半平面交 求多边形内核问题
- poj 3335 Rotating Scoreboard(半平面交,求解多边形内核)
- POJ 3335 Rotating Scoreboard(半平面交 多边形是否有核 模板)
- POJ1279/ZOJ1369 Art Gallery,POJ2451 Uyuw's Concert(半平面交求多边形的核)
- POJ 1279 Art Gallery(半平面交求多边形核)
- POJ 1279 Art Gallery 半平面交 多边形的核
- POJ 3335(半平面交—判断多边形的核是否存在)
- POJ 3335 半平面交求多边形的核
- POJ 1279 Art Gallery 半平面交求多边形核