參考資料:《ACM/ICPC程序設計與分析》
判斷點在線段上這個算法非常的簡單,只要學過叉乘(CrossProduct)就很容易搞定
設點為Q,線段為P1P2,判斷點Q是否在P1P2上。
算法依據:
1.點Q首先要在P1P2所在的直線上。
比較原始的辦法是利用P1P2的坐標做出直線方程,然后代入點Q看是否滿足方程,這樣代碼稍微麻煩些。
簡單點就是用叉乘,如果點Q在P1P2直線上,那么:
P1Q x P1P2 = 0(x代表叉乘)
這個代碼實現很容易。
P x Q = P.x * Q.y - P.y * Q.x(交叉相乘)PS:叉積的結果還是一個向量,二維向量的叉積是垂直於兩個向量形成的平面的一個向量。這行公式實際上求的是標量。
2.Q要在以P1P2為對角線的平行矩形內
這個就更簡單了,做一下比較即可
下面給出偽代碼:
<span style="font-family:Microsoft YaHei;font-size:14px;">bool On_Segment(Point P1,Point P2,Point Q) { int condition1 = condition2 = 0 if(CrossProduct(P1Q,P1P1) == 0)//條件1 condition1 = 1; if((min(P1.x,P2.x) <= Q.x) && (Q.x <= max(P1.x,P2.x)) && (min(P1.y,P2.y) <= Q.y) && (Q.y <= max(P1.y,P2.y)))//條件2 condition2 = 1; if(condition1 && condition2) return true; else return false; }</span>
如果給出三點ABC,其位置關系如下:
給出求AB x AC叉乘的偽代碼
<span style="font-family:Microsoft YaHei;font-size:14px;">double CrossProduct(Point A,Point B,Point C) { return (B.x - A.x) * (C.y - A.y) - (C.x - A.x) * (B.y - A.y); } </span>
有了這些基礎,就可以對折線段的拐向進行判斷
對於有公共端點的線段AB,BC,通過計算AB x AC可以確定AB的拐向
圖示情況為AB x AC > 0 即AB在B點向左側拐向C
圖示情況為AB x AC < 0 即AB在B點拐向右側后到C
不要忘了AB x AC == 0 的情況,此時ABC共線。