首页 > 其他 > 详细

poj1039(计算几何)线段相交

时间:2014-05-21 16:38:48      阅读:343      评论:0      收藏:0      [点我收藏+]

题意:给一个管道求光线能穿到的最大x坐标。

bubuko.com,布布扣

解法:通过旋转光线一定可以使得光线接触一个上点和一个下点。枚举接触的上下点,然后逐一判断光线是否穿过每个拐点面。碰到一个拐点面没有穿过的,则是因为与其左边线段相交,求出直线与线段交点更新答案即可。不想交则说明在前一个拐点已经穿出去了。


代码:

/******************************************************
* author:xiefubao
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <string.h>
//freopen ("in.txt" , "r" , stdin);
using namespace std;

#define eps 1e-10
const double pi=acos(-1.0);
typedef long long LL;
const int Max=10100;
const int INF=1000000007;
struct point
{
    double x,y;
} points1[30],points2[30];
int n;
int mult(point a,point b,point c)
{
    a.x-=c.x;
    a.y-=c.y;
    b.x-=c.x;
    b.y-=c.y;
    double tool=a.x*b.y-a.y*b.x;
    if(abs(tool)<=eps)
        return 0;
    if(tool<0)
        return -1;
    return 1;
}
double mult2(point a,point b,point c)
{
    a.x-=c.x;
    a.y-=c.y;
    b.x-=c.x;
    b.y-=c.y;
    return a.x*b.y-a.y*b.x;
}
bool OK(point p1,point p2,int i)
{
    return mult(p1,p2,points1[i])*mult(p1,p2,points2[i])<=0;
}

bool inter(point p1,point p2,point p3,point p4)
{
    if(mult(p1,p2,p3)*mult(p1,p2,p4)<0)
        return true;
    return false;
}
double getx(point p1,point p2,point p3,point p4)
{
    double area1=abs(mult2(p1,p2,p3)),area2=abs(mult2(p1,p2,p4));
    return area1/(area1+area2)*p4.x+area2/(area1+area2)*p3.x;
}
double solve(point p1,point p2)
{
    if(!OK(p1,p2,0))
        return points1[0].x;
    for(int i=1; i<n; i++)
    {
        if(!OK(p1,p2,i))
        {
            if(inter(p1,p2,points1[i-1],points1[i]))
                return getx(p1,p2,points1[i-1],points1[i]);
            if(inter(p1,p2,points2[i-1],points2[i]))
                return getx(p1,p2,points2[i-1],points2[i]);
            return points1[i-1].x;
        }
    }
    return points1[n-1].x;
}
int main()
{
    while(scanf("%d",&n)==1&&n)
    {
        for(int i=0; i<n; i++)
        {
            scanf("%lf%lf",&points1[i].x,&points1[i].y);
            points2[i].x=points1[i].x;
            points2[i].y=points1[i].y-1.0;
        }
        double ans=points1[0].x;
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
            {
                if(i==j)continue;
                ans=max(ans,solve(points1[i],points2[j]));//cout<<i<<" "<<j<<" "<<solve(points1[i],points2[j])<<endl;
            }
        if(abs(ans-points1[n-1].x)<eps)
            printf("Through all the pipe.\n");
        else
            printf("%.2f\n",ans);
    }
    return 0;
}
/*
4
0 1
1 2
2 1
3 -1
4
-301 1
-254 8
-196 3
-52 13
4
0 1
2 2
4 1
6 4
6
0 1
2 -0.6
5 -4.45
7 -5.57
12 -10.8
17 -16.55
*/

poj1039(计算几何)线段相交,布布扣,bubuko.com

poj1039(计算几何)线段相交

原文:http://blog.csdn.net/xiefubao/article/details/26396051

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!