求兩直線的交點


直線與直線的位置關系

平面上的兩條直線如果不平行,那么他們一定相交,並且有唯一的交點

Ax+By+C = 0

直線一般式適用平面上任意直線

根據兩點求解一般式的系數

設兩個點為 (x1, y1) , (x2, y2),則有:
A = y2 - y1
B = x1 - x2
C = x2y1-x1y2

直線標准式求系數

Ax + By = C

A = y2 - y1
B = x1 - x2
C = Ax1 + By1

直線一般式求交點

首先設交點坐標為 (x, y),兩線段對應直線的一般式為:

a1x + b1y + c1 = 0
a2x + b2y + c2 = 0

那么對 1 式乘 a2,對 2 式乘 a1 得:
a2*a1x + a2*b1y + a2*c1 = 0
a1*a2x + a1*b2y + a1*c2 = 0
兩式相減得:
y = (c1 * a2 - c2 * a1) / (a1 * b2 - a2 * b1)

同樣可以推得:
x = (c2 * b1 - c1 * b2) / (a1 * b2 - a2 * b1)

如果(x,y)在兩線段上,則(x,y)即為答案,否則交點不存在。

直線標准式求交點

首先設交點坐標為(x,y),兩線段對應直線的標准式為

A1x + B1y = C1 
A2x + B2y = C2

將1式成以B2,將2式乘以B1在相減

  A1B2x + B1B2y = B2C1
- A2B1x + B1B2y = B1C2 

x = ( B2C1 - B1C2 ) / ( A1B2 - A2B1)

同理可得

y = (A1C2 - A2C1) / ( A1B2 - A2B1)

判斷線段是否平行

如果兩直線平行,則有 A1/B1 == A2/B2。
為了避免除零的問題,可轉化為 A1*B2 == A2*B1    

利用一般式求兩直線的交點

	function lineIntersect(p0, p1, p2, p3) {
		var A1 = p1.y - p0.y,
			B1 = p0.x - p1.x,
			C1 = A1 * p0.x + B1 * p0.y,
			A2 = p3.y - p2.y,
			B2 = p2.x - p3.x,
			C2 = A2 * p2.x + B2 * p2.y,
			denominator = A1 * B2 - A2 * B1;

		return {
			x: (B2 * C1 - B1 * C2) / denominator,
			y: (A1 * C2 - A2 * C1) / denominator
		}
	}

window.onload = function() {
	var canvas = document.getElementById("canvas"),
		context = canvas.getContext("2d"),
		width = canvas.width = window.innerWidth,
		height = canvas.height = window.innerHeight;

	var p0 = {
			x: 100,
			y: 100
		},
		p1 = {
			x: 500,
			y: 500
		},
		p2 = {
			x: 600,
			y: 50
		},
		p3 = {
			x: 80,
			y: 600
		};

	context.beginPath();
	context.moveTo(p0.x, p0.y);
	context.lineTo(p1.x, p1.y);
	context.moveTo(p2.x, p2.y);
	context.lineTo(p3.x, p3.y);
	context.stroke();

	var intersect = lineIntersect(p0, p1, p2, p3);

	context.beginPath();
	context.arc(intersect.x, intersect.y, 20, 0, Math.PI * 2, false);
	context.stroke();



	function lineIntersect(p0, p1, p2, p3) {
		var A1 = p1.y - p0.y,
			B1 = p0.x - p1.x,
			C1 = A1 * p0.x + B1 * p0.y,
			A2 = p3.y - p2.y,
			B2 = p2.x - p3.x,
			C2 = A2 * p2.x + B2 * p2.y,
			denominator = A1 * B2 - A2 * B1;

		return {
			x: (B2 * C1 - B1 * C2) / denominator,
			y: (A1 * C2 - A2 * C1) / denominator
		}
	}

};

判斷直線平行和相交的情況

交點在一條直線的延長線上或者交點在兩條直線的延長線上不畫出交點

function segmentIntersect(p0, p1, p2, p3) {
		var A1 = p1.y - p0.y,
			B1 = p0.x - p1.x,
			C1 = A1 * p0.x + B1 * p0.y,
			A2 = p3.y - p2.y,
			B2 = p2.x - p3.x,
			C2 = A2 * p2.x + B2 * p2.y,
			denominator = A1 * B2 - A2 * B1;

        // 如果分母為0 則平行或共線, 不相交  
		if(denominator == 0) {
			return null;
		}

     
		var intersectX = (B2 * C1 - B1 * C2) / denominator,
			intersectY = (A1 * C2 - A2 * C1) / denominator,
			rx0 = (intersectX - p0.x) / (p1.x - p0.x),
			ry0 = (intersectY - p0.y) / (p1.y - p0.y),
			rx1 = (intersectX - p2.x) / (p3.x - p2.x),
			ry1 = (intersectY - p2.y) / (p3.y - p2.y);

        /** 2 判斷交點是否在兩條線段上 **/  
		if(
            // 交點在線段1上  
            ((rx0 >= 0 && rx0 <= 1) || (ry0 >= 0 && ry0 <= 1)) && 
            // 且交點也在線段2上  
		   ((rx1 >= 0 && rx1 <= 1) || (ry1 >= 0 && ry1 <= 1))) {
			return {
				x: intersectX,
				y: intersectY
			};
		}
		else {
			return null;
		}
	}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM