hdu 4629 Burning(二维图形学)

二维图形学,还是相当烦人的

#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const double eps = 1e-8;
const int MAXN = 55;
const int MAXNUM = 25000;
int nump, n;
inline int dbCmp(const double x, const double y)
{
	if ( fabs(x-y) < eps) return 0;
	return x<y?-1:1;
}

struct point
{
	double x, y;
	point(){}
	point(double a, double b){x = a; y = b;}
	void getin(){scanf("%lf%lf", &x, &y);}
	bool operator < (const point & a) const
	{
		return -1 == dbCmp(x,a.x);
	}
	bool operator == (const point & a) const
	{
		return 0 == dbCmp(x,a.x);
	}
	point operator - (const point & a)
	{
		return point(x-a.x, y-a.y);
	}
	double operator * (const point &a)
	{
		return x*a.y-y*a.x;
	}
}tpp[MAXNUM];	// 临时数据 
double getCal(point frm, point ta, point tb) // 
{
	return (ta-frm)*(tb-frm);
}
struct line
{
	point a, b;
	double A,B,C;
	int sz; // sz == 0 : up+, down-;
	line(){}
	line(point c, point d){a = c, b = d;}
	bool operator < (const line & e) const
	{
		return -1 == dbCmp(a.y+b.y, e.a.y+e.b.y);
	}
	int isCross(const line & e)
	{
		if (getCal(e.a, a, b) * getCal(e.b, a, b)<0.0) return 1;
		return 0;
	}
	void operator *(const line &exa) const
	{
		tpp[nump++] = point((B*exa.C-exa.B*C)/(exa.B*A-B*exa.A), 0.0);
	}
	void mset(double x1, double x2)
	{
		a.x = x1; b.x = x2;
		a.y = (C+A*x1)/-B;
		b.y = (C+A*x2)/-B;
	}
}tpl[MAXN*3];
struct triangles 
{
	point pt[3];
	line mlin[3];
	void getin()
	{
		pt[0].getin(); pt[1].getin(); pt[2].getin();
		for (int i = 0; i< 3; ++i)
		{
			int ii = (i+1)%3;
			if (pt[i].x < pt[ii].x) mlin[i] = line(pt[i], pt[ii]);
			else mlin[i] = line(pt[ii], pt[i]);
			mlin[i].A = pt[i].y - pt[ii].y;
			mlin[i].B = pt[ii].x - pt[i].x;
			mlin[i].C = pt[i].x*(-mlin[i].A) - pt[i].y*(mlin[i].B);
			if (dbCmp(pt[i].x, pt[ii].x) == 0)
			{
				mlin[i].sz = 0;
			}
			else
			{
				int tt = (i+2)%3;
				if (getCal(mlin[i].a, mlin[i].b, pt[tt]) < 0.0)
					mlin[i].sz = -1;
				else
					mlin[i].sz = 1;
			}
		}
	}
	void getCross(const triangles & exa)
	{
		for (int i = 0; i< 3; ++i)
		{
			for (int j = 0; j< 3; ++j)
			{
				if (mlin[i].isCross(exa.mlin[j]))
				{
					mlin[i]*exa.mlin[j];
				}
			}
		}
	}
}mtr[MAXN];	// 三角形 
double res[MAXN];
int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
#endif
	int t;
	scanf("%d", &t);
	while (t--)
	{
		scanf("%d", &n);
		nump = 0;
		int cnt = 0;
		for (int i = 0; i< n; ++i)
		{
			mtr[i].getin();
			tpp[nump++] = mtr[i].pt[0];tpp[nump++] = mtr[i].pt[1];tpp[nump++] = mtr[i].pt[2];
			res[i] = 0.0;
		}
		for (int i = 0; i< n; ++i)
		{
			for (int j = i+1; j< n; ++j)
			{
				mtr[i].getCross(mtr[j]);
			}
		}
		sort(tpp, tpp+nump);
		nump = unique(tpp, tpp+nump) - tpp;
		for (int i = 1; i< nump; ++i)
		{
			cnt = 0;
			for (int j = 0; j< n; ++j)
			{
				for (int k = 0; k< 3; ++k)
				{
					if (mtr[j].mlin[k].a.x <= tpp[i-1].x && mtr[j].mlin[k].b.x >= tpp[i].x)
					{
						tpl[cnt] = mtr[j].mlin[k];
						tpl[cnt++].mset(tpp[i-1].x, tpp[i].x);
					}
				}
			}
			sort(tpl, tpl+cnt);
			int tp = 1;
			for (int j = 1; j< cnt; ++j)
			{
				res[tp] += (tpp[i].x-tpp[i-1].x)*(tpl[j].a.y - tpl[j-1].a.y + tpl[j].b.y - tpl[j-1].b.y)/2;
				tp += tpl[j].sz;
			}
		}
		for (int i = 1; i<= n; ++i)
		{
			printf("%.10lf\n", res[i]);
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值