我搜索非迭代的闭合形式算法,以找到最接近3d线组的点的最小二乘解。它类似于3d点三角测量(最小化重新投影),但似乎更简单,更快?
线条可以任何形式描述,2点,点和单位方向或类似。
答案 0 :(得分:5)
让 i 行由点 a i 和单位方向向量 d i 的。我们需要找到最小化点到线距离平方和的单点。这是渐变是零向量的地方:
扩展渐变
代数产生规范的3x3线性系统,
其中矩阵M的第k行(3元素行向量)是
使用vector e k 各自的单位基矢量,
将其转换为代码并不难。我从Rosettacode借用(并修复了一个小错误)高斯消除函数来解决系统问题。感谢作者!
<class 'numpy.ndarray'>
0.6930587610394646
这还没有经过广泛测试,但似乎工作正常。
答案 1 :(得分:1)
让行的基点为p
,单位方向向量为d
。
然后,可以计算从v
点到此线的距离using cross product
SquaredDist = ((v - p) x d)^2
使用Maple包符号计算,我们可以得到
d := <dx, dy, dz>;
v := <vx, vy, vz>;
p := <px, py, pz>;
w := v - p;
cp := CrossProduct(d, w);
nrm := BilinearForm(cp, cp, conjugate=false); //squared dist
nr := expand(nrm);
//now partial derivatives
nrx := diff(nr, vx);
//results:
nrx := -2*dz^2*px-2*dy^2*px+2*dz^2*vx+2*dy^2*vx
+2*dx*py*dy-2*dx*vy*dy+2*dz*dx*pz-2*dz*dx*vz
nry := -2*dx^2*py-2*dz^2*py-2*dy*vz*dz+2*dx^2*vy
+2*dz^2*vy+2*dy*pz*dz+2*dx*dy*px-2*dx*dy*vx
nrz := -2*dy^2*pz+2*dy^2*vz-2*dy*dz*vy+2*dx^2*vz
-2*dx^2*pz-2*dz*vx*dx+2*dy*dz*py+2*dz*px*dx
为了最小化平方距离的总和,我们必须为零偏导数建立线性方程组,如下所示:
vx*2*(Sum(dz^2)+Sum(dy^2)) + vy * (-2*Sum(dx*dy)) + vz *(-2*Sum(dz*dx)) =
2*Sum(dz^2*px)-2*Sum(dy^2*px) -2*Sum(dx*py*dy)-2*Sum(dz*dx*pz)
where
Sum(dz^2) = Sum{over all i in line indexes} {dz[i] * dz[i]}
并为unknowns vx,vy,vz
解决它编辑:对于飞机而不是线的旧错误答案,留待参考
如果我们使用线的一般方程
A * x + B * y + C * z + D = 0
然后从点(x,y,z)到该线的距离为
Dist = Abs(A * x + B * y + C * z + D) / Sqrt(A^2 + B^2 + C^2)
简化 - 只需将Norm
的所有线方程归一化
Norm = Sqrt(A^2 + B^2 + C^2)
a = A / Norm
b = B / Norm
c = C / Norm
d = D / Norm
现在等式是
a * x + b * y + c * z + d = 0
和距离
Dist = Abs(a * x + b * y + c * z + d)
我们可以像LS方法一样使用平方距离(ai, bi, ci, di
是第i行的系数)
F = Sum(ai*x + bi*y + ci * z + d)^2 =
Sum(ai^2*x^2 + bi^2*y^2 + ci^2*z^2 + d^2 +
2 * (ai*bi*x*y + ai*ci*x*z + bi*y*ci*z + ai*x*di + bi*y*di + ci*z*di))
partial derivatives
dF/dx = 2*Sum(ai^2*x + ai*bi*y + ai*ci*z + ai*di) = 0
dF/dy = 2*Sum(bi^2*y + ai*bi*x + bi*ci*z + bi*di) = 0
dF/dz = 2*Sum(ci^2*z + ai*ci*x + bi*ci*y + ci*di) = 0
so we have system of linear equation
x * Sum(ai^2) + y * Sum(ai*bi) + z * Sum(ai*ci)= - Sum(ai*di)
y * Sum(bi^2) + x * Sum(ai*bi) + z * Sum(bi*ci)= - Sum(bi*di)
z * Sum(ci^2) + x * Sum(ai*ci) + y * Sum(bi*ci)= - Sum(ci*di)
x * Saa + y * Sab + z * Sac = - Sad
x * Sab + y * Sbb + z * Sbc = - Sbd
x * Sac + y * Sbc + z * Scc = - Scd
where S** are corresponding sums
可以解决未知问题x, y, z