先求点到线段的距离
/**
* 点到线段的距离
* @param {Array} point1 [x1, y1] 直线上点1
* @param {Array} point2 [x2, y2] 直线上点2
* @param {Array} point [xx, yy]
* @returns {Number}
*/
distanceOfPoint2LineSegment([x1, y1], [x2, y2], [xx, yy]) {
/** 求垂线交点
* 直线方程 (y - y1) / (y2 - y1) = (x - x1) / (x2 - x1) => y = (x - x1) / (x2 - x1) * (y2 - y1) + y1
* 斜率 k1 = (y2 - y1) / (x2 - x1)
* 垂线斜率 k2 = -1 / k1
* 垂线平移 b = yy - k2 * xx
* 垂线方程 y = k2 * x + b
* 求两直线交点 (x - x1) / (x2 - x1) * (y2 - y1) + y1 = k2 * x + b
* => ((y2 - y1) / (x2 - x1) - k2) * x = b - y1 + ((y2 - y1) / (x2 - x1)) * x1
* => (k1 - k2) * x = b - y1 + k1 * x1
*/
const k1 = (y2 - y1) / (x2 - x1)
const k2 = -1 / k1
const b = yy - k2 * xx
// 两直线交点
const x = (b - y1 + k1 * x1) / (k1 - k2)
const y = k2 * x + b
const [[minX, minY], [maxX, maxY]] = x1 < x2 ? [[x1, y1], [x2, y2]] : [[x2, y2], [x1, y1]]
// 如果中垂线的交点在线段外,那么距离就是点到直线端点的距离
if (x > maxX) {
return Math.sqrt((xx - maxX) ** 2 + (yy - maxY) ** 2)
}
if (x < minX) {
return Math.sqrt((xx - minX) ** 2 + (yy - minY) ** 2)
}
return Math.sqrt((xx - x) ** 2 + (yy - y) ** 2)
},