Пример #1
0
        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++;
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
    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++);
    }
Пример #4
0
            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;
                }
            }
Пример #5
0
            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;
                }
            }
Пример #6
0
            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);
            }