193 lines
5.0 KiB
C#
193 lines
5.0 KiB
C#
using System;
|
|
using System.Collections;
|
|
|
|
namespace KDTree
|
|
{
|
|
// Token: 0x02000008 RID: 8
|
|
public class NearestNeighbour<T> : IEnumerator
|
|
{
|
|
// Token: 0x06000037 RID: 55 RVA: 0x00003360 File Offset: 0x00001560
|
|
public NearestNeighbour(KDNode<T> pRoot, double[] tSearchPoint, DistanceFunctions kDistance, int iMaxPoints, double fThreshold)
|
|
{
|
|
if (tSearchPoint.Length != pRoot.iDimensions)
|
|
{
|
|
throw new Exception("Dimensionality of search point and kd-tree are not the same.");
|
|
}
|
|
this.tSearchPoint = new double[tSearchPoint.Length];
|
|
Array.Copy(tSearchPoint, this.tSearchPoint, tSearchPoint.Length);
|
|
this.iPointsRemaining = Math.Min(iMaxPoints, pRoot.Size);
|
|
this.fThreshold = fThreshold;
|
|
this.kDistanceFunction = kDistance;
|
|
this.pRoot = pRoot;
|
|
this.iMaxPointsReturned = iMaxPoints;
|
|
this._CurrentDistance = -1.0;
|
|
this.pEvaluated = new IntervalHeap<T>();
|
|
this.pPending = new MinHeap<KDNode<T>>();
|
|
this.pPending.Insert(0.0, pRoot);
|
|
}
|
|
|
|
// Token: 0x06000038 RID: 56 RVA: 0x00003444 File Offset: 0x00001644
|
|
public bool MoveNext()
|
|
{
|
|
bool flag;
|
|
if (this.iPointsRemaining == 0)
|
|
{
|
|
this._Current = default(T);
|
|
flag = false;
|
|
}
|
|
else
|
|
{
|
|
while (this.pPending.Size > 0 && (this.pEvaluated.Size == 0 || this.pPending.MinKey < this.pEvaluated.MinKey))
|
|
{
|
|
KDNode<T> kdnode = this.pPending.Min;
|
|
this.pPending.RemoveMin();
|
|
while (!kdnode.IsLeaf)
|
|
{
|
|
KDNode<T> kdnode2;
|
|
if (this.tSearchPoint[kdnode.iSplitDimension] > kdnode.fSplitValue)
|
|
{
|
|
kdnode2 = kdnode.pLeft;
|
|
kdnode = kdnode.pRight;
|
|
}
|
|
else
|
|
{
|
|
kdnode2 = kdnode.pRight;
|
|
kdnode = kdnode.pLeft;
|
|
}
|
|
double num = this.kDistanceFunction.DistanceToRectangle(this.tSearchPoint, kdnode2.tMinBound, kdnode2.tMaxBound);
|
|
if (this.fThreshold < 0.0 || num <= this.fThreshold)
|
|
{
|
|
if (this.pEvaluated.Size < this.iPointsRemaining || num <= this.pEvaluated.MaxKey)
|
|
{
|
|
this.pPending.Insert(num, kdnode2);
|
|
}
|
|
}
|
|
}
|
|
if (kdnode.bSinglePoint)
|
|
{
|
|
double num = this.kDistanceFunction.Distance(kdnode.tPoints[0], this.tSearchPoint);
|
|
if (this.fThreshold < 0.0 || num < this.fThreshold)
|
|
{
|
|
if (this.pEvaluated.Size < this.iPointsRemaining || num <= this.pEvaluated.MaxKey)
|
|
{
|
|
for (int i = 0; i < kdnode.Size; i++)
|
|
{
|
|
if (this.pEvaluated.Size == this.iPointsRemaining)
|
|
{
|
|
this.pEvaluated.ReplaceMax(num, kdnode.tData[i]);
|
|
}
|
|
else
|
|
{
|
|
this.pEvaluated.Insert(num, kdnode.tData[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < kdnode.Size; i++)
|
|
{
|
|
double num = this.kDistanceFunction.Distance(kdnode.tPoints[i], this.tSearchPoint);
|
|
if (this.fThreshold < 0.0 || num < this.fThreshold)
|
|
{
|
|
if (this.pEvaluated.Size < this.iPointsRemaining)
|
|
{
|
|
this.pEvaluated.Insert(num, kdnode.tData[i]);
|
|
}
|
|
else if (num < this.pEvaluated.MaxKey)
|
|
{
|
|
this.pEvaluated.ReplaceMax(num, kdnode.tData[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (this.pEvaluated.Size == 0)
|
|
{
|
|
flag = false;
|
|
}
|
|
else
|
|
{
|
|
this.iPointsRemaining--;
|
|
this._CurrentDistance = this.pEvaluated.MinKey;
|
|
this._Current = this.pEvaluated.Min;
|
|
this.pEvaluated.RemoveMin();
|
|
flag = true;
|
|
}
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
// Token: 0x06000039 RID: 57 RVA: 0x000037D4 File Offset: 0x000019D4
|
|
public void Reset()
|
|
{
|
|
this.iPointsRemaining = Math.Min(this.iMaxPointsReturned, this.pRoot.Size);
|
|
this._CurrentDistance = -1.0;
|
|
this.pEvaluated = new IntervalHeap<T>();
|
|
this.pPending = new MinHeap<KDNode<T>>();
|
|
this.pPending.Insert(0.0, this.pRoot);
|
|
}
|
|
|
|
// Token: 0x1700000D RID: 13
|
|
// (get) Token: 0x0600003A RID: 58 RVA: 0x00003840 File Offset: 0x00001A40
|
|
object IEnumerator.Current
|
|
{
|
|
get
|
|
{
|
|
return this._Current;
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700000E RID: 14
|
|
// (get) Token: 0x0600003B RID: 59 RVA: 0x00003860 File Offset: 0x00001A60
|
|
public double CurrentDistance
|
|
{
|
|
get
|
|
{
|
|
return this._CurrentDistance;
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700000F RID: 15
|
|
// (get) Token: 0x0600003C RID: 60 RVA: 0x00003878 File Offset: 0x00001A78
|
|
public T Current
|
|
{
|
|
get
|
|
{
|
|
return this._Current;
|
|
}
|
|
}
|
|
|
|
// Token: 0x04000017 RID: 23
|
|
private double[] tSearchPoint;
|
|
|
|
// Token: 0x04000018 RID: 24
|
|
private DistanceFunctions kDistanceFunction;
|
|
|
|
// Token: 0x04000019 RID: 25
|
|
private MinHeap<KDNode<T>> pPending;
|
|
|
|
// Token: 0x0400001A RID: 26
|
|
private IntervalHeap<T> pEvaluated;
|
|
|
|
// Token: 0x0400001B RID: 27
|
|
private KDNode<T> pRoot = null;
|
|
|
|
// Token: 0x0400001C RID: 28
|
|
private int iMaxPointsReturned = 0;
|
|
|
|
// Token: 0x0400001D RID: 29
|
|
private int iPointsRemaining;
|
|
|
|
// Token: 0x0400001E RID: 30
|
|
private double fThreshold;
|
|
|
|
// Token: 0x0400001F RID: 31
|
|
private double _CurrentDistance = -1.0;
|
|
|
|
// Token: 0x04000020 RID: 32
|
|
private T _Current = default(T);
|
|
}
|
|
}
|