Calculate the angle from two points and the direction vector

I have two vectors in the game. One vector is a player, one vector is an object. I also have a vector that determines the direction of the player, if he is facing. The direction vector does not have a z-part. This is a point that has a value of 1, located somewhere around the origin.

I want to calculate the angle between the direction the soldier is in and the object, so I can correctly pan some sound (stereo only).

The diagram below describes my problem. I want to calculate the angle between two dashed lines. One dashed line connects the player and the object, and the other a line representing the direction the player is facing from the point the player is at.

Angle problemm

I'm currently doing this (suppose the player, object and direction are all vectors with three points, x, y and z):

Vector3d v1 = direction; Vector3d v2 = object - player; v1.normalise(); v2.normalise(); float angle = acos(dotProduct(v1, v2)); 

But that seems to give me the wrong results. Any tips?

Code Verification:

 Vector3d soldier = Vector3d(1.f, 1.f, 0.f); Vector3d object = Vector3d(1.f, -1.f, 0.f); Vector3d dir = Vector3d(1.f, 0.f, 0.f); Vector3d v1 = dir; Vector3d v2 = object - soldier; long steps = 360; for (long step = 0; step < steps; step++) { float rad = (float)step * (M_PI / 180.f); v1.x = cosf(rad); v1.y = sinf(rad); v1.normalise(); float dx = dotProduct(v2, v1); float dy = dotProduct(v2, soldier); float vangle = atan2(dx, dy); } 
+4
source share
2 answers

When calculating the angular delta, you always use atan2 and then normalize. The reason is that, for example, acos - a function with domain -1 ... 1; even if it normalizes, if the input absolute value (due to approximations) becomes greater than 1, the function will fail, even if it is clear that in this case you would like the angle 0 or PI. In addition, acos cannot measure the full range of -PI..PI, and you will need to explicitly use tests to find the correct quadrant.

Instead of atan2 only feature is in (0, 0) (where, of course, there is no point in calculating the angle), and its codename is the full circle -PI ... PI.

Here is an example in C ++

 // Absolute angle 1 double a1 = atan2(object.y - player.y, object.x - player.x); // Absolute angle 2 double a2 = atan2(direction.y, direction.x); // Relative angle double rel_angle = a1 - a2; // Normalize to -PI .. +PI rel_angle -= floor((rel_angle + PI)/(2*PI)) * (2*PI) - PI; 

In the case of a general three-dimensional orientation, you need two orthogonal directions, for example. the vector where the nose points, and the vector where your right ear is located. In this case, the formulas are a little more complicated, but easier if you have a point product:

 // I'm assuming that '*' is defined as the dot product // between two vectors: x1*x2 + y1*y2 + z1*z2 double dx = (object - player) * nose_direction; double dy = (object - player) * right_ear_direction; double angle = atan2(dx, dy); // Already in -PI ... PI range 

enter image description here

+9
source

In 3D space, you also need to calculate the axis :

 Vector3d axis = normalise(crossProduct(normalise(v1), normalise(v2))); 
+1
source

Source: https://habr.com/ru/post/1338152/


All Articles