public static Line3d Line(this V3d[] points) { // compute covariance matrix of k closest points relative to centroid var kk = points.Length; // compute covariance matrix of k closest points relative to centroid var c = V3d.Zero; for (var j = 0; j < kk; j++) { c += points[j]; } c /= kk; var cvm = M33d.Zero; for (var j = 0; j < kk; j++) { CovarianceMatrixExtensions.AddOuterProduct(ref cvm, points[j] - c); } cvm /= kk; // solve eigensystem -> eigenvector with largest eigenvalue is best fit line Eigensystems.Dsyevh3(cvm, out M33d q, out V3d w); var n = ((w.X > w.Y) ? ((w.X > w.Z) ? q.C0 : q.C2) : ((w.Y > w.Z) ? q.C1 : q.C2)); return(new Line3d(c - n, c + n)); }
public static Plane3d Fit(this V3d[] points) { var kk = points.Length; // compute covariance matrix of k closest points relative to centroid var c = V3d.Zero; for (var j = 0; j < kk; j++) { c += points[j]; } c /= kk; var cvm = M33d.Zero; for (var j = 0; j < kk; j++) { CovarianceMatrixExtensions.AddOuterProduct(ref cvm, points[j] - c); } cvm /= kk; // solve eigensystem -> eigenvector for smallest eigenvalue gives normal Eigensystems.Dsyevh3(cvm, out M33d q, out V3d w); var n = ((w.X < w.Y) ? ((w.X < w.Z) ? q.C0 : q.C2) : ((w.Y < w.Z) ? q.C1 : q.C2)); return(new Plane3d(n, c)); }