半平面求交——放置守卫

原创 2015年11月21日 10:04:47
#include <bits/stdc++.h>
//using namespcace std;
const int maxn = 1510;
const double EPS = 1E-12;
struct Point
{
	double x, y;
};
Point convex[maxn];
struct Line
{
	Point a, b;
	double ang;
};
Line l[maxn], st[maxn];
int n, ccnt;
double operator *(const Point &x, const Point &y)
{
	return x.x * y.y - x.y * y.x;
}
Point operator - (Point x, const Point &y)
{
	x.x -= y.x, x.y -= y.y;
	return x;
}
Point operator * (const Line &x, const Line &y)
{
	double a1 = (y.b - x.a) * (y.a - x.a) , a2 = (y.a - x.b) * (y.b - x.b);
	Point r;
	r.x =  (x.a.x * a2 + x.b.x * a1) / (a2 + a1);
	r.y = (x.a.y * a2 + x.b.y * a1) / (a2 + a1);
	return r;
}
bool operator == (const Point &a, const Point &b)
{
	return fabs(a.x - b.x) < EPS && fabs(a.y - b.y) < EPS;
}
bool operator <(const Line &x, const Line &y)
{
	if (fabs(x.ang - y.ang) < EPS)
		return (y.b - x.a) * (x.b - y.a) > EPS;
	return x.ang < y.ang;
}
bool JudgeOut(const Line &x, const Point &p)
{
	return (p - x.a) * (x.b - x.a) > EPS;
}
bool Parellel(const Line &x, const Line &y)
{
	return fabs((x.b - x.a) * (y.b - y.a)) < -EPS;
}
void InputData()
{
	scanf("%d", &n);
	scanf("%lf%lf", &l[0].b.x, &l[0].b.y);
	l[n - 1].a.x = l[0].b.x, l[n - 1].a.y = l[0].b.y;
	for (int i = 1; i < n; i++)
	{
		scanf("%lf%lf", &l[i].b.x, &l[i].b.y);
		l[i - 1].a.x = l[i].b.x; l[i - 1].a.y = l[i].b.y;
	}
	for (int i = 0; i < n; i++)
		l[i].ang = atan2(l[i].b.y - l[i].a.y, l[i].b.x - l[i].a.x);
}
double HplaneIntersection()
{
	int top = 1, bot  = 0;
	std::sort(l, l + n);
	int tmp = 1;
	for (int i = 1; i < n; i++)
		if (l[i].ang - l[i - 1].ang > EPS) l[tmp++] = l[i];
	n = tmp;
	st[0] = l[0], st[1] = l[1];
	for (int i = 2; i < n; i++)
	{
		if (Parellel(st[top], st[top - 1]) || Parellel(st[bot], st[bot - 1])) return 0;
		while (bot < top && JudgeOut(l[i], st[top]*st[top - 1])) top--;
		while (bot < top && JudgeOut(l[i], st[bot]*st[bot + 1])) bot++;
		st[++top] = l[i];
	}
	while (bot < top && JudgeOut(st[bot], st[top]*st[top - 1])) top--;
	while (bot < top && JudgeOut(st[top], st[bot]*st[bot + 1])) bot++;
	if (top <= bot + 1) return 0.00;
	st[++top] = st[bot];
	ccnt = 0;
	for (int i = bot; i < top; i++)
		convex[ccnt++] = st[i] * st[i + 1];
	double ans = 0;
	convex[ccnt] = convex[0];
	for (int i = 0; i < ccnt; i++)
		ans += convex[i] * convex[i + 1];
	return ans / 2;
}
double CheckDirection()
{
	double ans = 0;
	for (int i = 0; i < n; i++)
		ans += l[i].a * l[i].b;
	return ans;
}
void ChangeDirection()
{
	for (int i = 0; i < n; i++)
		std::swap(l[i].a, l[i].b);
}
int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		InputData();
		if (CheckDirection() < 0) ChangeDirection();
		printf("%.2f\n", HplaneIntersection());
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

poj1279——Art Gallery//半平面交 求面积

用上题模板,一次AC。#include #include #include using namespace std; const int maxn=20010; const int boun...

半平面交——学习笔记

这次讲半平面交。

poj2451——Uyuw's Concert//半平面交

资料详见:朱泽圆06年论文。半平面交思想:1,对半平面预先处理,求极角并排序、去重。2,在凸多边形交里面,根据论文所讲,反复做删去、加入半平面的操作。具体实现,可以参考http://hi.baidu....

【POJ3335】博物馆守卫Rotating Scoreboard 半平面交

题目描述   现在有一个博物馆,俯瞰图是一个多边形。现在想要在博物馆内部设立一个守卫,但要求他可以看见博物馆的每一个角落。现在想知道是否存在这样一个点,使得安置其上的守卫可以完成任务。 数据范围 ...

POJ 2540 Hotter Colder(半平面交求可行域)

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove 题目:从0,0出发,走到某...

poj 1755 Triathlon 半平面交求不等式的 是否为空集-------构造有向直线

题目来源: http://poj.org/problem?id=1755 分析: 设比赛总长度为 1, 其中游泳长度为x, 自行车长度为y, 赛跑长度为 1 - x - y, 则选手 i 打败 ...

<模板><计算几何>半平面求交学习小记

主要是依靠这篇博文学习的 http://blog.csdn.net/accry/article/details/6070621 我的半平面交代码模板也参考自这里,个人进行了简单优化。 刚发...

POJ 3525 || Most Distant Point from the Sea (凸包求最大内接圆,半平面交内推r

题目在问这样一个问题:给定一个凸多边形,找到其中的一个点,使得其到每条边的距离最小值最大,输出这个距离。 其实就是在问你,这个多边形中最大的一个内切圆有多大。 怎么做呢?如果我们事先知道一...
  • FXXKI
  • FXXKI
  • 2015年05月12日 21:08
  • 496

半平面求交

• Step 1: Separate the h-planes into two sets. One has polar angles of (-½π, ½π], the other has thos...

POJ 3130 How I Mathematician Wonder What You Are! 半平面交求多边形内核是否存在

题目大意:定义一种多边形,叫做星形多边形。这种多边形就是有内核的多边形。给出一些多边形,问是否是星形多边形。 思路:利用半平面交求解。PS:我的第一个多边形内核的代码不对。。一定要看这个,这...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:半平面求交——放置守卫
举报原因:
原因补充:

(最多只允许输入30个字)