How to Know the Angle Between Two Vectors

Calculating angle between two vectors?

If I see it correctly, the formula

angle = atan2(x, -y) * 180.0/M_PI;

should work in all quadrants, making all the if statements unnecessary.


atan2(y, x) returns the angle between the vector (x, y) and the positive x-axis, the return value is always between -pi and pi.

Replacing (y, x) by (x, -y) in the arguments
means that the vector is rotated by 90 degrees, therefore the result of the above formula
is the angle measured to the negative y-axis, which is what you wanted.


Update (according to "edit2" in the question): If the requirement is "south = 0 deg", "east = -90 deg", "west = +90 deg" then the formula would be

angle = atan2(-x, -y) * 180.0/M_PI;

How to calculate obtuse angle between two vectors?

Before applying acos, check if the dot product is negative. If negative, the angle is obtuse :)

Further, as acos has a range of 0 to pi, you will do fine as long as you do not want reflex angles (>pi)

how to calculate angle between two vectors code in php

function norm($vec)
{
$norm = 0;
$components = count($vec);

for ($i = 0; $i < $components; $i++)
$norm += $vec[$i] * $vec[$i];

return sqrt($norm);
}

function dot($vec1, $vec2)
{
$prod = 0;
$components = count($vec1);

for ($i = 0; $i < $components; $i++)
$prod += ($vec1[$i] * $vec2[$i]);

return $prod;
}

And to calculate the actual angle:

$v1 = array(-1, -2);
$v2 = array(90, -5);

$ang = acos(dot($v1, $v2) / (norm($v1) * norm($v2)));

echo $ang; // angle in radians
> 1.97894543055

Fastest way to find the angle between two points

As angle(v1, v2) = acos( (v1x * v2x + v1y * v2y) / (sqrt(v1x^2+v1y^2) * sqrt(v2x^2+v2y^2)) ) and we know v2 = [1, 0]

var v = {x: 0, y: 1},
angleRad = Math.acos( v.x / Math.sqrt(v.x*v.x + v.y*v.y) ),
angleDeg = angleRad * 180 / Math.PI;

where v is the vector [point2.x - point1.x , point2.y - point1.y]


Edit - I just realised you may have meant treat each point as a vector, in which case it'd be

var v1 = {x: 0, y: 1}, v2 = {x: 1, y: 0},
angleRad = Math.acos( (v1.x * v2.x + v1.y * v2.y) / ( Math.sqrt(v1.x*v1.x + v1.y*v1.y) * Math.sqrt(v2.x*v2.x + v2.y*v2.y) ) ),
angleDeg = angleRad * 180 / Math.PI;

where v1 is the vector [point1.x , point1.y] and v2 is [point2.x , point2.y]


Edit 2

To speed up if you're using the vectors length many times, save it as e.g. v.length = ... so you can get it without re-calculating again.
If you know every vector will need it's angles calculated multiple times, use the first method I wrote and cache it, i.e. v.angle = .... You can then you can do v2.angle - v1.angle to find angle between the two, etc.

i.e. have

function Vector(x, y){
this.x = x;
this.y = y;
this.length = Math.sqrt(x*x + y*y);
this.angle = Math.acos( x / this.length );
}

jsperf of pre-computing and finding in an array of 3601 items vs using acos directly

Calculating the angle between a line and the x-axis

Assumptions: x is the horizontal axis, and increases when moving from left to right.
y is the vertical axis, and increases from bottom to top. (touch_x, touch_y) is the
point selected by the user. (center_x, center_y) is the point at the center of the
screen. theta is measured counter-clockwise from the +x axis. Then:

delta_x = touch_x - center_x
delta_y = touch_y - center_y
theta_radians = atan2(delta_y, delta_x)

Edit: you mentioned in a comment that y increases from top to bottom. In that
case,

delta_y = center_y - touch_y

But it would be more correct to describe this as expressing (touch_x, touch_y)
in polar coordinates relative to (center_x, center_y). As ChrisF mentioned,
the idea of taking an "angle between two points" is not well defined.

Calculating the angle between two vectors

Given a offset vector (relative to 0,0,0 for instance)

float resultInDegrees = (360 + Mathf.Atan2(rotateVector.x, rotateVector.z) * (180 / Mathf.PI)) % 360;

Note that we're adding 360 and taking the modulus of the result, otherwise you'll get from 0 - 180, then negative angles.. This converts -1 degrees to 359 degrees, as the original poster had requested.

How to calculate the angle between two vectors?

The denominator was having the problem.

