如何检查一个点是否在另外两个点之间,但不限于在一条直线上对齐?

How to check if a point is between two other points, but not limited to be aligned on a straight line?

我需要检查经纬度坐标 (A) 是否位于另外两个经纬度坐标(BC)之间。但是,点 A 不必在 B->C.
线上 参考这张图,其中A应该算作"between" BC:

我该如何计算?

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

假设我们在一个平面上而不是一个球体上,即使您提到 lattitude/longitude...

如果角∠ABC和角∠ACB都小于或等于九十度,则A是"between"B和C。

很方便,我们甚至不需要三角函数来检测它;角∠PQR 大于九十度当且仅当 PQ^2 + QR^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)

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

你要做的基本上就是把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° 之间,包括地球另一端的赤道点。不过这不一定是错的。