示例#1
0
    //recursively lerp the influences of the neighboring grid points to the pixel
    //in the first iteration, the last index is split between 0 and 1
    //  (0, 0, ..., 0) (0, 1, ..., 0) vs. (0, 0, ..., 1) (0, 1, ..., 1)
    //  the weight by which these two groups will be lerped is the faded value
    //  weight = last coordinate of ((the map coordinate of v) - (the basis node))
    //then for the second iteration, the second last index is split between 0 and 1
    //  weight = 2nd last of ...
    //and so on
    private float RecurLerpTree(
        PerlinNode[] influencers, VecN[] deviations, VecN w,
        int left, int right, int iteration
        )
    {
        if (right - left == 1)
        {
            //only two elements to be processed
            //by def. the iteration number will be d-1 at this point
            //calculate left and right influences with dist dot grad
            float lInf = w.Subtract(deviations[left]).Dot(influencers[left].gradient);
            float rInf = w.Subtract(deviations[right]).Dot(influencers[right].gradient);

            //lerp the two influences using the weight of the first digit
            //this is because the 01 difference of the deviations are at the first digit
            float lerped = Lerp(
                lInf,
                rInf,
                Fade(w.coord[d - iteration - 1])
                );
            return(lerped);
        }

        //for more than one element, by def the length of influencers should always be even
        //lerp the left and right influences using the last iteration'th value of w\
        return(Lerp(
                   RecurLerpTree(influencers, deviations, w, left, left + (right - left) / 2, iteration + 1),
                   RecurLerpTree(influencers, deviations, w, left + (right - left) / 2 + 1, right, iteration + 1),
                   Fade(w.coord[d - iteration - 1])
                   ));
    }
示例#2
0
 //return a new VecN instance representing the result of a VecN instance multiplied
 //by a scalar value
 public static VecN Scale(VecN a, float b)
 {
     float[] c = new float[a.d];
     for (int i = 0; i < a.d; i++)
     {
         c[i] = a.coord[i] * b;
     }
     return(new VecN(c));
 }
示例#3
0
 //return the radian angle of a VecN instance
 public static float Angle(VecN a)
 {
     if (a.d != 2)
     {
         throw new System.ArgumentException("angle only applies to 2D vectors, not "
                                            + a.d + "D");
     }
     return(Mathf.Atan2(a.coord[1], a.coord[0]));
 }
示例#4
0
 //returns a new VecN instance representing the modulo b version of a VecN instance
 //basically applies mod b to every coordinate of a
 public static VecN Mod(VecN a, float b)
 {
     float[] coord = new float[a.d];
     for (int i = 0; i < a.d; i++)
     {
         coord[i] = a.coord[i] % b;
     }
     return(new VecN(coord));
 }
示例#5
0
        public PerlinNode(VecN coord)
        {
            this.coord = coord;

            //generate random d-dimensional unit vector
            gradient = Gaussian.UnitVecN(coord.d);

            //gradient = new VecN(new float[] {
            //1, 0
            //});
        }
示例#6
0
    //return a new VecN instance representing the normalized result of
    //a VecN instance
    public static VecN Normalize(VecN a)
    {
        float l = a.Norm();

        if (l != 0.0f)
        {
            return(a.Scale(1 / l));
        }
        else
        {
            return(a.Scale(1.0f)); //not returning a for the sake of cloning
        }
    }
示例#7
0
 //return a new VecN instance (for N = 3) representing the cross product
 //of two 3D vectors
 public static VecN Cross(VecN a, VecN b)
 {
     if (a.d != 3 || b.d != 3)
     {
         throw new System.ArgumentException("cross product only takes 3D vectors, not "
                                            + a.d + " and " + b.d + "D vectors");
     }
     else
     {
         return(new VecN(new float[] {
             a.coord[1] * b.coord[2] - a.coord[2] * b.coord[1],
             a.coord[2] * b.coord[0] - a.coord[0] * b.coord[2],
             a.coord[0] * b.coord[1] - a.coord[1] * b.coord[0],
         }));
     }
 }
示例#8
0
    //find the base adjacent grid-coordinate for a given d-dimensional vector
    //the first element returned is the basis node
    //the second element is the deviation vector that goes from the pixel to the basis node
    public ArrayList FindBasis(VecN a)
    {
        if (a.d != d)
        {
            throw new System.ArgumentException(
                      "dimension of pixel (" + a.d +
                      ") does not match the dimension of this noise map (" + d + ")");
        }
        else
        {
            int[]   coord     = new int[a.d];
            float[] deviation = new float[a.d];
            for (int i = 0; i < a.d; i++)
            {
                //fit the i'th item of the coordinate into the range [0, w]
                float temp = a.coord[i];
                if (temp < 0) //for negative values of a coordinate
                {
                    if (temp % w == 0.0f)
                    {
                        temp = 0;
                    }
                    else
                    {
                        temp += (int)(-1 * temp / w + 1) * w;
                    }
                }
                else if (temp > w) //for positive overflow (repeat)
                {
                    temp = temp % w;
                }

                deviation[i] = temp % 1.0f;
                //round the coordinate value down to get the basis value
                coord[i] = (int)temp;
            }
            int l = Unwrap(coord);
            if (l < 0 || l > nodes.Length)
            {
                throw new ArgumentException("length is out of bounds, " + l);
            }
            ArrayList result = new ArrayList();
            result.Add(nodes[l]);
            result.Add(new VecN(deviation));
            return(result);
        }
    }
示例#9
0
    //convert a Vec-d instance to the corresponding
    //length coordinate on the space filling curve
    public int Unwrap(VecN a)
    {
        if (a.d != d)
        {
            throw new System.ArgumentException(
                      "the coordinate's dimension " + a.d +
                      " does not match with the noise map's dimension " + d);
        }

        int result = 0;

        for (int i = 0; i < d; i++)
        {
            result += (int)a.coord[i] * (int)Mathf.Pow(w, i);
        }
        return(result);
    }
