【问题标题】:How to check if a point is between two other points, but not limited to be aligned on a straight line?如何检查一个点是否在其他两个点之间,但不限于在一条直线上对齐?
【发布时间】:2016-01-14 07:22:12
【问题描述】:

我需要检查一个 lat-lon 坐标 (A) 是否位于另外两个 lat-lon 坐标 (BC) 之间。但是,A 的点不必在线上B->C
参考这张图,其中A应该算作“介于”BC

我该如何计算?

PS: 位置可以转换为 SWEREF99TM,这是一个网格系统,如果这样更适合计算的话。我已经有了该转换的公式。

【问题讨论】:

  • 请更清楚地定义“介于两者之间”。它是否包括绘制线之间的所有点,包括距离 B 和 C 很远的点?

标签: math geometry coordinates


【解决方案1】:

假设我们在一个平面上而不是一个球体上,即使你提到了纬度/经度......

如果角∠ABC和角∠ACB都小于或等于九十度,则A在B和C之间。

很方便,我们甚至不需要三角函数来检测它;当 PQ^2 + QR^2

def lies_between(A,B,C):
    a = distance(B,C)
    b = distance(C,A)
    c = distance(A,B)
    return a**2 + b**2 >= c**2 and a**2 + c**2 >= b**2

def distance(A,B):
    return math.sqrt((A.x - B.x)**2 + (A.y - B.y)**2)

(其中** 是幂运算符。)

【讨论】:

  • 再看一遍,这种方法可能也适用于球面几何......不确定它是否适用于几乎对映的 B 点和 C 点。
  • 这不能按要求工作...请参阅我在这里使用的代码:gist.github.com/anonymous/6525fc5fbac28116a93a
  • 糟糕,我很抱歉。我的return 声明是错误的——它检查的是角度 BAC 而不是角度 ABC。已编辑。
  • 修改后完美运行!感谢您的帮助!
【解决方案2】:

您要做的基本上是将 A 投影到 BC 上。它不直观但简单,是点积最明显的应用。

你可以在这里阅读数学... http://math.oregonstate.edu/home/programs/undergrad/CalculusQuestStudyGuides/vcalc/dotprod/dotprod.html

dot(x, y) 是两个元组的点积,vec(x, y) 是从 x 到 y 的向量。那么你的答案就是……

// Dot product
dot = lambda d1,d2: sum(a*b for a,b in zip(d1,d2))

// Vector between two points
vec = lambda d1,d2: tuple(b-a for a,b in zip(d1,d2))

BA=vec(b,a)
BC=vec(b,c)

BA_scalar = dot(BA, BC) / dot(BC, BC) # BA * BC / |BC|
# BA_scalar = 0 means A is co-planar with B
# BA_scalar = 1 means A is co-planar with C

is_between = 0 < BA_scalar and BA_scalar < 1

这适用于 3d 和 2d 坐标。不过,它会在 3d 中产生有趣的结果,例如,所有赤道点都位于 10°N、0° 和 10°S、0° 之间,包括地球另一端的赤道点。不过这不一定是错的。

【讨论】:

    猜你喜欢
    • 2012-08-08
    • 2013-02-21
    • 2020-02-03
    • 2011-04-19
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多