Skip to content

Commit

Permalink
Merged KDtree & KDTreeBuilder, added Lorenz System
Browse files Browse the repository at this point in the history
  • Loading branch information
viliwonka committed Nov 7, 2018
1 parent a3ffc18 commit 59405fc
Show file tree
Hide file tree
Showing 16 changed files with 168 additions and 216 deletions.
107 changes: 0 additions & 107 deletions Assets/KDTree.cs

This file was deleted.

13 changes: 0 additions & 13 deletions Assets/KDTree.cs.meta

This file was deleted.

8 changes: 8 additions & 0 deletions Assets/KDTree.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
145 changes: 77 additions & 68 deletions Assets/KDTreeBuilder.cs → Assets/KDTree/KDTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,77 +22,103 @@

namespace DataStructures {

public class KDTreeBuilder {
public partial class KDTree {

public static KDTreeBuilder Instance = new KDTreeBuilder();
public KDNode RootNode { get; private set; }

public KDNode rootNode;
public Vector3[] Points { get { return points; } } // points on which kd-tree will build on. This array will stay unchanged when re/building kdtree!
private Vector3[] points;

private Vector3[] points; // points on which kd-tree will build on. This array will stay unchanged!
// to optimize this tree further, remove permutation array and modify points array directly (it will make kd-tree magic in-place)
public int[] Permutation { get { return permutation; } } // index aray, that will get permuted
private int[] permutation;

private int[] permutation; // index aray, that will get permuted
public int Count { get; private set; }

int maxPointsPerLeafNode = 0;
private int maxPointsPerLeafNode = 8;

public KDTreeBuilder() {
private KDNode[] kdNodes;

public KDTree(int maxPointsPerLeafNode = 8) {

Count = 0;
points = new Vector3[0];
permutation = new int[0];

kdNodes = new KDNode[0];

this.maxPointsPerLeafNode = maxPointsPerLeafNode;
}

#if FL_KD_DEBUG
int nodeCount = 0;
int maxDepth = 0;
long depthCount = 0;
#endif
/// <summary>
/// Starting point for building KDTree
/// </summary>
/// <param name="points">Accepts </param>
/// <returns>Returns built KDTree</returns>
public KDTree Build(Vector3[] points, int maxPointsPerLeafNode = 8) {

#if FL_KD_DEBUG
nodeCount = 1;
maxDepth = 0;
depthCount = 0;
#endif
//! consider IList<Vector3> to make library more general
//! or IReadOnlyList<Vector3> (might not be supported
public KDTree(Vector3[] points, int maxPointsPerLeafNode = 8) {

this.points = points;
this.permutation = new int[points.Length];

this.maxPointsPerLeafNode = 5;
Count = points.Length;
kdNodes = new KDNode[0];

permutation = new int[points.Length];
this.maxPointsPerLeafNode = maxPointsPerLeafNode;

// permutation array is identiy "[i] = i" at first
for (int i = 0; i < points.Length; i++)
permutation[i] = i;
Rebuild();
}

BuildTree();

var tree = new KDTree(rootNode, this.points, permutation);
public void Build(Vector3[] newPoints, int maxPointsPerLeafNode = -1) {

SetCount(newPoints.Length);

return tree;
for(int i = 0; i < Count; i++) {
points[i] = newPoints[i];
}

Rebuild(maxPointsPerLeafNode);
}

public void Build(List<Vector3> newPoints, int maxPointsPerLeafNode = -1) {

void BuildTree() {
SetCount(newPoints.Count);

rootNode = new KDNode();
rootNode.bounds = MakeBounds();
rootNode.start = 0;
rootNode.end = permutation.Length;
for(int i = 0; i < Count; i++) {
points[i] = newPoints[i];
}

#if !FL_KD_DEBUG
SplitNode(rootNode);
#else
SplitNode(rootNode, 1);
Rebuild(maxPointsPerLeafNode);
}

public void Rebuild(int maxPointsPerLeafNode = -1) {

Debug.Log("NodeCount: " + nodeCount);
Debug.Log("AvgDepth: " + depthCount / nodeCount);
Debug.Log("MaxDepth: " + maxDepth);
#endif
SetCount(Count);

for(int i = 0; i < Count; i++) {
permutation[i] = i;
}

if(maxPointsPerLeafNode > 0) {
this.maxPointsPerLeafNode = maxPointsPerLeafNode;
}

BuildTree();
}

public void SetCount(int newSize) {

Count = newSize;
// upsize internal arrays
if(Count > points.Length) {

Array.Resize(ref points, Count);
Array.Resize(ref permutation, Count);
}
}

void BuildTree() {

RootNode = new KDNode();
RootNode.bounds = MakeBounds();
RootNode.start = 0;
RootNode.end = Count;

SplitNode(RootNode);

}

Expand All @@ -105,7 +131,7 @@ KDBounds MakeBounds() {
Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);

int even = points.Length & ~1; // calculate even Length
int even = Count & ~1; // calculate even Length

// min, max calculations
// 3n/2 calculations instead of 2n
Expand Down Expand Up @@ -169,7 +195,7 @@ KDBounds MakeBounds() {
}

// if array was odd, calculate also min/max for the last element
if(even != points.Length) {
if(even != Count) {
// X
if (min.x > points[even].x)
min.x = points[even].x;
Expand Down Expand Up @@ -203,15 +229,8 @@ KDBounds MakeBounds() {
/// <param name="parent">This is where root node goes</param>
/// <param name="depth"></param>
///
#if !FL_KD_DEBUG
void SplitNode(KDNode parent) {
#else
void SplitNode(KDNode parent, int depth) {

maxDepth = Mathf.Max(maxDepth, depth);
nodeCount += 2;
depthCount += 2*depth;
#endif
// center of bounding box
KDBounds parentBounds = parent.bounds;
Vector3 parentBoundsSize = parentBounds.size;
Expand Down Expand Up @@ -264,22 +283,12 @@ void SplitNode(KDNode parent, int depth) {
posNode.end = parent.end;
parent.positiveChild = posNode;

#if !KD_DEBUG
// Constraint function deciding if split should be continued
if (ContinueSplit(negNode))
SplitNode(negNode);

if (ContinueSplit(posNode))
SplitNode(posNode);
#else
// Constraint function deciding if split should be continued
if (ContinueSplit(negNode))
SplitNode(negNode, depth + 1);

if (ContinueSplit(posNode))
SplitNode(posNode, depth + 1);
#endif

}

/// <summary>
Expand Down Expand Up @@ -376,7 +385,7 @@ int Partition(int start, int end, float partitionPivot, int axis) {

if (LP < RP) {
// swap
temp = permutation[LP];
temp = permutation[LP];
permutation[LP] = permutation[RP];
permutation[RP] = temp;
}
Expand Down
File renamed without changes.
10 changes: 6 additions & 4 deletions Assets/Query/QueryClosest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ public void ClosestPoint(KDTree tree, Vector3 queryPosition, List<int> resultInd

Reset();

///Smallest Squared Radius
Vector3[] points = tree.Points;
int[] permutation = tree.Permutation;

int smallestIndex = 0;
/// Smallest Squared Radius
float SSR = Single.PositiveInfinity;


var rootNode = tree.rootNode;
var rootNode = tree.RootNode;

Vector3 rootClosestPoint = rootNode.bounds.ClosestPoint(queryPosition);

Expand Down Expand Up @@ -99,9 +101,9 @@ public void ClosestPoint(KDTree tree, Vector3 queryPosition, List<int> resultInd
// LEAF
for(int i = node.start; i < node.end; i++) {

int index = tree.permutation[i];
int index = permutation[i];

sqrDist = Vector3.SqrMagnitude(tree.points[index] - queryPosition);
sqrDist = Vector3.SqrMagnitude(points[index] - queryPosition);

if(sqrDist <= SSR) {

Expand Down
Loading

0 comments on commit 59405fc

Please sign in to comment.