248 lines
5.7 KiB
C#
248 lines
5.7 KiB
C#
using System;
|
|
|
|
namespace KDTree
|
|
{
|
|
// Token: 0x02000005 RID: 5
|
|
public class KDNode<T>
|
|
{
|
|
// Token: 0x0600001B RID: 27 RVA: 0x00002A10 File Offset: 0x00000C10
|
|
protected KDNode(int iDimensions, int iBucketCapacity)
|
|
{
|
|
this.iDimensions = iDimensions;
|
|
this.iBucketCapacity = iBucketCapacity;
|
|
this.Size = 0;
|
|
this.bSinglePoint = true;
|
|
this.tPoints = new double[iBucketCapacity + 1][];
|
|
this.tData = new T[iBucketCapacity + 1];
|
|
}
|
|
|
|
// Token: 0x17000007 RID: 7
|
|
// (get) Token: 0x0600001C RID: 28 RVA: 0x00002A60 File Offset: 0x00000C60
|
|
// (set) Token: 0x0600001D RID: 29 RVA: 0x00002A77 File Offset: 0x00000C77
|
|
public int Size { get; private set; }
|
|
|
|
// Token: 0x17000008 RID: 8
|
|
// (get) Token: 0x0600001E RID: 30 RVA: 0x00002A80 File Offset: 0x00000C80
|
|
public bool IsLeaf
|
|
{
|
|
get
|
|
{
|
|
return this.tPoints != null;
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600001F RID: 31 RVA: 0x00002AA0 File Offset: 0x00000CA0
|
|
public void AddPoint(double[] tPoint, T kValue)
|
|
{
|
|
KDNode<T> kdnode = this;
|
|
while (!kdnode.IsLeaf)
|
|
{
|
|
kdnode.ExtendBounds(tPoint);
|
|
kdnode.Size++;
|
|
if (tPoint[kdnode.iSplitDimension] > kdnode.fSplitValue)
|
|
{
|
|
kdnode = kdnode.pRight;
|
|
}
|
|
else
|
|
{
|
|
kdnode = kdnode.pLeft;
|
|
}
|
|
}
|
|
kdnode.AddLeafPoint(tPoint, kValue);
|
|
}
|
|
|
|
// Token: 0x06000020 RID: 32 RVA: 0x00002B0C File Offset: 0x00000D0C
|
|
private void AddLeafPoint(double[] tPoint, T kValue)
|
|
{
|
|
this.tPoints[this.Size] = tPoint;
|
|
this.tData[this.Size] = kValue;
|
|
this.ExtendBounds(tPoint);
|
|
this.Size++;
|
|
if (this.Size == this.tPoints.Length - 1)
|
|
{
|
|
if (this.CalculateSplit())
|
|
{
|
|
this.SplitLeafNode();
|
|
}
|
|
else
|
|
{
|
|
this.IncreaseLeafCapacity();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000021 RID: 33 RVA: 0x00002B90 File Offset: 0x00000D90
|
|
private bool CheckBounds(double[] tPoint)
|
|
{
|
|
int i = 0;
|
|
while (i < this.iDimensions)
|
|
{
|
|
bool flag;
|
|
if (tPoint[i] > this.tMaxBound[i])
|
|
{
|
|
flag = false;
|
|
}
|
|
else
|
|
{
|
|
if (tPoint[i] >= this.tMinBound[i])
|
|
{
|
|
i++;
|
|
continue;
|
|
}
|
|
flag = false;
|
|
}
|
|
return flag;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Token: 0x06000022 RID: 34 RVA: 0x00002BEC File Offset: 0x00000DEC
|
|
private void ExtendBounds(double[] tPoint)
|
|
{
|
|
if (this.tMinBound == null)
|
|
{
|
|
this.tMinBound = new double[this.iDimensions];
|
|
this.tMaxBound = new double[this.iDimensions];
|
|
Array.Copy(tPoint, this.tMinBound, this.iDimensions);
|
|
Array.Copy(tPoint, this.tMaxBound, this.iDimensions);
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < this.iDimensions; i++)
|
|
{
|
|
if (double.IsNaN(tPoint[i]))
|
|
{
|
|
if (!double.IsNaN(this.tMinBound[i]) || !double.IsNaN(this.tMaxBound[i]))
|
|
{
|
|
this.bSinglePoint = false;
|
|
}
|
|
this.tMinBound[i] = double.NaN;
|
|
this.tMaxBound[i] = double.NaN;
|
|
}
|
|
else if (this.tMinBound[i] > tPoint[i])
|
|
{
|
|
this.tMinBound[i] = tPoint[i];
|
|
this.bSinglePoint = false;
|
|
}
|
|
else if (this.tMaxBound[i] < tPoint[i])
|
|
{
|
|
this.tMaxBound[i] = tPoint[i];
|
|
this.bSinglePoint = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000023 RID: 35 RVA: 0x00002D27 File Offset: 0x00000F27
|
|
private void IncreaseLeafCapacity()
|
|
{
|
|
Array.Resize<double[]>(ref this.tPoints, this.tPoints.Length * 2);
|
|
Array.Resize<T>(ref this.tData, this.tData.Length * 2);
|
|
}
|
|
|
|
// Token: 0x06000024 RID: 36 RVA: 0x00002D58 File Offset: 0x00000F58
|
|
private bool CalculateSplit()
|
|
{
|
|
bool flag;
|
|
if (this.bSinglePoint)
|
|
{
|
|
flag = false;
|
|
}
|
|
else
|
|
{
|
|
double num = 0.0;
|
|
for (int i = 0; i < this.iDimensions; i++)
|
|
{
|
|
double num2 = this.tMaxBound[i] - this.tMinBound[i];
|
|
if (double.IsNaN(num2))
|
|
{
|
|
num2 = 0.0;
|
|
}
|
|
if (num2 > num)
|
|
{
|
|
this.iSplitDimension = i;
|
|
num = num2;
|
|
}
|
|
}
|
|
if (num == 0.0)
|
|
{
|
|
flag = false;
|
|
}
|
|
else
|
|
{
|
|
this.fSplitValue = (this.tMinBound[this.iSplitDimension] + this.tMaxBound[this.iSplitDimension]) * 0.5;
|
|
if (this.fSplitValue == double.PositiveInfinity)
|
|
{
|
|
this.fSplitValue = double.MaxValue;
|
|
}
|
|
else if (this.fSplitValue == double.NegativeInfinity)
|
|
{
|
|
this.fSplitValue = double.MinValue;
|
|
}
|
|
if (this.fSplitValue == this.tMaxBound[this.iSplitDimension])
|
|
{
|
|
this.fSplitValue = this.tMinBound[this.iSplitDimension];
|
|
}
|
|
flag = true;
|
|
}
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
// Token: 0x06000025 RID: 37 RVA: 0x00002EB4 File Offset: 0x000010B4
|
|
private void SplitLeafNode()
|
|
{
|
|
this.pRight = new KDNode<T>(this.iDimensions, this.iBucketCapacity);
|
|
this.pLeft = new KDNode<T>(this.iDimensions, this.iBucketCapacity);
|
|
for (int i = 0; i < this.Size; i++)
|
|
{
|
|
double[] array = this.tPoints[i];
|
|
T t = this.tData[i];
|
|
if (array[this.iSplitDimension] > this.fSplitValue)
|
|
{
|
|
this.pRight.AddLeafPoint(array, t);
|
|
}
|
|
else
|
|
{
|
|
this.pLeft.AddLeafPoint(array, t);
|
|
}
|
|
}
|
|
this.tPoints = null;
|
|
this.tData = null;
|
|
}
|
|
|
|
// Token: 0x04000006 RID: 6
|
|
protected internal int iDimensions;
|
|
|
|
// Token: 0x04000007 RID: 7
|
|
protected internal int iBucketCapacity;
|
|
|
|
// Token: 0x04000008 RID: 8
|
|
protected internal double[][] tPoints;
|
|
|
|
// Token: 0x04000009 RID: 9
|
|
protected internal T[] tData;
|
|
|
|
// Token: 0x0400000A RID: 10
|
|
protected internal KDNode<T> pLeft;
|
|
|
|
// Token: 0x0400000B RID: 11
|
|
protected internal KDNode<T> pRight;
|
|
|
|
// Token: 0x0400000C RID: 12
|
|
protected internal int iSplitDimension;
|
|
|
|
// Token: 0x0400000D RID: 13
|
|
protected internal double fSplitValue;
|
|
|
|
// Token: 0x0400000E RID: 14
|
|
protected internal double[] tMinBound;
|
|
|
|
// Token: 0x0400000F RID: 15
|
|
protected internal double[] tMaxBound;
|
|
|
|
// Token: 0x04000010 RID: 16
|
|
protected internal bool bSinglePoint;
|
|
}
|
|
}
|