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