| 935 | // are processed. |
| 936 | template <typename TIds> |
| 937 | double BucketList<TIds>::FindNPointsInShell(int N, const double x[3], vtkDist2TupleArray& results, |
| 938 | double minR2, bool sort, vtkDoubleArray* spheres) |
| 939 | { |
| 940 | // Clear out any previous results. |
| 941 | results.clear(); |
| 942 | |
| 943 | // Find the bucket/bin the point is in. This is the center of the request |
| 944 | // footprint. |
| 945 | int center[3]; |
| 946 | this->GetBucketIndices(x, center); |
| 947 | |
| 948 | // Traverse and gather points in the bucket/bins contained in the shell |
| 949 | // request (minR,maxR]. |
| 950 | double minR = sqrt(minR2); |
| 951 | double maxR = 0, maxR2 = 0; |
| 952 | |
| 953 | // Determine absolute limits of iteration (based on possible number of points). |
| 954 | vtkIdType numPts = this->DataSet->GetNumberOfPoints(); |
| 955 | N = (numPts < N ? numPts : N); |
| 956 | |
| 957 | // Gather N points if possible and determine maxR2. Make sure all points within maxR2 |
| 958 | // have been found. We use a shell iterator to grow a "rectangular" shell from the center bin. |
| 959 | // Skip over bins inside the inner radius minR2. The bin index is updated during iteration, |
| 960 | // a binIdx<0 is returned when the iteration is exhausted. |
| 961 | vtkIdType binIdx; |
| 962 | int currentLevel = (minR <= 0 ? 0 : static_cast<int>(std::floor(minR / (2.0 * this->BinRadius)))); |
| 963 | ShellIterator<TIds> siter( |
| 964 | this->DataSet, this, this->Divisions, this->BinRadius, spheres, x, center); |
| 965 | |
| 966 | // Loop across levels, accruing points as we go. This will determine the maxR2. It also |
| 967 | // carves out some inner levels (based on current level) that do not have to be revisited. |
| 968 | while (static_cast<int>(results.size()) < N && currentLevel < this->MaxLevel) |
| 969 | { |
| 970 | int i, j, k; |
| 971 | binIdx = siter.Initialize(currentLevel, i, j, k); |
| 972 | // Basically iterating over a "rectangular" footprint defined from |
| 973 | // the current level. |
| 974 | while (binIdx >= 0) |
| 975 | { |
| 976 | maxR2 = siter.GatherPoints(i, j, k, binIdx, currentLevel, N, minR2, maxR2, results); |
| 977 | binIdx = siter.NextBin(i, j, k); |
| 978 | } |
| 979 | ++currentLevel; |
| 980 | } |
| 981 | int level = currentLevel - 1; // reset to the last level processed |
| 982 | |
| 983 | // We have determined maxR2 and ~N points in the request annulus |
| 984 | // (minR2 < p_d2 <= maxR2). Now gather any other remaining points |
| 985 | // within the request. It's typical that the number of points |
| 986 | // returned is >N. |
| 987 | maxR = sqrt(maxR2); |
| 988 | |
| 989 | // Determine the range of indices in each direction based on radius maxR. |
| 990 | // This block of bins is processed to gather any additional points with |
| 991 | // radius <=maxR2. |
| 992 | double xMin[3], xMax[3]; |
| 993 | xMin[0] = x[0] - maxR; |
| 994 | xMin[1] = x[1] - maxR; |
nothing calls this directly
no test coverage detected