简体   繁体   中英

Project (x, y) coordinates onto a line as a distance

I would like to project two (x, y) points C and E normally onto a line defined by two (x, y) points A and B. I want the projection result as a distance from A towards B (eg AD and AF in the below image), not as (x, y) coordinates on the line. Notice the negative distance for AF when it falls outside the A to B line. Please help me out with the below coordinates_to_distances function.

通常将点 C 和 E 投影到从 A 到 B 的直线上

import numpy as np

A = np.array([2, 1])   # (x, y) coordinates of A
B = np.array([6, 2])   # (x, y) coordinates of B

x = np.array([3, 1])   # x-coordinates of C and E
y = np.array([3, 2])   # y-coordinates of C and E

def coordinates_to_distances(A, B, x, y):
    # Help
    return distances

distances = coordinates_to_distances(A, B, x, y) # expected result: [1.46, -0.73]

I've modified your task a little to work with points as dictionaries ({x, y}).

projection returns a projection point of c to line ab

distance_to_point returns distance of point c to point a , where direction from a is given by point b

NOTE : The sample will not work when the line ab is vertical!

import math

def projection(a,b,c):
  n = (b['y'] - a['y']) / (b['x'] - a['x'])
  m = a['y'] - n * a['x']
  p = c['y'] + c['x'] / n
  x = (p - m) / (n + 1 / n)
  y = n * x + m
  return {'x': x, 'y': y}

def distance_to_point(a, b, c):
  dir = 1 if bool(b['x'] > a['x']) == bool(c['x'] > a['x']) else -1
  return math.hypot(c['y'] - a['y'], c['x'] - a['x']) * dir

a = {'x': 2, 'y': 1}  
b = {'x': 6, 'y': 2}  
c = {'x': 3, 'y': 3}
d = projection(a, b, c)
dta = distance_to_point(a, b, d)
print(dta)

NumPy solution:

import numpy as np

A = np.array([2, 1])   # (x, y) coordinates of A
B = np.array([6, 2])   # (x, y) coordinates of B

x = np.array([3, 1])   # x-coordinates of C and E
y = np.array([3, 2])   # y-coordinates of C and E

def coordinates_to_distances(A, B, x, y):
    dy = B[1] - A[1]
    dx = B[0] - A[0]
    x_new, y_new = x * 0 + 1, y * 0 + 1
    if dx == 0:
        x_new, y_new = x * 0 + A[0], y
    if dy == 0:
        x_new, y_new = x, y * 0 + A[1]
    if dx != 0 and dy != 0:
        n = dy / dx
        m = A[1] - n * A[0]
        p = y + x / n
        x_new = (p - m) / (n + 1 / n)
        y_new = n * x_new + m
    dir = x_new * 0 - 1
    dir[(B[0] > A[0]) == (x_new > A[0])] = 1
    return dir * np.sqrt((A[0] - x_new)**2 + (A[1] - y_new)**2)

distances = coordinates_to_distances(A, B, x, y)

print(distances)   # [1.46, -0.73]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM