判断两条线段是否相交 java_判断两个线段是否相交02
寫在前面
在其他博客中看到這方面的知識(shí),很多都是重復(fù),并且說(shuō)的總是云里霧里的,所以這里我就自己總結(jié)一下這種問(wèn)題如何求解,判斷兩個(gè)線段是否相交在前面我們提到了會(huì)用到叉積的一點(diǎn)知識(shí),那么這里就來(lái)詳細(xì)說(shuō)一下怎么判斷兩個(gè)線段是否相交
算法詳解
首先我們看一下快速排斥實(shí)驗(yàn),快速排斥實(shí)驗(yàn)也就是以兩條線段作為對(duì)角線做矩形,判斷兩個(gè)矩形是否相交,那么我們這里可以知道:
1)如果兩個(gè)矩形不相交,那么線段一定不相交
2)如果兩個(gè)矩形相交,那么線段不一定相交,如下圖
所以這里我們首先就要判斷兩條線段形成的矩形是否相交,只有相交我們才要繼續(xù)進(jìn)行判斷后面的線段是否相交.......
跨立實(shí)驗(yàn):前面我們知道叉積可以用來(lái)判斷兩個(gè)向量之間的位置關(guān)系(順時(shí)針還是逆時(shí)針關(guān)系),那么這里我們就會(huì)用到這個(gè)性質(zhì)
我們知道如果兩個(gè)線段相交的話,那么一條線段兩邊的兩個(gè)點(diǎn)要位于另一條線段的兩邊,只有兩條線段都滿足這個(gè)條件,我們就可以判定這兩條直線相交了,那么我們這里所說(shuō)的一條線段兩個(gè)端點(diǎn)位于另一條線段的兩邊,這就是其他博客中提到的跨立吧
那么我們就用叉積來(lái)對(duì)是否滿足這個(gè)條件進(jìn)行判斷:
取其中一個(gè)向量作為中間向量,中間向量中開始端點(diǎn)作為另外兩個(gè)向量的起點(diǎn),判斷三個(gè)向量之間的位置關(guān)系即可:
第一個(gè)圖中: (ca × cd)(cd × cb) >= 0 我們即可判斷滿足跨立條件
第二個(gè)圖中: (bc × ba)(ba × bd) >=0 我們即可判斷滿足跨立條件
第三個(gè)圖中: (bc × ba)(ba × bd)? < 0不滿足跨立條件
第四個(gè)圖中: (ca?× cd)(cd?× cb) >= 0我們即可判斷滿足跨立條件
即計(jì)算(ca × cd)(cd × cb) 與(bc × ba)(ba × bd)的結(jié)果必須同時(shí)大于零,這兩個(gè)線段才是相交的;
當(dāng)然,單獨(dú)判斷其中一個(gè),可以獲得一個(gè)線段所在的直線是否與另一個(gè)線段相交。
那么我們就可以知道上面條件就是判斷跨立是否成立的條件了,那么這樣我們線段是否相交就已經(jīng)可以解決了.
栗子及模板
zoj1648
#include
#include
#include
#include
#include
#define INF 0x3f3f3f3f
using namespace std;
const int MAXN = 2100;
struct Point
{
double x,y;
}line[MAXN][2];
double mult(Point p0,Point p1,Point p2) //叉積計(jì)算,p0為公用節(jié)點(diǎn)
{
return (p0.x - p1.x) * (p0.y - p2.y) - (p0.y - p1.y) * (p0.x - p2.x);
}
//aa、bb屬于同一個(gè)矩形 cc、dd屬于同一個(gè)矩形 相交返回true,不相交返回false
bool Judge(Point aa,Point bb,Point cc,Point dd)
{
//判斷兩個(gè)形成的矩形不相交
if(max(aa.x , bb.x) < min(cc.x , dd.x)) return false;
if(max(aa.y , bb.y) < min(cc.y , dd.y)) return false;
if(max(cc.x , dd.x) < min(aa.x , bb.x)) return false;
if(max(cc.y , dd.y) < min(aa.y , bb.y)) return false;
//現(xiàn)在已經(jīng)滿足快速排斥實(shí)驗(yàn),那么后面就是跨立實(shí)驗(yàn)內(nèi)容(叉積判斷兩個(gè)線段是否相交)
if(mult(aa,cc,bb) * mult(aa,bb,dd) < 0) return false; //正確的話也就是aa,bb要在cc或者dd的兩邊
if(mult(cc,aa,dd) * mult(cc,dd,bb) < 0) return false;
return true;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
bool flag = true;
for(int i = 0;i < n;i ++)
scanf("%lf%lf%lf%lf",&line[i][0].x,&line[i][0].y,&line[i][1].x,&line[i][1].y);
for(int i = 0;i < n;i ++)
for(int j = i+1;j < n;j ++)
{
if(Judge(line[i][0],line[i][1],line[j][0],line[j][1])) // 判斷兩條直線是否相交
{
flag = false;
break;
}
if(!flag) break;
}
if(!flag) printf("burned!\n");
else printf("ok!\n");
}
return 0;
}
參考博客
https://blog.csdn.net/Dacc123/article/details/51219491
https://blog.csdn.net/sizaif/article/details/79192165
---------------------
作者:阿_波_
來(lái)源:CSDN
原文:https://blog.csdn.net/li1615882553/article/details/80372202
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!
C#代碼
usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;public classMathTool : MonoBehaviour
{publicTransform A, B, C, D;//Start is called before the first frame update
voidStart()
{
}//Update is called once per frame
voidUpdate()
{
Debug.Log(IsIntersection0(A.position, B.position, C.position, D.position));
}//不優(yōu)化的情況下
boolIsIntersection0(Vector3 a, Vector3 b, Vector3 c, Vector3 d)
{
Vector3 ca= A.position -C.position;
Vector3 cb= B.position -C.position;
Vector3 cd= D.position -C.position;
Vector3 ba= A.position -B.position;
Vector3 bc= C.position -B.position;
Vector3 bd= D.position -B.position;
Vector3 c1=Vector3.Cross(ca, cd);
Vector3 c2=Vector3.Cross(cd, cb);float f1 =Vector3.Dot(c1, c2);
Vector3 c3=Vector3.Cross(bc, ba);
Vector3 c4=Vector3.Cross(ba, bd);float f2 =Vector3.Dot(c3, c4);//必須f1,f2同時(shí)滿足大于等于0才能算相交
if (f1 >= 0&&f2>=0) return true;else return false;
}
}
總結(jié)
以上是生活随笔為你收集整理的判断两条线段是否相交 java_判断两个线段是否相交02的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 在演讲中如何吸引你的听众技巧
- 下一篇: jsmap(桔色棉袄配什么颜色打底衫)