1. 程式人生 > >判斷兩個線段是否相交

判斷兩個線段是否相交

.net stream pri nbsp cstring mes using style 相交

判斷兩條直線是否相交有兩步:

1:快速排斥(可以篩除大部分)

2:跨立試驗(下面會有所說明)

現在開始解釋:

第一步快速排斥,實際上就是先判斷一下,假設現在有兩條線段ab,cd,現在我們需要判斷以ab為對角線的矩形是否和以cd為對角線的矩形是否有重合的部分,如果有則我們可以進行下一步判斷,如果沒有那麽這兩條線段肯定不可能相交。

那麽問題來了,我們怎麽判斷兩個矩形是否有重合的部分呢?
如下圖中的兩個矩形;

技術分享圖片

重和的情況:

對於橫向:min(a.x,b.x)<=max(d.x,c.x)&&min(c.x,d.x)<=max(a.x,b.x);

對於縱向: min(a.y,b.y)<=max(d.y,c.y)&&min(c.y,d.y)<=max(a.y,b.y);

只有同時滿足橫向與縱向才能滿足兩個矩形重合。

如果滿足上面的重合要求後,我們就可以進行第二步判斷了,判斷是否相互跨立,註意必須是相互跨立。

對於什麽是跨立?如果兩條線段相交,那麽某一條線段的兩個端點必定分布在另一條線段的兩側,或者這條直線的端點在另一條直線上。具體情況如下:

技術分享圖片

那麽這時候我們就可以用叉乘來判斷了,沒學過的話可以點這個鏈接 點擊打開鏈接。

如圖:

技術分享圖片

若(ca x cd)*(cb x cd)<=0 則說明ca cb先對於cd的方向不同(叉乘的結果),則a b在線段cd的兩側。

同理若(ac x ab)*(ad x ab)<=0,則可以說明兩條線段相互跨立了。

上代碼:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
double x;
double y;
}; 
node a,b,c,d;
bool judge(node a,node b,node c,node d)
{
if(min(a.x,b.x) <= max(c.x,d.x) && min(c.x,d.x) <= max(a.x,b.x) && min(a.y,b.y) <= max(c.y,d.y) &&min(c.y,d.y)<=max(a.y,b.y))
{

double u,v,w,z;//保存叉乘 u=(c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y); v=(d.x-a.x)*(b.y-a.y)-(b.x-a.x)*(d.y-a.y); w=(a.x-c.x)*(d.y-c.y)-(d.x-c.x)*(a.y-c.y); z=(b.x-c.x)*(d.y-c.y)-(d.x-c.x)*(b.y-c.y); return (u*v<=0.00000001 && w*z<=0.00000001); //浮點數判斷大小 } return false; } int main() { cin >> a.x >> a.y; cin >> b.x >> b.y; cin >> c.x >> c.y; cin >> d.x >> d.y; if(judge(a,b,c,d)) { printf("相交\n"); } else { printf("不相交\n"); } return 0; }


水波,借鑒某位大佬的圖,thanks。
---------------------
作者:白黑菜
來源:CSDN
原文:https://blog.csdn.net/qq_36556340/article/details/70039800
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

技術分享圖片

判斷兩個線段是否相交