public float GetDistsQuantile(float quantile)
        {
            float[] d       = Dists.Data;
            int[]   indices = Enumerable.Range(0, d.Length).ToArray();
            int     n       = (int)(d.Length * quantile);

            QuickSelect.Select(indices, 0, d.Length - 1, n, i => d[i]);
            return(d[indices[n]]);
        }
Beispiel #2
0
        /// <summary>
        /// This method essentially recurses, building a k-d tree of the points between first and last
        /// Once the number of points is smaller than knn, it uses that set of points to compute a surface normal
        /// From that set of points,
        /// </summary>
        void buildNew(BuildData data, int first, int last, Vector3 minValues, Vector3 maxValues)
        {
            int count = last - first;

            if (count <= knn)
            {
                // compute for this range
                fuseRange(data, first, last);
                // TODO: make another filter that creates constant-density clouds,
                // typically by stopping recursion after the median of the bounding cuboid
                // is below a threshold, or that the number of points falls under a threshold
                return;
            }

            // find the largest dimension of the box
            int cutDim = MaxDim(maxValues - minValues);

            // compute number of elements
            int rightCount = count / 2;
            int leftCount  = count - rightCount;

            Debug.Assert(last - rightCount == first + leftCount);

            // select the cut point and partition the indices around it
            var pts = data.points;

            QuickSelect.Select(data.indices, first, last - 1, first + leftCount, i => GetAt(data.points[i].point, cutDim));

            // get value
            int   cutIndex = data.indices[first + leftCount];
            float cutVal   = GetAt(data.points[cutIndex].point, cutDim);

            // update bounds for left
            Vector3 leftMaxValues = SetAt(maxValues, cutDim, cutVal);
            // update bounds for right
            Vector3 rightMinValues = SetAt(minValues, cutDim, cutVal);

            // recurse
            buildNew(data, first, first + leftCount, minValues, leftMaxValues);
            buildNew(data, first + leftCount, last, rightMinValues, maxValues);
        }