POJ - 2826 An Easy Problem (computational geometry, good question)?!

Topic links: Click here

Subject to the effect: given two segments, consisting of container up to then ask how much rain

Topic Analysis: Since it is rainwater, then it is surely only be a funnel-shaped, it is easy to exclude both cases:

  1. Wherein there is a line parallel to the x-axis
  2. Two line segments do not intersect

There is also a more difficult situation to think kuangbin great God mentioned, and that is the case sealed, that corresponds to the following three conditions:

After discussing the individual, and the remaining cases will certainly solvable, the direct area of ​​the triangle according to the calculations is the answer

Note that the results need to add a -0.00 eps prevent the emergence of, I guess, without words will WA, add to A, and metaphysics

Code:

#include<iostream>
#include<cstdio> 
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;
 
typedef long long LL;
 
const int inf=0x3f3f3f3f;

const int N=60;

const double eps = 1e-8;

int sgn(double x){
	if(fabs(x) < eps)return 0;
	if(x < 0)return -1;
	else return 1;
}

struct Point{
	double x,y;
	Point(){}
	Point(double _x,double _y){
		x = _x;
		y = _y;
	}
	void input(){
		scanf("%lf%lf",&x,&y);
	}
	Point operator -(const Point &b)const{
		return Point(x-b.x,y-b.y);
	}
	//叉积
	double operator ^(const Point &b)const{
		return x*b.y - y*b.x;
	}
	//点积
	double operator *(const Point &b)const{
		return x*b.x + y*b.y;
	}
	//返回两点的距离
	double distance(Point p){
		return hypot(x-p.x,y-p.y);
	}
};

struct Line{
	Point s,e;
	Line(){}
	Line(Point _s,Point _e){
		s = _s;
		e = _e;
	}
	void input(){
		s.input();
		e.input();
	}
	//求线段长度
	double length(){
		return s.distance(e);
	}
	//`两线段相交判断`
	//`2 规范相交`
	//`1 非规范相交`
	//`0 不相交`
	int segcrossseg(Line v){
		int d1 = sgn((e-s)^(v.s-s));
		int d2 = sgn((e-s)^(v.e-s));
		int d3 = sgn((v.e-v.s)^(s-v.s));
		int d4 = sgn((v.e-v.s)^(e-v.s));
		if( (d1^d2)==-2 && (d3^d4)==-2 )return 2;
		return (d1==0 && sgn((v.s-s)*(v.s-e))<=0) ||
			(d2==0 && sgn((v.e-s)*(v.e-e))<=0) ||
			(d3==0 && sgn((s-v.s)*(s-v.e))<=0) ||
			(d4==0 && sgn((e-v.s)*(e-v.e))<=0);
	}
	//`直线和线段相交判断`
	//`-*this line   -v seg`
	//`2 规范相交`
	//`1 非规范相交`
	//`0 不相交`
	int linecrossseg(Line v){
		int d1 = sgn((e-s)^(v.s-s));
		int d2 = sgn((e-s)^(v.e-s));
		if((d1^d2)==-2) return 2;
		return (d1==0||d2==0);
	}
	//`求两直线的交点`
	//`要保证两直线不平行或重合`
	Point crosspoint(Line v){
		double a1 = (v.e-v.s)^(s-v.s);
		double a2 = (v.e-v.s)^(e-v.s);
		return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
	}
	//点到直线的距离
	double dispointtoline(Point p){
		return fabs((p-s)^(e-s))/length();
	}
}l1,l2;

int main()
{
//	freopen("input.txt","r",stdin);
//	ios::sync_with_stdio(false);
	int w;
	cin>>w;
	while(w--)
	{
		l1.input();
		l2.input();
		if(sgn(l1.s.y-l1.e.y)==0||sgn(l2.s.y-l2.e.y)==0)//有一条线平行于x轴 
		{
			puts("0.00");
			continue;
		}
		if(sgn(l1.s.y-l1.e.y)<0)
			swap(l1.s,l1.e);
		if(sgn(l2.s.y-l2.e.y)<0)
			swap(l2.s,l2.e);
		if(l1.segcrossseg(l2)==0)//不相交 
		{
			puts("0.00");
			continue;
		}
		if(l1.segcrossseg(Line(Point(l2.s.x,100000),l2.s))||l2.segcrossseg(Line(Point(l1.s.x,100000),l1.s)))//口被封上 
		{
			puts("0.00");
			continue;
		}
		double ans1=1e10,ans2=1e10;
		Point point=l1.crosspoint(l2);//交点
		Line temp1=Line(l2.s,Point(100000,l2.s.y));//与x轴平行,且过l2上面的点的直线 
		Line temp2=Line(l1.s,Point(100000,l1.s.y));//与x轴平行,且过l1上面的点的直线 
		if(temp1.linecrossseg(l1))
		{
			Point temp=temp1.crosspoint(l1);//当前三个点构成三角形temp point l2.s 
			ans1=0.5*(temp1.dispointtoline(point)*temp.distance(l2.s));
		}
		if(temp2.linecrossseg(l2))
		{
			Point temp=temp2.crosspoint(l2);//当前三个点构成三角形temp point l1.s 
			ans2=0.5*(temp2.dispointtoline(point)*temp.distance(l1.s));
		}
		printf("%.2f\n",min(ans1,ans2)+eps);
	}
	
	
 
 
 
 
 
 
 
	
	
	
	
	
	
	
	
	
	return 0;
}

 

Published 577 original articles · won praise 18 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_45458915/article/details/104096820