Example #1
0
        /// <summary>
        /// Returns true if a unique plane was found i.e. the given points are not coincident or colinear.
        /// </summary>
        /// <param name="points"></param>
        /// <param name="start"></param>
        /// <param name="direction"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public static bool FitLineToPoints(IEnumerable <Vector3d> points, Vector3d start, out Vector3d direction, double tolerance = D.ZeroTolerance)
        {
            // impl refs
            // https://www.geometrictools.com/Documentation/LeastSquaresFitting.pdf

            var covm = Matrix3d.CreateCovariance(points, start);

            Matrix3d.Decompose.EigenSymmetric(ref covm, out Matrix3d vecs, out Vector3d vals, tolerance);
            direction = vecs.Column0;

            // Check for degeneracy -> if 1st eigenvalue is 0, then points are coincident
            return(Math.Abs(vals.X) >= tolerance);
        }
Example #2
0
        /// <summary>
        /// Returns true if a unique plane was found i.e. the given points are not coincident or colinear.
        /// </summary>
        /// <param name="points"></param>
        /// <param name="origin"></param>
        /// <param name="normal"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public static bool FitPlaneToPoints(IEnumerable <Vector3d> points, Vector3d origin, out Vector3d normal, double tolerance = D.ZeroTolerance)
        {
            // impl refs
            // https://www.geometrictools.com/Documentation/LeastSquaresFitting.pdf
            // http://www.ilikebigbits.com/blog/2017/9/24/fitting-a-plane-to-noisy-points-in-3d

            var covm = Matrix3d.CreateCovariance(points, origin);

            Matrix3d.Decompose.EigenSymmetric(ref covm, out Matrix3d vecs, out Vector3d vals, tolerance);
            normal = vecs.Column2;

            // Check for degeneracy -> if 2nd eigenvalue is 0, the points are colinear at best
            return(Math.Abs(vals.Y) >= tolerance);
        }
Example #3
0
        /// <summary>
        /// Returns 0 if the given points are coincident, 1 if they're colinear, 2 if they're coplanar, and 3 otherwise.
        /// </summary>
        /// <param name="points"></param>
        /// <param name="origin"></param>
        /// <param name="xAxis"></param>
        /// <param name="yAxis"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public static int PrincipalComponentAnalysis(IEnumerable <Vector3d> points, out Vector3d origin, out Vector3d xAxis, out Vector3d yAxis, double tolerance = D.ZeroTolerance)
        {
            origin = points.Mean();
            var covm = Matrix3d.CreateCovariance(points, origin);

            Matrix3d.Decompose.EigenSymmetric(ref covm, out Matrix3d vecs, out Vector3d vals, tolerance);
            xAxis = vecs.Column0;
            yAxis = vecs.Column1;

            return
                (Math.Abs(vals.X) < tolerance ? 0 :
                 Math.Abs(vals.Y) < tolerance ? 1 :
                 Math.Abs(vals.Z) < tolerance ? 2 : 3);
        }