Exemplo n.º 1
0
        /**
         * Recursively create a BSP tree for a given set of points
         * */
        public static BspTreeNode CreateBspTree(BspTreeNode parentNode, List <Vector3> allPoints, List <int> pointIndices)
        {
            if (pointIndices.Count == 1)
            {
                InsertNode(parentNode, allPoints, pointIndices[0]);
            }
            else if (pointIndices.Count == 2)
            {
                // Two nodes - create separating plane
                BspTreeNode node = new BspTreeNode();
                Vector3     p0   = allPoints[pointIndices[0]];
                Vector3     p1   = allPoints[pointIndices[1]];

                node.P = Vector3.Multiply(Vector3.Add(p0, p1), 0.5f);
                node.N = Vector3.Subtract(p0, p1).Normalized();

                InsertNode(node, allPoints, pointIndices[0]);
                InsertNode(node, allPoints, pointIndices[1]);

                return(node);
            }
            else
            {
                // PCA-based separation
                BspTreeNode node = new BspTreeNode();
                PrincipalComponentAnalysis pca = new PrincipalComponentAnalysis();
                foreach (int index in pointIndices)
                {
                    pca.Add(allPoints[index]);
                }
                pca.applyPCA();
                node.P = pca.getCentroid();
                node.N = pca.getEigenVector(2);

                // Handle children
                List <int> pos = new List <int>();
                List <int> neg = new List <int>();
                foreach (int index in pointIndices)
                {
                    if (node.IsPositive(allPoints[index]))
                    {
                        pos.Add(index);
                    }
                    else
                    {
                        neg.Add(index);
                    }
                }
                node.SetChild(BspTreeNode.Orientation.POSITIVE, CreateBspTree(node, allPoints, pos));
                node.SetChild(BspTreeNode.Orientation.NEGATIVE, CreateBspTree(node, allPoints, neg));

                return(node);
            }

            return(null);
        }