Mega Code Archive

 
Categories / C# / Collections Data Structure
 

Defines a 2D Array

#region Using Statements using System; using System.Collections.Generic; using System.Text; using System.Collections; #endregion namespace JigLibX.Utils {     /// <summary>     /// Defines a 2D Array     /// </summary>     public class Array2D     {         public delegate float Function(int x, int z, Array2D arrInstance);         private int nx, nz;         private bool wrap;         public float[] Array;         public Array2D(Array2D arr)         {             if (arr == null || arr.Array == null)                 return;             this.Array = new float[arr.Array.Length];             this.nx = arr.Nx;             this.nz = arr.Nz;             Buffer.BlockCopy(arr.Array, 0, this.Array, 0, this.Array.Length * 4);         }         public Array2D(int nx, int nz)         {             Array = new float[nx * nz];             this.nx = nx;             this.nz = nz;         }         public Array2D(int nx, int nz, float val)         {             Array = new float[nx * nz];             this.nx = nx;             this.nz = nz;             for (int i = 0; i < Array.Length; i++)                 Array[i] = val;         }         /// <summary>         /// Creates 2D array from mathematical function         /// </summary>         /// <param name="nx"></param>         /// <param name="ny"></param>         /// <param name="yScale"></param>         /// <returns></returns>         public static Array2D CreateArray(int nx, int nz, Function func)         {             Array2D arr = new Array2D(nx, nz);             if (func == null)                 return arr;             for (int xx = 0; xx < nx; xx++)             {                 for (int zz = 0; zz < nz; zz++)                 {                     arr.Array[xx + zz * nx] = func(xx, zz, arr);                 }             }             return arr;         }         /// <summary>         /// allows resizing. Data will be lost if resizing occurred         /// </summary>         /// <param name="nx"></param>         /// <param name="ny"></param>         public void Resize(int nx, int nz)         {             if (nx == this.nx && nz == this.nz)                 return;             Array = new float[nx * nz];             this.nx = nx;             this.nz = nz;         }         /// <summary>         /// raise array elements to a power         /// </summary>         /// <param name="rhs"></param>         /// <returns></returns>         public Array2D Pow(float rhs)         {             for (int i = 0; i < this.nx * this.nz; ++i)             {                 Array[i] = (float)System.Math.Pow(Array[i], rhs);             }             return this;         }         /// <summary>         /// sets each value to its absolute value by comparison with float(0)         /// </summary>         public void Abs()         {             for (int i = 0; i < Array.Length; ++i)             {                 if (Array[i] < 0)                     Array[i] = -Array[i];             }         }         /// <summary>         /// Apply a Gaussian filter with length scale r, extending over a         /// square of half-width n (so n=1 uses a square of 9 points, n = 2         /// uses 25 etc). Suggest using n at least 2*r.         /// </summary>         /// <param name="r">length scale</param>         /// <param name="n">half-width</param>         public void GaussianFilter(float r, int n)         {             int i, j, ii, jj, iii, jjj;             int size = (n * 2 + 1);             float[] filter = new float[size * size];             for (i = 0; i < size; ++i)             {                 for (j = 0; j < size; ++j)                     filter[i + j * size] = (float)System.Math.Exp(-((i - n) * (i - n) + (j - n) * (j - n)) / (r * r));             }             for (i = 0; i < (int)this.nx; ++i)             {                 for (j = 0; j < (int)this.nz; ++j)                 {                     float total = 0;                     float weight_total = 0;                     for (ii = -n; ii < (int)n; ++ii)                     {                         if ((((iii = i + ii) >= 0) && (iii < this.nx)) || (wrap))                         {                             for (jj = -n; jj < (int)n; ++jj)                             {                                 if ((((jjj = j + jj) >= 0) && (jjj < this.nz)) || (wrap))                                 {                                     // in a valid location                                     int index = (n + ii) + (n + jj) * size;                                     weight_total += filter[index];                                     total += filter[index] * GetAt(iii, jjj);                                 }                             }                         }                     }                     SetAt(i, j, total / weight_total);                 }             }         }         /// <summary>         /// shifts all the elements...         /// </summary>         /// <param name="offsetX"></param>         /// <param name="offsetY"></param>         public void Shift(int offsetX, int offsetZ)         {             Array2D orig = new Array2D(this);             for (int i = 0; i < this.nx; ++i)             {                 for (int j = 0; j < this.nz; ++j)                 {                     int i0 = (i + offsetX) % this.nx;                     int j0 = (j + offsetZ) % this.nz;                     this.SetAt(i0, j0, orig.GetAt(i, j));                 }             }         }         /// <summary>         /// scale to fit within range...         /// </summary>         /// <param name="valMin"></param>         /// <param name="valMax"></param>         public void SetRange(float valMin, float valMax)         {             int i;             float origMin = this.Min;             float origMax = this.Max;             // set min to 0 and scale...             float scale = (valMax - valMin) / (origMax - origMin);             float offset = valMin - scale * origMin;             for (i = 0; i < Array.Length; ++i)             {                 Array[i] = scale * Array[i] + offset;             }         }         /// <summary>         /// Set to a constant value         /// </summary>         /// <param name="val"></param>         public void SetTo(float val)         {             for (int i = 0; i < Array.Length; ++i)             {                 Array[i] = val;             }         }         /// <summary>         /// checked access - unwraps if wrapping set         /// </summary>         /// <param name="i"></param>         /// <param name="j"></param>         /// <returns></returns>         public float GetAt(int i, int j)         {             UnwrapIndices(ref i, ref j);             return Array[i + j * this.nx];         }         /// <summary>         /// checked access - unwraps if wrapping set         /// </summary>         public void SetAt(int i, int j, float val)         {             UnwrapIndices(ref i, ref j);             Array[i + j * this.nx] = val;         }         private void UnwrapIndices(ref int i, ref int j)         {             if (wrap == false)                 return;             while (i < 0)                 i += this.nx;             while (j < 0)                 j += this.nz;             i = i % this.nx;             j = j % this.nz;         }         /// <summary>         /// ! Unchecked access - no wrapping         /// </summary>         /// <param name="i"></param>         /// <param name="j"></param>         /// <returns></returns>         public float this[int i, int j]         {             get             {                 return Array[i + j * this.nx];             }         }         /// <summary>         /// enables/disables wrapping         /// </summary>         public bool Wrap         {             get { return wrap; }             set { wrap = value; }         }         /// <summary>         /// Gets the 'x' size of the array         /// </summary>         public int Nx         {             get { return this.nx; }         }         /// <summary>         /// Gets the 'y' size of the array         /// </summary>         public int Nz         {             get { return this.nz; }         }         public float Min         {             get             {                 float min = Array[0];                 for (int i = 0; i < Array.Length; ++i)                 {                     if (Array[i] < min)                         min = Array[i];                 }                 return min;             }         }         public float Max         {             get             {                 float max = Array[0];                 for (int i = 0; i < Array.Length; ++i)                 {                     if (max < Array[i])                         max = Array[i];                 }                 return max;             }         }     } }