int num = (vx*ux + vy*uy);
double den = (Math.sqrt(Math.pow(vx, 2) + Math.pow(vy, 2)) * (Math.sqrt(Math.pow(ux, 2) + Math.pow(uy, 2))) );
double cos = num / den;
System.out.println(cos);
System.out.println(Math.acos(cos));

How to know the angle between two vectors?

The tangent of the angle between two points is defined as delta y / delta x
That is (y2 - y1)/(x2-x1). This means that math.atan2(dy, dx) give the angle between the two points assuming that you know the base axis that defines the co-ordinates.

Your gun is assumed to be the (0, 0) point of the axes in order to calculate the angle in radians. Once you have that angle, then you can use the angle for the remainder of your calculations.

Note that since the angle is in radians, you need to use the math.pi instead of 180 degrees within your code. Also your test for more than 360 degrees (2*math.pi) is not needed. The test for negative (< 0) is incorrect as you then force it to 0, which forces the target to be on the x axis in the positive direction.

Your code to calculate the angle between the gun and the target is thus

myradians = math.atan2(targetY-gunY, targetX-gunX)

If you want to convert radians to degrees

mydegrees = math.degrees(myradians)

To convert from degrees to radians

myradians = math.radians(mydegrees)

Python ATAN2

The Python ATAN2 function is one of the Python Math function which is
used to returns the angle (in radians) from the X -Axis to the
specified point (y, x).

math.atan2()

Definition Returns the tangent(y,x) in radius.

Syntax
math.atan2(y,x)

Parameters
y,x=numbers

Examples
The return is:

>>> import math  
>>> math.atan2(88,34)
1.202100424136847
>>>

How to find out if the angle between two vectors is external or internal?

You're looking for the atan2(y,x) function (http://en.wikipedia.org/wiki/Atan2). If you give it the two components of a 2D vector, it will give you the angle of the vector from the x axis, in the counter-clockwise direction. To solve your specific problem try:

atan2(v_y, v_x) - atan2(u_y, u_x)

Then you can add or subtract 360 degrees if the answer is out of the range of angles you desire.

Direct way of computing clockwise angle between 2 vectors

2D case

Just like the dot product is proportional to the cosine of the angle, the determinant is proprortional to its sine. So you can compute the angle like this:

dot = x1*x2 + y1*y2      # dot product between [x1, y1] and [x2, y2]
det = x1*y2 - y1*x2 # determinant
angle = atan2(det, dot) # atan2(y, x) or atan2(sin, cos)

The orientation of this angle matches that of the coordinate system. In a left-handed coordinate system, i.e. x pointing right and y down as is common for computer graphics, this will mean you get a positive sign for clockwise angles. If the orientation of the coordinate system is mathematical with y up, you get counter-clockwise angles as is the convention in mathematics. Changing the order of the inputs will change the sign, so if you are unhappy with the signs just swap the inputs.

3D case

In 3D, two arbitrarily placed vectors define their own axis of rotation, perpendicular to both. That axis of rotation does not come with a fixed orientation, which means that you cannot uniquely fix the direction of the angle of rotation either. One common convention is to let angles be always positive, and to orient the axis in such a way that it fits a positive angle. In this case, the dot product of the normalized vectors is enough to compute angles.

dot = x1*x2 + y1*y2 + z1*z2    #between [x1, y1, z1] and [x2, y2, z2]
lenSq1 = x1*x1 + y1*y1 + z1*z1
lenSq2 = x2*x2 + y2*y2 + z2*z2
angle = acos(dot/sqrt(lenSq1 * lenSq2))

Edit: Note that some comments and alternate answers advise against the use of acos for numeric reasons, in particular if the angles to be measured are small.

Plane embedded in 3D

One special case is the case where your vectors are not placed arbitrarily, but lie within a plane with a known normal vector n. Then the axis of rotation will be in direction n as well, and the orientation of n will fix an orientation for that axis. In this case, you can adapt the 2D computation above, including n into the determinant to make its size 3×3.

dot = x1*x2 + y1*y2 + z1*z2
det = x1*y2*zn + x2*yn*z1 + xn*y1*z2 - z1*y2*xn - z2*yn*x1 - zn*y1*x2
angle = atan2(det, dot)

One condition for this to work is that the normal vector n has unit length. If not, you'll have to normalize it.

As triple product

This determinant could also be expressed as the triple product, as @Excrubulent pointed out in a suggested edit.

det = n · (v1 × v2)

This might be easier to implement in some APIs, and gives a different perspective on what's going on here: The cross product is proportional to the sine of the angle, and will lie perpendicular to the plane, hence be a multiple of n. The dot product will therefore basically measure the length of that vector, but with the correct sign attached to it.



Related Topics



Leave a reply



Submit