我需要一个好的算法来计算最接近python中线集合的点,最好使用最小二乘法。我在无效的python实现上找到了这篇文章:
Finding the centre of multiple lines using least squares approach in Python
然后我在Matlab中找到了每个人都喜欢的资源...但是我不确定如何将其转换为python:
https://www.mathworks.com/matlabcentral/fileexchange/37192-intersection-point-of-lines-in-3d-space
我很难相信有人还没有做过……肯定是numpy或标准软件包的一部分,对吧?我可能只是没有在寻找正确的词-但是我还没有找到它。我可以分别定义两个点或一个点和一个方向来定义线。任何帮助将不胜感激!
以下是我正在处理的一组示例要点:
第一组线的初始XYZ点
array([[-7.07107037, 7.07106748, 1. ],
[-7.34818339, 6.78264559, 1. ],
[-7.61352972, 6.48335745, 1. ],
[-7.8667115 , 6.17372055, 1. ],
[-8.1072994 , 5.85420065, 1. ]])
属于第一组线的角度
[-44.504854, -42.029223, -41.278573, -37.145774, -34.097022]
第二组线的初始XYZ点
array([[ 0., -20. , 1. ],
[ 7.99789129e-01, -19.9839984, 1. ],
[ 1.59830153e+00, -19.9360366, 1. ],
[ 2.39423914e+00, -19.8561769, 1. ],
[ 3.18637019e+00, -19.7445510, 1. ]])
属于第二组线的角度
[89.13244, 92.39087, 94.86425, 98.91849, 99.83488]
解决方案应该是原点或非常接近原点(数据只是有点杂乱,这就是为什么线条在单个点上没有完美相交的原因)。
答案 0 :(得分:4)
如果this wikipedia equation具有任何重量:
然后您可以使用:
def nearest_intersection(points, dirs):
"""
:param points: (N, 3) array of points on the lines
:param dirs: (N, 3) array of unit direction vectors
:returns: (3,) array of intersection point
"""
dirs_mat = dirs[:, :, np.newaxis] @ dirs[:, np.newaxis, :]
points_mat = points[:, :, np.newaxis]
I = np.eye(3)
return np.linalg.lstsq(
(I - dirs_mat).sum(axis=0),
((I - dirs_mat) @ points_mat).sum(axis=0),
rcond=None
)[0]
如果您需要帮助以第一原理导出/检查该方程式,那么math.stackexchange.com将是一个更好的地方。
当然这是numpy的一部分
请注意,numpy为您提供了足够的工具来非常简洁地表达这一点
答案 1 :(得分:3)
这是使用this link
中描述的方法的解决方案def intersect(P0,P1):
"""P0 and P1 are NxD arrays defining N lines.
D is the dimension of the space. This function
returns the least squares intersection of the N
lines from the system given by eq. 13 in
http://cal.cs.illinois.edu/~johannes/research/LS_line_intersect.pdf.
"""
# generate all line direction vectors
n = (P1-P0)/np.linalg.norm(P1-P0,axis=1)[:,np.newaxis] # normalized
# generate the array of all projectors
projs = np.eye(n.shape[1]) - n[:,:,np.newaxis]*n[:,np.newaxis] # I - n*n.T
# see fig. 1
# generate R matrix and q vector
R = projs.sum(axis=0)
q = (projs @ P0[:,:,np.newaxis]).sum(axis=0)
# solve the least squares problem for the
# intersection point p: Rp = q
p = np.linalg.lstsq(R,q,rcond=None)[0]
return p
作品
编辑:这是嘈杂的测试数据的生成器
n = 6
P0 = np.stack((np.array([5,5])+3*np.random.random(size=2) for i in range(n)))
a = np.linspace(0,2*np.pi,n)+np.random.random(size=n)*np.pi/5.0
P1 = np.array([5+5*np.sin(a),5+5*np.cos(a)]).T
答案 2 :(得分:1)
这是我最终使用的最终代码。感谢kevinkayaks和其他所有人的回应!非常感谢您的帮助!
此函数的前半部分只是将点和角度的两个集合转换为方向向量。我相信其余的内容基本上与Eric和Eugene提出的内容相同。我碰巧首先在Kevin's身上获得了成功,并一直坚持下去,直到对我来说这是一个端到端的解决方案。
request.Headers.Add(ApiCustomHttpHeaders.UserId, "1");