Search code examples
c#xnacollision-detectionintersectionbounding-box

How does this code perform 'Per Pixel Collision Detection'?


I'm currently trying to understand per pixel collision detection.

This is the code I don't understand:

static bool IntersectPixels(Rectangle rectangleA, Color[] dataA,
                            Rectangle rectangleB, Color[] dataB)
{
    // Find the bounds of the rectangle intersection
    int top = Math.Max(rectangleA.Top, rectangleB.Top);
    int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
    int left = Math.Max(rectangleA.Left, rectangleB.Left);
    int right = Math.Min(rectangleA.Right, rectangleB.Right);

    // Check every point within the intersection bounds
    for (int y = top; y < bottom; y++)
    {
        for (int x = left; x < right; x++)
        {
            // Get the color of both pixels at this point
            Color colorA = dataA[(x - rectangleA.Left) +
                                 (y - rectangleA.Top) * rectangleA.Width];
            Color colorB = dataB[(x - rectangleB.Left) +
                                 (y - rectangleB.Top) * rectangleB.Width];

            // If both pixels are not completely transparent,
            if (colorA.A != 0 && colorB.A != 0)
            {
                // then an intersection has been found
                return true;
            }
        }
    }

    // No intersection found
    return false;
}

I really don't understand these nested loops. I'll be glad for some explanation about how it works.


Solution

  • It's not that hard (in this case). You give the algorithm the two bounding-boxes of your objects (so the whole object is inside its box), and an array with color-information for them.
    The algorithm assumes that a point belongs to the object if it is not transparent. This is important.

    The first step is to calculate the intersecting rectangle. If you intersect two rectangles that have sides parallel to the axes like in this case, you will get a rectangle again or else an empty set.

    The next step is to iterate in this intersecting rectangle for all (x,y) coordinates inside, first y, then x, so you get your normal first x, then y inside, but this is a minor point and not important.

    Then finally the algorithm gets the color for objects A and B at the current pixel (x,y). If both colors are NOT transparent then the pixel is in both objects and the objects have to intersect at this point. Then the algorithm terminates with "YES they intersect".

    If all pixels in the intersection of the bounding boxes were checked and no common (e.g. non-transparent) pixel was found the objects don't intersect and so the algorithm terminates with "NO they don't intersect".

    I hope this helps.