First read my post Isolating distinct, arbitrary shapes on a 2D grid.

In this post I’ll explain how to break up polygons on a 2D grid into distinct rectangles. This is useful, for example, if you’re aiming to add shapes to Box2D physics engine, as convex shapes cannot be used in Box2D. The easiest way to eliminate concavity is slicing your polygons into smaller rectangles.

Here’s the 2D grid from the previous post, with two polygonal shapes (n = 2) distinguished on the grid:

{0,0,0,0,0,0}
{0,1,1,0,0,0}
{0,1,1,0,0,2}
{1,1,0,2,0,2}
{0,0,0,2,0,2}
{0,0,2,2,2,2}

This algorithm requires you to iterate the grid left-to-right, top-to-bottom. You’ll need to know the how many distinct shapes are already present on the grid (i.e. n = 2, in this example).

The method is to find how long the first row of the shape r1 is, assign each cell in r1 with the value vx,y = n, and then copy down r1 to rows rj, 1 < j < h – j (h = height of grid) below, as many times as it will continue to fit within the shape.

For example:

{0,0,0,0}
{0,1,1,0} <-- r1
{0,1,1,0}
{1,1,0,0}

r1 of the shape currently with v = 1, contains cells (x2,y2) and (x3,y2) and it’s width is 2. Give those cells the value n++ (in this case, 2). r1 can be copied down to r2 successfully, but not r3. This is because r3 has the same width as r1, but it’s left-most cell is obviously not in the same column as r1’s left-most cell.

So the algorithm would identify the first two rows as part of one rectangle, and further on would distinguish the third row as another rectangle, assigning it’s cells the value n++:

{0,0,0,0}
{0,2,2,0}
{0,2,2,0}
{3,3,0,0}

To return to the original example, for each cell (xi, yj) with a value vi where i > 0, and v < n, find out how long it’s row is by checking each tile to it’s right i.e. xi+k where k is iterated between k = 1 and k = w – x (the width of the grid – x). Stop when you reach a cell where vi+k != vi. The length of the row ri will then be l = j-i. Now, iterate yi+k, where 1 < k < h – y (where h is the height of the grid). Continue until you can no longer fit l tiles into the row ri+k. The number of rows you can copy down will be m = k – i.

Your identified rectangle will be of size l x m, starting at point (xi, yj). Each cell in that rectangle is now assigned the value vx,y = n. Once you’ve done that, increment n and continue running the algorithm.

Once you’ve finished you’ll end up with this:

{0,0,0,0,0,0}
{0,3,3,0,0,0}
{0,3,3,0,0,4}
{5,5,0,6,0,4}
{0,0,0,6,0,4}
{0,0,7,6,8,4}

You can then “normalise” the grid the so the lowest shape number is 1:

{0,0,0,0,0,0}
{0,1,1,0,0,0}
{0,1,1,0,0,2}
{3,3,0,4,0,2}
{0,0,0,4,0,2}
{0,0,5,4,6,2}

The algorithm has divided the original 2 polygonal shapes into 6 rectangles.

Here’s a Lua implementation of the algorithm:

