POJ 1410 || Intersection(线段矩形相交

本文详细介绍了如何使用计算几何方法判断线段与矩形的相交情况,包括两种相交方式的判断流程,并通过代码实例展示了实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

判断线段与矩形相交有两种相交方式:

1)线段与矩形的四条边的其中一条至少有一个交点(X积判断

2)线段再矩形内(用坐标大小判断

得意十分钟一A一计算几何水题,感觉自己越来越棒了。

513KB,0MS

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps = 1e-8;
int dcmp( double x )
{
    if( fabs(x)<eps)
        return 0;
    return x < 0 ? -1: 1;
}

//================= 点结构 ===============
struct pnode
{
    double x,y;
    pnode( double a=0.0,double b=0.0):x(a),y(b){}

    // X乘重载
    double operator ^ (const pnode &b)const
    {
        return x*b.y - b.x*y;
    }

    pnode operator - ( const pnode &b)const
    {
        return pnode( x-b.x,    y-b.y);
    }
};
//================ 线结构 ==============
typedef pnode myvec;
struct pline
{
    pnode st,ed;//st:起始点 ed:终点
    myvec vec;//向量
    pline(){}

    pline(pnode a,pnode b):st(a),ed(b)
    {
        vec = pnode(b-a);
    }
    void readl()
    {
        scanf("%lf %lf %lf %lf",&st.x,&st.y,&ed.x,&ed.y);
    }
};
double cross( pnode p0,pnode p1,pnode p2)
{
    return (p1-p0) ^ (p2-p0);
}
pline seg;
pline rec[5];
double xl,yt,xr,yb;
void set_rec()
{
    rec[0] = pline( pnode(xl,yb),pnode(xl,yt) );
    rec[1] = pline( pnode(xl,yt),pnode(xr,yt) );
    rec[2] = pline( pnode(xr,yt),pnode(xr,yb) );
    rec[4] = pline( pnode(xr,yb),pnode(xl,yb) );
}
//线段是否与矩形四条边至少有一个交点
bool seg_inter_seg(pline a,pline b)
{

    return
        max( a.st.x, a.ed.x) >=  min( b.st.x, b.ed.x)
    &&
        max( b.st.x, b.ed.x) >=  min( a.st.x, a.ed.x)
    &&
        max( a.st.y, a.ed.y) >=  min( b.st.y, b.ed.y)
    &&
        max( b.st.y, b.ed.y) >=  min( a.st.y, a.ed.y)
    &&//以上端点判断
        dcmp(cross( a.st, a.ed, b.st ))*dcmp(cross( a.st, a.ed, b.ed ))<=0
    &&  dcmp(cross( b.st, b.ed, a.st ))*dcmp(cross( b.st, b.ed, a.ed ))<=0;
}
//线段是否再矩形内
bool seg_in_rec()
{
    return
        seg.st.x >= min(xl,xr) && seg.st.x <= max(xl,xr)
    &&  seg.ed.x >= min(xl,xr) && seg.ed.x <= max(xl,xr)
    &&  seg.st.y >= min(yt,yb) && seg.st.y <= max(yt,yb)
    &&  seg.ed.y >= min(yt,yb) && seg.ed.y <= max(yt,yb);
}
int main()
{

    int n;
    scanf("%d",&n);
    while( n-- )
    {
        seg.readl();
        scanf("%lf %lf %lf %lf",&xl,&yt,&xr,&yb);

        set_rec();

        bool ok = false;
        for( int i = 0;i<4;++i)
        {
            if(seg_inter_seg(seg,rec[i]))
            {
                ok = true;
                break;
            }
        }

        if( ok == false )
            if( seg_in_rec())
                ok = true;
        if( ok )
            puts("T");
        else
            puts("F");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值