判断同一平面内任意两线段是否相交的方法

本文介绍了一种用于判断同一平面内两条线段是否相交的方法,并提供了详细的数学原理及C++代码实现。

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

本文给出一种判断同一平面内两线段相交的判定方法。如下图:

如果两线段相交,则两线段必然相互跨立对方。
若P1P2跨立Q1Q2 ,则矢量(P1-Q1)和( P2 - Q1)位于矢量(Q2 - Q1)的两侧,
即((P1-Q1)×(Q2-Q1))*((P2-Q1)×(Q2 -Q1))< 0。
上式可改写成((P1-Q1)×(Q2-Q1))*(( Q2 -Q1)×(P2-Q1 )) > 0。
当(P1-Q1)×(Q2 - Q1)= 0 时,说明 (P1 - Q1 ) 和(Q2 - Q1)共线, 但是因为已经通过快速排斥试验,所以P1一定在线段 Q1Q2上;
同理,(Q2-Q1)×(P2-Q1)=0说明P2一定在线段Q1Q2上。
所以判断P1P2跨立Q1Q2的依据是:
((P1- Q1)×(Q2 - Q1))**((Q2 -Q1)×(P2-Q1))>=0。
同理判断Q1Q2跨立P1P2的依据是:
(Q1-P1 )×(P2-P1)*(P2 -P1)×(Q2 - P1) >= 0。

代码实现:

#include <iostream> #include <math.h> using namespace std; #define ABS_FLOAT_0 0.0001 struct pointf { float x; float y; }; struct Vectorf3D { float x; float y; float z; }; bool IsIntersectLine( const pointf p1, // 线段1起点 const pointf p2, // 线段1终点 const pointf q1, // 线段2起点 const pointf q2 // 线段2终点 ) { Vectorf3D v1, v2, v3, v4; v1.x = (p1.x - q1.x); v1.y = (p1.y - q1.y); v1.z = 0.0; v2.x = (q2.x - q1.x); v2.y = (q2.y - q1.y); v2.z = 0.0; //计算v1,v2的叉乘 v3.x = v1.y * v2.z - v1.z * v2.y; v3.y = v1.z * v2.x - v1.x * v2.z; v3.z = v1.x * v2.y - v1.y * v2.x; v1.x = (p2.x - q1.x); v1.y = (p2.y - q1.y); v1.z = 0.0; //计算v2,v1的叉乘 v4.x = v2.y * v1.z - v2.z * v1.y; v4.y = v2.z * v1.x - v2.x * v1.z; v4.z = v2.x * v1.y - v2.y * v1.x; // 计算v3,v4的点积 float fTemp1 = v3.x * v4.x + v3.y * v4.y + v3.z * v4.z; v1.x = (q1.x - p1.x); v1.y = (q1.y - p1.y); v1.z = 0.0; v2.x = (p2.x - p1.x); v2.y = (p2.y - p1.y); v2.z = 0.0; //计算v1,v2的叉乘 v3.x = v1.y * v2.z - v1.z * v2.y; v3.y = v1.z * v2.x - v1.x * v2.z; v3.z = v1.x * v2.y - v1.y * v2.x; v1.x = (q2.x - p1.x); v1.y = (q2.y - p1.y); v1.z = 0.0; //计算v2,v1的叉乘 v4.x = v2.y * v1.z - v2.z * v1.y; v4.y = v2.z * v1.x - v2.x * v1.z; v4.z = v2.x * v1.y - v2.y * v1.x; // 计算v3,v4的点积 float fTemp2 = v3.x * v4.x + v3.y * v4.y + v3.z * v4.z; if ((fTemp1 >= ABS_FLOAT_0) && (fTemp2 >= ABS_FLOAT_0)) { return true; } else { return false; } } void main(void) { pointf p1, p2, q1, q2; p1.x = 0.0; p1.y = 0.0; p2.x = 30.0; p2.y = 30.0; q1.x = 0.0; q1.y = 20.0; q2.x = 20.0; q2.y = 0.0; if (IsIntersectLine(p1, p2, q1, q2)) { cout<<"线段相交!"<<endl; } else { cout<<"线段不相交!"<<endl; } }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值