-- grid is the 2D grid to input
-- n is the number of distinct polygons on the grid
local function createRectObjects (grid, n)
    local max = n
    local objNum = max
     
    -- Iterate grid
    for y = 1, #grid, 1 do
        for x = 1, #grid[y], 1 do
             
            --Subject tile
            local subject = {}
            subject.val = grid[y][x]
            subject.x = x
            subject.y = y
             
            if subject.val > 0 and subject.val <= max then
                objNum = objNum + 1
                --grid[y][x] = objNum
                 
                --Determine width
                local blockWidth = 1
                for i = 1, #grid[y] - x, 1 do
                    if grid[y][x+i] == subject.val then
                        blockWidth = blockWidth + 1
                    else
                        break
                    end
                end
                 
                --Determine height
                local blockHeight = 1
                for i = 1, #grid - y, 1 do
                    local invalidRow = false
                    for j = 1, blockWidth, 1 do
                        if grid[y+i][x+j-1] ~= subject.val then
                            invalidRow = true
                            break
                        end
                    end
                    if invalidRow then
                        blockHeight = i
                        break
                    elseif i == (#grid - y) then
                        blockHeight = i
                        break
                    end
                end
                 
                --Stamp the new objNum onto the tiles in the block
                for i = subject.y, subject.y + blockHeight - 1, 1 do
                    for j = subject.x, subject.x + blockWidth -1, 1 do
                        grid[i][j] = objNum
                    end
                end
            end
        end
    end
     
    --Normalise numbers
    for y = 1, #grid, 1 do
        for x = 1, #grid[y], 1 do
            if grid[y][x] ~= 0 then
                grid[y][x] = grid[y][x] - max
            end
        end
    end
     
    obj.max = objNum - max
    return grid
end

This code is part of my Lua Grid Tools repo on Bitbucket: https://bitbucket.org/anthonygore/luagridtools

Next I’ll explain how to trace these shapes and return a table of points which outline each rectangle. Tools like Box2D take an array of vertices.


I had quite a bit of trouble setting up automatic deployment of a git repo to a Linux instance on EC2.

I’m using the PHP script outlined in the blog post below, which is triggered by Bitbucket’s POST web hook:

http://brandonsummers.name/blog/2012/02/10/using-bitbucket-for-automated-deployments/

But my log contained the following error when a git pull was attempted:

Could not create directory '/var/www/.ssh'. Host key verification failed. fatal: Could not read from remote repository.  Please make sure you have the correct access rights and the repository exists.

The problem is that the PHP script runs as user apache, which has no SSH key setup.

The solution:

  1. From the Linux command line, give user apache shell access. Without this, you can’t generate an SSH key to get access rights to the repo. This can be done by editing /etc/passwd

     sudo nano /etc/passwd
    

    Then change line:

     apache:x:48:48:Apache:/var/www:/sbin/nologin
    

    To:

     apache:x:48:48:Apache:/var/www:/bin/bash
    
  2. Create directory /var/www/.ssh

     sudo mkdir -p /var/www/.ssh/
    
  3. Change the owner of directory to user apache

     sudo chown -R apache /var/www/.ssh/
    
  4. Switch to user apache

     su - apache
    
  5. Generate an SSH key

     ssh-keygen
    

    Leave the password blank.

  6. Copy the SSH key and put it in Bitbucket

     cat /var/www/.ssh/id_rsa.pub
    

    And add to Bitbucket’s SSH keys.

  7. Change back to the root user and remove shell access to user apache.

     sudo nano /etc/passwd
    

    Change line:

       apache:x:48:48:Apache:/var/www:/bin/bash
    

    Back to:

     apache:x:48:48:Apache:/var/www:/sbin/nologin
    

And the deploy script now works.

Further reading:

http://jondavidjohn.com/git-pull-from-a-php-script-not-so-simple/

http://stackoverflow.com/questions/7306990/generating-ssh-keys-for-apache-user

http://stackoverflow.com/questions/9370975/running-git-pull-from-a-php-script

http://serverfault.com/questions/362012/running-git-pull-from-a-php-script

http://stackoverflow.com/questions/5144039/shell-exec-and-git-pull

http://stackoverflow.com/questions/9370975/running-git-pull-from-a-php-script


The player can only face in eight directions i.e. the cardinal (N, E, S, W) and ordinal (NE, SE, SW, NW) directions. This constraint is in response to the graphic art requirements; it can’t be expected that there will be animation in all possible directions. My assertion is that these eight directions will be enough, as they are for many top-down games.

To make a suitable algorithm, my idea is to break a proposed movement down into components which are directed in the eight such directions. For example, let’s say the user selects a destination about 10 steps away, slightly north of east. The player can’t move directly to that point, but you could instead make him move east for, say, 8 steps, and then north-east for, say, 2 steps and have him land on the required point.

The algorithm I designed to do this works as follows:

  1. The user selects a point destination d they want the player to move to. Now imagine a single vector is drawn between the point current location c and d.
  2. This single vector is now broken down into a list of component vectors s, the direction of each necessarily being one of the cardinal or ordinal compass directions, while the magnitude of each will be roughly the same (to ensure movement appears regular). The method profile will be something like:

     private LinkedList<Vector> buildVectorList (Point c, Point d)
    

    Now elect a standard length l for these component vectors. l shouldn’t be too small, otherwise the player’s movement will look abrupt, nor should it be too long, as he will deviate too far from the track. Let’s say l = 20. A method is also needed to measure the angle between c and d. I found it best to measure the angle in radians, with the y-axis being parallel to north on the map, as you’d expect. With that in mind, here are the sub-steps for creating s:

    1. Check that the distance between c and d is greater than l. If so proceed, if not, end.
    2. Get the angle a in radians between between c and d. Let’s say a is slightly larger than 0.
    3. Now find the compass direction that gives the closest approximation to a. In this example, it will be east, as east is equivalent to 0 radians on a cartesian plane.
    4. Now create a vector v and add it to your list (I think a linked list is the best data structure here, but an array list or similar would be fine). The magnitude will be l, and the direction will be east.
    5. Now create a point c1 = c + l so the c1 sits at the end of v, were v to be extended from c. Let c = c1 and discard c1.
    6. Repeat the above steps until c is within l from the d.
  3. Now if you iterate s and follow the vectors sequentially tail to head, you will get the player to point d1 which approximates d. Below is an example.

    Vector

    To get the player exactly to d, you need another method:

     private LinkedList<Vector> adjustVectors (LinkedList<Vector> s, Point c, Point d)
    
    1. Firstly, check the offset o between d and d1. Let’s say d1 is 10 pixels right and 10 pixels below d
    2. Iterate s and distribute o among the vectors vi by changing their magnitude appropriately until d1 == d. I do this with a while loop, adding or subtracting 1 to the length of vi until o == 0.

Finally we end up with a list of vectors which, if the player follows sequentially, will take him in a smooth path to the user’s elected destination.


In this game, the player will move to a location on the screen determined by user input. The following are constraints that will need to be considered when constructing an algorithm:

  1. The player can only face in eight directions i.e. the cardinal and ordinal compass directions (N, NE, E, SE etc). This limitation is necessary is to keep the graphics simple. As such, the player can only move in those eight directions or the movement animation will look weird.
  2. The player’s destination can be changed mid-walk i.e. the user is free to set the destination as often as they like, and the player must respond accordingly.
  3. The player can only move on “walkable” tiles i.e. he can’t walk over buildings. He needs to walk around unwalkable tiles.

Each of these constraints bring up a whole lot of sub-constraints and necessary decisions and compromises. I’ll deal with these individually.