【问题标题】:solve two simultaneous equations: one contains a Python function求解两个联立方程:一个包含 Python 函数
【发布时间】:2022-01-17 09:05:27
【问题描述】:

在下面的地图上,我有两个已知点(A 和 B)及其坐标(经度、纬度)。我需要导出一个点 C 的坐标,该点在线上,距离 A 100 公里。

首先我创建了一个函数来计算两点之间的距离(以公里为单位):

# pip install haversine
from haversine import haversine

def get_distance(lat_from,long_from,lat_to,long_to):
    distance_in_km = haversine((lat_from,long_from),
                               (lat_to, long_to),
                                unit='km')

    return distance_in_km

然后使用斜率和距离,点C的坐标应该是以下方程的解:

# line segment AB and AC share the same slope, so
# (15.6-27.3)/(41.6-34.7) = (y-27.3)/(x-34.7)

# the distance between A and C is 100 km, so
# get_distance(y,x,27.3,34.7) = 100

然后我尝试在 Python 中解决这两个方程:

from sympy import symbols, Eq, solve

slope = (15.6-27.3)/(41.6-34.7)
x, y = symbols('x y')
eq1 = Eq(y-slope*(x-34.7)-27.3)
eq2 = Eq(get_distance(y,x,34.7,27.3)-100)
solve((eq1,eq2), (x, y))

错误是TypeError: can't convert expression to float。我可能理解错误,因为get_distance 函数期望输入为浮点数,而eq2 中的xysympy.core.symbol.Symbol

我尝试添加np.float(x),但同样的错误仍然存​​在。

有没有办法解决这样的方程?还是您有更好的方法来实现所需的目标?

非常感谢!

# there is a simple example of solving equations:
from sympy import symbols, Eq, solve
x, y = symbols('x y')
eq1 = Eq(2*x-y)
eq2 = Eq(x+2-y)
solve((eq1,eq2), (x, y))

# output: {x: 2, y: 4}

【问题讨论】:

  • 我并不感到惊讶。我对havesine 一无所知,但假设它使用某种类型的三角计算,它要么使用math.sin 要么使用np.sinmath.sin(x) 产生此错误。看到完整的回溯会很有趣,但我认为这不会有帮助。 scipy 有一些数值求解器可能会更好。
  • 数据类型sympy.core.symbol.Symbol 是否包含某种可以从中获取浮点值的字段/属性?
  • 如果你想要一个符号解决方案,你需要重写你的函数以只使用真正的 sympy 函数。参见例如this post 用于公式,您应该在其中更改所有 sincosasinsqrt 并将弧度转换为等效的弧度。
  • 这个是可以计算的,不需要用solver求解。也就是说,如果有解决方案。如果两个点相距小于100KM,则无解
  • stackoverflow.com/questions/38767074/… 是相关的。如果你想要一个 python 示例,请告诉我

标签: python sympy


【解决方案1】:

您可以直接计算该点。我们可以implement a python version of the intermediate calculation for lat long

请注意,此计算假设地球是一个球体,并考虑了曲线,即这不是像您原来的帖子那样的欧几里得近似值。

假设我们有两个(纬度、经度)点AB

import numpy as np

A = (52.234869, 4.961132)
B = (46.491267, 26.994655)

EARTH_RADIUS = 6371.009

我们可以通过取 100/distance-between-a-b-in-km 来计算中间点分数f

from sklearn.neighbors import DistanceMetric
dist = DistanceMetric.get_metric('haversine')

point_1 = np.array([A])
point_2 = np.array([B])

delta = dist.pairwise(np.radians(point_1), np.radians(point_2) )[0][0] 

f = 100 / (delta * EARTH_RADIUS)

phi_1, lambda_1 = np.radians(point_1)[0]
phi_2, lambda_2 = np.radians(point_2)[0]

a = np.sin((1-f) * delta) / np.sin(delta)
b = np.sin( f * delta) / np.sin(delta)

x = a * np.cos(phi_1) * np.cos(lambda_1) + b * np.cos(phi_2) * np.cos(lambda_2)
y = a * np.cos(phi_1) * np.sin(lambda_1) + b * np.cos(phi_2) * np.sin(lambda_2)

z = a * np.sin(phi_1) + b * np.sin(phi_2)
phi_n = np.arctan2(z, np.sqrt(x**2 + y**2) )
lambda_n = np.arctan2(y,x)

点C,从A到B,距离A有100公里,比

C = np.degrees( phi_n ), np.degrees(lambda_n)

在这种情况下

(52.02172458025681, 6.384361456573444)

【讨论】:

  • 感谢您的回答,我还在考虑您的回答,并用我的真实研究数据尝试您的代码,我会尽快批准。
  • 最初,由于在此解决方案或任何其他解决方案中做出的假设(例如地球半径的固定值),我担心精度。但后来我认为这些是不可避免的。而且我的研究数据(即卫星检索)已经存在很大的不确定性。所以现在,我决定继续。感谢您的解决方案!
  • 谢谢并高兴它(有点)工作。确实存在精度错误,很高兴在此阅读movable-type.co.uk/scripts/latlong.html#ellipsoid。这也提到了文森蒂的替代品。它涉及更多但更精确。我不知道有一种(优雅的)表格可以为 vincenty 获得中间点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-12
  • 2012-11-29
  • 1970-01-01
相关资源
最近更新 更多