一种更简单的方法是用几何基元运算来表达问题,例如点积 https://en.wikipedia.org/wiki/Dot_product, the 叉积 https://en.wikipedia.org/wiki/Cross_product,以及三重积 https://en.wikipedia.org/wiki/Triple_product。行列式的符号u, v, and w告诉你飞机的哪一侧跨越v and w包含u。这使我们能够检测两个点何时位于平面的相对位置。这相当于测试一个大圆线段是否与另一个大圆相交。执行此测试两次可以告诉我们两个大圆线段是否相互交叉。
该实现不需要三角函数,不需要除法,不需要与 pi 进行比较,也不需要围绕极点的特殊行为!
class Vector:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def dot(v1, v2):
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z
def cross(v1, v2):
return Vector(v1.y * v2.z - v1.z * v2.y,
v1.z * v2.x - v1.x * v2.z,
v1.x * v2.y - v1.y * v2.x)
def det(v1, v2, v3):
return dot(v1, cross(v2, v3))
class Pair:
def __init__(self, v1, v2):
self.v1 = v1
self.v2 = v2
# Returns True if the great circle segment determined by s
# straddles the great circle determined by l
def straddles(s, l):
return det(s.v1, l.v1, l.v2) * det(s.v2, l.v1, l.v2) < 0
# Returns True if the great circle segments determined by a and b
# cross each other
def intersects(a, b):
return straddles(a, b) and straddles(b, a)
# Test. Note that we don't need to normalize the vectors.
print(intersects(Pair(Vector(1, 0, 1), Vector(-1, 0, 1)),
Pair(Vector(0, 1, 1), Vector(0, -1, 1))))
如果您想根据角度 theta 和 phi 初始化单位向量,您可以这样做,但我建议立即转换为笛卡尔 (x, y, z) 坐标以执行所有后续计算。