您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: