Exemple #1
0
        public static Line2 FitLine(IList <Vector2> points)
        {
            var n = points.Count;

            if (n < 2)
            {
                throw new ArgumentException("At least two points are required to fit a line.");
            }

            var x        = new double[n, 2];
            var centroid = Vector2.Centroid(points);

            for (int i = 0; i < n; i++)
            {
                x[i, 0] = points[i].X - centroid.X;
                x[i, 1] = points[i].Y - centroid.Y;
            }

            double[] w;
            double[,] u, vt;
            const int uNeeded  = 0;                  // don't need left singular vectors
            const int vtNeeded = 1;                  // need first set of right singular vectors
            const int extraMemoryAllowedSetting = 2; // it's ok to use more memory for performance

            alglib.rmatrixsvd(x, n, 2, uNeeded, vtNeeded, extraMemoryAllowedSetting, out w, out u, out vt);


            // because alglib.rmatrixsvd promises to return singular values, w, in descending order, we can be sure that w[0] is the greatest
            const int IndexOfGreatestSingularValue = 0;

            var a = vt[IndexOfGreatestSingularValue, 0];
            var b = vt[IndexOfGreatestSingularValue, 1];

            var direction = new Vector2(a, b);

            return(Line2.FromPointAndDirection(centroid, direction));
        }