3
\$\begingroup\$

If I have two objects, Person A and Person B, and I want to know if Person B is facing the same direction as Person A; once I have the vectors, how do I use the normalized vector to show direction?


I've read the math on vectors, but I'm still learning, and I am not understanding how the unit vector shows direction. I know it does, but I don't know why.

One person said they imagine it on the unit circle. I understand how that can show a direction, but what I don't understand is how the normalized vector shows me a direction.

I have seen "What is a direction vector and why should it be normalized?", but I am still missing it.

\$\endgroup\$
6
  • \$\begingroup\$ All vectors show direction, it doesn't have to be normalized. A vector contains both direction and magnitude; normalizing it removes the magnitude component so that it's direction only, which then makes it useful in certain calculations. \$\endgroup\$ Commented Jan 1, 2017 at 9:41
  • \$\begingroup\$ @LeComteduMerde-fou the only exceptions are the zero-length vectors :P \$\endgroup\$
    – Vaillancourt
    Commented Jan 1, 2017 at 14:57
  • \$\begingroup\$ @Gnemlock The original text had a question that was talking about objects facing the same direction. This is what half of my answer is about, and I think it should be included in the text. \$\endgroup\$
    – Lasse
    Commented Jan 2, 2017 at 6:14
  • \$\begingroup\$ Do you wish to know if A is facing B, or if A and B are facing the same direction (e.g. both facing north)? \$\endgroup\$ Commented Jan 2, 2017 at 9:09
  • \$\begingroup\$ @Lasse, I'm not entirely sure I understand what you mean. All edits (mine and the other) have been grammar and punctuation improvements; in fact, the part about 'finding if two objects are facing the same direction' is still mostly intact. The only changes to this part were to correct incorrect capitalisation and replace symbols with the correct words. \$\endgroup\$
    – Gnemlock
    Commented Jan 2, 2017 at 9:13

1 Answer 1

11
\$\begingroup\$

First we get a vector from B to A, as in the following picture:

A vector from B to A

Now we have a vector that tells us how to get exactly from B to A. In code it looks something along these lines:

var BtoA = A - B;

In the above image's case, the resulting vector is X:15 Y:-20. At this point we actually already know the direction, as it is included in the information of how to get from B to A. Then if we need to know just the direction, we get that by normalizing the vector we have:

var direction = normalize(BtoA);

Normalizing a vector does this to it:

vec2 normalize(vec2 v)
{
    return v / sqrt(v.x * v.x + v.y * v.y);
}

To break it down, first we get the length (aka magnitude) of the vector by Pythagorean theorem which you probably have learned at school. After we have the length of the vector, we divide the original vector by it's own length to make it a unit vector. In other words, we reduce the length of BtoA into just one, which makes it an unit vector.

Now we have a direction vector that looks like this:

Unit vector

And the resulting unit vector is X:0.6 Y:-0.8. If you want to make sure, you can check it's length, which should be 1:

var v = vec2(0.6, -0.8);
var length = sqrt(v.x * v.x + v.y * v.y);
print(length); // Should print 1

Now at this point, the unit vector we got from normalizing the BtoA vector is now just pointing at the direction of A from the point of B.

Basically we have only reduced the length of the BtoA vector to 1, which is why it is just pointing at the direction of A from the viewpoint of B.

And then as you asked, how to figure out if person B is facing at the same direction of person A, you need to know the orientation of person B and A. You don't get that just by calculating the direction to A from B.

Orientation of B

The orientation is found by first figuring out the orientation vector of B, which you can calculate if you have the rotation angle of B:

var rotation = 1.5708; // 90 degrees in radians, radians are easier in code
var orientationVec = vec2(sin(rotation), cos(rotation));

Orientation Vector of B

Now the orientation vector should be X:0 Y:1, because it is in 90 degree angle. Now that we have the orientation of B, we can check if it is facing A by checking the dot product:

var facing = dot(direction, orientationVec);
if(facing > 0)
    print("Yes, the B vector is roughly facing A");

What is a dot product then? It looks like this:

float dot(vec2 a, vec2 b)
{
    return a.x * b.x + a.y * b.y;
}

The dot product has a property of telling if two unit vectors are in parallel, and if not how much they differ. If the dot product is 1, the two unit vectors are pointing exactly at the same direction. If it is 0, the unit vectors are perpendicular to each other. So any values above 0 means that the unit vectors are going in roughly the same direction.

The dot product

Of course using 0 as a threshold for determining if B is facing A is a bit wrong here, as you are talking about a person. If you define that a person is facing the other when the orientation towards the other is in 90 degree range, you can just check if the facing value is more than 0.5, which probably gives better results. You can also define that a person is facing another only when they are exactly looking at the other, which then requires you to use a value very close to 1.

So to put it all together:

bool IsBFacingA(vec2 A, vec2 B, float bRotation, float tolerance)
{
    var BtoA = A - B;
    var dir = normalize(BtoA);
    var orientation = vec2(sin(bRotation), cos(bRotation));
    var facing = dot(dir, orientation);
    return facing >= tolerance;
}

Now you can tell if B is facing A. It requires a bit more than just the normalized direction from B to A.

But this still does not answer your question.

You can use all that information to determine if A and B are facing the same direction, by getting the orientation of both A and B and comparing them with the dot product. Like this:

bool IsBFacingTheSameDirectionAsA(float aRotation, float bRotation, float tolerance)
{
    var aOrientation = vec2(sin(aRotation), cos(aRotation));
    var bOrientation = vec2(sin(bRotation), cos(bRotation));
    var facing = dot(aOrientation , bOrientation );
    return facing >= tolerance;
}

And there you go, that is how you determine if A and B are facing the same direction.

\$\endgroup\$
6
  • \$\begingroup\$ This is great. Thank you. What I don't understand is how "if you have the rotation angle of B:" How do I get that? I think I am considering this as stationary set of points, no one is turning. They're just two points on a graph. I don't turn them at all (in this example.) Are you saying, when, for example, someone hits the left button then I get an angle of rotation? \$\endgroup\$
    – johnny
    Commented Jan 2, 2017 at 2:16
  • \$\begingroup\$ The angle is a value on the object you have defined in your program. And yes, it can be something that changes when the player hits the left button. \$\endgroup\$
    – Lasse
    Commented Jan 2, 2017 at 6:12
  • \$\begingroup\$ @johnny If you consider them as only points, then how would your question even make sense? "Person B is facing the same direction as Person A". How can mere points face anywhere? There has to be a separate vector to say where the points' forward is. \$\endgroup\$
    – eclmist
    Commented Jan 2, 2017 at 10:57
  • \$\begingroup\$ @Sam That's my point, no pun intended. I was looking at it as nothing but points. I think everyone else was looking at it in the context of a game where two objects turned and faced a given direction. I was not. \$\endgroup\$
    – johnny
    Commented Jan 5, 2017 at 3:13
  • \$\begingroup\$ @johnny, I don't think you understand what I'm saying. First of all, you ask this in gamedev.stackexchange. Not math.stackexchange, or something similar. Of course we would look at it in the context of game development. Secondly, your question makes zero sense if you are looking at it as nothing but points. Game context or not. \$\endgroup\$
    – eclmist
    Commented Jan 5, 2017 at 15:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .