Ejemplo n.º 1
0
        public void BuildBSPTree(ref BSPTree tree, List <Polygon3> polygons)
        {
            Polygon3 root = polygons.First();

            polygons.RemoveAt(0);
            tree.partition = new Plane(root.Points[0], root.Points[1], root.Points[2]);
            tree.polygons.Add(root);

            List <Polygon3> frontlist = new List <Polygon3>();
            List <Polygon3> backlist  = new List <Polygon3>();

            while (polygons.Count > 0)
            {
                var poly = polygons.First();
                polygons.RemoveAt(0);
                var result = tree.partition.ClassifyPolygon(poly);
                switch (result)
                {
                case Result.COINCIDENT:
                    tree.polygons.Add(poly);
                    break;

                case Result.IN_BACK_OF:
                    backlist.Add(poly);
                    break;

                case Result.IN_FRONT_OF:
                    frontlist.Add(poly);
                    break;

                case Result.SPANNING:
                    Polygon3 front_piece = new Polygon3(), back_piece = new Polygon3();
                    Split_Polygon(poly, tree.partition, ref front_piece, ref back_piece);
                    backlist.Add(back_piece);
                    frontlist.Add(front_piece);
                    break;
                }
            }
            if (!(frontlist.Count() == 0))
            {
                tree.front = new BSPTree();
                BuildBSPTree(ref tree.front, frontlist);
            }
            if (!(backlist.Count() == 0))
            {
                tree.back = new BSPTree();
                BuildBSPTree(ref tree.back, backlist);
            }
        }
Ejemplo n.º 2
0
        internal Result ClassifyPolygon(Polygon3 poly)
        {
            List <double> results = new List <double>();

            foreach (var point in poly.Points)
            {
                var x = (Normal.X * point.X + Normal.Y * point.Y + Normal.Z * point.Z + D);
                if (Math.Floor(x) == 0)
                {
                    results.Add(0);
                }
                else
                {
                    results.Add(x);
                }
            }

            if (results.Any(result => result <= 0))
            {
                if (results.Any(result => result >= 0))
                {
                    if (results.Any(result => result == 0))
                    {
                        if (results.Any(result => result != 0))
                        {
                            if (results.Any(result => result < 0))
                            {
                                if (results.Any(result => result > 0))
                                {
                                    return(Result.SPANNING); //0-+ 0+- +0- +-0 -0+ -+0
                                }
                                else
                                {
                                    return(Result.IN_BACK_OF); //0-- -00 --0 00- -0- 0-0
                                }
                            }
                            else
                            {
                                return(Result.IN_FRONT_OF); //0++ +00 ++0 00+ +0+ 0+0
                            }
                        }
                        else
                        {
                            return(Result.COINCIDENT); //000
                        }
                    }
                    else
                    {
                        return(Result.SPANNING); //++- +-- --+ +-+ -+- -++
                    }
                }
                else
                {
                    return(Result.IN_BACK_OF);//---
                }
            }
            else
            {
                return(Result.IN_FRONT_OF); //+++
            }
        }
Ejemplo n.º 3
0
        private void Split_Polygon(Polygon3 poly, Plane part, ref Polygon3 front, ref Polygon3 back)
        {
            int count = poly.NumVertices(),
                out_c = 0, in_c = 0;
            Vector4 ptA, ptB;
            double  sideA, sideB;

            Vector4[] outpts = new Vector4[MAXPTS],
            inpts = new Vector4[MAXPTS];
            List <Vector4> outptsl = new List <Vector4>(),
                           inptsl  = new List <Vector4>();

            ptA   = poly.Points.Last();
            sideA = part.ClassifyPoint(ptA);
            for (short i = -1; ++i < count;)
            {
                ptB   = poly.Points.ElementAt(i);
                sideB = part.ClassifyPoint(ptB);
                if (sideB > 0)
                {
                    if (sideA < 0)
                    {
                        // compute the intersection point of the line
                        // from point A to point B with the partition
                        // plane. This is a simple ray-plane intersection.
                        Vector4 v    = ptB - ptA;
                        float   sect = -part.ClassifyPoint(ptA) / Vector4.Distance(part.Normal, v);
                        outptsl.Add(ptA + (v * sect));
                        inptsl.Add(ptA + (v * sect));
                        in_c++;
                        out_c++;
                    }
                    //outpts[out_c++] = ptB;
                    outptsl.Add(ptB);
                    out_c++;
                }
                else if (sideB < 0)
                {
                    if (sideA > 0)
                    {
                        // compute the intersection point of the line
                        // from point A to point B with the partition
                        // plane. This is a simple ray-plane intersection.
                        Vector4 v    = ptB - ptA;
                        float   sect = -part.ClassifyPoint(ptA) / Vector4.Distance(part.Normal, v);
                        //outpts[out_c++] = inpts[in_c++] = ptA + (v * sect);
                        outptsl.Add(ptA + (v * sect));
                        inptsl.Add(ptA + (v * sect));
                        in_c++;
                        out_c++;
                    }
                    inptsl.Add(ptB);
                    in_c++;
                }
                else
                {
                    // outpts[out_c++] = inpts[in_c++] = v;
                    outptsl.Add(ptB);
                    inptsl.Add(ptB);
                    in_c++;
                    out_c++;
                }
                ptA   = ptB;
                sideA = sideB;
            }
            front        = new Polygon3();
            front.Points = outptsl.ToList();
            back         = new Polygon3();
            back.Points  = inptsl.ToList();
        }