从线找到点距离 - python

问题描述 投票:0回答:5

我有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
的值应该是多少

python geometry line distance
5个回答
1
投票

使用 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

1
投票

这是使用 haversine 的答案,在 python 中,使用

Lat/Lng 点到 Minor Arc 段的距离

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


1
投票

这很容易使用,例如,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)

0
投票

如果您谈论的是地球表面以纬度和经度坐标给出的点,地球被建模为半径为

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))

0
投票

我无法理解的是如何使用 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)
© www.soinside.com 2019 - 2024. All rights reserved.