假設線段的兩個端點分別為:a、b,另外一點為 p。
問題:判斷 p 點是否位於線段 ab 上。
方法1:通過線段確定的直線方程判斷。
(1) 在二維空間中,三點座標表示為:a(xa,ya), b(xb,yb), p(xp,yp)。
ab確定的直線方程(點斜式)為:
k = (yb - ya) * 1 / (xb - xa)
y = k * (x - xa) + ya
p點若位於直線上,首先應該滿足直線的方程:
yp = k * (xp - xa) + ya。
若上式成立,說明a、b、p共線,接下來只需判斷 p 位於 a 和 b 中間,即
(xa <= xb && xa <= xp <= xb) || (xa > xb && xa >= xp >= xb)
(ya <= yb && ya <= yp <= yb) || (ya > yb && ya >= yp >= yb)
注意到直線方程中有除法運算,需做一步ab是否重合的判斷,否則除數為零。上式稍作變形,便可去掉除法運算,即:
(y - ya) / (yb - ya) = (x - xa) / (xb - xa) 進而
(y - ya) * (xb - xa) - (yb - ya) * (x - xa) = 0。
上式成立的條件,(x,y)與a或b點重合,或者(x,y)、a、b三點共線。接下來再做 p 是否位於ab中間的判斷即可。
上述變形後的等式,其實表示的是二維平面中向量的一種運算:叉積(cross product),
a x b = xa*yb - ya*xb
由直線方程的啟示,不難理解叉積為零,則可判定兩向量共線或者乙個向量為零。
變形後的直線方程和向量的叉積是二維空間向三維空間推廣的基礎。
(2) 在三維空間中,三點座標分別為a(xa,ya,za), b(xb,yb,zb), p(xp,yp,zp)。
ab確定的直線方程相應變為:
(y - ya) / (yb - ya) = (x - xa) / (xb - xa) = (z - za) / (zb - za)。
按(1)中所述,將p點代入直線方程成立後,只需再多做一步 z 軸座標的判斷:
(za <= zb && za <= zp <= zb) || (za > zb && za >= zp >= zb)。
所有條件同時成立,則 p 點位於線段 ab 上。
三維空間中的叉積判斷就是接下來的方法2。
方法2:利用向量的叉積做判斷[3]。
二維空間中的叉積定義已經介紹,三維空間的描述可以參考「4」,叉積可以作為判定兩個向量是否共線的乙個工具,三維空間中的叉積結果會得到乙個新的向量。
先求得兩個向量:v1 = b - a, v2 = p - a。然後 v1 和 v2 做叉積:v = v1 x v2,如果 v 是零向量,即 v 的x、y、z分量都為 0,則v1 和 v2 至少有乙個為零或者兩個向量共線。
if v2 == 0,then p == a;
else if v1 == 0 then a == b and p doesn't lie in ab ; // v2 != 0
else p,a,b are colinear;
end如果判定共線後,接下來判斷 p 是否位於 ab 內的方式同方法1.
方法3:面積法。
如果a、b、p三點組成的三角形的面積為零,那麼可以得出三點共線的結論。
三角形面積可以使用海**式直接得出,另外上述v1和v2叉積得到的向量的長度的一半,也是三點組成的三角形的面積(參考叉積的定義)。
不過這兩種方式都涉及到開根號的運算,代價較高。
另外在判定了三點共線後,v1 和 v2 的夾角要麼0度,要麼180度,點積的符號可以用來確定p點的位置,如:v1 ・ v2 < 0。那麼,v1 和 v2 夾角為180,反向,p點位於ab之外。
接下來再以 b 點為基準做兩個向量v1』 = a - b, v2』 = p - b,若v1』 ・ v2』 > 0,即可斷定 p 位於線段ab上。
如果不以 b 為基準做兩個向量,可以通過長度來判斷,由內積的定義可以知道:
v1 ・ v2 = |v1| |v2| cos= |v1| |v2| cos(0) = |v1| |v2|。
如果v1 ・ v2 > |v1|*|v1| = v1 ・ v1 => |v2| > |v1|,即pa的長度大於ba,又pa和ba同向,那麼p點一定位於ab之外。
不過上述的點積判定符號的方法,包含了許多乘法的運算,進行座標比較的方法反而更加直接簡單。綜上所述,方法2更值得推薦。
參考:[1]
[2]
[3][4]
判斷頂點是否位於三角形內
這是乙個三維空間中的平面問題 三角形確定乙個平面 假設三角形的三個頂點為a xa,ya,za b xb,yb,zb c xc,yc,zc 另外乙個頂點為p xp,yp,zp 問題 判斷頂點 p 是否位於abc組成的三角形上 內部和邊界 方法1 效率較低的方法。1 利用面積判斷。如果頂點落在三角形上,...
python判斷兩線段是否相交 判斷兩線段是否相交
演算法一 1.快速排斥實驗 設一線段p1p2為對角線的矩形為p,設一線段q1q2為對角線的矩形為q,如果p和q不相交,顯然兩線段不會相交。以下2種 方法1 方法2 方法判斷矩形是否相交僅限於正矩形。方法1 已知2個正矩形rect1 rect2 設兩個正矩形相交一定得到乙個正矩形rect 如果minx...
判斷兩線段是否平行
判斷兩條線段是否相交的測試 對於垂直的線段暫時沒有作考慮,如果需要後續加上判斷即可,應該不難 author challenking data 2010 07 06 class test 分別給出兩條線段的兩個點,判斷是否相交 static boolean xiangjiao int x11,int ...