Search code examples
phparraysalgorithmsortinganimation

Sort rows of a square matrix array according to an anti-clockwise spiralling path


I've already asked a similar question, but I need a different effect. The original question is here.


I have a simple array. The array length is always a square number. So 16, 25, 36 etc.

$array = array('1', '2', '3', '4' ... '25');

What I do, is arrange the array with HTML so that it looks like a block with even sides.

What I want to do, is sort the elements, so that when I pass the JSON encoded array to jQuery, it will iterate the array, fade in the current block, and so I'd get a circular animation. So I'd like to sort the array kind of like this

So my sorted array would look like

$sorted = array('1', '6', '11'', '16', '21', '22', '23' .. '13');

Is there way to do so?.. Thanks


Edit:

I'm trying to do this by creating matrix-like column/row arrays with this:

$side = 5;

$elems = $side*$side;
$array = range(1,$elems);

for($i=1; $i <= $side; $i++) {
   for($x=$i; $x <= $elems; $x=$x+$side) {
      $columns[$i][] = $x; 
   }
}

for($i=1, $y=1; $i <= $elems; $i=$i+$side, $y++) {
   for($x=$i; $x < $side+$i; $x++) {
      $rows[$y][] = $x;
   }
}

My next step is to go down the first column, at the end if it go right on the last elements column, at the end up on the last element etc.. If anyone has a better idea that would be great :)


Solution

  • This will work as long as the grid is always square:

    <?php
    
        // The size of the grid - 5x5 in the example above
        $gridSize = 5;
    
        // Create a 2D array representing the grid
        $elements = array_chunk(range(1, pow($gridSize, 2)), $gridSize);
    
        // Find the half way point - this will be the end of the loop since we
        // want to stop in the middle
        $end = ceil($gridSize / 2);
    
        // An array to hold the result    
        $result = array();
    
        // The stopping point of the current interation
        $stop = $gridSize;
    
        // Loop from start to the middle
        for ($i = 0; $i < $end; $i++) {
    
            // start in the top left corner
            $x = $y = $i;
    
            // Traverse Y top to bottom
            while ($y < $stop) {
                $result[] = $elements[$y++][$x];
            }
            $y--;
            $x++;
    
            // Traverse X left to right
            while ($x < $stop) {
                $result[] = $elements[$y][$x++];
            }
            $x--;
            $y--;
    
            // Traverse Y bottom to top
            while ($y >= $gridSize - $stop) {
                $result[] = $elements[$y--][$x];
            }
            $y++;
            $x--;
    
            // Make sure we come in a level
            $stop--;
    
            // Traverse X right to left
            while ($x >= $gridSize - $stop) {
                $result[] = $elements[$y][$x--];
            }
        }
    
        print_r($result);
    

    See it working