**'radial' collision handling**, can be used to model objects which can be enclosed by bounding cylinders. It is ideal for objects such as trees and poles, and can even be used to simulate collisions with small rectangular objects. I call the second method

**'nodal' collision handling**, and it can be used to provide bounding regions for a series of connected walls in any arrangement. It could be used to model the interior of a house or hut, or the walls of a maze. It will hopefully be discussed in a future article. I created these methods (or rather implemented them, as it's likely they've been used before) with two aims. First off, each method should allow me to detect collisions, which is an obvious requirement of collision detection! Second, each method should handle collisions in such a way as to 'slide' the player/object around the obstacle rather than bringing them to an awkward halt as soon as they touch it.

# Radial collision handling

## The Concept

As mentioned, this system allows you to handle collisions with objects which can be enclosed by bounding cylinders. These cylinders can be defined by two numbers, or rather, a vector and a float - one containing a**location**, and the other containing a

**radius**. Let's imagine we have a simple scenario with a triangle of trees placed on a simple flat plane:

**If the camera has entered a tree's bounding cylinder, register a collision.****Calculate a new location for the camera which puts it back outside the bounding cylinder.**

## The Implementation

We'll start out by defining the location of each tree using an array of 2D vectors. We only need 2D vectors because the trees are not going to affect our motion in the up-down direction. If you wanted to use this algorithm for objects on 3D terrain rather than a 2D plane, it should work just as well with the same vector format because it's not possible for a walking person to collide with a tree from above or below, only from the side. Because of this, we only need to worry about the positions of the trees in the x-z plane, whether we have a flat terrain or not. As mentioned, we will use DirectX syntax and functions from here on in:```
//The array contains 3 vectors - one for each tree:
D3DXVECTOR2 v_treePositions[3] = {D3DXVECTOR2(0, 1), D3DXVECTOR2(1, 0), D3DXVECTOR2(-1, 0)};
```

We will also define a variable to describe the radius of each tree trunk. We will assume they're all the same radius, but if you wanted to personalise each one, you could define an array of numbers, or add a third component to the vectors describing tree locations.
```
//Each tree is 1m in radius:
float f_treeRadius = 1.0f;
```

...and while we're at it, we will define a vector to hold the location of our first-person camera as it changes from frame to frame:
```
//This is a global vector holding the camera's location. It starts at the centre of the world (0, 0, 0):
D3DXVECTOR3 v_camPos(0, 0, 0);
```

OK, now each tree has an entry in our program, and we know where our player's camera is from frame to frame. All that remains is to put this information to use! We will define a function which will be called every frame. This function will loop through the tree locations, comparing each one to the location of the camera for that frame. If it registers a collision (i.e. if the camera's location is closer to one of the trees than is permitted by the bounding radius), then we will push the camera back outside the bounding radius. The effect is cumulative, meaning that each tree makes its own contribution to the overall position change. This way, the algorithm also works for closely bound groups of trees where the camera could be in contact with more than one at once.
Let's go through the function line by line:
```
D3DXVECTOR2 handle_Collisions_Radial()
{
D3DXVECTOR2 v_deltaPos = D3DXVECTOR2(0, 0);
for (int i = 0; i < 3, i++)
{
D3DXVECTOR2 v_vectorToCentre(v_camPos.x - v_treePositions.x, v_camPos.z - v_treePositions.z);
if (D3DXVec2Length(&v_vectorToCentre) < f_treeRadius)
{
v_deltaPos += ((f_treeRadius / D3DXVec2Length(&v_vectorToCentre)) - 1) * v_vectorToCentre;
}
}
return v_deltaPos;
}
```

**First**, we notice that the function returns a

*D3DXVECTOR2*. This corresponds to the amount by which the camera needs to move to put it outside of the bounding cylinders of all the trees. It returns a

*D3DXVECTOR2*because the trees only affect the location of the camera in the x-z plane.

**Second**, we create an inline vector called

*v_deltaPos*which will be filled with the overall change in position required to put the camera outside the bounding radii of all the trees. This is the vector which the function will eventually return. Next, we enter a loop which will iterate through all the trees. Since we have three trees, we will have three iterations.

**Third**, we create a temporary vector called

*v_vectorToCentre*. This contains a directional vector between the location of the camera and the location of

*tree*in the x-z plane.

**Fourth**, we compare the length of this vector to the bounding radius. Note that the +y direction is up.

**Fifth**and finally, if the camera is indeed within the bounding radius of the current tree, we will add on just enough of

*v_vectorToCentre*to put it back outside the tree trunk. Once the loop is complete, we return the resulting position change. The process is fairly intuitive until the final step. This diagram explains the maths behind it a little clearer:

*tree*. In order to put the camera back outside of the bounding radius while simultaneously making it slide smoothly around the edge, we need to add a certain amount of the vector

*v_vectorToCentre*to the camera's position until it is once again outside the bounding radius, such that: In this equation, |

*v_vectorToCentre*| denotes the length of the vector between the camera position and the tree's centre. It is calculated using the

*D3DXVec2Length()*function. We are looking for the value of

*k*- that is, the linear multiple of

*v_vectorToCentre*which we should add to our camera position in order to put it back outside the bounding radius. In order to find the value of

*k*, we can first divide through by |

*v_vectorToCentre*|. This gives us: This can easily be rearranged to get: We have now calculated our value of

*k*. All that remains is to add this linear multiple of

*v_vectorToCentre*to our overall change in location (

*v_deltaPos*). If you review the fifth step in the function, you can see that this is exactly what is happening. If called every frame, this function will calculate a collision contribution for each tree in the loop. Once this contribution is acquired, it should be added to the camera position vector as follows:

```
//Call the function to assess collisions:
D3DXVECTOR2 v_camPosCollisionDelta = handle_Collisions_Radial();
//Since this function returns a D3DXVECTOR2 and our camera position is a D3DXVECTOR3, we
//will need to create a dummy D3DXVECTOR3 with no y-component to add to v_camPos:
D3DXVECTOR3 v_camPosCollisionDelta3D(v_camPosCollisionDelta.x, 0, v_camPosCollisionDelta.y);
//Finally, we will move the camera according to our collison delta vector:
v_camPos += v_camPosCollisionDelta3D;
//Now that we have our new camera position, we can continue to render the frame as normal...
```

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account## Sign in

Already have an account? Sign in here.

Sign In Now