已知两线段的四点坐标,如何判断两线段是否相交的思路

本文介绍了如何通过定义TPoint和TLineSeg数据结构来简化线段相交问题的处理,并详细阐述了一种用于判断两条线段是否相交的算法。该算法首先检查由两条线段构成的矩形是否相交,然后利用矢量叉乘判断线段是否跨越对方。文章还讨论了几种特殊情况,并提供了一个简洁的判断函数。

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

说明TPoint和TLineSeg的定义了:) 
struct TPoint { 
float x,y; 
}; 
//TPoint是指线段端点的坐标 
  
struct TLineSeg { 
TPoint a,b; 
}; 
//TLineSeg是指线段的两个端点 
//这里编者巧妙地把线段和坐标两个事物通过定义一对嵌套的数据结构来简化。许多初学者会定义诸如dot1x,dot1y,dot2x,dot2y这种难以区分的数据结构。 
算法简单说明: 
①判断以两条线段为对角线的矩形是否相交,如果不相交两条线段肯定也不相交。 
②如果相交的话,利用矢量叉乘判断两条线段是否相互跨越,如果相互跨越显然就相交,反之则不相交。 
算法不难,但是一些特殊情况需要考虑到,比如两条相段共线且在断点处相交。 
  
/******************************************************** * * 
  * 返回(P1-P0)*(P2-P0)的叉积。 * 
  * 若结果为正,则 <P0,P1> 在 <P0,P2> 的顺时针方向;(夹角为正) * 
  * 若为0则 <P0,P1> <P0,P2> 共线;(夹角为0) * 
  * 若为负则 <P0,P1> 在 <P0,P2> 的在逆时针方向; (夹角为负)* 
  * 可以根据这个函数确定两条线段在交点处的转向, * 
  * 比如确定<p0,p1>和<p1,p2>在p1处是左转还是右转,只要 * 
  * 求(p2-p0)×(p1-p0),若小于0则左转,大于0则右转,等于0则 * 
  * 共线 * 
  * * 
\********************************************************/ 
float multiply(TPoint p1,TPoint p2,TPoint p0) 

return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y)); 

//a(x1,y1),b(x2,y2) 
//x1*y2-x2*y1 
  
//确定两条线段是否相交 
int intersect(TLineSeg u,TLineSeg v) 

return( (max(u.a.x,u.b.x)> =min(v.a.x,v.b.x))&&  //u中最右的点是否在v最左的点的右边 
  (max(v.a.x,v.b.x)> =min(u.a.x,u.b.x))&& //v中最右的点是否在u最左的点的右边 
//判断这两条线段在水平层面上是否可能相交 
  (max(u.a.y,u.b.y)> =min(v.a.y,v.b.y))&& //u中最上的点是否在v最下的点的上边 
  (max(v.a.y,v.b.y)> =min(u.a.y,u.b.y))&& //v中最上的点是否在u最下的点的上边 
//判断这两条线段在垂直层面上是否可能相交 
(multiply(v.a,u.b,u.a)*multiply(u.b,v.b,u.a)> =0)&&   
//判断v.a,v.b是否分布在u.b两侧(或线上) 
  (multiply(u.a,v.b,v.a)*multiply(v.b,u.b,v.a)> =0));   
  //判断u.a,u.b是否分布在v.a两侧(或线上) 

几点思考: 
一、对于两线段在同一直线上且头尾一点相交,最后两个判断能过这种情况。如果头尾不想交,前面四个判断不能过。 
二、对于两线段平行的情况,最后两个判断不能过。 
三、对于端点在另一线段中间的情况,最后两个判断能过。 
四、综上,这个简单精练的判断函数值得大家进行进一步的思考与探究。 
附图一张: 
见附件 
-- 
### 计算两条相交直线的内角平分线方向 对于给定的两条相交直线,假设这两条直线分别表示为 \(L_1\) 和 \(L_2\),其斜率分别为 \(m_1\) 和 \(m_2\)[^2]。为了找到这两条直线之间形成的两个角度之一的内部平分线的方向,可以采用以下方法: #### 方法概述 考虑通过几何关系来求解这个问题。当已知两直线的斜率时,可以通过下面给出的方法计算得到内角平分线的斜率。 #### 斜率转换成角度 每条直线相对于x轴的角度 \(\theta_i (i=1,2)\),可以根据反正切函数由各自的斜率得出: \[ \theta_1 = \arctan(m_1) \] \[ \theta_2 = \arctan(m_2) \] 这里需要注意的是,在实际编程实现中应使用 `atan2` 函数而不是简单的 `atan` 来处理不同象限的情况。 #### 平均角度作为内角平分线方向 一旦获得了这两个角度,就可以取平均值得到夹在这两者中间的那个角——即所求的内角平分线对应的角度 \(\alpha\): \[ \alpha = (\theta_1 + \theta_2)/2 \] 最后一步是将这个角度转回斜率的形式用于描述这条新的直线。因此, \[ m_{bisector} = \tan(\alpha) \] 这便是所需的结果:新直线上任意一点处的导数或者说该直线的斜率。 ```python import math def angle_to_slope(theta): """Convert an angle to a slope.""" return math.tan(math.radians(theta)) def bisecting_line_slope(slope1, slope2): theta1 = math.degrees(math.atan2(slope1, 1)) theta2 = math.degrees(math.atan2(slope2, 1)) alpha = (theta1 + theta2) / 2 return angle_to_slope(alpha) # Example usage with two slopes slope_a = 0.5 # example value for L1's slope slope_b = -1.0 # example value for L2's slope print(f"The slope of the internal angle bisector is {bisecting_line_slope(slope_a, slope_b)}") ``` 上述代码展示了如何基于输入的两条直线的斜率计算出它们之间的内角平分线的斜率。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值