我有3分
p1 = 48.36736702002282, 11.112351406920268
p2 = 48.36728222003929, 11.112716801718284
p3 = 48.36720362305641,11.112587917596102
我想找到从
p3
到p1
和p2
的垂直距离。
为此,我的计划是,使用
p1
和 p2
创建一条线,然后尝试找到从点 p3
到线(从 p1
和 p2
创建)的垂直距离。
我正在关注HERE
代码来自 geeksforgeeks:
# Python program to find the distance between
# a given point and a given line in 2 D.
import math
# Function to find distance
def shortest_distance(x1, y1, a, b, c):
d = abs((a * x1 + b * y1 + c)) / (math.sqrt(a * a + b * b))
print("Perpendicular distance is"),d
# Driver Code
x1 = 5
y1 = 6
a = -2
b = 3
c = 4
shortest_distance(x1, y1, a, b, c)
我无法理解的是如何使用
p1
和 p2
创建线以及上面代码中 x1, y1, a, b, c
的值应该是多少
使用 wikipedia 中的方程式(在我看来这是一个很好的来源,但值得商榷):
import math
def find_distance(p1,p2,p3):
nom = abs((p2[0]-p1[0])*(p1[1]-p3[1])-(p1[0]-p3[0])*(p2[1]-p1[1]))
denom = math.sqrt((p2[0]-p1[0])**2+(p2[1]-p1[1])**2)
return nom/denom
print(find_distance(p1,p2,p3))
输出:
0.0001056989661888993
这是使用 haversine 的答案,在 python 中,使用
import numpy as np
from sklearn.neighbors import DistanceMetric
dist = DistanceMetric.get_metric('haversine')
def bear( latA,lonA,latB,lonB ):
b= np.arctan2( np.sin(lonB-lonA)*np.cos(latB) , np.cos(latA)*np.sin(latB) - np.sin(latA)*np.cos(latB)*np.cos(lonB-lonA) )
return b
def crossarc( p1, p2, p3 ):
"""
CROSSARC Calculates the shortest distance
between an arc (defined by p1 and p2) and a third point, p3.
Input lat1,lon1,lat2,lon2,lat3,lon3 in degrees.
"""
lat1,lon1 = p1
lat2,lon2 = p2
lat3,lon3 = p3
lat1= np.radians(lat1);
lat2= np.radians(lat2);
lat3= np.radians(lat3);
lon1= np.radians(lon1);
lon2= np.radians(lon2);
lon3= np.radians(lon3);
bear12 = bear(lat1,lon1,lat2,lon2);
bear13 = bear(lat1,lon1,lat3,lon3);
dis13 = dist.pairwise(np.array([[lat1, lon1]]), np.array([[lat3, lon3]]))[0][0]
diff = np.abs(bear13-bear12);
if diff > np.pi:
diff = 2 * np.pi - diff;
if diff > (np.pi/2):
dxa = dis13
else:
dxt = np.arcsin( np.sin(dis13)* np.sin(bear13 - bear12) );
dis12 = dist.pairwise(np.array([[lat1, lon1]]), np.array([[lat2, lon2]]))[0][0]
dis14 = np.arccos( np.cos(dis13) / np.cos(dxt) );
if dis14 > dis12:
dxa = dist.pairwise(np.array([[lat2, lon2]]), np.array([[lat3, lon3]]))[0][0]
else:
dxa = np.abs(dxt);
return dxa
我们有
p1 = 48.36736702002282, 11.112351406920268
p2 = 48.36728222003929, 11.112716801718284
p3 = 48.36720362305641, 11.112587917596102
然后
crossarc(p1,p2,p3)
将返回距离(haversine),例如将其转换为米使用地球半径与
print("Distance in meters: {}".format( 6371000 * crossarc(p1,p2,p3) ))
输出
Distance in meters: 11.390566923942787
这很容易使用,例如,scikit-spatial 库:
from skspatial.objects import Point, Line
# Define points
p1 = Point([48.36736702002282, 11.112351406920268])
p2 = Point([48.36728222003929, 11.112716801718284])
p3 = Point([48.36720362305641,11.112587917596102])
# Define line passing through p1 and p2
line_p12 = Line.from_points(p1, p2)
# Compute p3-line_p12 distance
distance = line_p12.distance_point(p3)
如果您谈论的是地球表面以纬度和经度坐标给出的点,地球被建模为半径为
R = 6371000
米的完美球体,那么很多公式内容可以很容易地从简单的 3D 矢量中推导出来几何。
import numpy as np
import math
R = 6371000
def cos_sin(angle):
return math.cos(math.pi*angle/180), math.sin(math.pi*angle/180)
def S(point):
cos_phi, sin_phi = cos_sin(point[0])
cos_lambda, sin_lambda = cos_sin(point[1])
return np.array([cos_phi*cos_lambda,
cos_phi*sin_lambda,
sin_phi])
def height(P1, P2, P3):
N = np.cross(S(P1), S(P2))
N = N / np.linalg.norm(N)
return R*(math.pi/2 - math.acos( abs( S(P3).dot(N)) ))
p1 = 48.36736702002282, 11.112351406920268
p2 = 48.36728222003929, 11.112716801718284
p3 = 48.36720362305641, 11.112587917596102
print(height(p1, p2, p3))
我无法理解的是如何使用 p1 和 p2 创建线以及上面代码中 x1、y1、a、b、c 的值应该是多少
这里,(x1, y1) 是需要找出距离的点的坐标。 a,b,c 是线性方程 ax+by+c = 0
的系数以ax + by + c = 0的形式从p1、p2创建一条直线, 你可以使用斜率截距公式 (y = mx + c)
斜率 = m = (y2-y1)/(x2-x1)
截距 = i = y1 - m * x1
现在方程可以写成 mx -y + i = 0
因此 a = m, b = -1, c = i
另外,如果一条直线有两个点,则不需要找到方程来求解它。您可以使用以下公式
np.cross(p3-p1, p2-p1) / np.linalg.norm(p2-p1)