矢量法, 速度快。
// 返回点到直线的最短距离
public static double PointToSegDist(double x, double y, double x1, double y1, double x2, double y2)
{
double cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);
if (cross <= 0) return Math.Sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
double d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
if (cross >= d2) return Math.Sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
double r = cross / d2;
double px = x1 + (x2 - x1) * r;
double py = y1 + (y2 - y1) * r;
return Math.Sqrt((x - px) * (x - px) + (py - y1) * (py - y1));
}
/**
* 点到直线的最短距离的判断 点(x,y) 到由两点组成的线段(x1,y1) ,( x2,y2 )
* @returns {boolean|{x: number, y: number}} 距离大于 lineDistanceThreshold 时返回false, 否则返回点到线段的垂线的交点。
*/
function pointToSegmentDistance(x, y, x1, y1, x2, y2) {
let cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);
if (cross <= 0) return false;
let d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
if (cross >= d2) return false;
let r = cross / d2;
let px = x1 + (x2 - x1) * r;
let py = y1 + (y2 - y1) * r;
let d = Math.sqrt((x - px) * (x - px) + (py - y) * (py - y));
if (d < lineDistanceThreshold) {
return {
x: Math.round(px),
y: Math.round(py)
}
} else return false;
}
先算面积
// 点到直线的最短距离的判断 点(x0,y0) 到由两点组成的线段(x1,y1) ,( x2,y2 )
function pointToLine(x1, y1, x2, y2, x0, y0) {
var space = 0;
var a, b, c;
a = lineSpace(x1, y1, x2, y2);// 线段的长度
b = lineSpace(x1, y1, x0, y0);// (x1,y1)到点的距离
c = lineSpace(x2, y2, x0, y0);// (x2,y2)到点的距离
if (c <= 0.000001 || b <= 0.000001) {
space = 0;
return space;
}
if (a <= 0.000001) {
space = b;
return space;
}
if (c * c >= a * a + b * b) {
space = b;
return space;
}
if (b * b >= a * a + c * c) {
space = c;
return space;
}
var p = (a + b + c) / 2;// 半周长
var s = Math.sqrt(p * (p - a) * (p - b) * (p - c));// 海伦公式求面积
space = 2 * s / a;// 返回点到线的距离(利用三角形面积公式求高)
return space;
}
评论区