예제 #1
0
        ///<summary>
        /// Computes the center, volume, and surface triangles of a convex hull defined by a point set.
        ///</summary>
        ///<param name="vertices">Point set defining the convex hull.</param>
        ///<param name="volume">Volume of the convex hull.</param>
        ///<param name="outputSurfaceTriangles">Indices of surface triangles of the convex hull.</param>
        ///<param name="outputLocalSurfaceVertices">Local positions of vertices on the convex hull.</param>
        ///<returns>Center of the convex hull.</returns>
        public static Vector3 ComputeCenter(IList <Vector3> vertices, out float volume, IList <int> outputSurfaceTriangles, IList <Vector3> outputLocalSurfaceVertices)
        {
            Vector3 centroid = Toolbox.ZeroVector;

            for (int k = 0; k < vertices.Count; k++)
            {
                centroid += vertices[k];
            }
            centroid /= vertices.Count;

            //Toolbox.GetConvexHull(vertices, outputSurfaceTriangles, outputLocalSurfaceVertices);
            ConvexHullHelper.GetConvexHull(vertices, outputSurfaceTriangles, outputLocalSurfaceVertices);

            volume = 0;
            var volumes   = CommonResources.GetFloatList();
            var centroids = CommonResources.GetVectorList();

            for (int k = 0; k < outputSurfaceTriangles.Count; k += 3)
            {
                volumes.Add(Vector3.Dot(
                                Vector3.Cross(vertices[outputSurfaceTriangles[k + 1]] - vertices[outputSurfaceTriangles[k]],
                                              vertices[outputSurfaceTriangles[k + 2]] - vertices[outputSurfaceTriangles[k]]),
                                centroid - vertices[outputSurfaceTriangles[k]]));
                volume += volumes[k / 3];
                centroids.Add((vertices[outputSurfaceTriangles[k]] + vertices[outputSurfaceTriangles[k + 1]] + vertices[outputSurfaceTriangles[k + 2]] + centroid) / 4);
            }
            Vector3 center = Toolbox.ZeroVector;

            for (int k = 0; k < centroids.Count; k++)
            {
                center += centroids[k] * (volumes[k] / volume);
            }
            volume /= 6;
            for (int k = 0; k < outputLocalSurfaceVertices.Count; k++)
            {
                outputLocalSurfaceVertices[k] -= center;
            }
            CommonResources.GiveBack(centroids);
            CommonResources.GiveBack(volumes);
            return(center);
        }