Vector math problem

Oct 25, 2017 at 6:55pm
below is a function that (assuming a bullet impact) is intended to determine if a character was shot from in front or behind.

This is my solution:
1. Calculate length of vectors
2. Calculate the dot product between the two
3. plugin cosine formula to figure out the angle between both vectors

I am wondering what I am doing wrong here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  bool WasShotFromBehind(const Vec3D& bulletVelocity, const Vec3D& CharacterFacing)
{
// bullet vector length
	float bVecLength = sqrt(bulletVelocity.x * bulletVelocity.x + bulletVelocity.y * bulletVelocity.y + bulletVelocity.z * bulletVelocity.z);
	// character vector length
	float cVecLength = sqrt(CharacterFacing.x * CharacterFacing.x + CharacterFacing.y * CharacterFacing.y + CharacterFacing.z * CharacterFacing.z);
	
	// dot product of two vectors
	float dotProduct = bulletVelocity.x * CharacterFacing.x + bulletVelocity.y * CharacterFacing.y + bulletVelocity.z * CharacterFacing.z;

	float cosAngle = dotProduct / (bVecLength * cVecLength);
	if (cosAngle > 0)
            return true;

	return false;
}
Oct 25, 2017 at 7:01pm
do you have the positions of the bullet and char? that is much easier and faster to solve...

I will look deeper but busy for a bit..
Last edited on Oct 25, 2017 at 7:03pm
Oct 25, 2017 at 7:15pm
It doesn't look wrong. What kind of problems are you having?
Last edited on Oct 25, 2017 at 7:16pm
Oct 25, 2017 at 7:19pm
it always returns true.

I have a test case with:
CharacterFacing = {0, 0, 1}; // forward
bulletVelocity = { -1, 0, 1};

I believe this should be hitting the character from behind but it always returns true.
Oct 25, 2017 at 7:20pm
If all you need is whether cosAngle is positive or not ... then all you need is whether dotProduct is positive or not - you can avoid actually working out those two square roots.

I should think your function could be reduced to

1
2
3
4
bool WasShotFromBehind(const Vec3D& bulletVelocity, const Vec3D& CharacterFacing)
{
   return bulletVelocity.x * CharacterFacing.x + bulletVelocity.y * CharacterFacing.y + bulletVelocity.z * CharacterFacing.z > 0;
}


I have a test case with:
CharacterFacing = {0, 0, 1}; // forward
bulletVelocity = { -1, 0, 1};

I believe this should be hitting the character from behind but it always returns true.


Well, the dot product of those vectors is 1.0, so it returns true!
0 * (-1) + 0 * 0 + 1 * 1 = 0 + 0 + 1 = 1
Last edited on Oct 25, 2017 at 7:28pm
Oct 25, 2017 at 7:35pm
No, your code works properly.
You're right, for those coordinates, the bullet is hitting the character from the back so it returns true.

But for coordinates like
CharacterFacing = {0, 0, 1}
bulletVelocity = {-1, 0, -1}
It returns false.

Maybe you're having difficult time generating proper test cases?
Here's a bit of help to visualize it. (A - player, B - bullet)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
  z
  |
  *--x (y points downwards)

  B   A 
   \  | A = (0,  0,  1)
    \#| B = (-1, 0,  1)
     \| O = (0,  0,  0)
      O (angle < pi/2) -> (cos > 0) -> True

      A
      | A = (0,  0,  1)
      | B = (-1, 0 ,-1)
    ##| O = (0,  0,  0)
   ###O (angle > pi/2) -> (cos < 0) -> False
   ##/
    /
   /
  B
Last edited on Oct 25, 2017 at 7:36pm
Oct 25, 2017 at 7:37pm
Does this mean the fault is in my testing?
Oct 25, 2017 at 7:41pm
I believe this should be hitting the character from behind but it <always> returns true.


You believe this should be hitting the character from behind ...

and a function called WasShotFromBehind returns true ...

so where is the problem?
Oct 25, 2017 at 7:59pm
lastchance is right! You only need to check if dot product is greater than zero making the code that more efficient.

Does this mean the fault is in my testing?

Maybe, since like I said, your code was correct.
If you are making a FPS though, this probably isn't what you want since the bullet can hit you outside your Fov yet it would be detected as a frontal hit (see the picture bellow). And maybe that's why you though it was incorrect?
1
2
3
4
 \ fov /  _B
  \   / _/
   \ /_/
~~~~A~~~~

Perhaps you should elaborate a bit more on what exactly you're trying to do?
Last edited on Oct 25, 2017 at 8:01pm
Oct 25, 2017 at 10:37pm
thank you all so much
Topic archived. No new replies allowed.