将house的右端点跟所有障碍物的左端点连接起来,之后延长交与property_line点x_left。
将将house的左端点跟所有障碍物的右端点连接起来,之后延长交与property_line点x_right。
这样得到bleacher线上的left跟right点,从左到右扫描一次。 就可以算出答案了。
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
const double eps = 1e-8;
const int MAXN = 1111;
double hx1,hx2,hy; // house
double fx1,fx2,hf; // property line
int n;
bool isZero(double a){
if(fabs(a) < eps)
return true;
else return false;
}
struct point
{
double x,y;
point(){}
point(double _x,double _y){ x=_x,y=_y;}
};
struct line
{
point a,b;
line(){}
line(point _a,point _b){a = _a,b=_b;}
}L[MAXN];
//通过一条直线的两个点,计算在某一个y坐标时的坐标
point pointGetFromLine(line &l,double y){
if( isZero(l.a.y - l.b.y) ){
if(isZero(l.a.y - y))
return point(0.0,y);
return point(0.0,0.0);
}else if(isZero(l.a.x - l.b.x)){
return point(l.a.x,y);
}else{
double ret = l.a.x - (l.a.y - y)*(l.b.x-l.a.x)/(l.b.y - l.a.y);
return point(ret,y);
}
}
struct inFireLine{
point p1;
point p2;
inFireLine(){}
inFireLine(point _p1,point _p2){
p1=_p1; p2=_p2;
}
}inFire[MAXN<<1];
//bool cmp(int i,int j){
// return inFire[i].p.x < inFire[j].p.x || ( inFire[i].p.x == inFire[j].p.x && !is_right);
//}
bool cmp(const inFireLine &f1, const inFireLine &f2){
return f1.p1.x < f2.p1.x || ( f1.p1.x == f2.p1.x && f1.p2.x < f2.p2.x);
}
int firCur;
void solve(){
point p_house_left = point(hx1,hy),p_house_right = point(hx2,hy);
firCur = 0;
for(int i = 0;i < n;i++){
if(L[i].a.y + eps > hy || L[i].a.y + eps < hf || isZero(hy - L[i].a.y) || isZero(hf - L[i].a.y) ) //不在中间的障碍物直接抛弃
continue;
//房子的右点 跟遮挡物的左点 ,y
line l1 = line(p_house_right,L[i].a);
point t1 = pointGetFromLine( l1, hf);
t1.x = max(1.0*fx1,t1.x);
line l2 = line(p_house_left,L[i].b);
//房子的左点 跟遮挡物的左点 ,y
point t2 = pointGetFromLine( l2, hf);
t2.x = min(1.0*fx2,t2.x);
if(t1.x > fx2 + eps || t2.x +eps < fx1)
continue;
inFire[firCur++] = inFireLine(t1,t2);
}
sort(inFire,inFire+firCur,cmp);
double ans = 0;
double lastX = fx1,left_tot = 0; //left_tot是计算左节点的数目
if(firCur){
for(int i = 0;i < firCur;i++){
if(inFire[i].p1.x > lastX + eps){
ans = max(ans, inFire[i].p1.x - lastX);
lastX = inFire[i].p2.x;
}else if(inFire[i].p2.x > lastX + eps){
lastX = inFire[i].p2.x;
}
}
if(lastX + eps < fx2)
ans = max(ans,fx2 - lastX);
}else{
ans = fx2-fx1;
}
if(isZero(ans)){
printf("0.00\n");
}else{
printf("%.2lf\n",ans);
}
}
int main(){
while(cin >> hx1 >> hx2 >> hy){
if(isZero(hx1+hx2+hy))
break;
cin >> fx1 >> fx2 >> hf;
cin >> n;
double a,b,c;
for(int i = 0;i < n;i++){
cin >> a >> b >> c;
L[i].a = point(a,c); L[i].b = point(b,c);
}
solve();
}
return 0;
}