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

说明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两侧(或线上) 

几点思考: 
一、对于两线段在同一直线上且头尾一点相交,最后两个判断能过这种情况。如果头尾不想交,前面四个判断不能过。 
二、对于两线段平行的情况,最后两个判断不能过。 
三、对于端点在另一线段中间的情况,最后两个判断能过。 
四、综上,这个简单精练的判断函数值得大家进行进一步的思考与探究。 
附图一张: 
见附件 
-- 
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在C++中,可以通过计算两条直线的斜率和截距来判断它们是否相交,并且计算出交点的坐标。 假设我们已知两条直线上的两个点的坐标分别为 (x1, y1) 和 (x2, y2),(x3, y3) 和 (x4, y4)。我们可以使用以下步骤来判断它们是否相交,并计算出交点的坐标: 1. 计算第一条直线的斜率 m1 和截距 b1: ```cpp double m1 = (y2 - y1) / (x2 - x1); double b1 = y1 - m1 * x1; ``` 2. 计算第二条直线的斜率 m2 和截距 b2: ```cpp double m2 = (y4 - y3) / (x4 - x3); double b2 = y3 - m2 * x3; ``` 3. 判断斜率是否相等,若相等则两条直线平行,不相交。 ```cpp if (m1 == m2) { // 两条直线平行,不相交 return false; } ``` 4. 计算交点的 x 坐标: ```cpp double x = (b2 - b1) / (m1 - m2); ``` 5. 计算交点的 y 坐标: ```cpp double y = m1 * x + b1; ``` 6. 判断交点是否在两条直线的线段范围内,若不在范围内则两条直线相交的是延长线而不是线段。 ```cpp if (x < min(x1, x2) || x > max(x1, x2) || x < min(x3, x4) || x > max(x3, x4)) { // 交点不在两条直线的线段范围内 return false; } ``` 7. 返回交点坐标。 ```cpp intersectionPointX = x; intersectionPointY = y; return true; ``` 以下是一个完整的示例代码: ```cpp #include <iostream> #include <algorithm> bool areIntersecting(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double& intersectionPointX, double& intersectionPointY) { double m1 = (y2 - y1) / (x2 - x1); double b1 = y1 - m1 * x1; double m2 = (y4 - y3) / (x4 - x3); double b2 = y3 - m2 * x3; if (m1 == m2) { return false; } double x = (b2 - b1) / (m1 - m2); double y = m1 * x + b1; if (x < std::min(x1, x2) || x > std::max(x1, x2) || x < std::min(x3, x4) || x > std::max(x3, x4)) { return false; } intersectionPointX = x; intersectionPointY = y; return true; } int main() { double x1 = 1.0, y1 = 1.0; // 第一条直线上的点1坐标 double x2 = 5.0, y2 = 5.0; // 第一条直线上的点2坐标 double x3 = 2.0, y3 = 5.0; // 第二条直线上的点1坐标 double x4 = 6.0, y4 = 1.0; // 第二条直线上的点2坐标 double intersectionPointX, intersectionPointY; if (areIntersecting(x1, y1, x2, y2, x3, y3, x4, y4, intersectionPointX, intersectionPointY)) { std::cout << "两条直线相交,交点坐标为 (" << intersectionPointX << ", " << intersectionPointY << ")" << std::endl; } else { std::cout << "两条直线不相交" << std::endl; } return 0; } ``` 这样,我们就可以判断两条直线是否相交,并且得到它们的交点坐标

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值