POJ 1410 Intersection [线段相交+点在多边形内]




点击打开链接



题意:

       给你一个矩形,一条线段。请你判断线段和矩形的关系,

相交T 否则 F

       注意一点线段完全在矩形内的话也是T



题解:

       每个线段找出来,判断线段相交,

       构造出多边形,判断线段两点和矩形关系。


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
//#include<pair>
#include<cmath>
#include<vector>
#define x first
#define y second
using namespace std;
inline int read(){int x=0,f=1;char c=getchar();for(;!isdigit(c);c=getchar())
if(c=='-')f=-1;for(;isdigit(c);c=getchar())x=x*10+c-'0';return x*f;}
const double eps=1e-8;
const double PI=acos(-1.0);
const int maxn=1e5+10;
const int inf=0xffffff;
int sgn(double x){
    if(fabs(x)<eps) return 0;
    if(x<0) return -1;
    return 1;
}
struct Point{
    double x,y;
    Point(){}
    Point(double _x,double _y){
        x=_x;y=_y;
    }
    Point operator -(const Point &b)const{
        return Point(x-b.x,y-b.y);
    }
    Point operator +(const Point &b)const{
        return Point(x+b.x,y+b.y);
    }
    double operator ^ (const Point &b)const{
        return x*b.y - y*b.x;
    }
};
struct Line{
    Point s,e;
    Line(){}
    Line(Point _s,Point _e){
        s=_s;e=_e;
    }
};
bool inter(Line l1,Line l2){
    return
    max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&&
    max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&&
    max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&&
    max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&&
    sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0&&
    sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e))<=0;
}
bool OnSeg(Point P,Line L){
    return
    sgn((L.s-P)^(L.e-P))&&
    sgn((P.x-L.s.x)*(P.x-L.e.x))<=0&&
    sgn((P.y-L.s.y)*(P.y-L.e.y))<=0;
}
int inConvexPoly(Point a,Point p[],int n){
    for(int i=0;i<n;++i){
        if(sgn((p[i]-a)^(p[(i+1)%n]-a))<0) return -1;
        else if(OnSeg(a,Line(p[i],p[(i+1)%n]))) return 0;
    }
    return 1;
}
int inpoly(Point p,Point poly[],int n){
    int cnt=0;
    Line ray,side;
    ray.s=p;
    ray.e.y=p.y;
    ray.e.x=-inf;
    for(int i=0;i<n;++i){
        side.s=poly[i];
        side.e=poly[(i+1)%n];
        if(OnSeg(p,side)) return 0;
        if(sgn(side.e.y-side.e.y)==0) continue;
        if(OnSeg(side.s,ray))
            if(sgn(side.s.y-side.e.y)>0) cnt++;
        else if(OnSeg(side.e,ray))
            if(sgn(side.e.y-side.s.y)>0) cnt++;
        else if(inter(ray,side)) cnt++;
    }
    if(cnt%2==1) return 1;
    return -1;
}
Point p[5],p1,p2,p3;
Line l[maxn],t1,t2,t3,t4;
bool v[maxn];
int main(){
    int t,n,cnt;
    double x1,x2,x3,x4,y1,y2,y3,y4;
    scanf("%d",&t);
    while(t--){
        scanf("%lf %lf %lf %lf %lf %lf %lf %lf",&x3,&y3,&x4,&y4,&x1,&y1,&x2,&y2);
        //x1=read();y1=read();x2=read();y2=read();
        p[0]={x1,y1};p[1]={x2,y1};
        p[2]={x1,y2};p[3]={x2,y2};
        p2={x3,y3};p3={x4,y4};
        l[1]={p[0],p[2]};
        l[2]={p[0],p[3]};
        l[3]={p[1],p[2]};
        l[4]={p[1],p[3]};
        t1={p2,p3};
        int f=0;
        for(int i=1;i<=4;++i){
            //printf("%f %f   %f %f\n",l[i].s.x,l[i].s.y,l[i].e.x,l[i].e.y);
            if(inter(t1,l[i])) f=1;
        }
        if(f)puts("T");
        //else if(inpoly(p2,p,4)>=0||inpoly(p3,p,4)>=0) puts("T");//这里用哪个都对
        else if(inConvexPoly(p2,p,4)>=0||inConvexPoly(p3,p,4)>=0) puts("T");
        else puts("F");
    }
	return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值