线段判交——poj2826
目前poj似乎数据出了问题,拿以前a的代码交上去也是wa
总体来说,要考虑三种答案0.00的情况
1.线段不相交
2.一根线段水平
3.开口被封闭,即高的那一端把低的那一端完全遮住了
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; typedef double db; const db eps=1e-6; const db pi=acos(-1); int sign(db k){if (k>eps) return 1; else if (k<-eps) return -1; return 0;} int cmp(db k1,db k2){return sign(k1-k2);} struct point{ db x,y; point(){} point(db x,db y):x(x),y(y){} point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};} point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};} point operator * (db k1) const{return (point){x*k1,y*k1};} point operator / (db k1) const{return (point){x/k1,y/k1};} }; struct line{ point p[2]; }; db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;} int intersect(db l1,db r1,db l2,db r2){ if(l1>r1)swap(l1,r1);if(l2>r2)swap(l2,r2); return cmp(r1,l2)!=-1 && cmp(r2,l1)!=-1; } int checkSS(point k1,point k2,point k3,point k4){ return intersect(k1.x,k2.x,k3.x,k4.x)&&intersect(k1.y,k2.y,k3.y,k4.y)&& sign(cross(k3-k1,k4-k1))*sign(cross(k3-k2,k4-k2))<=0 && sign(cross(k1-k3,k2-k3))*sign(cross(k1-k4,k2-k4))<=0; } point getLL(point k1,point k2,point k3,point k4){ db w1=cross(k1-k3,k4-k3),w2=cross(k4-k3,k2-k3); return (k1*w2+k2*w1)/(w1+w2); } point p[10],k1,k2,k3,k4,k5,k6,k7; line l1,l2,l3; int main(){ int t;cin>>t; while(t--){ scanf("%lf%lf",&k1.x,&k1.y); scanf("%lf%lf",&k2.x,&k2.y); scanf("%lf%lf",&k3.x,&k3.y); scanf("%lf%lf",&k4.x,&k4.y); l1.p[0]=k1;l1.p[1]=k2; l1.p[0]=k3;l1.p[1]=k4; if(checkSS(k1,k2,k3,k4)==0){ puts("0.00");continue; } int tot=0; k5=getLL(k1,k2,k3,k4);//两线段交点 if(k1.y>k5.y)p[++tot]=k1;//找两个比交点高的点 if(k2.y>k5.y)p[++tot]=k2; if(k3.y>k5.y)p[++tot]=k3; if(k4.y>k5.y)p[++tot]=k4; if(tot!=2){ puts("0.00");continue; } if(p[1].y>p[2].y)swap(p[1],p[2]); //判封闭,从p1用一根直线向上 point tmp=p[1];tmp.y+=100000; if(checkSS(p[1],tmp,k5,p[2])){ point k8=getLL(p[1],tmp,k5,p[2]); if(k8.y>p[1].y){ puts("0.00");continue; } } //求面积,从p1用一根直线横向延伸 k6=p[1];k6.x++; k7=getLL(k6,p[1],k5,p[2]); db area=0.5*(k6.y-k5.y)*fabs(k7.x-p[1].x); printf("%.2f\n",area); } } /* 9 6259 2664 8292 9080 1244 2972 9097 9680 0 1 1 0 1 0 2 1 0 1 2 1 1 0 1 2 0 0 10 10 0 0 9 8 0 0 10 10 0 0 8 9 0.9 3.1 4 0 0 3 2 2 0 0 0 2 0 0 -3 2 1 1 1 4 0 0 2 3 1 2 1 4 0 0 2 3 */