POJ 2826 An Easy Problem?! (判点与线段的位置,求线段交点)

真的不是简单的问题啊!

雨水从上方落下。接不到雨的情况:


注意这两种是可以接到雨的


都判断清楚了这题就好做了。

//Memory: 192K		
//Time: 32MS
#include <stdio.h>
#include <iostream>
#include <math.h>
#define EP 1E-6
#define INF 1E100
using namespace std;
struct POINT
{
	double x,y;
};
struct LINESEG
{
	POINT s,e;
};
struct LINE
{
	double a,b,c;
	POINT A,B;
	LINE(){};
	LINE(POINT _a,POINT _b)
	{
		A=_a;
		B=_b;
		a=B.y-A.y;
		b=A.x-B.x;
		c=B.x*A.y-A.x*B.y;
	};
};
double multiply(POINT sp,POINT ep,POINT op)//叉积
{
	return (sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y);
}
bool intersect(LINESEG u,LINESEG v)//求线段交点
{
	return ((max(u.s.x,u.e.x)>=min(v.s.x,v.e.x)) &&
		(max(v.s.x,v.e.x)>=min(u.s.x,u.e.x)) &&
		(max(u.s.y,u.e.y)>=min(v.s.y,v.e.y)) &&
		(max(v.s.y,v.e.y)>=min(u.s.y,u.e.y)) &&
		(multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s)>=0) &&
		(multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=0));
}
int main()
{
	//freopen("data.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int cas,i;
	double ans;
	POINT p[5];
	LINESEG l1,l2;
	scanf("%d",&cas);
	while(cas--)
	{
		ans=0;
		int my=0;
		double lx=0;
		scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&p[1].x,&p[1].y,&p[2].x,&p[2].y,&p[3].x,&p[3].y,&p[4].x,&p[4].y);
		l1.s=p[1];l1.e=p[2];
		l2.s=p[3];l2.e=p[4];
		if(intersect(l1,l2))
		{
			LINE t[3];
			t[1]=LINE(p[1],p[2]);
			t[2]=LINE(p[3],p[4]);
			if(fabs(t[1].b/t[1].a-t[2].b/t[2].a)>EP)
			{
				double d=t[1].a*t[2].b-t[2].a*t[1].b;
				p[0].x=(t[2].c*t[1].b-t[1].c*t[2].b)/d;
				p[0].y=(t[2].a*t[1].c-t[1].a*t[2].c)/d;
				for(i=1;i<=4;i++)
				{
					if(p[i].y>p[0].y)
					{
						if(my==0)
							my=i;
						else
						{
							if(p[i].y<p[my].y)
							{
								lx=p[i].x+(t[(my+1)/2].b*p[i].y+t[(my+1)/2].c)/t[(my+1)/2].a;
								if((multiply(p[i],p[my],p[0])>0 && p[my].x>=p[i].x) ||
									(multiply(p[i],p[my],p[0])<0 && p[my].x<=p[i].x))
									lx=0;
								ans=(p[i].y-p[0].y)*lx/2;
							}
							else
							{
								lx=p[my].x+(t[(i+1)/2].b*p[my].y+t[(i+1)/2].c)/t[(i+1)/2].a;
								if((multiply(p[my],p[i],p[0])>0 && p[i].x>=p[my].x) ||
									(multiply(p[my],p[i],p[0])<0 && p[i].x<=p[my].x))
									lx=0;
								ans=(p[my].y-p[0].y)*lx/2;
							}
						}
					}	
				}
			}
			ans=fabs(ans);
		}
		printf("%.2lf\n",ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值