internal InternalKdNode Split(out LeafKdNode rightSibling) { Particle.Dim splitDirection = Dimension(Particle.Dim.Horizontal) > Dimension(Particle.Dim.Vertical) ? Particle.Dim.Horizontal : Particle.Dim.Vertical; Particle.Dim nonSplitDirection = splitDirection == Particle.Dim.Horizontal ? Particle.Dim.Vertical : Particle.Dim.Horizontal; int n = Size(), nLeft = n / 2, nRight = n - nLeft; Particle[][] leftParticles = new Particle[][] { new Particle[nLeft], new Particle[nLeft] }, rightParticles = new Particle[][] { new Particle[nRight], new Particle[nRight] }; int lCtr = 0, rCtr = 0; for (int i = 0; i < n; ++i) { Particle p = particles[(int)splitDirection][i]; if (i < nLeft) { leftParticles[(int)splitDirection][i] = p; p.splitLeft = true; } else { rightParticles[(int)splitDirection][i - nLeft] = p; p.splitLeft = false; } } for (int i = 0; i < n; ++i) { Particle p = particles[(int)nonSplitDirection][i]; if (p.splitLeft) { leftParticles[(int)nonSplitDirection][lCtr++] = p; } else { rightParticles[(int)nonSplitDirection][rCtr++] = p; } } Debug.Assert(lCtr == nLeft); Debug.Assert(rCtr == nRight); Disc parentMED = med; particles = leftParticles; ComputeMED(); rightSibling = new LeafKdNode(rightParticles); return(new InternalKdNode(parentMED, this, rightSibling)); }
/// <summary> /// Create a KDTree over the specified particles, with the leaf partitions each containing bucketSize particles. /// </summary> /// <param name="particles"></param> /// <param name="bucketSize"></param> public KDTree(Particle[] particles, int bucketSize) { this.particles = particles; Particle[][] ps = new Particle[][] { particlesBy(Particle.Dim.Horizontal), particlesBy(Particle.Dim.Vertical) }; leaves = new List <LeafKdNode>(); LeafKdNode l = new LeafKdNode(ps), r; leaves.Add(l); root = l.Split(out r); leaves.Add(r); var splitQueue = new SplitQueue(bucketSize); splitQueue.Enqueue(l, r); while (splitQueue.Count > 0) { l = splitQueue.Dequeue(); l.Split(out r); leaves.Add(r); splitQueue.Enqueue(l, r); } }