/// <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); } } }
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); } } }