这是一些应该可以解决问题的示例代码。该算法适用于所有情况,并且始终遵循两个位置之间的最短大圆路径。数学与 Drew Hall 的答案基本相同,但使用 percent_traveled 并忽略了地球的半径。
为简单起见,此代码假定纬度和经度以弧度存储。
def get_new_location(current_location, target_location, percent_traveled):
# convert locations into cartiesian co-ordinates
current_vector = location_to_vector(current_location)
target_vector = location_to_vector(target_location)
# compute the angle between current_vector and target_vector
complete_angle = acos(vector_dot_product(current_vector, target_vector))
# determine the current partial angle, based on percent_traveled
partial_angle = percent_traveled*complete_angle
# compute a temporary vector to simplify calculation
temporary_vector = vector_cross_product(current_vector, target_vector)
temporary_vector = vector_cross_product(current_vector, temporary_vector)
# calculate new_vector
scalar_one = cos(partial_angle)
scalar_two = -sin(partial_angle)/sin(complete_angle)
vector_one = vector_multiply_by_scalar(scalar_one, current_vector)
vector_two = vector_multiply_by_scalar(scalar_two, temporary_vector)
new_vector = vector_sum(vector_one, vector_two)
# convert new_vector back into latitude & longitude and return
new_location = vector_to_location(new_vector)
return new_location
将纬度和经度转换为笛卡尔坐标的函数:
def location_to_vector(location)
vector.x = cos(location.lat)*sin(location.lon)
vector.y = sin(location.lat)
vector.z = cos(location.lat)*cos(location.lon)
return vector
将笛卡尔坐标转换为纬度和经度的函数:
def vector_to_location(vector)
location.lat = asin(vector.y)
if (vector.z == 0):
if (vector.x < 0):
location.lon = -pi/2
else:
location.lon = pi/2
else:
if (vector.z < 0):
if (vector.x < 0):
location.lon = atan(vector.x/vector.z) - pi
else:
location.lon = pi - atan(-vector.x/vector.z)
else:
if (vector.x < 0):
location.lon = -atan(-vector.x/vector.z)
else:
location.lon = atan(vector.x/vector.z)
return location
计算两个向量的点积的函数:
def vector_dot_product(A, B):
dot_product = A.x*B.x + A.y*B.y + A.z*B.z
return dot_product
计算两个向量的叉积的函数:
def vector_cross_product(A, B):
cross_product.x = A.y*B.z - A.z*B.y
cross_product.y = A.z*B.x - A.x*B.z
cross_product.z = A.x*B.y - A.y*B.x
return cross_product
将向量乘以标量的函数:
def vector_multiply_by_scalar(scalar, vector)
scaled_vector.x = scalar*vector.x
scaled_vector.y = scalar*vector.y
scaled_vector.z = scalar*vector.z
return scaled_vector
计算两个向量之和的函数:
def vector_sum(A, B)
sum.x = A.x + B.x
sum.y = A.y + B.y
sum.z = A.z + B.z
return sum