/// <summary>
        /// Initializes a new instance of the <see cref="TriangleQuadTree" /> class.
        /// </summary>
        /// <param name="mesh">Mesh containing triangles.</param>
        /// <param name="maxDepth">The maximum depth of the tree.</param>
        /// <param name="sizeBound">The maximum number of triangles contained in a leaf.</param>
        /// <remarks>
        /// The quadtree does not track changes of the mesh. If a mesh is refined or
        /// changed in any other way, a new quadtree has to be built to make the point
        /// location work.
        /// 
        /// A node of the tree will be split, if its level if less than the max depth parameter
        /// AND the number of triangles in the node is greater than the size bound.
        /// </remarks>
        public TriangleQuadTree(Mesh mesh, int maxDepth = 10, int sizeBound = 10)
        {
            this.maxDepth = maxDepth;
            this.sizeBound = sizeBound;

            triangles = mesh.Triangles.ToArray();

            int currentDepth = 0;

            root = new QuadNode(mesh.Bounds, this, true);
            root.CreateSubRegion(++currentDepth);
        }
            public void CreateSubRegion(int currentDepth)
            {
                // The four sub regions of the quad tree
                //   +--------------+
                //   | nw 2 | ne 3  |
                //   |------+pivot--|
                //   | sw 0 | se 1  |
                //   +--------------+
                Rectangle box;

                var width = bounds.Right - pivot.x;
                var height = bounds.Top - pivot.y;

                // 1. region south west
                box = new Rectangle(bounds.Left, bounds.Bottom, width, height);
                regions[0] = new QuadNode(box, tree);

                // 2. region south east
                box = new Rectangle(pivot.x, bounds.Bottom, width, height);
                regions[1] = new QuadNode(box, tree);

                // 3. region north west
                box = new Rectangle(bounds.Left, pivot.y, width, height);
                regions[2] = new QuadNode(box, tree);

                // 4. region north east
                box = new Rectangle(pivot.x, pivot.y, width, height);
                regions[3] = new QuadNode(box, tree);

                Point[] triangle = new Point[3];

                // Find region for every triangle vertex
                foreach (var index in triangles)
                {
                    ITriangle tri = tree.triangles[index];

                    triangle[0] = tri.GetVertex(0);
                    triangle[1] = tri.GetVertex(1);
                    triangle[2] = tri.GetVertex(2);

                    AddTriangleToRegion(triangle, index);
                }

                for (int i = 0; i < 4; i++)
                {
                    if (regions[i].triangles.Count > tree.sizeBound && currentDepth < tree.maxDepth)
                    {
                        regions[i].CreateSubRegion(currentDepth + 1);
                    }
                }
            }
Пример #3
0
        public void CreateSubRegion(int currentDepth)
        {
            // The four sub regions of the quad tree
            //   +--------------+
            //   |  nw  |  ne   |
            //   |------+pivot--|
            //   |  sw  |  se   |
            //   +--------------+
            BoundingBox box;

            // 1. region south west
            box = new BoundingBox(bounds.Xmin, bounds.Ymin, pivot.X, pivot.Y);
            regions[0] = new QuadNode(box, tree);

            // 2. region south east
            box = new BoundingBox(pivot.X, bounds.Ymin, bounds.Xmax, pivot.Y);
            regions[1] = new QuadNode(box, tree);

            // 3. region north west
            box = new BoundingBox(bounds.Xmin, pivot.Y, pivot.X, bounds.Ymax);
            regions[2] = new QuadNode(box, tree);

            // 4. region north east
            box = new BoundingBox(pivot.X, pivot.Y, bounds.Xmax, bounds.Ymax);
            regions[3] = new QuadNode(box, tree);

            Point[] triangle = new Point[3];

            // Find region for every triangle vertex
            foreach (var index in triangles)
            {
                ITriangle tri = tree.triangles[index];

                triangle[0] = tri.GetVertex(0);
                triangle[1] = tri.GetVertex(1);
                triangle[2] = tri.GetVertex(2);

                AddTriangleToRegion(triangle, tri.ID);
            }

            for (int i = 0; i < 4; i++)
            {
                if (regions[i].triangles.Count > tree.sizeBound && currentDepth < tree.maxDepth)
                {
                    regions[i].CreateSubRegion(currentDepth + 1);
                }
            }
        }