示例#1
0
 private OctreeBox(List <Point> pts, OctreeBox parent,
                   int remainingNotLeafLayers, int positionInParent)
 {
     // I'm even more proud about this boundary finder :)
     for (int i = 2; i >= 0; i--)
     {
         int n = (int)System.Math.Pow(2, i);
         if (positionInParent >= n)
         {
             _dimensionsMax[i] = parent._dimensionsMax[i];
             _dimensionsMin[i] = parent.Mean(i);
             positionInParent -= n;
         }
         else
         {
             _dimensionsMax[i] = parent.Mean(i);
             _dimensionsMin[i] = parent._dimensionsMin[i];
         }
     }
     if (remainingNotLeafLayers == 0)
     {
         this.IsLeaf   = true;
         this.SubBoxes = null;
         this.Points   = pts;
     }
     else
     {
         // All points in pts MUST lie within this box!
         Subdivide(pts, remainingNotLeafLayers - 1);
     }
 }
示例#2
0
        //DOKU
        private List <OctreeBox> BoxesInRange(Point query, double squareRange,
                                              OctreeBox node)
        {
            List <OctreeBox> fittingSubBoxes = new List <OctreeBox>();

            if (node.IsLeaf)
            {
                fittingSubBoxes.Add(node);
            }
            else
            {
                foreach (OctreeBox box in node.SubBoxes)
                {
                    // skip nodes that are too far away
                    if (box.MinimumSquareDistanceTo(query) > squareRange)
                    {
                        continue;
                    }

                    if (box.IsLeaf)
                    {
                        fittingSubBoxes.Add(box);
                    }
                    else
                    {
                        fittingSubBoxes.AddRange(
                            BoxesInRange(query, squareRange, box));
                    }
                }
            }

            return(fittingSubBoxes);
        }
示例#3
0
        //DOKU
        private void TraverseSearch(Point query,
                                    OctreeBox node, NeigbourCollector neighbours)
        {
            if (node.IsLeaf)
            {
                foreach (Point p in node.Points)
                {
                    neighbours.AddNeighbour(p);
                }
                return;
            }

            // not leaf
            foreach (OctreeBox subNode in node.SubBoxes)
            {
                double curMinSDist = subNode.MinimumSquareDistanceTo(query);
                //TODO that shit about the Neighbourlist count
                // is really, really crappy!
                if (neighbours.BestNeighbours.Count > 0 &&
                    curMinSDist > neighbours.LargestSquareDistance)
                {
                    continue;
                }

                TraverseSearch(query, subNode, neighbours);
            }
            return;
        }
示例#4
0
        //DOKU
        public List <OctreeBox> GetLeafs(OctreeBox parent)
        {
            List <OctreeBox> leafs = new List <OctreeBox>();

            if (parent.IsLeaf)
            {
                leafs.Add(parent);
                return(leafs);
            }
            foreach (OctreeBox child in parent.SubBoxes)
            {
                leafs.AddRange(GetLeafs(child));
            }
            return(leafs);
        }
示例#5
0
        //DOKU
        private OctreeBox[] Subdivide(List <Point> pts, int remainingNoLeafLayers)
        {
            this.SubBoxes = new OctreeBox[8];

            List <Point>[] subdividedPointCloud = new List <Point> [8];

            // initialize array
            for (int i = 0; i < 8; i++)
            {
                subdividedPointCloud[i] = new List <Point>();
            }

            foreach (Point p in pts)
            {
                // I'm proud of this simple method of assigning the point :-)
                int boxNumber = 0;
                if (p.Z > Zmean)
                {
                    boxNumber += 4;
                }
                if (p.Y > Ymean)
                {
                    boxNumber += 2;
                }
                if (p.X > Xmean)
                {
                    boxNumber += 1;
                }
                subdividedPointCloud[boxNumber].Add(p);
            }

            // write divided points to subboxes
            for (int i = 0; i < 8; i++)
            {
                SubBoxes[i] =
                    new OctreeBox(subdividedPointCloud[i], this, remainingNoLeafLayers, i);
            }

            // reset Points to null, for all points are now Points of the SubBoxes
            this.Points = null;
            this.IsLeaf = false;

            return(this.SubBoxes);
        }
示例#6
0
        //DOKU
        public Octree(Point[] pts, int nonLeafLayers, int maxPointsPerBox)
        {
            if (maxPointsPerBox == 0)
            {
                throw new ArgumentException(
                          "An octree with the maximul leaf size 0 is impossible!");
            }

            _rootNode = new OctreeBox(pts.ToList(), nonLeafLayers);

            // If there is no point cap, the tree is done here.
            if (maxPointsPerBox < 0)
            {
                return;
            }

            // Get all the leafs to decide if a subdivision is
            // necessary or not
            List <OctreeBox> leafs = GetLeafs(_rootNode);

            // Divide all leafs into smaller boxes.
            // If a box has too many points, add it to
            //  the list of boxes that shall be divided.
            int i = 0;

            while (i < leafs.Count)
            {
                OctreeBox box = leafs[i];
                if (box.Points.Count <= maxPointsPerBox)
                {
                    i++;
                    continue;
                }

                leafs.RemoveAt(i);
                leafs.AddRange(box.Subdivide());
            }
        }