public float RidgedMultifractal(float[] f, float fOctaves, float fOffset, float fGain)
        {
            // Initialize locals
            float fSignal = fOffset - Math.Abs(GetNoise(f));

            fSignal *= fSignal;
            float fValue = fSignal;

            float[] fTemp = new float[MaxDimensions];
            for (int i = 0; i < m_nDimensions; i++)
            {
                fTemp[i] = f[i];
            }

            // Inner loop of spectral construction, where the fractal is built
            for (int i = 1; i < fOctaves; i++)
            {
                for (int j = 0; j < m_nDimensions; j++)
                {
                    fTemp[j] *= m_fLacunarity;
                }
                float fWeight = NoiseHelper.Clamp(0, 1, fSignal * fGain);
                fSignal  = fOffset - Math.Abs(GetNoise(fTemp));
                fSignal *= fSignal;
                fSignal *= fWeight;
                fValue  += fSignal * m_fExponent[i];
            }

            return(NoiseHelper.Clamp(-0.99999f, 0.99999f, fValue));
        }
        public float HybridMultifractal(float[] f, float fOctaves, float fOffset, float fGain)
        {
            // Initialize locals
            float fValue  = (GetNoise(f) + fOffset) * m_fExponent[0];
            float fWeight = fValue;

            float[] fTemp = new float[MaxDimensions];
            for (int i = 0; i < m_nDimensions; i++)
            {
                fTemp[i] = f[i] * m_fLacunarity;
            }

            // Inner loop of spectral construction, where the fractal is built
            for (int i = 1; i < fOctaves; i++)
            {
                if (fWeight > 1)
                {
                    fWeight = 1;
                }
                float fSignal = (GetNoise(fTemp) + fOffset) * m_fExponent[i];
                fValue  += fWeight * fSignal;
                fWeight *= fGain * fSignal;
                for (int j = 0; j < m_nDimensions; j++)
                {
                    fTemp[j] *= m_fLacunarity;
                }
            }

            return(NoiseHelper.Clamp(-0.99999f, 0.99999f, fValue));
        }
        public float fBmTest(float[] f, float fOctaves)
        {
            // Initialize locals
            float fValue = 0;

            float[] fTemp = new float[MaxDimensions];
            for (int i = 0; i < m_nDimensions; i++)
            {
                fTemp[i] = f[i] * 2;
            }

            //fOctaves *= Math.Abs(GetNoise(fTemp)) + 1.0f;
            //fOctaves = NoiseHelper.Clamp(2, 16, fOctaves);

            // Inner loop of spectral construction, where the fractal is built
            for (int i = 0; i < fOctaves; i++)
            {
                fValue += GetNoise(fTemp) * m_fExponent[i];
                for (int j = 0; j < m_nDimensions; j++)
                {
                    fTemp[j] *= m_fLacunarity;
                }
            }

            if (fValue <= 0.0f)
            {
                fValue = (float)-Math.Pow(-fValue, 0.7f);
            }
            else
            {
                fValue = (float)Math.Pow(fValue, 1 + GetNoise(fTemp) * fValue);
            }

            return(NoiseHelper.Clamp(-0.99999f, 0.99999f, fValue));
        }
        public float Heterofractal(float[] f, float fOctaves, float fOffset)
        {
            // Initialize locals
            float fValue = GetNoise(f) + fOffset;

            float[] fTemp = new float[MaxDimensions];
            for (int i = 0; i < m_nDimensions; i++)
            {
                fTemp[i] = f[i] * m_fLacunarity;
            }

            // Inner loop of spectral construction, where the fractal is built
            for (int i = 1; i < fOctaves; i++)
            {
                fValue += (GetNoise(fTemp) + fOffset) * m_fExponent[i] * fValue;
                for (int j = 0; j < m_nDimensions; j++)
                {
                    fTemp[j] *= m_fLacunarity;
                }
            }

            return(NoiseHelper.Clamp(-0.99999f, 0.99999f, fValue));
        }
        public float Turbulence(float[] f, float fOctaves)
        {
            // Initialize locals
            float fValue = 0;

            float[] fTemp = new float[MaxDimensions];
            for (int i = 0; i < m_nDimensions; i++)
            {
                fTemp[i] = f[i];
            }

            // Inner loop of spectral construction, where the fractal is built
            for (int i = 0; i < fOctaves; i++)
            {
                fValue += Math.Abs(GetNoise(fTemp)) * m_fExponent[i];
                for (int j = 0; j < m_nDimensions; j++)
                {
                    fTemp[j] *= m_fLacunarity;
                }
            }

            return(NoiseHelper.Clamp(-0.99999f, 0.99999f, fValue));
        }
        /// <summary>
        ///   Get the noise function at a given position specified by f
        /// </summary>
        /// <param name="f">A position in space (dimension 1-4)</param>
        /// <returns>Amplitude of noise from this pass at the given location.</returns>
        public float GetNoise(float[] f)
        {
            int[]   n = new int[MaxDimensions];                 // Indexes to pass to lattice function
            float[] r = new float[MaxDimensions];               // Remainders to pass to lattice function
            float[] w = new float[MaxDimensions];               // Cubic values to pass to interpolation function

            for (int i = 0; i < m_nDimensions; i++)
            {
                n[i] = (int)Math.Floor(f[i]);
                r[i] = f[i] - n[i];
                w[i] = NoiseHelper.Cubic(r[i]);
            }

            float fValue;

            switch (m_nDimensions)
            {
            case 1:
                fValue = Lerp(Lattice(n[0], r[0]),
                              Lattice(n[0] + 1, r[0] - 1),
                              w[0]);
                break;

            case 2:
                fValue = Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1]),
                                   Lattice(n[0] + 1, r[0] - 1, n[1], r[1]),
                                   w[0]),
                              Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1),
                                   Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1),
                                   w[0]),
                              w[1]);
                break;

            case 3:
                fValue = Lerp(Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1], n[2], r[2]),
                                        Lattice(n[0] + 1, r[0] - 1, n[1], r[1], n[2], r[2]),
                                        w[0]),
                                   Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1, n[2], r[2]),
                                        Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1, n[2], r[2]),
                                        w[0]),
                                   w[1]),
                              Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1], n[2] + 1, r[2] - 1),
                                        Lattice(n[0] + 1, r[0] - 1, n[1], r[1], n[2] + 1, r[2] - 1),
                                        w[0]),
                                   Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1, n[2] + 1, r[2] - 1),
                                        Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1, n[2] + 1, r[2] - 1),
                                        w[0]),
                                   w[1]),
                              w[2]);
                break;

            case 4:
                fValue = Lerp(Lerp(Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1], n[2], r[2], n[3], r[3]),
                                             Lattice(n[0] + 1, r[0] - 1, n[1], r[1], n[2], r[2], n[3], r[3]),
                                             w[0]),
                                        Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1, n[2], r[2], n[3], r[3]),
                                             Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1, n[2], r[2], n[3], r[3]),
                                             w[0]),
                                        w[1]),
                                   Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1], n[2] + 1, r[2] - 1, n[3], r[3]),
                                             Lattice(n[0] + 1, r[0] - 1, n[1], r[1], n[2] + 1, r[2] - 1, n[3], r[3]),
                                             w[0]),
                                        Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1, n[2] + 1, r[2] - 1),
                                             Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1, n[2] + 1, r[2] - 1, n[3], r[3]),
                                             w[0]),
                                        w[1]),
                                   w[2]),
                              Lerp(Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1], n[2], r[2], n[3] + 1, r[3] - 1),
                                             Lattice(n[0] + 1, r[0] - 1, n[1], r[1], n[2], r[2], n[3] + 1, r[3] - 1),
                                             w[0]),
                                        Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1, n[2], r[2], n[3] + 1, r[3] - 1),
                                             Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1, n[2], r[2], n[3] + 1, r[3] - 1),
                                             w[0]),
                                        w[1]),
                                   Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1], n[2] + 1, r[2] - 1, n[3] + 1, r[3] - 1),
                                             Lattice(n[0] + 1, r[0] - 1, n[1], r[1], n[2] + 1, r[2] - 1, n[3] + 1, r[3] - 1),
                                             w[0]),
                                        Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1, n[2] + 1, r[2] - 1),
                                             Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1, n[2] + 1, r[2] - 1, n[3] + 1, r[3] - 1),
                                             w[0]),
                                        w[1]),
                                   w[2]),
                              w[3]);
                break;

            default:
                throw new Exception("Invalid value for dimension");
            }
            return(NoiseHelper.Clamp(-0.99999f, 0.99999f, fValue));
        }