直線與直線的位置關系
平面上的兩條直線如果不平行,那么他們一定相交,並且有唯一的交點
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;
}
}