判斷原理:
先判斷線段四點在空間中是否共面
可以用行列式來判斷
用四個點求出三個向量分別為(x1,y1,z1),(x2,y2,z2),(x3,y3,z3)
判斷行列式
| x1 x2 x3|
| y1 y2 y3|
| z1 z2 z3|
或者它的轉置是否為零
若為零則四點共面
判斷平面內兩線段是否有交點
快速排斥實驗+跨立實驗
演算法詳解可以了解:
快速排斥、跨立實驗判斷線段是否相交
public bool intersect
(double
aa,
double
bb,
double
cc,
double
dd)
double x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4, r1, r2, r3, r4, r5, r6, r7, r8, r9;
for(
int i =
0; i <
3; i++
)//將陣列中的所有值保留兩位小數點
x1 = aa[0]
; x2 = bb[0]
;x3 = cc[0]
;x4 = dd[0]
; y1 = aa[1]
; y2 = bb[1]
; y3 = cc[1]
; y4 = dd[1]
; z1 = aa[2]
; z2 = bb[2]
; z3 = cc[2]
; z4 = dd[2]
;//計算行列式,判斷其行列式值是否為0,說明四點是否共面
r1 = x1 - x2; r2 = y1 - y2; r3 = z1 - z2;
r4 = x1 - x3; r5 = y1 - y3; r6 = z1 - z3;
r7 = x1 - x4; r8 = y1 - y4; r9 = z1 - z4;
if(r1 * r5 * r9 + r2 * r6 * r7 + r3 * r8 * r4 - r1 * r8 * r6 - r2 * r4 * r9 - r3 * r5 * r7 ==0)
if(!fequ
(math.
max(aa[1]
, bb[1]
), math.
min(cc[1]
, dd[1]
))&& math.
max(aa[1]
, bb[1]
)< math.
min(cc[1]
, dd[1]
))if(
!fequ
(math.
max(cc[0]
, dd[0]
), math.
min(aa[0]
, bb[0]
))&& math.
max(cc[0]
, dd[0]
)< math.
min(aa[0]
, bb[0]
))if(
!fequ
(math.
max(cc[1]
, dd[1]
), math.
min(aa[1]
, bb[1]
))&& math.
max(cc[1]
, dd[1]
)< math.
min(aa[1]
, bb[1]
))if(
mult
(cc, bb, aa)
*mult
(bb, dd, aa)
<0)
if(mult
(aa, dd, cc)
*mult
(dd, bb, cc)
<0)
return true;
}else
}double
mult
(double
a,double
b,double
c)//叉積計算,c為共用節點
計算空間中兩條線段的最小距離
一 基礎知識 本來是空間三維座標系,只是為了便於理解所以採用一般的2維座標,其實是一樣的 1 設ab線段 a a.x,a.y b b.x,b.y 在ab上有一點為q,q.x a.x s a.x b.x q.y a.y s a.y b.y 2 設cd線段 c c.x,c.y d d.x,d.y 在cd...
判斷兩條線段是否相交(C )
背景 在做51nod上的第1951題時,需要根據給出的兩條線段來判斷這兩條線段是否相交。所以在這裡記錄一下。判斷兩條線段是否相交有兩步 快速排斥計算 跨立計算 快速排斥 給出線條ab cd,如果以ab cd為對角線的矩形不相交,那麼ab cd也必不可能相交 如果矩形相交,那麼需要再通過跨立計算進行判...
判斷兩條線段是否相交
如上圖,判斷線段ab和線段cd相交。分析 如果線段ab和線段cd相交,只能是圖中的兩種相交情況。可以用向量叉乘來判斷。如果 向量ab叉乘向量ac 向量ab叉乘向量ad 0 並且 向量cd叉乘向量ca 向量cd叉乘向量cb 0,那麼說明線段ab與線段cd相交。設a x1,y1 b x2,y2 c x3...