2点の線分(座標)から交点を求める
2点の線分(座標)から交点を求めるには、次のような方法で可能です。
関数定義
JavaScript (ES5)
/**
* 2点の線分(座標)から交点を求める
* @param {{start:{x:number,y:number},end:{x:number,y:number}}} line1 1つ目の直線
* @param {{start:{x:number,y:number},end:{x:number,y:number}}} line2 2つ目の直線
* @return {{x:number,y:number,overlap:boolean,parallelLine:boolean}} 交点の座標と交差しているかどうか、平行かどうかを返す
*/
var getIntersectionLineSegments = function(line1, line2) {
var x0 = line1.start.x,
y0 = line1.start.y,
x1 = line1.end.x,
y1 = line1.end.y,
x2 = line2.start.x,
y2 = line2.start.y,
x3 = line2.end.x,
y3 = line2.end.y;
var a0 = x3 - x2,
a1 = y3 - y2;
var b0 = (a0 * (y0 - y2) - a1 * (x0 - x2)) / 2,
b1 = (a0 * (y2 - y1) - a1 * (x2 - x1)) / 2;
var x = x0 + (x1 - x0) * b0 / (b0 + b1),
y = y0 + (y1 - y0) * b0 / (b0 + b1);
var overlap = (x >= x0 || x >= x1) && (x <= x0 || x <= x1) &&
(y >= y0 || y >= y1) && (y <= y0 || y <= y1) &&
(x >= x2 || x >= x3) && (x <= x2 || x <= x3) &&
(y >= y2 || y >= y3) && (y <= y2 || y <= y3)
var parallelLine = (Math.abs(x) === Infinity && isNaN(y)) ||
(isNaN(x) && Math.abs(y) === Infinity) ||
(Math.abs(x) === Infinity && Math.abs(y) === Infinity);
return {
x : parallelLine ? 0 : x,
y : parallelLine ? 0 : y,
overlap : parallelLine ? false : overlap,
parallelLine : parallelLine
};
};
JavaScript (ES6以降)
/**
* 2点の線分(座標)から交点を求める
* @param {{start:{x:number,y:number},end:{x:number,y:number}}} line1 1つ目の直線
* @param {{start:{x:number,y:number},end:{x:number,y:number}}} line2 2つ目の直線
* @returns {{x:number,y:number,overlap:boolean,parallelLine:boolean}} 交点の座標と交差しているかどうか、平行かどうかを返す
*/
const getIntersectionLineSegments = (line1, line2) => {
const x0 = line1.start.x,
y0 = line1.start.y,
x1 = line1.end.x,
y1 = line1.end.y,
x2 = line2.start.x,
y2 = line2.start.y,
x3 = line2.end.x,
y3 = line2.end.y;
const a0 = x3 - x2,
a1 = y3 - y2;
const b0 = (a0 * (y0 - y2) - a1 * (x0 - x2)) / 2,
b1 = (a0 * (y2 - y1) - a1 * (x2 - x1)) / 2;
const x = x0 + (x1 - x0) * b0 / (b0 + b1),
y = y0 + (y1 - y0) * b0 / (b0 + b1);
const overlap = (x >= x0 || x >= x1) && (x <= x0 || x <= x1) &&
(y >= y0 || y >= y1) && (y <= y0 || y <= y1) &&
(x >= x2 || x >= x3) && (x <= x2 || x <= x3) &&
(y >= y2 || y >= y3) && (y <= y2 || y <= y3)
const parallelLine = (Math.abs(x) === Infinity && isNaN(y)) ||
(isNaN(x) && Math.abs(y) === Infinity) ||
(Math.abs(x) === Infinity && Math.abs(y) === Infinity);
return {
x : parallelLine ? 0 : x,
y : parallelLine ? 0 : y,
overlap : parallelLine ? false : overlap,
parallelLine : parallelLine
};
};
使い方
引数
引数名 | 型 | 説明 | |
---|---|---|---|
第一引数 必須 |
line1 | { start : { x : number, y : number }, end : { x : number, y : number } } |
1つ目の直線の座標 |
第二引数 必須 |
line2 | { start : { x : number, y : number }, end : { x : number, y : number } } |
2つ目の直線の座標 |
戻り値
交点の座標(x軸、y軸)と交差しているかどうか、平行かどうかを返します。
{
x : ...,
y : ...,
overlap : ...,
parallelLine : ...
}
プロパティ | 型 | 説明 |
---|---|---|
x | number | 交点のX座標。平行の場合は0。 |
y | number | 交点のY座標。平行の場合は0。 |
overlap | boolean | 交差している場合はtrue、そうでなければfalse。 |
parallelLine | boolean | 平行の場合はtrue、そうでなければfalse。 |
サンプルコード
JavaScript (ES5)
// 直線1
var line1 = {
start : { x : 165, y : 86 }, // 始点
end : { x : 65, y : 1 } // 終点
};
// 直線2
var line2 = {
start : { x : 180, y : 15 }, // 始点
end : { x : 85, y : 78 } // 終点
};
var point = getIntersectionLineSegments(line1, line2);
alert('X : ' + point.x + ', Y : ' + point.y);
JavaScript (ES6以降)
// 直線1
const line1 = {
start : { x : 165, y : 86 }, // 始点
end : { x : 65, y : 1 } // 終点
};
// 直線2
const line2 = {
start : { x : 180, y : 15 }, // 始点
end : { x : 85, y : 78 } // 終点
};
const point = getIntersectionLineSegments(line1, line2);
console.log(`X : ${point.x}, Y : ${point.y}`);