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}`);

JavaScript逆引きリファレンス一覧へ戻る