本文利用向量的點積和叉積來判斷點是否線上段上。 基礎知識補充 從零開始的高中數學——向量、向量的點積、帶你一次搞懂點積(內積)、叉積(外積)、Unity游戲開發——向量運算(點乘和叉乘 說明 點積可以用來判斷兩個向量的夾角,如果這個夾角是0或者180度,說明這個點在直線上; 叉積可以用來判斷一個點到 ...
本文利用向量的點積和叉積來判斷點是否線上段上。
基礎知識補充 從零開始的高中數學——向量、向量的點積、帶你一次搞懂點積(內積)、叉積(外積)、Unity游戲開發——向量運算(點乘和叉乘
說明
點積可以用來判斷兩個向量的夾角,如果這個夾角是0或者180度,說明這個點在直線上;
叉積可以用來判斷一個點到一條直線的距離,如果這個距離是0,說明這個點在直線上。
假設有a、b、c三點,其中a和b是線段的兩個端點,c是要判斷的點:
- 計算向量ab和ac的點積,記為dot。
- 如果dot小於0,說明c在ab的垂直平分線上;
- 如果dot等於ab的模長的平方,說明c在ab的延長線上;
- 如果dot在0和ab的模長的平方之間,說明c在ab的方向上,可能在ab線段上;
- 如果dot小於0或者大於ab的模長的平方,說明c不在ab的直線上,也不在ab線段上。
- 計算向量ab和ac的叉積,記為cross。
- 如果cross不等於0,說明c不在ab的直線上,也不在ab線段上;
- 如果cross等於0,說明c在ab的直線上。
- 當判斷出c在ab的直線上時,還需要判斷c的x坐標或者y坐標是否在a和b的x坐標或者y坐標之間,才能確定c是否在ab的線段上。
綜合上面兩個條件,叉積和點積都可以用來判斷一個點是否在一條直線上,但是叉積更簡單一些,因為它需要的條件更少。
JS代碼
/**
* 判斷點c是否在ab組成的線段上
* @param {x,y} a 點
* @param {x,y} b 點
* @param {x,y} c 點
* @returns boolean
*/
function isPointOnLineSegment(a, b, c) {
// 計算向量ab和ac的叉積
let crossProduct = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
// 如果不等於0,說明不共線,直接返回false
if (crossProduct !== 0) {
return false;
}
// 否則,檢查c點是否在ab線段的範圍內
return (
Math.min(a.x, b.x) <= c.x &&
c.x <= Math.max(a.x, b.x) &&
Math.min(a.y, b.y) <= c.y &&
c.y <= Math.max(a.y, b.y)
);
}
// 測試
const a = {x:0,y:0}
const b = {x:0,y:1}
const c = {x:0,y:2}
const d = {x:1,y:1}
const e = {x:1,y:2}
const f = {x:2,y:2}
console.log(isPointOnLineSegment(a, c, b)); // true
console.log(isPointOnLineSegment(a, f, d)); // true
console.log(isPointOnLineSegment(c, f, e)); // true
console.log(isPointOnLineSegment(a, b, c)); // false
console.log(isPointOnLineSegment(a, f, c)); // false
console.log(isPointOnLineSegment(a, c, f)); // false
https://www.cnblogs.com/weizwz/p/17834931.html
本博客所有文章除特別聲明外,均採用 「署名-非商業性使用-相同方式共用 4.0 國際」 許可協議,轉載請註明出處!
內容粗淺,如有錯誤,歡迎大佬批評指正