Friday, October 5, 2012

Split mXm 2 dimensional Square array into N – Two dimensional Sub Square arrays



Today while working on a relatively complex project I stumbled for couple of hours to split a square matrix into multiple subsets of square arrays. As usual I Googled and Binged for few minutes and did not find any articles or source code on how to tackle the problem, the result is this small article.

Here is my 2 – dimensional array for a Telugu letter మౌ (pronounced as mou).





This is  partially normalized character for 32X32 pixels. To compute Zonal/rotational characteristics of this letter I wanted to split this letter into 4 horizontal and 4 vertical tracks, so that each subset contains 8X8 pixels with total of 16 squares. In other words I wanted to split 32X32 Square into 16 equally sized squares.




Following function returns a jagged array. Jagged array is an array of arrays. In this case I wanted 16, 8X8 sub squares and the result for the above matrix is
  



Function :


 public static int[][,] SplitSquareMatrix(int[,] characterMatrix, int horizintalTrackCountForSubsquares,
            int verticalTrackCountForSubsquares)
        {
            int cwidth = characterMatrix.GetLength(0);
            int cheight = characterMatrix.GetLength(1);
            int xstep = cwidth / verticalTrackCountForSubsquares;
            int ystep = cheight / horizintalTrackCountForSubsquares;
            int xincrement = xstep, yincriment = ystep;          
            int xcor = 0,ycor = 0;

            int loopCount=0;

            int ycounter=0,xcounter=0,j=0,k=0;
            // Declare a jagged array of Squares. Squares is an array of 2 dimensional with
            // (x,y) == (row,column).

            int[][,] Squares = new int[verticalTrackCountForSubsquares * horizintalTrackCountForSubsquares][,];
          
            while (j < horizintalTrackCountForSubsquares)
            {

                while(k<verticalTrackCountForSubsquares)
                {
                    Squares[loopCount]=new int[xstep, ystep];
                    for (int x = xcor; x < xincrement; x++)
                    {
                        if (x >= cwidth) break;
                        for (int y = ycor; y < yincriment; y++)
                        {
                            if (y >= cheight) break;
                            Squares[loopCount][xcounter, ycounter]  = characterMatrix[x, y];
                            ycounter++;
                        }
                        ycounter = 0;
                        xcounter++;
                    }
                    loopCount++;
                    xcounter = 0;
                    xcor = xincrement;
                    xincrement = xincrement + xstep;
                    k++;                   
                }
                // reset variables to next y step.  
                k = 0;
                xcor = 0;
                xincrement = xstep;
                ycor = yincriment;
                yincriment = yincriment + ystep;
                j++;
               
            }
            return Squares;
        }