詳情點選數學基礎之向量點乘與叉乘
常用的方法是通過向量叉乘來判斷,這種方法不需要算出直線方程(再判斷交點有否),在**實現上比較簡便。
用這種方法判別線段是否相交一般分為兩步:
1. 快速排斥實驗
2. 跨立實驗
首先判斷兩條線段在$x$以及$y$座標的投影是否有重合。也就是判斷乙個線段中$x$較大的端點是否小於另乙個線段中$x$較小的段點,若是,則說明兩個線段必然沒有交點,同理判斷下$y$。
//如果四條判斷有乙個為真,則代表兩線段必不可交,否則應該進行第二步判斷。
max(c.x,d.x)顯然,上圖通不過快速排斥實驗。
計算向量叉乘是與直線和線段相關演算法的核心部分。
設向量$\vec p = (x_1, y_1)$,$\vec q = (x_2, y_2)$,則向量叉乘定義為:$\vec p \times \vec q = x_1 * y_2 - x_2 * y_1$,其結果是乙個向量,且為向量$\vec p$, $\vec q$所在平面的法向量。顯然有性質$\vec p \times \vec q = - (\vec q \times \vec p)$和$\vec p \times (-\vec q) = - (\vec p \times \vec q)$。
叉乘的乙個非常重要性質是可以通過它的符號判斷兩向量相互之間的順逆時針關係:
0'>然後我們來看看臨界情況,也就是上式恰好等於 0 的情況下:
當出現如上圖所示的情況的時候,($\vec $ $\times$ $\vec $) * ($\vec $ $\times$ $\vec $) (a−
d)×(
c−d)
∗(b−
d)×(
c−d)
=0'>= 0,
顯然,這種情況是相交的。只要將等號直接補上即可。(a
−d)×
(c−d
)∗(b
−d)×
(c−d
)=0'>再接得想一想,如果沒有第一步的快速排斥實驗,僅判斷第二步,會出現什麼問題?
當出現如上所示的情況的時候,叉積都為 0, 可以通過跨立實驗,但是兩個線段並沒有交點。不過還好,這種情況在第一步快速排斥已經被排除了。
struct
line ;
bool intersection(const line &l1, const line &l2)
//跨立實驗
if ((((l1.x1 - l2.x1)*(l2.y2 - l2.y1) - (l1.y1 - l2.y1)*(l2.x2 - l2.x1))*((l1.x2 - l2.x1)*(l2.y2 - l2.y1) - (l1.y2 - l2.y1)*(l2.x2 - l2.x1))) > 0 ||(((l2.x1 - l1.x1)*(l1.y2 - l1.y1) - (l2.y1 - l1.y1)*(l1.x2 - l1.x1))*((l2.x2 - l1.x1)*(l1.y2 - l1.y1) - (l2.y2 - l1.y1)*(l1.x2 - l1.x1))) > 0
)
return
true
;}
向量叉乘 判斷兩條線段是否相交
向量叉乘 行列式計算 向量a x1,y1 向量b x2,y2 首先我們要明白乙個定理 向量a 向量b 為向量叉乘 若結果小於0,表示向量b在向量a的順時針方向 若結果大於0,表示向量b在向量a的逆時針方向 若等於0,表示向量a與向量b平行。順逆時針是指兩向量平移至起點相連,從某個方向旋轉到另乙個向量...
判斷兩條線段是否相交 (向量叉乘)
問題 給出兩條線段,問兩線段是否相交?向量叉乘 行列式計算 向量a x1,y1 向量b x2,y2 首先我們要明白乙個定理 向量a 向量b 為向量叉乘 若結果小於0,表示向量b在向量a的順時針方向 若結果大於0,表示向量b在向量a的逆時針方向 若等於0,表示向量a與向量b平行。順逆時針是指兩向量平移...
判斷兩條線段是否相交
如上圖,判斷線段ab和線段cd相交。分析 如果線段ab和線段cd相交,只能是圖中的兩種相交情況。可以用向量叉乘來判斷。如果 向量ab叉乘向量ac 向量ab叉乘向量ad 0 並且 向量cd叉乘向量ca 向量cd叉乘向量cb 0,那麼說明線段ab與線段cd相交。設a x1,y1 b x2,y2 c x3...