求两直线的交点

直线与直线的位置关系

平面上的两条直线如果不平行,那么他们一定相交,并且有唯一的交点

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;
		}
	}
posted @ 2020-10-11 23:33  pluscat  阅读(21637)  评论(0编辑  收藏  举报