Beispiel #1
0
        public static Shape Rectangle(Vector3D size)
        {
            Shape    s        = new Shape();
            Mesh     m        = s.CreateConvex();
            Face     f        = m.CreateFace(4);
            Vector3D halfsize = size * 0.5;

            f.Vertices[0].Pos = new Point3D(-halfsize.X, -halfsize.Y, 0);
            f.Vertices[1].Pos = new Point3D(-halfsize.X, halfsize.Y, 0);
            f.Vertices[2].Pos = new Point3D(halfsize.X, halfsize.Y, 0);
            f.Vertices[3].Pos = new Point3D(halfsize.X, -halfsize.Y, 0);

            return(s);
        }
Beispiel #2
0
        public Face Split(Edge edge0, Edge edge1)
        {
            //get indices
            int idx0 = Edges.IndexOf(edge0);
            int idx1 = Edges.IndexOf(edge1);

            //verify indices
            if (idx0 == idx1)
            {
                throw new System.ApplicationException("Can not split face between 2 vertices");
            }
            if (((idx0 + 1) % Edges.Count) == idx1)
            {
                throw new System.ApplicationException("Edge 1 is next edge after edge 0 - edges must be at least 1 vertex apart");
            }
            if (((idx1 + 1) % Edges.Count) == idx0)
            {
                throw new System.ApplicationException("Edge 0 is next edge after edge 1 - edges must be at least 1 vertex apart");
            }

            //we have a list of edges in the face, and are transferring those between edge0 and edge1 to new face
            //so if keeping 'a' on this face, and transfer 'b' to new face
            //will be in one of these 2 orders, depending on which comes first - edge0 or edge1
            //b-b-b-e1-a-a-a-e0-b-b-b
            //a-a-a-e0-b-b-b-e1-a-a-a

            //so, check indices to work out if edge0 comes first or edge1 comes first
            List <Edge> my_edges, other_edges;

            if (idx0 < idx1)
            {
                //edge0 is first, so have:
                //a-a-a-e0-b-b-b-e1-a-a-a
                //after splitting it should be:
                //a-a-a-e0(b)-b-b-b-e1(a)-a-a-a
                my_edges    = Edges.Skip(idx0).Take(idx1 - idx0).ToList();
                other_edges = Edges.Skip(idx1).Concat(Edges.Take(idx0)).ToList();
            }
            else
            {
                //edge1 is first, so have:
                //b-b-b-e1-a-a-a-e0-b-b-b
                //after splitting it should be:
                //b-b-b-e1(a)-a-a-a-e0(b)-b-b-b
                other_edges = Edges.Skip(idx1).Take(idx0 - idx1).ToList();
                my_edges    = Edges.Skip(idx0).Concat(Edges.Take(idx1)).ToList();
            }

            //store new list of edges (effectively linking face->edge for all edges we keep)
            Edges = my_edges;

            //creatre new face
            Face new_face = OwnerMesh.CreateFace();

            //transfer all other edges from this face to new face
            foreach (Edge e in other_edges)
            {
                e.OwnerFaces.Remove(this);          //unlink edge->face (face->edge was automatically unlinked when changed edge list)
                new_face.AddEdge(e);                //add edge to new face (adds it to list, linking edge->face and face->edge)
                RemoveVertex(e.Vertices[0]);        //unlink vertex0<->face
                new_face.AddVertex(e.Vertices[0]);  //link vertex0<->newface
            }

            //add last vertex in other face tot the other face
            new_face.AddVertex(other_edges.Last().Vertices[1]);

            //re-add just the first vert in the other face, which will have been incorrectly removed from this one
            AddVertex(other_edges.First().Vertices[0]);

            //edge transfer should have left a gap in the edge list for current and new face, so create new edges to fill gap
            CreateJoiningEdge();                    //create edge from end to start (sets up face->edge and edge->face)
            new_face.CreateJoiningEdge();           //other create edge from end to start (sets up face->edge and edge->face)

            return(new_face);
        }
Beispiel #3
0
        public Shape Copy()
        {
            //create a new shape and copy the vertices
            Shape shape = new Shape();

            foreach (Vertex v in Vertices)
            {
                Vertex copy = shape.CreateVertex();
                copy.Pos = v.Pos;
            }

            //put new vertices in a quick look up table
            Vertex[] newverts = shape.Vertices.ToArray();

            //go over each convex
            foreach (Mesh c in Convexes)
            {
                //create a new convex in the new shape
                Mesh convexcopy = shape.CreateConvex();

                //copy edges
                foreach (Edge e in c.Edges)
                {
                    //create the edge and use look up table to build new vertex list
                    Edge edgecopy = convexcopy.CreateEdge();
                    edgecopy.Vertices = e.Vertices.Select(a => newverts[a.Idx]).ToArray();

                    //add this edge to each of the vertices it uses
                    foreach (Vertex v in edgecopy.Vertices)
                    {
                        v.OwnerEdges.Add(edgecopy);
                    }
                }

                //build look up table for the edges
                Edge[] newedges = convexcopy.Edges.ToArray();

                //copy faces
                foreach (Face f in c.Faces)
                {
                    //create the face and use look up tables to build new vertex/edge list
                    Face facecopy = convexcopy.CreateFace();
                    facecopy.Vertices = f.Vertices.Select(a => newverts[a.Idx]).ToList();
                    facecopy.Edges    = f.Edges.Select(a => newedges[a.Idx]).ToList();

                    //add this face to each of the vertices it uses
                    foreach (Vertex v in facecopy.Vertices)
                    {
                        v.OwnerFaces.Add(facecopy);
                    }

                    //add this face to each of the edges it uses
                    foreach (Edge e in facecopy.Edges)
                    {
                        e.OwnerFaces.Add(facecopy);
                    }
                }
            }

            return(shape);
        }