Пример #1
0
        private static void CalculatePCA(List <Point3D> _points, out Point3D pivotO,
                                         out Vector3D vecX, out Vector3D vecY, out Vector3D vecZ)
        {
            pivotO = new Point3D(0, 0, 0);
            vecX   = new Vector3D(0, 0, 0);
            vecY   = new Vector3D(0, 0, 0);
            vecZ   = new Vector3D(0, 0, 0);
            if (_points == null || _points.Count < 1)
            {
                return;
            }

            Point3D pivot = GeometricTransforms.GetPivot(_points);

            pivotO = new Point3D(pivot.X, pivot.Y, pivot.Z);
            List <Vector3D> point_deviations = _points.Select(x => x - pivot).ToList();
            int             nrP = _points.Count;

            #region COVARIANCE:Old
            //// compute the covariance matrix
            //double[] m = new double[3*nrP];
            //for(int i = 0; i < nrP; i++)
            //{
            //    m[i*3] = point_deviations[i].X;
            //    m[i*3 + 1] = point_deviations[i].Y;
            //    m[i*3 + 2] = point_deviations[i].Z;
            //}
            //MatrixNxN M = new MatrixNxN(nrP, 3, m);
            //MatrixNxN MtxM = MatrixNxN.Squared(M);
            //MtxM.Scale(1.0 / nrP);
            #endregion

            // compute the covariance matrix ...
            // using 3rd party library DotNetMatrix
            double[][] pd_as_array = new double[nrP][];
            for (int i = 0; i < nrP; i++)
            {
                pd_as_array[i] = new double[] { point_deviations[i].X, point_deviations[i].Y, point_deviations[i].Z };
            }
            GeneralMatrix gm_M    = new GeneralMatrix(pd_as_array);
            GeneralMatrix gm_Mt   = gm_M.Transpose();
            GeneralMatrix gm_Msq  = gm_Mt.Multiply(gm_M);
            GeneralMatrix gm_Msqn = gm_Msq.Multiply(1.0 / nrP);

            // extract the sorted Eigenvalues of the matrix...
            // using 3rd party library DotNetMatrix
            EigenvalueDecomposition decomp  = gm_Msqn.Eigen();
            GeneralMatrix           gm_EVec = decomp.GetV();
            double[] gm_EVal = decomp.RealEigenvalues;

            // from smallest to largest eigenvalue
            vecX = new Vector3D(gm_EVec.GetElement(0, 0), gm_EVec.GetElement(1, 0), gm_EVec.GetElement(2, 0));
            vecY = new Vector3D(gm_EVec.GetElement(0, 1), gm_EVec.GetElement(1, 1), gm_EVec.GetElement(2, 1));
            vecZ = new Vector3D(gm_EVec.GetElement(0, 2), gm_EVec.GetElement(1, 2), gm_EVec.GetElement(2, 2));
        }