假設point1
和point2
是不同的,首先檢查點是否在線上。爲此,您只需要一個載體point1 -> currPoint
和point1 -> point2
的「交叉產品」。
dxc = currPoint.x - point1.x;
dyc = currPoint.y - point1.y;
dxl = point2.x - point1.x;
dyl = point2.y - point1.y;
cross = dxc * dyl - dyc * dxl;
你點位於當且僅當cross
等於零行。
if (cross != 0)
return false;
現在,你知道點也騙就行了,現在是時候來檢查它是否位於原始點之間。這可以通過比較所述x
座標來容易地完成,如果線是「比垂直更水平的」,或以其他方式y
座標
if (abs(dxl) >= abs(dyl))
return dxl > 0 ?
point1.x <= currPoint.x && currPoint.x <= point2.x :
point2.x <= currPoint.x && currPoint.x <= point1.x;
else
return dyl > 0 ?
point1.y <= currPoint.y && currPoint.y <= point2.y :
point2.y <= currPoint.y && currPoint.y <= point1.y;
注意上面的算法,如果如果輸入數據是積分完全積分,即它整數輸入不需要浮點計算。雖然計算cross
時要小心潛在的溢出。
P.S.這個算法絕對精確,這意味着它會拒絕非常接近線但不在線上的點。有時候這不是我們所需要的。但這是一個不同的故事。
來源
2012-08-10 19:37:36
AnT
下面有一些很好的答案,但我想我會指出你應該注意的浮動點精度問題。無論您使用哪種方法,例如,在測試兩個不同的斜率是否相同時,您可能必須允許少量的錯誤。 – 2012-08-10 20:45:26
@Adrian McCarthy:這是基於斜率的方法的主要問題。斜率隨着角度變化不均勻:線越接近垂直,斜率越快增長(甚至沒有提到垂直線和幾乎垂直線的特殊情況)。沒有好的斜坡策略。我會不惜一切代價避免以斜率爲基礎的方法。 – AnT 2012-08-11 05:27:50