POJ 2074 计算几何 障碍物与视线的问题

来源:互联网 发布:七十二柱魔神 知乎 编辑:程序博客网 时间:2024/04/30 21:47

将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;  // housedouble fx1,fx2,hf;  // property lineint 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;//房子的右点 跟遮挡物的左点 ,yline 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);//房子的左点 跟遮挡物的左点 ,ypoint 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;}


0 0
原创粉丝点击