我为通用坐标编写了一个函数,如果需要,可以将其转换为与 HTML 多边形一起使用。
一个非常简单的解决方案:为每对多边形顶点求解一个方程。
具有点a和b的多边形的一段(图中的灰色)的算法:
- 向量 A 只是点一个坐标
- 向量 S(egment) = b - a
- 向量 N 垂直于 S (-ys, xs)
- 矢量 P 是点的坐标
您要检查从点到Segment的法线长度,并确保目标点在Segment内。
这是您要解决的等式:
在解中,i必须在 0 和 1 之间。如果是,则距离为|iN| 并且该点是P + iN,否则它是顶点(a&b)之间最近的点。然后你可以找到每条边的最近点。
这是一个搜索最近距离的 Javascript 代码,但它应该很容易修改最近点:
function vlen(vector) {
return Math.sqrt(vector[0]*vector[0] + vector[1] * vector[1]);
}
function vsub(v1, v2) {
return [v1[0] - v2[0], v1[1] - v2[1]];
}
function vscale(vector, factor) {
return [vector[0] * factor, vector[1] * factor];
}
function vnorm(v) {
return [-v[1], v[0]];
}
function distance_to_poly(point, poly) {
var dists = $.map(poly, function(p1, i) {
var prev = (i == 0 ? poly.length : i) - 1,
p2 = poly[prev],
line = vsub(p2, p1);
if (vlen(line) == 0)
return vlen(vsub(point, p1));
var norm = vnorm(line),
x1 = point[0],
x2 = norm[0],
x3 = p1[0],
x4 = line[0],
y1 = point[1],
y2 = norm[1],
y3 = p1[1],
y4 = line[1],
j = (x3 - x1 - x2 * y3 / y2 + x2 * y1 / y2) / (x2 * y4 / y2 - x4),
i;
if (j < 0 || j > 1)
return Math.min(
vlen(vsub(point, p1)),
vlen(vsub(point, p2)));
i = (y3 + j * y4 - y1) / y2;
return vlen(vscale(norm, i));
});
return Math.min.apply(null, dists);
}