Collision Detection Algorithm

closed account (DEhqDjzh)
Hi, I've got an array of GameObject class and I want to do something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
vector<Gamobject> objects
Trigger t; // will there be a problem if the trigger is a game object? e.g  //Gameobject trigger
if(t.detectdanobject() == true)  
{

// do stuff


}

bool Trigger::detectanobject()
{
//Main question: what should i write here ?

}

 

Note: It will be amazing if you post the answer as a code + little explanation :)
Last edited on
Collision Detection is a very broad subject, and the techniques can differ widely depending on what you're dealing with.

A basic type of collision detection is axis-aligned rectangle-rectangle collision detection.

Usually, a collision detection method will take in two objects (at some current position in space), and see if they overlap in either 2D or 3D.

If you want to see an example of basic 2D collision, check out:
https://github.com/SFML/SFML/blob/master/include/SFML/Graphics/Rect.inl

"Intersects" means if there is overlap between the first rectangle and the second rectangle. Note that you can simplify the following logic if you don't allow for rectangles with negatives dimensions.

It even has some comments! (It also produces the resulting intersection as its own rectangle, but this is not necessary.)

Credit goes to Laurent Gomila and the SFML team:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
template <typename T>
bool Rect<T>::intersects(const Rect<T>& rectangle, Rect<T>& intersection) const
{
    // Rectangles with negative dimensions are allowed, so we must handle them correctly

    // Compute the min and max of the first rectangle on both axes
    T r1MinX = std::min(left, static_cast<T>(left + width));
    T r1MaxX = std::max(left, static_cast<T>(left + width));
    T r1MinY = std::min(top, static_cast<T>(top + height));
    T r1MaxY = std::max(top, static_cast<T>(top + height));

    // Compute the min and max of the second rectangle on both axes
    T r2MinX = std::min(rectangle.left, static_cast<T>(rectangle.left + rectangle.width));
    T r2MaxX = std::max(rectangle.left, static_cast<T>(rectangle.left + rectangle.width));
    T r2MinY = std::min(rectangle.top, static_cast<T>(rectangle.top + rectangle.height));
    T r2MaxY = std::max(rectangle.top, static_cast<T>(rectangle.top + rectangle.height));

    // Compute the intersection boundaries
    T interLeft   = std::max(r1MinX, r2MinX);
    T interTop    = std::max(r1MinY, r2MinY);
    T interRight  = std::min(r1MaxX, r2MaxX);
    T interBottom = std::min(r1MaxY, r2MaxY);

    // If the intersection is valid (positive non zero area), then there is an intersection
    if ((interLeft < interRight) && (interTop < interBottom))
    {
        intersection = Rect<T>(interLeft, interTop, interRight - interLeft, interBottom - interTop);
        return true;
    }
    else
    {
        intersection = Rect<T>(0, 0, 0, 0);
        return false;
    }
}


Another example would be circle-circle collision. This one is even easier, because all you need to check is if the distance from the center of one circle to the center of the second circle is less than the sum of their radii. You can avoid a square root operation (relatively slow) by squaring all the lengths (although this is just an optimization).

Here's some interactive examples from Mozilla:
https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection
Last edited on
Topic archived. No new replies allowed.