Reputation: 2610
Given Multiple (N) lines in 3D space, find the 3D Point minimizing the distance to all lines using Least Squares.
How can I express this in Least Square Matrix Form? Thus, Having:
[A] - Variables matrix ( known )
[x] - Unknown vector
[b] - dependent variables vector
Ax=b => Least-Square
Having the distance formula in mind, What should go in A, x, and 'b' ?
Upvotes: 3
Views: 1469
Reputation: 7824
If you expand the formula for d^2
above you find it is of the form
d^2 = Cxx Px Px + Cxy Px Py + ... + Ex Px + Ey Py + Ez Pz + F
where Cxx, Ex, F etc are constants depending on A and B vectors. Now take the sum of these for each line, lets call this sum S which is a quadratic in Px, Py and Pz.
S = Sxx Px Px + Sxy Px Py + ... + Rx Px + Ry Py + Rz Pz + T
Now differentiate
dS/dx = 2 Sxx Px + Sxy Py + Sxz Pz + Rx
dS/dy = Syx Px + 2 Syy Py + Syz Pz + Ry
dS/dz = Szx Px + Szy Py + 2 Szz Pz + Rz
As S is a minimum each of these must be zero. You can write this in matrix form A x = b. [A] is the matrix of the Sxx etc , b is the vector -[Rx,Ry,Rz] and x is the vector [Px,Py,Pz].
I've now implemented a 2D version as a jsfiddle http://jsfiddle.net/SalixAlba/Y3yT9/1/ it suprisingly simple to do the guts of the algorithm is
var sxx = 0;
var sxy = 0;
var syy = 0;
var rx = 0;
var ry = 0;
var t = 0;
// each line is defined by a x + b y + c = 0
lines.forEach(function(line, index, array) {
var div = line.a * line.a + line.b * line.b;
sxx += line.a * line.a / div;
sxy += line.a * line.b / div;
syy += line.b * line.b / div;
rx += line.a * line.c / div;
ry += line.b * line.c / div;
t += line.c * line.c / div;
});
// Derivative of S wrt x and y is
// 2 sxx x + 2 sxy y + 2 rx = 0
// 2 sxy x + 2 syy y + 2 ry = 0
// Solve this pair of linear equations
var det = sxx * syy - sxy * sxy;
if(Math.abs(det) < 1e-6) {
sol = { x: -10, y: -10 };
return;
}
// (x) = 1 ( syy -sxy ) ( -rx )
// ( ) = --- ( ) ( )
// (y) det ( -sxy sxx ) ( -ry )
var x = ( - syy * rx + sxy * ry ) / det;
var y = ( sxy * rx - sxx * ry ) / det;
console.log("x "+x+" y "+y);
sol = { x: x, y: y };
return;
Upvotes: 4