public void Undelete(int pointNum) { pointNum = idNumberAssignment[pointNum]; included[pointNum] = true; KdNode node = bucketptr[pointNum]; int j = node.LoPt; while (perm[j] != pointNum) { j++; } if (j > node.HiPt) { node.HiPt++; //swap yOffset and hipt #region int temp = perm[j]; perm[j] = perm[node.HiPt]; perm[node.HiPt] = temp; #endregion if (node.Empty) { node.Empty = false; while ((node = node.Father) != null && node.Empty) { node.Empty = false; } } } }
private void SetRad(int target, double rad, bool delete) { nndist2 = rad * rad; KdNode node = bucketptr[target]; RecursiveSetRad(node, target, rad, delete); while (true) { KdNode lastNode = node; node = node.Father; if (node == null) { break; } double diff = vertexes[target][node.CutDim] - node.CutVal; if (nndist2 >= diff * diff) { if (lastNode == node.LoSon) { RecursiveSetRad(node.HiSon, target, rad, delete); } else { RecursiveSetRad(node.LoSon, target, rad, delete); } } if (node.Depth % this.bndslevel == 0 && BallInBounds(node.Bound, target, nndist2)) { break; } } }
private void RecursiveSetRad(KdNode node, int ptnum, double rad, bool delete) { if (node.Bucket) { if (delete) { node.IntersectingBalls.Remove(node.IntersectingBalls.Find(ptnum)); } else { node.IntersectingBalls.AddLast(ptnum); } } else { double diff = vertexes[ptnum][node.CutDim] - node.CutVal; if (diff < 0.0) { RecursiveSetRad(node.LoSon, ptnum, rad, delete); if (rad >= -diff) { RecursiveSetRad(node.HiSon, ptnum, rad, delete); } } else { RecursiveSetRad(node.HiSon, ptnum, rad, delete); if (rad >= diff) { RecursiveSetRad(node.LoSon, ptnum, rad, delete); } } } }
public List <int> BallSearch(int j) { List <int> results = new List <int>(); KdNode node = bucketptr[j]; foreach (int i in node.IntersectingBalls) { if (euclideanDistance(vertexes[i], vertexes[j]) <= radii[i]) { results.Add(i); } } for (int i = 0; i < results.Count; i++) { results[i] = vertexes[results[i]].Num; } return(results); }
private void Populate() { for (int i = 0; i < vertexes.Count; ++i) { perm.Add(i); bucketptr.Add(null); radii.Add(0.0); included.Add(true); idNumberAssignment.Add(vertexes[i].Num, i); } List <double> bounds = new List <double>(2 * dimension); for (int i = 0; i < dimension; i++) { bounds.Add(double.MinValue); bounds.Add(double.MaxValue); } root = Build(0, vertexes.Count - 1, null, 0, bounds); }
public List <int> FixedRadiusNearestNeighbour(int ptnum, double rad) { List <int> results = new List <int>(); nntarget = ptnum; nndist = rad; nndist2 = rad * rad; KdNode p = bucketptr[nntarget]; RecursiveFixedRadiusNN(p, results); while (true) { KdNode lastp = p; p = p.Father; if (p == null) { break; } double diff = vertexes[nntarget][p.CutDim] - p.CutVal; if (lastp == p.LoSon) { if (nndist >= -diff) { RecursiveFixedRadiusNN(p.HiSon, results); } } else { if (nndist >= diff) { RecursiveFixedRadiusNN(p.LoSon, results); } } if (p.Depth % bndslevel == 0 && BallInBounds(p.Bound, nntarget, nndist)) { break; } } for (int i = 0; i < results.Count; i++) { results[i] = vertexes[results[i]].Num; } return(results); }
private KdNode Build(int l, int u, KdNode father, int depth, List <double> bounds) { KdNode p = new KdNode(depth); p.Father = father; p.Bound = bounds; #region for displaying only p.LoPt = l; p.HiPt = u; #endregion if (u - l + 1 <= cutoff) { p.Bucket = true; //indices of perm p.LoPt = l; p.HiPt = u; for (int i = l; i <= u; i++) { bucketptr[perm[i]] = p; } } else { p.Bucket = false; p.Empty = false; p.CutDim = FindMaxSpread(l, u); int m = Select(l, u, (l + u) / 2, p.CutDim); p.CutVal = (vertexes[perm[m]][p.CutDim] + vertexes[perm[m + 1]][p.CutDim]) / 2; List <double> bound1 = new List <double>(2 * dimension); List <double> bound2 = new List <double>(2 * dimension); for (int i = 0; i < bounds.Count; i++) { bound1.Add(bounds[i]); bound2.Add(bounds[i]); } bound1[2 * p.CutDim + 1] = p.CutVal; p.LoSon = Build(l, m, p, depth + 1, bound1); bound1[2 * p.CutDim] = p.CutVal; p.HiSon = Build(m + 1, u, p, depth + 1, bound2); } return(p); }
private void RecursiveNearestNeighbour(KdNode node) { double thisDist, thisX, val; if (node.Bucket) { for (int i = node.LoPt; i <= node.HiPt; i++) { //exclude target from search // if (perm[i] == nntarget) { continue; } thisDist = euclideanDistance(vertexes[perm[i]], vertexes[nntarget]); if (thisDist < nndist) { nndist = thisDist; nnptnum = perm[i]; } } } else { val = node.CutVal; thisX = vertexes[nntarget][node.CutDim]; if (thisX < val) { RecursiveNearestNeighbour(node.LoSon); if (thisX + nndist > val) { RecursiveNearestNeighbour(node.HiSon); } } else { RecursiveNearestNeighbour(node.HiSon); if (thisX - nndist < val) { RecursiveNearestNeighbour(node.LoSon); } } } }
private void RecursiveTopDownNearestNeighbour(KdNode node, IVertex target) { double thisDist, thisX, val; if (node.Bucket) { for (int i = node.LoPt; i <= node.HiPt; i++) { thisDist = euclideanDistance(vertexes[perm[i]], target); if (thisDist < nndist) { nndist = thisDist; nnptnum = perm[i]; } } } else { val = node.CutVal; thisX = target[node.CutDim]; if (thisX < val) { RecursiveTopDownNearestNeighbour(node.LoSon, target); if (thisX + nndist > val) { RecursiveTopDownNearestNeighbour(node.HiSon, target); } } else { RecursiveTopDownNearestNeighbour(node.HiSon, target); if (thisX - nndist < val) { RecursiveTopDownNearestNeighbour(node.LoSon, target); } } } }
private void RecursiveFixedRadiusNN(KdNode node, List <int> results) { if (node.Empty) { return; } if (node.Bucket) { for (int i = node.LoPt; i <= node.HiPt; i++) { if (euclideanDistance(vertexes[perm[i]], vertexes[nntarget]) * euclideanDistance(vertexes[perm[i]], vertexes[nntarget]) <= nndist2) { results.Add(perm[i]); } } } else { double diff = vertexes[nntarget][node.CutDim] - node.CutVal; if (diff < 0.0) { RecursiveFixedRadiusNN(node.LoSon, results); if (nndist >= -diff) { RecursiveFixedRadiusNN(node.HiSon, results); } } else { RecursiveFixedRadiusNN(node.HiSon, results); if (nndist >= diff) { RecursiveFixedRadiusNN(node.LoSon, results); } } } }
public int NearestNeighbour(int j) { nntarget = j; nndist2 = double.MaxValue; nndist = double.MaxValue; nnptnum = -1; KdNode node = bucketptr[nntarget]; RecursiveNearestNeighbour(node); while (true) { KdNode lastNode = node; node = node.Father; if (node == null) { break; } double diff = vertexes[nntarget][node.CutDim] - node.CutVal; if (nndist2 >= diff * diff) { if (lastNode == node.LoSon) { RecursiveNearestNeighbour(node.HiSon); } else { RecursiveNearestNeighbour(node.LoSon); } } if (node.Depth % this.bndslevel == 0 && BallInBounds(node.Bound, nntarget, nndist2)) { break; } } return(nnptnum == -1 ? nnptnum : vertexes[nnptnum].Num); }