如何检查一个点相对于其位置和路线是否在另一个点之后?

How do I check if a point is behind another point relative to its location and course?

我正在开发一个高度依赖于地理位置和基于它的计算的应用程序。其中一个视图是列表视图,它给出了用户位置后面的移动 POI 列表。

+---------------------------+
+------  .            ------+
+-----    .            -----+
+----      .  [POI1]    ----+
+---        .     /      ---+
+--          .   /        --+
+-            . /          -+
+           [ME]            +
+-              .          -+
+--              .        --+
+---              .      ---+
+----  [POI2]      .    ----+
+-----              .  -----+
+------              .------+
+---------------------------+
/ = user course
..= perpendicular line
[POI1] = in front
[POI2] = Behind

到目前为止,我已经完成了以下步骤:

  1. 获取用户位置
  2. 检索 5 公里半径内的 POI
  3. 以更高的速度和相同的路线(+/- 45 度本方路线)过滤所有 POI

下一步是确定哪些 POI 在用户前面,哪些在后面。我想出的方法是创建一条垂直于用户路线的无限线(矢量)。 (例如,在 45 度的航向中,东北方向,该线将是西北-东南方向)。然后我需要弄清楚每个 poi 的 Lat-Lon 是在这条线的前面还是后面,以便知道它是在用户前面还是后面。

这一切都是在javascript中用经纬度完成的。所以我可能需要某种公式或函数来比较两个 latlng 点,相对于第一个点的过程。

Google 到目前为止没有太大帮助,所以我真的希望有人能解决这个问题!与此同时,我会因为没有对数学给予足够的重视而感到羞耻 class。

如上图所示,首先计算[ME]和[POI1]之间直线的斜率。通常,您想要计算用户和他们行进到的点之间的斜率(即他们的路线的斜率),在本例中为 POI1。为此,请使用点斜率形式获取线斜率,y1 - y2 = m * (x1 - x2),其中 [ME] 的坐标为 (x1,y1),[POI1] 的坐标为 (x2,y2)并求解 m。现在令 z = -1/m。这是垂直线的斜率。

回到点斜率形式,垂直于用户和POI1的线的一般方程为y - y1 = z * (x-x1)。然后做代数把方程的形式改成y = z * x + b,对于一些b。更改表格后,为 x 插入 x2。如果 y2 > z * x2 + b,那么我们的不等式将使用“<”符号。否则,我们使用“>”符号。 WLOG,说我们需要使用“>”符号。然后,对于坐标为(k,j)的每个POI,如果j > z * k + b,则该点在用户身后。

我知道这不是特别清楚的,特别是如果你有一段时间没有像这样做过几何,所以这里有一个例子。设 [ME] 的坐标为 (1,1) 并假设它们朝向点 (3,2) 的方向。然后,垂直线的斜率由 1 - 2 = m * (1 - 3) 给出,这意味着 m = 1/2。因此,垂直线的斜率 z = -1/(1/2) = -2。现在垂直线的方程由 y - 1 = -2 * (x - 1) 给出,在求解 y 后得到 y = -2x + 3。观察到 2 > -2*3 + 3。所以,我们的最终不等式需要使用“<”符号(相反的符号)。最终的不等式由 y < -2x + 3 给出。假设我们有两个其他 POI,坐标为 (0,0) 的 POI2 和坐标为 (4,4) 的 POI3。 POI2 在 [ME] 后面,因为 0 < -2 * 0 + 3。POI3 在 [ME] 前面,因为 4 < -2 * 4 + 3 不满足(即 4 < -5 为假)。

希望这对您有所帮助。另外,计算 m 时要小心,因为如果 x1 - x2 = 0,m 将是未定义的。这只是意味着坡度是直线上下,所以垂直坡度将为 0。同样,如果 m = 0,z 将是直线上下。

我有几个非常好的和有趣的方法来解决这个问题。 最简单有效的方法是使用一个库来计算 2 个 LatLon 点之间的方位角。

我使用 GeoDesy's latlon-spherical.js 及其 .bearing() 方法来获取我的 POI 相对于真北的方位。

1. Get bearing to POI relative to true north
2. Subtract my own bearing to get bearing relative to me
3. Normalize bearing (e.g. add 360 to negative values)
4. Check if bearing is between 90 and 270 (this means going backwards)

在我的代码中它看起来像这样:

function filterShipFromBehind(ship)
{
    // Get our and the ships latlon
    var shipLatLon = new LatLon(ship.location.latitude, ship.location.longitude);
    var myLatLon = new LatLon(myShip.location.latitude, myShip.location.longitude);

    // Calculate the bearing from us to the ship (relative to true north)
    var bearing = myLatLon.bearingTo(shipLatLon);

    // Calculate the relative bearing by subtracting our own bearing
    var difference = Ships.normalizeAngle(bearing - myShip.courseOverGround);

    // Finally check if the relative bearing is between 90 and 270 degrees
    // indicating it is behind us
    if(difference > 90 && difference < 270)
    {
        filterShipNearing(ship);
    }
}

我希望这对下一个寻求解决这个问题的人有所帮助!