1
\$\begingroup\$

Im developing a game which has a flying chopper and an enemy firing bullets at it. Whats the best way to detect when the bullet hits the bounds of the chopper. The chopper is placed to the left of screen, continously rotating around its center. Bullet is fired from the right, always in a straight line. Im using Marix post rotate and translate for the choppers rotation.To make it simpler, I just want to consider the chopper to be a rectangle. Lets say im not bothered about any more precision in terms of specific hit points.

\$\endgroup\$
  • 1
    \$\begingroup\$ "To make it simpler, I just want to consider the chopper to be a rectangle." To make it simpler compared to what? Are you aware that circle collisions are much simpler? Would the rect shown in this gif be precise enough? Could you post a screenshot of your game, just to clarify the situation? \$\endgroup\$ – Tyyppi_77 Aug 20 '16 at 17:21
  • \$\begingroup\$ Thanks - u see,what I meant was - Im not concerned which part of the chopper is hit. The chopper image is just a nxn matrix so hitting its bounds may not realistically be hitting the actual chopper image since there could be empty pixels surrounding the actual chopper image in the Bitmap. But still Im ok with that. I just want to make it simple by checking if any part of the bounding rectangle is hit. \$\endgroup\$ – Bloke Aug 20 '16 at 18:03
1
\$\begingroup\$

Checking if a point is inside a rectangle is easier when the rectangle is not rotated. You just have to check if the position of the point on the x axis is between the mininum and the maximum of the rectangle, then you do the same on the y axis.

This image shows how it works for the x axis. The blue point is between the min and the max of the rectangle. The red isn't.

projection on x

Example code:

if(point.x > bottom_left.x && point.x < top_right.x 
&& point.y > bottom_left.y && point.y < top_right.y)
{
    // the point is inside
}

To check if a point is inside a rotated rectangle you first rotate everything so that the rectangle is aligned with the axes. Then you do the same thing as before.

Note that you don't have to rotate the rectangle. You can use the coordinates before it was rotated. You just have to rotate the point by minus the angle of the rectangle, around the center of rotation of the rectangle.

enter image description here

To rotate a point around another point you do the following:

Vec2 Rotate(Vec2 point, float angle, Vec2 center_of_rotation)
{
    float sinus   = sin(angle)
    float cosinus = cos(angle);
    Vec2 temp;

    point  = point - center_of_rotation;
    temp.x = point.x * cosinus - point.y * sinus;
    temp.y = point.x * sinus   + point.y * cosinus;
    point  =  temp + center_of_rotation;

    return point;
}

If you're using matrices for your transformations you can use the inverse to find the position of the point.

\$\endgroup\$
  • \$\begingroup\$ I'm going to upvote this because it's the closest answer. As mentioned in the last statement, if your using a matrix than inversion is the key. Ala reversing the transformation. The helicopter itself has been transformed from Model space to World space. What ever mechanism used to transform into world NEEDS to be able to be reversed. If you can reverse/invert it, then it means the bullets themselves can then be transformed into model space. This makes your tests so much easier (and means you can use many other methods). \$\endgroup\$ – ErnieDingo Jul 8 '18 at 22:00
0
\$\begingroup\$

Calculate the inverse transform matrix of the chopper.

Transform the bullet's world position by that matrix (world-space -> object-space)

Check if the resulting coordinate is within the untransformed (axis aligned) bounding rectangle in object-space (aka local-space).

\$\endgroup\$
  • \$\begingroup\$ thanks but I dont get it - I have the choppers bottom left corner and bottom right corner coords. I also have the bullets coords. So a chopper at screen left and bullet fired from screen right to left. Lets say the chopper is rotated at -45 degrees. I tried doing tan(angle) * (bullet.y-chopperBottomRight.y) to get the distance of the adjacent side to find if the bullet has crossed over after hitting the hypotenuse formed after the choppers tilt. But no luck. \$\endgroup\$ – Bloke Aug 21 '16 at 4:24
  • \$\begingroup\$ en.wikipedia.org/wiki/Rotation_matrix \$\endgroup\$ – Stephane Hockenhull Aug 21 '16 at 17:31
0
\$\begingroup\$

A very very easy way to check for polygon-point collision is to use area calculations.

The point and the edges of the rectangle define 4 triangles. You can calculate the area of these triangles by calculating the distance from the point to the endpoints of the edges and using the sinus law:

triangle_area = 1/2 * a * b * sin P

Where a and b are the distances and P is the angle at the point.

You then add these areas together. If the sum is bigger than the area of the rectangle, then the point is outside, if it equals the area, then it's inside.

This isn't a cheap way to calculate this though, so if you use this, do a broad phase before.

\$\endgroup\$
0
\$\begingroup\$

The way this is usually done, because it avoids the any trig, is to take dot products of the line from the bullet to center of the box with each of the boxes axes. If the absolute value of any of the dot products is greater than half the dimensions of the box along the corresponding axis, then the point is outside the box.

\$\endgroup\$
-2
\$\begingroup\$

I'm assuming you are using Unity 5 for this, but it's possible that other game engines might have collision detection work in a similar or same way as this.

You should use OnTriggerEnter, because what you can do with it is not only deduct the helicopter's health, but also destroy the bullet object that still exists even after the collision.

You could also use OnCollisionEnter, but I think it's more for when you want to deform the helicopter as the collision occurs. Since you are only using a single image for your chopper, I think it's a little impractical to use this approach.

\$\endgroup\$
  • \$\begingroup\$ thanks - but no unity - android 2.1 studio.. But my point is to understand the Math \$\endgroup\$ – Bloke Aug 21 '16 at 4:25
  • 2
    \$\begingroup\$ You can't just assume he's using a game engine... \$\endgroup\$ – Bálint Mar 18 '17 at 12:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.