![](/img/trans.png)
[英]Given an arc with a known start(x, y), end(x, y) and angle, how can I calculate its bounding box?
[英]Calculate Projected Point location (x,y) on given line start(x,y) end(x,y)
此解决方案扩展到具有任何几何尺寸的点(2D、3D、4D、...)。 它假设所有点都是一维 numpy arrays (或一维形状 1 的二维)。 我不确定您是否需要投影落在线段或线段的延伸上,所以我将两者都包括在内。 您可以选择最适合您问题的选项:
#distance between p1 and p2
l2 = np.sum((p1-p2)**2)
if l2 == 0:
print('p1 and p2 are the same points')
#The line extending the segment is parameterized as p1 + t (p2 - p1).
#The projection falls where t = [(p3-p1) . (p2-p1)] / |p2-p1|^2
#if you need the point to project on line extention connecting p1 and p2
t = np.sum((p3 - p1) * (p2 - p1)) / l2
#if you need to ignore if p3 does not project onto line segment
if t > 1 or t < 0:
print('p3 does not project onto p1-p2 line segment')
#if you need the point to project on line segment between p1 and p2 or closest point of the line segment
t = max(0, min(1, np.sum((p3 - p1) * (p2 - p1)) / l2))
projection = p1 + t * (p2 - p1)
Numpy code that works for both 2D and 3D (based on https://gamedev.stackexchange.com/questions/72528/how-can-i-project-a-3d-point-onto-a-3d-line ):
import numpy as np
def point_on_line(a, b, p):
ap = p - a
ab = b - a
result = a + np.dot(ap, ab) / np.dot(ab, ab) * ab
return result
A = np.array([2, 0])
B = np.array([4, 4])
P = np.array([1, 3])
projected = point_on_line(A, B, P)
print(projected)
更新
Plot:
A = np.array([ 10.5, 15.6 ])
B = np.array([ 2, 6 ])
P = np.array([ 18.561, -19.451])
projected = point_on_line(A, B, P)
print(projected)
# [-3.35411076 -0.04699568]
plt.xlim(-20, 20)
plt.ylim(-20, 20)
plt.axis('equal')
x_values = [A[0], B[0]]
y_values = [A[1], B[1]]
plt.plot(B[0], B[1], 'ro')
plt.plot(A[0], A[1], 'ro')
plt.plot(P[0], P[1], 'ro')
plt.plot(x_values, y_values, 'b-')
plt.plot(projected[0], projected[1], 'rx')
更新 2
如果你需要点属于段,你需要做一个小的修改
def point_on_line(a, b, p):
ap = p - a
ab = b - a
t = np.dot(ap, ab) / np.dot(ab, ab)
# if you need the the closest point belonging to the segment
t = max(0, min(1, t))
result = a + t * ab
return result
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.