寻找线条或点是否靠近一条直线

7

我有一段代码,用于判断一条线是否在圆内。(或许你可以用这个作为参考来回答问题)

/**
*@param l1  Line point 1, containing latitude and longitude
*@param l2  Line point 2, containing latitude and longitude
*@param c   Center of circle, containing latitude and longitud
*@param r   Radius of the circle
**/
Maps.ui.inCircle = function(l1, l2, c, r){
    var a = l1.lat() - l2.lat()
    var b = l1.lng() - l2.lng()
    var x = Math.sqrt(a*a + b*b)
    return (Math.abs((c.lat() - l1.lat()) * (l2.lng() - l1.lng()) - (c.lng() - l1.lng()) * (l2.lat() - l1.lat())) / x <= r);
}

这对于那个问题完美地解决了。但现在我需要找出一个点是否在一条线的周围区域内。例如,这里的蓝点将返回true,并且我将返回紫色线true。但不是绿线或点。同时,我需要找出一条线是否穿过该线。
这是我的代码,用于检查一条线是否与该线相交:
function getLineIntersaction(y1,x1,y2,x2, y3,x3,y4,x4){
    if (Math.max(X1,X2) < Math.min(X3,X4)) // This means no same coordinates
        return false;  
    m1 = (y1-y2)/(x1-x2); 
    m2 = (y3-y4)/(x3-x4); 
    c1 = y1-m1x1; 
    c2 = y3-m2x3; 
    if(m1=m2)//segments are parallel.
        return false;
    var x = (c1-c2)/(m2-m1); 
    if(!isNaN(x) && isFinite(x)){
        if( x < Math.max(Math.min(x1,x2),math.min(x3,x4)) || x > Math.min(Math.max(x1,x2),Math.max(x3,x4)))
            return false;
        else
            return true;
    }
    return false;
}

因此,这需要与其他代码集成。

我该怎么做呢?我可以向函数传递一行或只传递一个点。

如果传递一条线,则我们将运行上面的函数。我希望它返回一个数组。数组中的第一项将返回是否接近它(在红色区域内),而数组中的第二项将返回线段是否与该线相交。也就是说,如果只是一个点,则第二项永远为false。

问题

如何判断线或点是否位于红色区域内?


1
加上附图。您需要欧几里得几何吗?我看到您正在使用纬度/经度。如果我们在一个球体上,答案会略有不同。您需要考虑穿越180子午线的线条(作为一名新西兰人,您与此相当接近),而且两个完全对立的点并不能确定一条单独的线等。 - fsw
我认为它不必太精确。我只需要检查它是否在大约100-200米的范围内,以便我可以将该线剪切到它上面。这只是用于区域的后处理工作,以便我们不会在两个区域之间有小线条。 - FabianCook
1
非常有趣的问题!但我没有看到明确表达的问题。 - BenSwayne
1
不是重复内容。另外,我会尽力让它更清晰 :) - FabianCook
@BrianWebster - 永远不要删除自动插入的文本。当重新打开时,它将自动删除(正如这里发生的)。只需投票以重新打开即可。 - Himanshu
1
我在编辑问题方面有着悠久的历史,这次也不例外。 - Brian Webster
2个回答

7

引用我在这个问题的答案

第一步是找到点在直线上的法向投影。这实际上很简单:找到从点1到目标的距离和从点2到目标的距离,并将它们称为D1和D2。然后计算D1+(D2-D1)/2。这是从点1到直线上投影点的距离。

现在你可以找到那个点,然后得到从那个点到目标的距离。如果距离为零,则目标正好在直线上。如果距离小于5,则目标距离小于5像素,等等。

编辑:一张图片胜过千言万语。下面是一个图示:

Diagram
(来源:adamhaskell.net

(事后看来,可能应该把那些圆圈换成不同的颜色……另外,紫色的线应该垂直于线段AB。怪我粗心的蓝线!)


2
你需要找到点到直线的距离,d。
首先,获取与原始问题中的直线垂直的线的斜率。(保持这个比率很方便: dx,dy是原始斜率,dy,-dx是垂直的,其中dx是原始线的x差异,而dy是原始线的y差异。)
要测试一个点p1,获取原始线和通过p1的垂线的交点(p2)。换句话说,原始线与线段p2到(p2.x+dy,p2.y-dx)的交点。
如果p2位于原始线的端点之间,则到线的距离(d)是P1和P2之间的距离。
如果P2位于原始线的端点之外,则到线的距离(d)是从P1到原始线端点的距离中较短的距离。
original line: points pq1 and pq2
point to measure: p1
distance to line: d

dx = pq2.x - pq1.x
dy = pq2.y - pq1.y

p2.x = p1.x + dy // get perpendicular, arbitrary length
p2.y = p1.y - dx

px = intersection(pq1-pq2, p1-p2)

if px.x is between pq1.x and pq2.x inclusive then // check y's instead if it's near vertical
  d = distance(p1-px)
else
  d = minimum(distance(p1, pq1), distance(p1, pq2))
end if

当然——如果你有任何问题,请告诉我。我有点快速地浏览了一下。 - xpda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接