/// <summary> /// Calculates the size of the area that's both in the specified face and closer to the specified vertex than any other vertex. /// </summary> public static double AreaSharedByVertexAndFace(IPolyhedron surface, Vertex vertex, Face face) { var vertexPosition = vertex.Position; var faces = surface.FacesOf(vertex); var edges = surface.EdgesOf(vertex); var index = faces.IndexOf(face); if (!faces.Contains(face)) { return(0.0); } var midpointOfFace = face.Center(); var previousEdge = edges.AtCyclicIndex(index - 1); var midpointOfPreviousEdge = BisectionPoint(surface, previousEdge); var nextEdge = edges.AtCyclicIndex(index); var midpointOfNextEdge = BisectionPoint(surface, nextEdge); var crossProductOfFirstSegment = Vector.CrossProduct(midpointOfPreviousEdge - vertexPosition, midpointOfFace - vertexPosition); var areaOfFirstSegment = Vector.ScalarProduct(crossProductOfFirstSegment, midpointOfFace.Normalize()) / 2; var crossProductOfSecondSegment = Vector.CrossProduct(midpointOfFace - vertexPosition, midpointOfNextEdge - vertexPosition); var areaOfSecondSegment = Vector.ScalarProduct(crossProductOfSecondSegment, midpointOfFace.Normalize()) / 2; return(areaOfFirstSegment + areaOfSecondSegment); }
private static int IndexOfFaceInVertex(IPolyhedron surface, Face face, Vertex vertex) { var facesAroundVertex = surface.FacesOf(vertex); var indexOfFace = facesAroundVertex.IndexOf(face); return(indexOfFace); }
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> /// Returns the neighbours of a face in the same order that the edges they have in common appear. /// </summary> public static IEnumerable <Face> NeighboursOf(this IPolyhedron polyhedron, Face face) { var faceSingleton = new[] { face }; var edges = polyhedron.EdgesOf(face); var neighbours = edges.SelectMany(edge => polyhedron.FacesOf(edge).Except(faceSingleton)); return(neighbours); }
public void FacesOf_OnEachVertex_IsInCorrectOrderWithRespectToEdgesOf (IPolyhedron polyhedron) { // Fixture setup // Exercise system // Verify outcome foreach (var vertex in polyhedron.Vertices) { var edges = polyhedron.EdgesOf(vertex); var expected = edges.SelectMany((edge, i) => polyhedron.FacesOf(edge).Intersect(polyhedron.FacesOf(edges.AtCyclicIndex(i - 1)))).ToList(); var actual = polyhedron.FacesOf(vertex); TestUtilities.WriteExpectedAndActual(expected, actual); Assert.True(Enumerable.SequenceEqual(expected, actual)); } // Teardown }
/// <summary> /// Calculates the point at which the specified edge is closest to the line between its neighbouring faces' centers. /// </summary> public static Vector BisectionPoint(IPolyhedron polyhedron, Edge edge) { var aFace = polyhedron.FacesOf(edge).First(); var origin = edge.A.Position; var edgeVector = edge.B.Position - origin; var vectorToFace = aFace.SphericalCenter() - origin; var vectorToBisector = Vector.ScalarProduct(vectorToFace, edgeVector.Normalize()) * edgeVector.Normalize(); return(vectorToBisector + origin); }
/// <summary> /// Constructs a table of the area of intersection between each vertex and the faces around it. /// </summary> public static double[][] AreaInEachFace(IPolyhedron surface) { var allAreas = new double[surface.Vertices.Count][]; foreach (var vertex in surface.Vertices) { var faces = surface.FacesOf(vertex); var areas = faces.Select(face => PolyhedronUtilities.AreaSharedByVertexAndFace(surface, vertex, face)).ToArray(); allAreas[surface.IndexOf(vertex)] = areas; } return(allAreas); }
public void FaceInVertices_ShouldBeCorrectIndices (IPolyhedron polyhedron) { // Fixture setup // Exercise system var vertexIndices = FaceIndexedTableFactory.FaceInFacesOfVertices(polyhedron); // Verify outcome for (int i = 0; i < polyhedron.Faces.Count; i++) { var face = polyhedron.Faces[i]; var expected = Enumerable.Repeat(face, face.Vertices.Count).ToList(); var indices = vertexIndices[i]; var vertices = face.Vertices; var actual = vertices.Select((v, j) => polyhedron.FacesOf(v)[indices[j]]).ToList(); TestUtilities.WriteExpectedAndActual(expected, actual); Assert.True(Enumerable.SequenceEqual(expected, actual)); } // Teardown }