/// <summary>
        /// Constructs a table of the indices of the vertices around each face.
        /// </summary>
        public static int[][] Vertices(IPolyhedron surface)
        {
            var indices = new int[surface.Faces.Count][];

            foreach (var face in surface.Faces)
            {
                var vertexIndices = face.Vertices.Select(vertex => surface.IndexOf(vertex)).ToArray();
                indices[surface.IndexOf(face)] = vertexIndices;
            }

            return(indices);
        }
        /// <summary>
        /// Constructs a table of the normals to the sphere at the center of each face.
        /// </summary>
        public static Vector[] Normals(IPolyhedron surface)
        {
            var normals = new Vector[surface.Faces.Count];

            foreach (var face in surface.Faces)
            {
                normals[surface.IndexOf(face)] = face.SphericalCenter().Normalize();
            }

            return(normals);
        }
        /// <summary>
        /// Constructs a table of the faces around each vertex.
        ///
        /// The ith edge given by surface.EdgesOf is anticlockwise of the ith face.
        /// </summary>
        public static int[][] Faces(IPolyhedron surface)
        {
            var faceTable = new int[surface.Vertices.Count][];

            foreach (var vertex in surface.Vertices)
            {
                faceTable[surface.IndexOf(vertex)] = FacesAroundVertex(vertex, surface);
            }

            return(faceTable);
        }
        /// <summary>
        /// Constructs a table of the index of each face in surface.Faces(vertex) for each vertex around that face.
        /// </summary>
        public static int[][] FaceInFacesOfVertices(IPolyhedron surface)
        {
            var indices = new int[surface.Faces.Count][];

            foreach (var face in surface.Faces)
            {
                var indicesOfFace = face.Vertices.Select(vertex => IndexOfFaceInVertex(surface, face, vertex)).ToArray();
                indices[surface.IndexOf(face)] = indicesOfFace;
            }

            return(indices);
        }
        /// <summary>
        /// Constructs a table of the lengths of edges surrounding each face.
        /// Edges are listed in the same order as the opposing faces are given by surface.NeighboursOf.
        /// </summary>
        public static double[][] EdgeLengths(IPolyhedron surface)
        {
            var edgeLengths = new double[surface.Faces.Count][];

            foreach (var face in surface.Faces)
            {
                var lengths = surface.EdgesOf(face).Select(edge => edge.Length());
                edgeLengths[surface.IndexOf(face)] = lengths.ToArray();
            }

            return(edgeLengths);
        }
        /// <summary>
        /// Constructs a table of the neighbours of each face.
        /// Neighbours are listed in the same order as given by surface.NeighboursOf.
        /// </summary>
        public static int[][] Neighbours(IPolyhedron surface)
        {
            var neighbours = new int[surface.Faces.Count][];

            foreach (var face in surface.Faces)
            {
                var indicesOfNeighbours = surface.NeighboursOf(face).Select(neighbour => surface.IndexOf(neighbour));
                neighbours[surface.IndexOf(face)] = indicesOfNeighbours.ToArray();
            }

            return(neighbours);
        }
        public static Vector[] Normals(IPolyhedron surface)
        {
            var normals = new Vector[surface.Vertices.Count];

            foreach (var vertex in surface.Vertices)
            {
                var normal = vertex.Position.Normalize();
                normals[surface.IndexOf(vertex)] = normal;
            }

            return(normals);
        }
        /// <summary>
        /// Constructs a table of the spherical distances from each vertex to its neighbours.
        /// </summary>
        public static double[][] Distances(IPolyhedron surface)
        {
            var distanceTable = new double[surface.Vertices.Count][];

            foreach (var vertex in surface.Vertices)
            {
                var edges     = surface.EdgesOf(vertex);
                var distances = edges.Select(edge => edge.Length()).ToArray();
                distanceTable[surface.IndexOf(vertex)] = distances;
            }

            return(distanceTable);
        }
        /// <summary>
        /// Constructs a table of the directions towards the faces neighbours in the face's tangent space.
        /// </summary>
        public static Vector[][] Directions(IPolyhedron surface)
        {
            var directions = new Vector[surface.Faces.Count][];

            foreach (var face in surface.Faces)
            {
                var neighboursOfFace = surface.NeighboursOf(face);
                var localDirections  = neighboursOfFace.Select(neighbour => Direction(face, neighbour));
                directions[surface.IndexOf(face)] = localDirections.ToArray();
            }

            return(directions);
        }
        /// <summary>
        /// Constructs a table of the vectors perpendicular to a vertex and normal to each adjoining edge.
        ///
        /// Normals point anticlockwise around the vertex.
        /// </summary>
        public static Vector[][] EdgeNormals(IPolyhedron surface)
        {
            var edgeNormalsTable = new Vector[surface.Vertices.Count][];

            foreach (var vertex in surface.Vertices)
            {
                var vertexVector = vertex.Position;
                var edgeVectors  = surface.NeighboursOf(vertex).Select(neighbour => (neighbour.Position - vertexVector));
                var edgeNormals  = edgeVectors.Select(edgeVector => Vector.CrossProduct(vertexVector, edgeVector).Normalize()).ToArray();
                edgeNormalsTable[surface.IndexOf(vertex)] = edgeNormals;
            }

            return(edgeNormalsTable);
        }
        /// <summary>
        /// Constructs a table of the area of intersection between each face and the vertices around it.
        /// </summary>
        public static double[][] AreaInEachVertex(IPolyhedron surface)
        {
            var allAreas = new double[surface.Faces.Count][];

            foreach (var face in surface.Faces)
            {
                var vertices = face.Vertices;
                var areas    = vertices.Select(vertex => PolyhedronUtilities.AreaSharedByVertexAndFace(surface, vertex, face)).ToArray();

                allAreas[surface.IndexOf(face)] = areas;
            }

            return(allAreas);
        }
