如何检查一个点是否在另外两个点之间,但不限于在一条直线上对齐?
How to check if a point is between two other points, but not limited to be aligned on a straight line?
我需要检查经纬度坐标 (A
) 是否位于另外两个经纬度坐标(B
和 C
)之间。但是,点 A
不必在 B->C
.
线上
参考这张图,其中A
应该算作"between" B
和C
:
我该如何计算?
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° 之间,包括地球另一端的赤道点。不过这不一定是错的。
我需要检查经纬度坐标 (A
) 是否位于另外两个经纬度坐标(B
和 C
)之间。但是,点 A
不必在 B->C
.
线上
参考这张图,其中A
应该算作"between" B
和C
:
我该如何计算?
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° 之间,包括地球另一端的赤道点。不过这不一定是错的。