/// <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);
        }
Exemple #2
0
        /// <summary>
        /// Calculates the center of a polygonal face then projects it onto the sphere the face is embedded in.
        ///
        /// Degenerate for faces whose centroid is the origin.
        /// </summary>
        public static Vector SphericalCenter(this Face face)
        {
            var vectors = face.Vertices.Select(v => v.Position).ToArray();

            var center = face.Center();
            var radius = vectors.Average(vector => vector.Norm());

            return(radius * center.Normalize());
        }