POJ 1279 Art Gallery 多边形内核面积

题目大意:按顺序给出一个多边形的顶点,求这个多边形内核的面积。答案保留两位输出。

思路:半平面交。加边的时候要讨论一下第一个点和最后一个点,否则会wa的很惨。

CODE:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 1510
#define EPS 1e-8
#define DCMP(a) (fabs(a) < EPS)
using namespace std;

struct Point{
	double x,y;

	Point(double _ = .0,double __ = .0):x(_),y(__) {}
	Point operator +(const Point &a)const {
		return Point(x + a.x,y + a.y);
	}
	Point operator -(const Point &a)const {
		return Point(x - a.x,y - a.y);
	}
	Point operator *(double a)const {
		return Point(x * a,y * a);
	}
	void Read() {
		scanf("%lf%lf",&x,&y);
	}
}point[MAX],p[MAX],ploygen[MAX];
struct Line{
	Point p,v;
	double alpha;

	Line(Point _,Point __):p(_),v(__) {
		alpha = atan2(v.y,v.x);
	}
	Line() {}
	bool operator <(const Line &a)const {
		return alpha < a.alpha;
	}
}line[MAX],q[MAX];

int cases;
int points,lines;

inline void Initialize();
inline void MakeLine(const Point &a,const Point &b);
inline double Cross(const Point &a,const Point &b);
inline bool OnLeft(const Line &l,const Point &p);

inline Point GetIntersection(const Line &a,const Line &b);
inline double HalfPlaneIntersection();
inline double GetArea(int cnt);

int main()
{
	for(cin >> cases;cases; --cases) {
		scanf("%d",&points);
		Initialize();
		for(int i = 1;i <= points; ++i)
			point[i].Read();
		for(int i = points;i > 1; --i)
			MakeLine(point[i],point[i - 1]);
		MakeLine(point[1],point[points]);
		sort(line + 1,line + lines + 1);
		printf("%.2lf\n",HalfPlaneIntersection());
	}
	return 0;
}

inline void Initialize()
{
	lines = 0;
}

inline void MakeLine(const Point &a,const Point &b)
{
	line[++lines] = Line(a,b - a);
}

inline double Cross(const Point &a,const Point &b)
{
	return a.x * b.y - a.y * b.x;
}

inline Point GetIntersection(const Line &a,const Line &b)
{
	Point u = a.p - b.p;
	double temp = Cross(b.v,u) / Cross(a.v,b.v);
	return a.p + a.v * temp;
}

inline bool OnLeft(const Line &l,const Point &p)
{
	return Cross(l.v,p - l.p) > 0;
}

inline double HalfPlaneIntersection()
{
	int front = 1,tail = 1;
	q[tail] = line[1];
	for(int i = 2;i <= lines; ++i) {
		while(front < tail && !OnLeft(line[i],p[tail - 1]))	--tail;
		while(front < tail && !OnLeft(line[i],p[front]))	++front;
		if(DCMP(Cross(line[i].v,q[tail].v)))
			q[tail] = OnLeft(q[tail],line[i].p) ? line[i]:q[tail];
		else	q[++tail] = line[i];
		if(front < tail)	p[tail - 1] = GetIntersection(q[tail],q[tail - 1]);
	}
	while(front < tail && !OnLeft(q[front],p[tail - 1]))	--tail;
	if(front == tail)	return .0;
	p[tail] = GetIntersection(q[front],q[tail]);
	int cnt = 0;
	for(int i = front;i <= tail; ++i)
		ploygen[++cnt] = p[i];
	return GetArea(cnt);
}

inline double GetArea(int cnt)
{
	double re = Cross(ploygen[cnt],ploygen[1]);
	for(int i = 1;i < cnt; ++i)
		re += Cross(ploygen[i],ploygen[i + 1]);
	return fabs(re / 2);
}

时间: 2024-09-30 10:41:07

POJ 1279 Art Gallery 多边形内核面积的相关文章

POJ 1279 Art Gallery 半平面交求多边形核

第一道半平面交,只会写N^2. 将每条边化作一个不等式,ax+by+c>0,所以要固定顺序,方便求解. 半平面交其实就是对一系列的不等式组进行求解可行解. 如果某点在直线右侧,说明那个点在区域内,否则出现在左边,就可能会有交点,将交点求出加入. //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #inc

poj 1279 -- Art Gallery (半平面交)

鏈接:http://poj.org/problem?id=1279 Art Gallery Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5337   Accepted: 2277 Description The art galleries of the new and very futuristic building of the Center for Balkan Cooperation have the form

POJ 1279 Art Gallery 半平面交+求多边形核的面积

裸的:半平面交+求多边形核的面积 Art Gallery Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5735   Accepted: 2419 Description The art galleries of the new and very futuristic building of the Center for Balkan Cooperation have the form of polygons (not

POJ 1279 Art Gallery [半平面交]

Art Gallery Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7324   Accepted: 2936 Description The art galleries of the new and very futuristic building of the Center for Balkan Cooperation have the form of polygons (not necessarily conve

POJ 1279 Art Gallery 半平面交 多边形的核

题意:求多边形的核的面积 套模板即可 #include <iostream> #include <cstdio> #include <cmath> #define eps 1e-18 using namespace std; const int MAXN = 1555; double a, b, c; int n, cnt; struct Point { double x, y; double operator ^(const Point &b) const {

POJ 1279 Art Gallery(半平面交求多边形核的面积)

题目链接 题意 : 求一个多边形的核的面积. 思路 : 半平面交求多边形的核,然后在求面积即可. #include <stdio.h> #include <string.h> #include <iostream> #include <math.h> using namespace std ; struct node { double x; double y ; } p[1510],temp[1510],newp[1510];//p是最开始的多边形的每个点,

poj 1279 Art Gallery(利用极角计算半平面交)

题意:给出n个点的坐标描述一个多边形画廊.在画廊平面上找到一片表面,从该区域能够看到画廊墙壁上的每一个点: 思路:将这片表面称为多边形的核.核中一点与多边形边界上任意一点的连线都在多边形内部.凸多边形的核为其本身,凹多边形的核为其内部的一部分或不存在: 将多边形的n个顶点转化为n条边的直线方程:逆时针用多边形的边剖分多边形所在平面,保留向里的部分,舍去向外的部分,剩下的即为核: 利用叉积公式计算核面积,即为所求面积: #include<cstdio> #include<cstring&g

poj 1279 求半平面交的 面积

poj 1279    求半平面交的 面积 题目来源: http://poj.org/problem?id=1279 分析: 求半平面交的 面积 代码如下: const double EPS = 1e-8; const int Max_N = 1505; struct Point{ double x,y; Point(){} Point(double x, double y):x(x),y(y){} Point operator - (Point p){ return Point(x- p.x

poj 1654 Area (多边形求面积)

链接:http://poj.org/problem?id=1654 Area Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14952   Accepted: 4189 Description You are going to compute the area of a special kind of polygon. One vertex of the polygon is the origin of the orth