/// <summary> /// Construct a FlatFace /// </summary> /// <param name="graphNode">The Node in the Graph that this Face should correspond to</param> /// <param name="parent">The parent of this FlatFace in the "tree" that forms the Net</param> /// <param name="points"></param> public FlatFace(GraphNode graphNode, FlatFace parent, Vector2[] points) { _graphNode = graphNode; _parent = parent; _points = points; _connectedTo = new FlatFace[points.Length]; }
/// <summary> /// Construct a 3D face from the corresponding 2D FlatFace in the Net /// As well as copying the corner points from the FlatFace we also get the dihedral angle from the cache that /// this Face should make along the hinge with its parent in a fully closed Polyhedron /// This face is then moved by hinge rotation. /// It is discarded and recreated from the 2D FlatFace before the next frame in the animation /// </summary> /// <param name="face"></param> public Face(FlatFace face) { _points = new Vector3[face.GraphNode.NumConnections]; for (int s = 0; s < _points.Length; s++) { _points[s].X = face.Points[s].X; _points[s].Z = face.Points[s].Y; } _flatFace = face; _connectedTo = new List <Face>(); if (face.Parent != null) { _dihedralAngle = face.GraphNode.Graph.DihedralCache.GetDihedralAngle(face.Parent.GraphNode.Id, face.GraphNode.Id); } foreach (FlatFace child in face.ConnectedTo) { if (child != null) { _connectedTo.Add(new Face(child)); } } }
/// <summary> /// Build a Net from the supplied Graph /// </summary> /// <param name="graph"></param> /// <returns></returns> public static Net Build(Graph graph) { GraphNode firstNode = graph.LookupNode("1"); List <GraphNode> toProcess = new List <GraphNode>(); Net rc = null; Vector2[] points = Geometry.GetPolyVectors(new Vector2(_sideLen, 0), new Vector2(0, 0), firstNode.NumConnections); FlatFace rootFace = new FlatFace(firstNode, null, points); if (rc == null) { rc = new Net(rootFace); } rc.AddFace(rootFace); rc.GraphNodeToFace[firstNode] = rootFace; toProcess.Add(firstNode); while (toProcess.Count > 0) { List <GraphNode> nextToProcess = new List <GraphNode>(); foreach (GraphNode node in toProcess) { FlatFace face = rc.GraphNodeToFace[node]; int s0 = 0; if (face.Parent != null) { foreach (GraphNode childNode in node.ConnectedTo) { FlatFace child = null; rc.GraphNodeToFace.TryGetValue(childNode, out child); if (childNode != null) { if (childNode == face.Parent.GraphNode) { break; } } s0++; } } for (int s = 0; s < node.NumConnections; s++) { int f = (s0 + s) % node.NumConnections; GraphNode childNode = node.ConnectedTo[f]; if (!rc.GraphNodeToFace.ContainsKey(childNode)) { points = Geometry.GetPolyVectors(face.Points[(s + 1) % face.NumSides], face.Points[s], childNode.NumConnections); FlatFace childFace = new FlatFace(childNode, face, points); rc.AddFace(childFace); rc.GraphNodeToFace[childNode] = childFace; face.ConnectedTo[s] = childFace; nextToProcess.Add(childNode); } } } toProcess = nextToProcess; } return(rc); }
/// <summary> /// Add a FlatFace to this Net /// </summary> /// <param name="face"></param> public void AddFace(FlatFace face) { _faces.Add(face); }
/// <summary> /// Construct a Net /// </summary> /// <param name="root">The FlatFace that is the root of the tee that forms the Net</param> public Net(FlatFace root) { _root = root; }