c语言 如何判断两个矩形是否有交集,如何判断线段与矩形有交集(降维法)

本文介绍了一种判断线段AB与矩形MN交集的高效方法,包括使用向量叉积排除快速判断和降维策略,详细步骤涉及计算线段上的特殊点并比较它们与矩形投影的交集。适用于平行边矩形的场景。

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

如何判断线段与矩形有交集(降维法)

判断线段AB是否与矩形范围有交集

这里的矩形指的是边与坐标轴平行的矩形,可用x和y上最大最小值表示。

判断是否相交,先快速排斥,再做跨立,通过向量的叉积判断矩形的四个顶点是否在线段的两侧,是说明有交集。

(如果判断与矩形的边是否有交集的话,可判断线段是否与矩形的每条边是否有交集,线段与线段的交集判断。)

这里在介绍另外一种方法,降维的方法:

例如,有线段AB和矩形MN,如图所示:

5847bea0ae8f6415f453ad900d7e1fe8.png

通过M和N点的y坐标计算直线AB上的D和C点,B和C点中取y值小的点B,A和D点中取y值大的点D,

最后确定了线段BD在x轴上的投影GH,矩形在x轴上的投影EF,判断EF和GH是否有交集。

typedef struct tagPOINT{//点

float x;

float y;

}POINT;

typedef struct tagRECT{//矩形

float top;

float bottom;

float left;

float right;

}RECT;

/**

* @brief 判断区间[x1, x2]和区间[x3, x4](x4可能小于x3)是否有交集

* @retval 有返回1,无0

*/

int IntervalOverlap(float x1, float x2, float x3, float x4)

{

float t;

if (x1 > x2)

{

t = x1;

x1 = x2;

x2 = t;

}

if (x3 > x4)

{

t = x3;

x3 = x4;

x4 = t;

}

if (x3 > x2 || x4 < x1)

return 0;

else

return 1;

}

/**

* @brief 判断线段AB与矩形R是否有交集

* @retval 有交集返回1,无0

*/

int RSIntersection(RECT R, POINT A, POINT B)

{

POINT t;

POINT C,D;

float k;

if(A.y == B.y) // 线段平行于x轴

{

if(A.y <= R.top && A.y >= R.bottom)

{

return IntervalOverlap(R.left, R.right, A.x, B.x);

}

else{

return 0;

}

}

// AB两点交换,让B点的y坐标最大

if(A.y > B.y)

{

t = A;

A = B;

B = t;

}

// 在线段AB上确定点C和D

// 两点确定一条直线: (x-x1)/(x2-x1)=(y-y1)/(y2-y1)

k = (B.x - A.x)/(B.y - A.y);

if(A.y < R.bottom)

{

C.y = R.bottom;

C.x = k * (C.y - A.y) + A.x;

}

else{

C = A;

}

if(B.y > R.top)

{

D.y = R.top;

D.x = k * (D.y - A.y) + A.x;

}

else{

D = B;

}

if (D.y >= C.y) // y维上有交集

{

return IntervalOverlap(R.left, R.right, D.x, C.x);

}

else

{

return 0;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值