示例#10
0
 //return a new VecN instance representing the difference of two
 //VecN instances with the same dimensions (a - b), not (b - a)
 public static VecN Subtract(VecN a, VecN b)
 {
     if (a.d != b.d)
     {
         throw new System.ArgumentException("dimensions do not agree when calculating difference: "
                                            + a.d + " and " + b.d);
     }
     else
     {
         float[] c = a.coord.Clone() as float[];
         for (int i = 0; i < a.d; i++)
         {
             c[i] = a.coord[i] - b.coord[i];
         }
         return(new VecN(c));
     }
 }
示例#11
0
    //notice that none of the functions below modify the original VecN instance

    //return the dot product of two vectors with the same dimensions
    public static float Dot(VecN a, VecN b)
    {
        if (a.d != b.d)
        {
            throw new System.ArgumentException("dimensions do not agree when calculating dot product: "
                                               + a.d + " and " + b.d);
        }
        else
        {
            float result = 0.0f;

            //Debug.Log("\t\tdot called with returning:");
            for (int i = 0; i < a.d; i++)
            {
                result += a.coord[i] * b.coord[i];
                //Debug.Log("\t\t\t" + i + "th value is" + (a.coord[i] * b.coord[i]));
            }

            return(result);
        }
    }
示例#12
0
    /*
     * The noise map is noted by a grid of d-dimensional vectors going from:
     * (0, 0, ..., 0), (1, 0, ..., 0), ..., (w-1, 0, ..., 0)
     * (0, 1, ..., 0), (1, 1, ..., 0), ..., (w-1, 1, ..., 0)
     *                               ...(w-1, w-1, ..., w-1)
     * and each vector corresponds to a measurement of length for a space filling curve
     * which works similar to a w-based number:
     *      digit 0 * 1 + digit 1 * w + ... + digit d-1 * w ^ d-1
     */

    //beware that this method is not very efficient as it uses a rectangular grid instead of triangular

    //initialize with flavor specification
    public Perlin(int w, int d, int f)
    {
        this.w = w;
        this.d = d;
        this.f = f;

        //initiate the relative positions of adjacent grids to the basis grid
        //use a cursor going from 0 to 2^n-1 to iterate across all the
        //possible deviations associated with adjacent coordinates
        grid_deviations = new VecN[(int)Mathf.Pow(2, d)];
        for (int i = 0; i < grid_deviations.Length; i++)
        {
            float[] c = new float[d];
            for (int j = 0; j < d; j++)
            {
                c[j] = (i >> j) & 1; //gets the bit value of the j'th digit of i
            }

            grid_deviations[i] = new VecN(c);
        }

        //there are w * ... * w pivots in total, w^d
        nodes = new PerlinNode[(int)Mathf.Pow(w, d)];
        //iterate through the space filling curve by length
        //populate the noise map and configure the adjacency relationships
        for (int i = 0; i < nodes.Length; i++)
        {
            //populate the map and set the gradient vector (see constructor for pn)
            PerlinNode pn = new PerlinNode(Wrap(i));
            nodes[i] = pn;
        }

        for (int i = 0; i < nodes.Length; i++)
        {
            //setup adjacency relationships
            nodes[i].neighbors = FindAdjacency(nodes[i]);
        }

        //Debug.Log(nodes[0].PrintNeighbors());
    }
示例#13
0
    //find the noise in the noisespace corresponding to v
    public float Noise(VecN v)
    {
        if (v.d != d)
        {
            throw new System.ArgumentException(
                      "dimension of pixel (" + v.d +
                      ") does not match the dimension of this noise map (" + d + ")");
        }

        ArrayList found = FindBasis(v);

        //the basis node
        PerlinNode[] influencers = (found[0] as PerlinNode).neighbors;

        //influences[0] is basically the basis grid node
        //w is how much it deviates from that node, it's values will be
        //for lerping purposes
        VecN w = found[1] as VecN;

        float n = RecurLerpTree(influencers, grid_deviations, w, 0, grid_deviations.Length - 1, 0);

        return(Mathf.Min(Mathf.Max(0, n + 0.5f), 1.0f));
    }
示例#14
0
    // update tex's content
    private void FillTexture()
    {
        for (int i = 0; i < resolution; i++)
        {
            for (int j = 0; j < resolution; j++)
            {
                //calculate noise
                VecN marker = new VecN(
                    new float[]
                {
                    i / (float)pixelPerGrid,
                    j / (float)pixelPerGrid,
                    t
                }
                    );
                float n = map.Noise(marker);

                //convert to color format
                byte col = (byte)(n * 255);
                tex.SetPixel(i, j, new Color32(col, col, col, 255));
            }
        }
        tex.Apply();
    }
示例#15
0
 //return a new VecN instance representing the sum of
 //this VecN instance with another vector
 public VecN Add(VecN a)
 {
     return(Add(this, a));
 }
示例#16
0
 //return dot product of the current VecN instance with another vector
 public float Dot(VecN a)
 {
     return(Dot(this, a));
 }
示例#17
0
 //return a new VecN instance (for N = 3) representing the cross product
 //of this VecN instance with another 3D vector
 public VecN Cross(VecN a)
 {
     return(Cross(this, a));
 }
示例#18
0
 //return a new VecN instance representing this VecN instance minus
 //another VecN instance
 public VecN Subtract(VecN a)
 {
     return(Subtract(this, a));
 }
示例#19
0
 //return the length of a VecN instance
 public static float Norm(VecN a)
 {
     return(Mathf.Sqrt(Dot(a, a)));
 }