public void Smooth(IMesh mesh, int limit)
        {
            var smoothedMesh = (Mesh)mesh;

            var mesher     = new GenericMesher(config);
            var predicates = config.Predicates();

            // The smoother should respect the mesh segment splitting behavior.
            this.options.SegmentSplitting = smoothedMesh.behavior.NoBisect;

            // Take a few smoothing rounds (Lloyd's algorithm).
            for (int i = 0; i < limit; i++)
            {
                Step(smoothedMesh, factory, predicates);

                // Actually, we only want to rebuild, if the mesh is no longer
                // Delaunay. Flipping edges could be the right choice instead
                // of re-triangulating...
                smoothedMesh = (Mesh)mesher.Triangulate(Rebuild(smoothedMesh), options);

                factory.Reset();
            }

            smoothedMesh.CopyTo((Mesh)mesh);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Smooth mesh with a maximum given number of rounds of Voronoi
        /// iteration.
        /// </summary>
        /// <param name="mesh">The mesh.</param>
        /// <param name="limit">The maximum number of iterations. If
        /// non-positive, no iteration is applied at all.</param>
        /// <param name="tol">The desired tolerance on the result. At each
        /// iteration, the maximum movement by any side is considered, both for
        /// the previous and the current solutions. If their relative difference
        /// is not greater than the tolerance, the current solution is
        /// considered good enough already.</param>
        /// <returns>The number of actual iterations performed. It is 0 if a
        /// non-positive limit is passed. Otherwise, it is always a value
        /// between 1 and the limit (inclusive).
        /// </returns>
        public int Smooth(IMesh mesh, int limit = 10, double tol = .01)
        {
            if (limit <= 0)
            {
                return(0);
            }

            var smoothedMesh = (Mesh)mesh;

            var mesher     = new GenericMesher(config);
            var predicates = config.Predicates();

            // The smoother should respect the mesh segment splitting behavior.
            this.options.SegmentSplitting = smoothedMesh.behavior.NoBisect;

            // The maximum distances moved from any site at the previous and
            // current iterations.
            double
                prevMax = Double.PositiveInfinity,
                currMax = Step(smoothedMesh, factory, predicates);
            // Take a few smoothing rounds (Lloyd's algorithm). The stop
            // criteria are the maximum number of iterations and the convergence
            // criterion.
            int i = 1;

            while (i < limit && Math.Abs(currMax - prevMax) > tol * currMax)
            {
                prevMax = currMax;
                currMax = Step(smoothedMesh, factory, predicates);

                // Actually, we only want to rebuild, if the mesh is no longer
                // Delaunay. Flipping edges could be the right choice instead
                // of re-triangulating...
                smoothedMesh = (Mesh)mesher.Triangulate(Rebuild(smoothedMesh), options);

                factory.Reset();

                i++;
            }

            smoothedMesh.CopyTo((Mesh)mesh);

            return(i);
        }