//working fine
    internal static void SmoothLineBackwardZHigh(Vector3 startPoint, ref float[,] betaHeights, float elevation)
    {
        //print("--SmoothLine:@"+startPoint);

        bool           trigger = false;
        List <Vector3> newIngredCenters;

        if (betaHeights.Length > 0)
        {
            newIngredCenters = new List <Vector3>();
            //Color[] colors = new Color[]{Color.black,Color.blue,Color.cyan,Color.gray,Color.green,Color.magenta,Color.red,Color.white,Color.yellow,Color.black};
            //String[] colorsS = new String[]{"black","blue","cyan","gray","green","magenta","red","white","yellow","black"};
            Vector3 ingredientsCenter0 = startPoint;            //for testing :ingredientsCenters[0];
            ingredientsCenter0 = SmoothersHelpers.SwichZandY(ingredientsCenter0);
            Vector3 ommak1 = ingredientsCenter0;
            newIngredCenters.Add(ommak1);
            for (int i = 0; i < 10; i++)
            {
                //Gizmos.color = colors[i];

                Vector3 ommak2 = ingredientsCenter0;
                ommak2.x--;                //next step
                if (ommak2.x < 0 || ingredientsCenter0.x < 1)
                {
                    continue;                                                        //donot allow minus values
                }
                //ommak2 = SwichZandY(ommak2);
                //print("-swiched:"+ommak2 +","+ingredientsCenter0);
                ommak2.z = betaHeights[(int)ingredientsCenter0.y - 1, (int)ingredientsCenter0.x] * elevation;
                Vector3 targetDir = ommak2 - ommak1;                // - ommak2;
                float   angle     = Vector3.Angle(targetDir, Vector3.forward);
                //print("	old point : "+ommak2);
                //Instantiate(testSubCube,SwichZandY(ommak2),Quaternion.identity);

                Vector3 newOmmak = ChnageTerrainElevationInPointAccordingToAngle(angle, ommak2, newIngredCenters[i], true);
                //print("	new point : "+newOmmak);
                betaHeights[(int)ingredientsCenter0.y - 1, (int)ingredientsCenter0.x] = newOmmak.z / elevation;
                //print("		angle:"+angle+" ,color:"+colorsS[i]);
                newIngredCenters.Add(newOmmak);

                if (trigger && ommak2 == newOmmak)
                {
                    trigger = false;
                    break;
                }
                else if (ommak2 != newOmmak)
                {
                    trigger = true;
                }
                ingredientsCenter0.x--;
                ommak1 = newOmmak;                //ommak2;
            }
        }
    }
    public static KeyValuePair <float, float> SquareSmootherForHighGround(Vector3[] square, ref float[,] betaHeights, float elevation, int width, int height)
    {
        float maxNoiseHeight = float.MinValue;
        float minNoiseHeight = float.MaxValue;

        Vector3 startPoint;
        Vector3 endPoint;
        Vector3 midPoint;
        Vector3 prevMidPoint = Vector3.zero;
        bool    xstop, zstop;

        for (int t = 0; t < 20; t++)
        {
            /*
             *      manual system to expand the corner points, this is done at the end to be ready for next round
             #####		##0##
             ##0##		#####
             #3#1#	=>	3###1
             ##2##		#####
             #####		##2##
             */
            if (square[0].z == 0 || square[3].x == 0 || square[1].x == width || square[2].z == height)
            {
                break;                //TODO: try to fix the value that hits boarder, and contiue loop.
            }
            square[0].z--; square[1].x++; square[2].z++; square[3].x--;

            for (int i = 0; i < 4; i++)
            {
                startPoint = midPoint = square[i];
                if (midPoint.z == 0 || midPoint.x == 0 || midPoint.x == width || midPoint.z == height)
                {
                    continue;
                }
                midPoint.y = betaHeights[(int)midPoint.z, (int)midPoint.x];
                int endIndex = (i == 3)? 0:(i + 1);
                endPoint = square[endIndex];

                xstop = zstop = false;

                while (midPoint.x != endPoint.x && midPoint.z != endPoint.z)
                {
                    prevMidPoint = new Vector3(midPoint.x, betaHeights[(int)midPoint.z, (int)midPoint.x], midPoint.z);

                    if (startPoint.x < endPoint.x && midPoint.x < endPoint.x)
                    {
                        midPoint.x++;                        //will stop one step from end point
                    }
                    else if (startPoint.x > endPoint.x && midPoint.x > endPoint.x)
                    {
                        midPoint.x--;                        //will stop one step from end point
                    }
                    else
                    {
                        xstop = true;
                    }

                    if (startPoint.z < endPoint.z && midPoint.z < endPoint.z)
                    {
                        midPoint.z++;                        //will stop one step from end point
                    }
                    else if (startPoint.z > endPoint.z && midPoint.z > endPoint.z)
                    {
                        midPoint.z--;                        //will stop one step from end point
                    }
                    else
                    {
                        zstop = true;
                    }

                    midPoint.y = betaHeights[(int)midPoint.z, (int)midPoint.x];



                    float newZ = SmoothHigherGround(SmoothersHelpers.SwichZandY(midPoint), SmoothersHelpers.SwichZandY(square[i]), t);
                    if (betaHeights[(int)midPoint.z, (int)midPoint.x] < (newZ / elevation))
                    {
                        betaHeights[(int)midPoint.z, (int)midPoint.x] = newZ / elevation;

                        if (betaHeights[(int)midPoint.z, (int)midPoint.x] > maxNoiseHeight)
                        {
                            maxNoiseHeight = betaHeights[(int)midPoint.z, (int)midPoint.x];
                        }
                        else if (betaHeights[(int)midPoint.z, (int)midPoint.x] < minNoiseHeight)
                        {
                            minNoiseHeight = betaHeights[(int)midPoint.z, (int)midPoint.x];
                        }
                    }
                    else
                    {
                        continue;
                    }
                }

                //more smoothing
                for (int y = (int)square[0].z; y <= square[2].z; y++)
                {
                    for (int x = (int)square[1].x; x < square[3].x; x++)
                    {
                        betaHeights [x, y] = Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, betaHeights [x, y]);
                    }
                }
            }
        }



        return(new KeyValuePair <float, float> (minNoiseHeight, maxNoiseHeight));
    }