示例#12
0
        // Constructs the indices into the vertex array that correspond to the mesh triangles for a specific face.
        private static IEnumerable <int> Triangles(IPolyhedron surface, Face face)
        {
            var vertices = face.Vertices;

            // Get the index of the vector of the center of the face
            var center = surface.Vertices.Count + surface.IndexOf(face);

            // Loop round the edges of the Face and use each as the base of a triangle, with the third point being the
            // center of the face.
            var triangles = new List <int>();

            for (int i = 0; i < vertices.Count; i++)
            {
                var triangle = new[]
                {
                    center,
                    surface.IndexOf(vertices.AtCyclicIndex(i + 1)),
                    surface.IndexOf(vertices.AtCyclicIndex(i))
                };
                triangles.AddRange(triangle);
            }

            return(triangles);
        }
        private static int[] FacesAroundVertex(Vertex vertex, IPolyhedron surface)
        {
            var edges = surface.EdgesOf(vertex);

            var faces = new List <int>();

            for (int i = 0; i < edges.Count; i++)
            {
                var previousEdge = edges.AtCyclicIndex(i - 1);
                var thisEdge     = edges[i];
                var faceInCommon = surface.FacesOf(previousEdge).Intersect(surface.FacesOf(thisEdge)).First();
                var indexOfFace  = surface.IndexOf(faceInCommon);
                faces.Add(indexOfFace);
            }

            return(faces.ToArray());
        }
        /// <summary>
        /// Constructs a table of the distances from each face's center to it's neighbour's centers.
        /// Neighbours are listed in the same order as given by surface.NeighboursOf.
        /// </summary>
        public static double[][] Distances(IPolyhedron surface)
        {
            var edgeLengths = new double[surface.Faces.Count][];

            foreach (var face in surface.Faces)
            {
                var distances =
                    surface.
                    NeighboursOf(face).
                    Select(neighbour => VectorUtilities.GeodesicDistance(face.SphericalCenter(), neighbour.SphericalCenter()));
                edgeLengths[surface.IndexOf(face)] = distances.ToArray();
            }

            //TODO: Work out how to turn this into spherical area.

            return(edgeLengths);
        }
        /// <summary>
        /// Constructs a table of the distances from each vertex to the bisectors running across each neighbouring edge.
        /// </summary>
        public static double[][] HalfEdgeLengths(IPolyhedron surface)
        {
            var halfLengthsTable = new double[surface.Vertices.Count][];

            foreach (var vertex in surface.Vertices)
            {
                var edges   = surface.EdgesOf(vertex);
                var lengths = new List <double>();
                foreach (var edge in edges)
                {
                    var neighbour      = edge.Vertices().First(v => v != vertex);
                    var bisectionPoint = PolyhedronUtilities.BisectionPoint(surface, edge);
                    var length         = (neighbour.Position - bisectionPoint).Norm();
                    //TODO: This is planar distance, not geodesic.
                    lengths.Add(length);
                }
                halfLengthsTable[surface.IndexOf(vertex)] = lengths.ToArray();
            }

            return(halfLengthsTable);
        }
        public void EdgeNormals_OnTheAllPositiveVertexOfACube_ShouldCalculateTheCorrectNormals
            (IPolyhedron polyhedron)
        {
            // Fixture setup
            var expected = new List <Vector>
            {
                VectorUtilities.NewVector(0, -1, 1).Normalize(),
                VectorUtilities.NewVector(1, 0, -1).Normalize(),
                VectorUtilities.NewVector(-1, 1, 0).Normalize(),
            };

            // Exercise system
            var normals = VertexIndexedTableFactory.EdgeNormals(polyhedron);

            // Verify outcome
            var vertex = polyhedron.Vertices.First(v => Vector.AlmostEqual(v.Position, VectorUtilities.NewVector(1, 1, 1)));
            var actual = normals[polyhedron.IndexOf(vertex)];

            TestUtilities.WriteExpectedAndActual(expected, actual);
            Assert.True(TestUtilities.UnorderedEquals(expected, actual, TestUtilities.RelativeAccuracy));

            // Teardown
        }
示例#17
0
        public static ScalarField <Face> XDependentScalarField(IPolyhedron polyhedron, double average, double deviation)
        {
            var normals = FaceIndexedTableFactory.Normals(polyhedron);
            var values  = polyhedron.Faces.Select(face => average + deviation * normals[polyhedron.IndexOf(face)][0]).ToArray();

            return(new ScalarField <Face>(polyhedron.IndexOf, values));
        }