萌萌哒的计算几何

对,我今天又没吃药。

poj2826

喜闻乐见的计算几何题,WA几十发就是爽!

思路很简单,然后程序写的我就萌萌哒了

  1. 两条线段没有交点,或者互相平行,或者至少有一条平行于x轴的线段,则答案为0.00
  2. 如果有一条线段覆盖了另一条,则答案为0.00
  3. 否则答案就是交点和交点上方最低的点和过这个点做的平行与x轴的线围成的三角形的距离

对,思路非常简单,谁也不会想错
就是写不对!

我已弃疗

附AC代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>

#define INF (999999.9)

using namespace std;

const double eps = 1e-8;
const double pi = acos(-1.0);

inline bool isint(double x){return fabs((x-int(x+0.5))) < eps;}
inline int cmp(double x){
	if (fabs(x)<eps)	return 0;
	if (x>0)	return 1;
	return -1;
}

struct point{
	double x,y;
	point(double x=0,double y=0):x(x),y(y) {}
	friend point operator + (const point &a,const point &b){return point(a.x+b.x,a.y+b.y);}
	friend point operator - (const point &a,const point &b){return point(a.x-b.x,a.y-b.y);}
	friend bool operator == (const point &a,const point &b){return cmp(a.x-b.x)==0 && cmp(a.y-b.y)==0;}
	friend bool operator != (const point &a,const point &b){return cmp(a.x-b.x)!=0 || cmp(a.y-b.y)!=0;}
	friend point operator * (const point &a,const double &b){return point(a.x*b,a.y*b);}
	friend point operator * (const double &a,const point &b){return point(a*b.x,a*b.y);}
	friend point operator / (const point &a,const double &b){return point(a.x/b,a.y/b);}
	friend double operator * (const point &a ,const point &b) { return a.x*b.y-b.x*a.y; }
	
	inline double len() const {return sqrt(x*x+y*y);}
	inline point rotate(double rad) const {return point(x*cos(rad)-y*sin(rad),x*sin(rad)+y*cos(rad));}
	#ifdef DEBUG
	void print(string debug="debug"){cout<<debug<<" "<<x<<" "<<y<<endl;}
	#endif

};
typedef point vec;
inline double dot(const point &a,const point &b){return a.x*b.x+a.y*b.y;}
inline double dis(const point &a,const point &b){return (a-b).len();}
inline double angle(const point &a,const point &b){return acos(dot(a,b)/a.len()/b.len());}
inline double area(point a,point b,point c){return (b-a)*(c-a)/2.0;}



point CircumCenter(point a,point b,point c){//三角形外心
	vec A=b-a , B=c-a;
	double c1=A.len()*A.len()/2.0 , c2=B.len()*B.len()/2.0;
	return point(a.x+(c1*B.y-c2*A.y)/(A*B),a.y+(A.x*c2-B.x*c1)/(A*B));
}

//点与直线相关
//L 是直线的方向向量
inline double dis_P2L(const point p,const vec L){return p*L/L.len();}
point projection(const point p,const vec L){return L*(dot(L,p)/dot(L,L));}//投影点
point getIntersection(point p,vec v,point q,vec w){//v,w是方向向量,p,q是直线上任意两点
	vec u=p-q;
	double t=(w*u)/(v*w);
	return p+v*t;
}
bool parallel(point a,point b,point c,point d){//平行
	return !(cmp((a-b)*(c-d)));
}




//点与线段相关
bool onSegment(point p,point a1,point a2){
	return cmp((a1-p)*(a2-p))==0 && cmp(dot(a1-p,a2-p))<0;
}
bool seg_intersection(point a1,point a2,point b1,point b2){
	if (onSegment(a1,b1,b2) || onSegment(a2,b1,b2) ||onSegment(b1,a1,a2)||onSegment(b2,a1,a2))	return true;//端点在另一条线段上
	if (a1==b1 || a1==b2 || a2==b1 || a2==b2)	return true;//端点相同
	double c1=(a2-a1)*(b1-a1),c2=(a2-a1)*(b2-a1),c3=(b2-b1)*(a1-b1),c4=(b2-b1)*(a2-b1);
	return cmp(c1)*cmp(c2)<0 && cmp(c3)*cmp(c4)<0;//规范相交
}


bool under(point p,point a,point b){
	if (b.x<a.x)	swap(a,b);
	if (onSegment(p,a,b))	return true;
	if (!seg_intersection(a,b,p,point(p.x,20000.0)))	return false;
	if (cmp(getIntersection(p,point(0,1),a,a-b).y-p.y)>0)	return true;
	return false;
}
int main (int argc, char *argv[])
{	
	int n;
	scanf("%d",&n);
	while (n--){
		double ans;
		double x1,y1,x2,y2,x3,y3,x4,y4;
		cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4;
		point a,b,c,d;
		a=point(x1,y1);
		b=point(x2,y2);
		c=point(x3,y3);
		d=point(x4,y4);
		
		if (!seg_intersection(a,b,c,d)){
			printf("0.00\n");
			continue;
		}
		if (a.y==b.y || c.y==d.y){//cout<<"w"<<endl;
			printf("0.00\n");
			continue;
		}	
		if (parallel(a,b,c,d)){//cout<<"w"<<endl;
			printf("0.00\n");
			continue;
		}	
		
		
		point ins=getIntersection(a,a-b,c,c-d);
		
		//ins.print("ins");
		
		point p;
		double ymin=900000;
		double s=0.0;
		int cnt=0;
		
		
		
		if (a.y>ins.y&&a.y<ymin&&!under(a,c,d)&&seg_intersection(point(-100001,a.y),point(10001,a.y),c,d))	ymin=a.y , p=getIntersection(a,vec(1,0),c,c-d) , s=area(a,p,ins);
		if (b.y>ins.y&&b.y<ymin&&!under(b,c,d)&&seg_intersection(point(-100001,b.y),point(10001,b.y),c,d))	ymin=b.y , p=getIntersection(b,vec(1,0),c,c-d) , s=area(b,p,ins);
		if (c.y>ins.y&&c.y<ymin&&!under(c,a,b)&&seg_intersection(point(-100001,c.y),point(10001,c.y),a,b))	ymin=c.y , p=getIntersection(c,vec(1,0),a,a-b) , s=area(c,p,ins);
		if (d.y>ins.y&&d.y<ymin&&!under(d,a,b)&&seg_intersection(point(-100001,d.y),point(10001,d.y),a,b))	ymin=d.y , p=getIntersection(d,vec(1,0),a,a-b) , s=area(d,p,ins);
		
		
		printf("%.2lf\n",fabs(s));

	}
	return 0;
}

你可能感兴趣的:(计算)