Example #1
0
        void fuseRange(BuildData data, int first, int last)
        {
            int colCount = last - first;

            var sum = Vector3.Zero;

            for (int i = 0; i < colCount; i++)
            {
                sum += data.points[data.indices[first + i]].point;
            }

            var mean = sum / colCount;
            var NN   = new MathNet.Numerics.LinearAlgebra.Single.DenseMatrix(3, colCount);
            var min  = new Vector3(float.MaxValue);
            var max  = new Vector3(float.MinValue);

            for (int i = 0; i < colCount; i++)
            {
                var v = data.points[data.indices[first + i]].point;
                var p = v - mean;
                NN.At(0, i, p.X);
                NN.At(1, i, p.Y);
                NN.At(2, i, p.Z);

                min = Vector3.Min(min, v);
                max = Vector3.Max(max, v);
            }

            Vector3 box    = max - min;
            float   boxDim = GetAt(box, MaxDim(box));

            // drop box if it is too large
            if (boxDim > maxBoxDim)
            {
                data.unfitPointsCount += colCount;
                return;
            }

            // compute covariance
            var C     = NN.TransposeAndMultiply(NN);
            var eigen = C.Evd();

            // Ensure that the matrix is suited for eigenvalues calculation
            if (eigen.Rank < 2)
            {
                data.unfitPointsCount += colCount;
                return;
            }

            var normal = computeNormal(eigen.EigenValues(), eigen.EigenVectors());

            /*T densitie = 0;
             * if(keepDensities)
             *      densitie = SurfaceNormalDataPointsFilter::computeDensity(NN);*/

            // Filter points randomly
            if (samplingMethod == SamplingMethod.RandomSampling)
            {
                for (int i = 0; i < colCount; i++)
                {
                    float x = (float)r.NextDouble();
                    if (x < ratio)
                    {
                        // Keep points with their descriptors
                        int k = data.indices[first + i];
                        // Mark the indices which will be part of the final data
                        data.pointsToKeep.Add(new DataPoint
                        {
                            point  = data.points[k].point,
                            normal = normal,
                        });;
                    }
                }
            }
            else if (samplingMethod == SamplingMethod.Bin)
            {
                // Use the average and norm
                data.pointsToKeep.Add(new DataPoint
                {
                    point  = mean,
                    normal = normal
                });
            }
        }