Exemplo n.º 1
0
        /// <summary>
        /// Splits a <see cref="Polygon"/> by this plane if needed. After that it puts the
        /// polygons or the polygon fragments in the appropriate lists
        /// (<c>front</c>, <c>back</c>). Coplanar polygons go into either
        /// <c>coplanarFront</c>, <c>coplanarBack</c> depending on their
        /// orientation with respect to this plane. Polygons in front or back of this
        /// plane go into either <c>front</c> or <c>back</c>.
        /// </summary>
        /// <param name="polygon">polygon to split</param>
        /// <param name="coplanarFront">"coplanar front" polygons</param>
        /// <param name="coplanarBack">"coplanar back" polygons</param>
        /// <param name="front">front polygons</param>
        /// <param name="back">back polgons</param>
        ///
        public void splitPolygon(
            Polygon polygon,
            List <Polygon> coplanarFront,
            List <Polygon> coplanarBack,
            List <Polygon> front,
            List <Polygon> back)
        {
            const int COPLANAR = 0;
            const int FRONT    = 1;
            const int BACK     = 2;
            const int SPANNING = 3; // == some in the FRONT + some in the BACK

            // Classify each point as well as the entire polygon into one of the
            // above four classes.
            int        polygonType = 0;
            List <int> types       = new List <int>(polygon.vertices.Count);

            for (int i = 0; i < polygon.vertices.Count; i++)
            {
                double t    = this.normal.dot(polygon.vertices[i].pos) - this.dist;
                int    type = (t < -Plane.EPSILON) ? BACK : (t > Plane.EPSILON) ? FRONT : COPLANAR;
                polygonType |= type;
                types.Add(type);
            }

            //System.out.println("> switching");
            // Put the polygon in the correct list, splitting it when necessary.
            switch (polygonType)
            {
            case COPLANAR:
                //System.out.println(" -> coplanar");
                (this.normal.dot(polygon._csg_plane.normal) > 0 ? coplanarFront : coplanarBack).Add(polygon);
                break;

            case FRONT:
                //System.out.println(" -> front");
                front.Add(polygon);
                break;

            case BACK:
                //System.out.println(" -> back");
                back.Add(polygon);
                break;

            case SPANNING:
                //System.out.println(" -> spanning");
                List <Vertex> f = new List <Vertex>();
                List <Vertex> b = new List <Vertex>();
                for (int i = 0; i < polygon.vertices.Count; i++)
                {
                    int    j  = (i + 1) % polygon.vertices.Count;
                    int    ti = types[i];
                    int    tj = types[j];
                    Vertex vi = polygon.vertices[i];
                    Vertex vj = polygon.vertices[j];
                    if (ti != BACK)
                    {
                        f.Add(vi);
                    }
                    if (ti != FRONT)
                    {
                        b.Add(ti != BACK ? vi.clone() : vi);
                    }
                    if ((ti | tj) == SPANNING)
                    {
                        double t = (this.dist - this.normal.dot(vi.pos))
                                   / this.normal.dot(vj.pos.minus(vi.pos));
                        Vertex v = vi.interpolate(vj, t);
                        f.Add(v);
                        b.Add(v.clone());
                    }
                }
                if (f.Count >= 3)
                {
                    front.Add(new Polygon(f, polygon.getStorage()));
                }
                if (b.Count >= 3)
                {
                    back.Add(new Polygon(b, polygon.getStorage()));
                }
                break;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Decomposes the specified concave polygon into convex polygons.
        /// </summary>
        /// <param name="points">the points that define the polygon</param>
        /// <returns>the decomposed concave polygon (list of convex polygons)</returns>
        ///
        public static List <Polygon> fromConcavePoints(params IVector3d[] points)
        {
            Polygon p = fromPoints(points);

            return(PolygonUtil.concaveToConvex(p));
        }