private static void Relax(Surface surface) { System.Random rand = new System.Random(); Graph g = new Graph(); foreach (SurfaceVertex v in surface.Vertices) { Vector3D v3d = new Vector3D(v.Vertex.X, v.Vertex.Y, v.Vertex.Z); //Vector3D v3d = new Vector3D( rand.NextDouble(), rand.NextDouble(), rand.NextDouble() ); //v3d.Normalize(); g.Nodes.Add(new GraphNode(new VectorND(new double[] { v3d.X, v3d.Y, v3d.Z }), new VectorND(dimension: 3))); } foreach (SurfaceEdge e in surface.Edges) { g.AddEdge(new Edge(e.V1 - 1, e.V2 - 1)); // more 0-indexed vs. 1-indexed stuff } GraphRelaxation relaxer = new GraphRelaxation(); relaxer.Graph = g; relaxer.EdgeAttraction = 0.1; relaxer.NodeRepulsion = 0; relaxer.Relax(50); int index = 0; foreach (GraphNode node in relaxer.Graph.Nodes) { SurfaceVertex sv = surface.Vertices[index]; sv.Vertex = new Vector3D(node.Position.X[0], node.Position.X[1], node.Position.X[2]); surface.Vertices[index] = sv; index++; } }
public static Vector3[] CalculateSurfaceVertices(Vector3 center, int height, float[] outer_heights) { if (outer_heights == null) { throw new System.ArgumentNullException("outer_heights"); } if (outer_heights.Length != 6) { throw new System.ArgumentException("Float array length must be 6.", "outer_heights"); } Vector3[] vertices = (Vector3[])SurfaceVertex.Clone(); //add center and apply heights to outer vertices for (int d = 0; d < 6; d++) { vertices[7 + d] = center + vertices[7 + d]; vertices[7 + d].y = height + outer_heights[d]; } //add center and apply heights to inner vertices float[] inner_heights = InnerVertexHeights(outer_heights); for (int d = 0; d < 6; d++) { vertices[1 + d] = center + vertices[1 + d]; vertices[1 + d].y = height + inner_heights[d]; } //add center and apply height to center vertex float center_height = CenterVertexHeight(inner_heights); vertices[0] = center + vertices[0]; vertices[0].y = height + center_height; return(vertices); }
private int AddVertex(Vector3 p, ref int vertexCount) { float length = Mathf.Sqrt(p.x * p.x + p.y * p.y + p.z * p.z); SurfaceVertex vertex = new SurfaceVertex(); vertex.position = new Vector3(p.x / length, p.y / length, p.z / length); vertices[vertexCount] = vertex; return(vertexCount++); }
public void Fill(Puzzle puzzle) { Vertices.Clear(); Edges.Clear(); Faces.Clear(); int baseV = 1; int baseE = 1; int baseF = 1; foreach (Cell cell in puzzle.IRPCells) { Vector3D[] verts = cell.TextureVertices; for (int i = 0; i < verts.Length; i++) { SurfaceVertex sv = new SurfaceVertex(verts[i]); sv.Index = baseV + i; Vertices.Add(sv); } const int lod = 3; int[] facets = TextureHelper.TextureElements(cell.Boundary.NumSides, lod); for (int i = 0; i < facets.Length; i += 3) { SurfaceEdge e1 = new SurfaceEdge(baseV + facets[i], baseV + facets[i + 1]); SurfaceEdge e2 = new SurfaceEdge(baseV + facets[i + 1], baseV + facets[i + 2]); SurfaceEdge e3 = new SurfaceEdge(baseV + facets[i + 2], baseV + facets[i]); e1.Index = baseE + i; e2.Index = baseE + i + 1; e3.Index = baseE + i + 2; Edges.Add(e1); Edges.Add(e2); Edges.Add(e3); SurfaceFace face = new SurfaceFace(e1.Index, e2.Index, e3.Index); face.Index = baseF + i / 3; face.Reverse = puzzle.MasterCells[cell.IndexOfMaster].Reflected; // Reflected doesn't seem to be set on the IRP cell. Faces.Add(face); } baseV += verts.Length; baseE += facets.Length; baseF += facets.Length / 3; } }
public void NormalizeVerts() { Vector3D centroid = new Vector3D(); double max = 0; foreach (SurfaceVertex v in Vertices) { centroid += v.Vertex / Vertices.Count; if (v.Vertex.Abs() > max) { max = v.Vertex.Abs(); } } for (int i = 0; i < Vertices.Count; i++) { SurfaceVertex v = Vertices[i]; v.Vertex = (v.Vertex - centroid) / max; // center and scale Vertices[i] = v; } }
public Surface RemoveDups(Puzzle puzzle) { // ZZZ - Clean up all the +1,-1s in this method. They are here because SurfaceEvolver is 1-indexed, but it is ugly! Surface newSurface = new Surface(); m_vertexMap.Clear(); Dictionary <SurfaceVertex, int> vMap = new Dictionary <SurfaceVertex, int>(new SurfaceVertexEqualityComparer(puzzle.IRPTranslations.ToArray())); Dictionary <SurfaceEdge, int> eMap = new Dictionary <SurfaceEdge, int>(new SurfaceEdgeEqualityComparer()); // Remove dups by adding to a map. foreach (SurfaceVertex v in Vertices) { int index; if (!vMap.TryGetValue(v, out index)) { index = newSurface.Vertices.Count + 1; SurfaceVertex newV = v; newV.Index = index; newSurface.Vertices.Add(newV); vMap[v] = index; } m_vertexMap[v.Index] = index; } // First map to new verts. List <SurfaceEdge> newEdges = new List <SurfaceEdge>(); foreach (SurfaceEdge e in Edges) { SurfaceEdge newEdge = new SurfaceEdge(vMap[Vertices[e.V1 - 1]], vMap[Vertices[e.V2 - 1]]); newEdge.Index = newEdges.Count + 1; newEdges.Add(newEdge); } // Remove dups by adding to a map. foreach (SurfaceEdge e in newEdges) { int index; if (!eMap.TryGetValue(e, out index)) { index = newSurface.Edges.Count + 1; SurfaceEdge newE = e; newE.Index = index; newSurface.Edges.Add(newE); eMap[e] = index; } } // Map to new edges. // We don't need to worry about duplicate faces showing up. foreach (SurfaceFace f in Faces) { int e1 = eMap[newEdges[f.E1 - 1]]; int e2 = eMap[newEdges[f.E2 - 1]]; int e3 = eMap[newEdges[f.E3 - 1]]; if (SurfaceEdge.Reversed(newSurface.Edges[e1 - 1], newEdges[f.E1 - 1])) { e1 *= -1; } if (SurfaceEdge.Reversed(newSurface.Edges[e2 - 1], newEdges[f.E2 - 1])) { e2 *= -1; } if (SurfaceEdge.Reversed(newSurface.Edges[e3 - 1], newEdges[f.E3 - 1])) { e3 *= -1; } SurfaceFace newFace = new SurfaceFace(e1, e2, e3); newFace.Index = newSurface.Faces.Count + 1; newFace.Reverse = f.Reverse; newSurface.Faces.Add(newFace); } newSurface.m_vertexMap = m_vertexMap; return(newSurface); }