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=numbersExamples
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
Calling Class Staticmethod Within the Class Body
Plotting a 2D Heatmap with Matplotlib
Given a Url to a Text File, What Is the Simplest Way to Read the Contents of the Text File
How to Forward-Declare a Function to Avoid 'Nameerror's for Functions Defined Later
Multi-Level Defaultdict with Variable Depth
How to See If There's an Available and Active Network Connection in Python
Read File from Line 2 or Skip Header Row
List VS Generator Comprehension Speed with Join Function
Differencebetween 'Same' and 'Valid' Padding in Tf.Nn.Max_Pool of Tensorflow
How to Trim Whitespace from a String
Color by Column Values in Matplotlib
Finding a Key Recursively in a Dictionary
How to Find the Location of Python Module Sources
How to Check a String for Specific Characters