This code is supposed to calculate and return the real part of a complex number with magnitude a and angle b in degrees. It gives me wrong numbers.
x = (a*(cos(b*(180/pi))));
This however, gives me the right numbers if the angle is given in radians.
x = (a*(cos(b)));
pi is defined as const double pi = 3.142
Any thoughts? I cannot see why the x should be wrong in the first but correct in the second example.
Since 180 degrees is 1 pi radian. The formula for degrees to radians should be
radian = (degree / 180) pi.
Thus the first formula should be
x = (a*(cos((b / 180)*pi))));
You have the conversion backwards: your formula changes b from radians to degrees before calculating its cosine. But you want to convert from degress to radians. The correct formula is
x = (a*(cos(b*(pi/180)));
though you could use fewer parentheses and use more spacing:
x = a * cos(b * pi / 180);
You are not using formula correctly
this can be written as:
x = (a*cos((b * pi)/180));
Related
I have two vectors and I want to get the angle between those vectors, I am currently doing it with this formula :
acos(dot(v1.unitVector, v2.unitVector))
Here is what I get with it :
I would want the green angle rather than the red angle, but I don't know what formula I should use...
Thank you.
EDIT : So, hen the vectors are still in a certain position (like the first two pairs of vectors, it's ok, but whenever it is in a configuration like in the third pair, it doesn't give me the right angle anymore)
With the dot product you get always an angle that is independent of the order of the vectors and the smaller of the two possibilities.
For what you want, you need the argument function of complex numbers that is realized by the atan2 function. The angle from a=ax+i*ay to b=bx+i*by is the argument of the conjugate of a times b (rotating b backwards by the angle of a, scale not considered), which in coordinates is
(ax-i*ay) * (bx+i*by) = ax*bx+ay*by + i*(ax*by-ay*bx)
so the angle is
atan2( ax*by-ay*bx, ax*bx+ay*by ).
Adding to the accepted answer, the problem with atan2 is that, if you imagine vector a being static and vector b rotating in anti-clockwise direction, you will see the return value ranging from 0 to π, but then it suddenly turns negative and proceeds from -π to 0, which is not exactly good if you're interested in an angle increasing from 0 to 2π.
To tackle that problem, the function below conveniently maps the result from atan2 and returns a value between 0 and 2π as one would expect:
const TAU = Math.PI * 2;
/**
* Gives the angle in radians from vector a to vector b in anticlockwise direction,
* ranging from 0 to 2π.
*
* #param {Vector} a
* #param {Vector} b
* #returns {Number}
*/
static angle(a, b) {
let angle = Math.atan2(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y);
if (angle < 0) {
angle += TAU;
}
return angle;
}
It is written in JavaScript, but it's easily portable to other languages.
Lutz already answered this correctly but let me add that I highly recommend basing modern vector math code on Geometric Algebra which raises the abstraction level dramatically.
Using GA, you can simply multiply the two vectors U and V to get a rotor. The rotor internally looks like A + Bxy where A = U dot V = |U|V|cos(angle) and Bxy = U wedge V = |U||V|sin(angle)xy (this is isomorphic to the complex numbers). Then you can return the rotor's signed CCW angle which is atan2( B, A ).
So with operator overloading, you can just type (u * v).Angle. The final calculations end up the same, but the abstraction level you think and work in is much higher.
Maybe this one is more fit:
atan2( ax*by-ay*bx, ax*bx+ay*by ) % (PI*2)
the calculation which could get the full anti-clockwise radian.
Could someone help me solve this problem? How can I find the angle shown in picture? I think I need to find angle between 2 vectors but im really bad at geometry.
http://i.stack.imgur.com/W0RKh.png
If you are developing your program in C++, then to calculating an angle between two vectors you can use the atan2 function, it is present in many programming languages.
You need to call atan2 giving it the two components of a single vector and then you make calculations this way:
Calculating for the first vector: atan2(v1_y, v1_x)
Calculating for the second vector: atan2(v2_y, v2_x)
Caution:
If the value returned by atan2 is negative (as atan2 returns value from range (-pi;+pi]), then you need to add 2 * pi to the result for each of the vector.
Finally you subtract the values of the vectors and what you get is the angle. The angle will be either positive or negative, depending which atan2 value you subtract from which one.
You need to normalize both vectors and then perform a dot product.
Step 1: Vector normalization:
A normalized vector has a length of 1. To achieve this, you divide its coordinates by its length:
float d = 1 / sqrt(X * X + Y * Y + Z * Z);
normalizedX = X * d;
normalizedY = Y * d;
normalizedZ = Z * d;
Note: The length is inversed and then multiplied instead of divided in order to increase performance.
Step 2: Dot product
After your normalized both vectors like in Step 1, you need to perform a dot product:
float angle = acos(x1 * x2 + y1 * y2 + z1 * z2);
The result is the cosine of the angle between the two vectors. After an acos you have your angle.
I am breaking my head trying to find an appropriate formula to calculate a what sounds to be an easy task but in practice is a big mathematical headache.
I want to find out the offset it needs to turn my vector's angle (X, Y, Angle) to face a coord ( X, Y )
My vector won't always be facing 360 degrees, so i need that as a variable as well..
Hoping an answer before i'm breaking my pc screen.
Thank you.
input
p1 = (x1,y1) point1 (vector origin)
p2 = (x2,y2) point2
a1 = 360 deg direction of vector
assuming your coodinate system is: X+ is right Y+ is up ang+ is CCW
your image suggest that you have X,Y mixed up (angle usually start from X axis not Y)
da=? change of a1 to match direction of p2-p1
solution 1:
da=a1-a2=a1-atanxy(x2-x1,y1-y1)
atanxy(dx,dy) is also called atan2 on some libs just make sure the order of operands is the right one
you can also use mine atanxy in C++
it is 4 quadrant arctangens
solution 2:
v1=(cos(a1),sin(a1))
v2=(x2-x1,y2-y1)
da=acos(dot(v1,v2)/(|v1|*|v2|))
or the same slightly different
v1=(cos(a1),sin(a1))
v2=(x2-x1,y2-y1)
v2/=|v2| // makes v2 unit vector, v1 is already unit
da=acos(dot(v1,v2))
so:
da=acos((cos(a1)*(x2-x1)+sin(a1)*(y2-y1)/sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)));
[notes]
just change it to match your coordinate system (which you did not specify)
use radians or degrees according to your sin,cos,atan dependencies ...
The difference between the vectors is also a vector.
Then calculate the tangens (y part / x part) and invert it to an angle.
Of course use the sign of y if x = 0.
if the coord to face is (x2 ,y2)
deltaY = y2 - y1
deltaX = x2 - x1
You have the angle in degrees between the two points using this formula...
angleInDegrees = arctan(deltaY / deltaX) * 180 / PI
subtract the original angle of your vector and you will get the correct offset!
I have a Vector2 in my 2D Game and what I would like to do now is set my vector2 x and y by calculating them using rotation in degrees
Do I need to use PI to calculate new X and Y coordinates then add move distance per second in order to get the correct coordinates?
Example : Lets say degree is 90, which means my gameobject would move forward,at 5 floating units per second, then Y would be 5,10,15 and if degree would be 180 then X would increase by 5 every second, this is simple, but how to do it for other degrees such as 38,268 etc?
The usual convention is that 0 degrees points in the positive X direction and as the angle increases you rotate the direction anti-clockwise. Your convention seems to be that 0 degrees points in the negative X direction and the angle increases clockwise, so first of all you must translate your angle, say alpha, into one with the usual convention, say beta
beta = 180.0 - alpha
Next, trigonometric functions assume radians which run from 0 to 2π rather than from 0 to 360, so you must translate beta into an angle in radians, say theta
theta = 2.0*PI*beta/360.0
Finally, cos(theta) gives the change in X for a move of 1 unit in the direction given by theta and sin(theta) gives the change in Y. So you need
X = X + D * cos(theta)
Y = Y + D * sintheta)
for a distance D. Using your convention this translates to
X = X + D * cos(2.0*PI*(180.0-alpha)/360.0)
Y = Y + D * sin(2.0*PI*(180.0-alpha)/360.0)
What is the inverse of the function
math.atan2
I use this in Lua where I can get the inverse of math.atan by math.tan.
But I am lost here.
EDIT
OK, let me give you more details.
I needed to calculate angle between 2 points (x1,y1) and (x2,y2) and I did,
local dy = y1-y2
local dx = x1-x2
local angle = atan2(dy,dx)* 180 / pi
Now if I have the angle, is it possible to get back dy and dx?
Given only the angle you can only derive a unit vector pointing to (dx, dy). To get the original (dx, dy) you also need to know the length of the vector (dx, dy), which I'll call len. You also have to convert the angle you derived from degrees back to radians and then use the trig equations mentioned elsewhere in this post. That is you have:
local dy = y1-y2
local dx = x1-x2
local angle = atan2(dy,dx) * 180 / pi
local len = sqrt(dx*dx + dy*dy)
Given angle (in degrees) and the vector length, len, you can derive dx and dy by:
local theta = angle * pi / 180
local dx = len * cos(theta)
local dy = len * sin(theta)
Apparently, something like this will help:
x = cos(theta)
y = sin(theta)
Simple Google search threw this up, and the guy who asked the question said it solved it.
You'll probably get the wrong numbers if you use:
local dy = y1-y2
local dx = x1-x2
local angle = atan2(dy,dx) * 180 / pi
If you are using the coordinate system where y gets bigger going down the screen and x gets bigger going to the right then you should use:
local dy = y1 - y2
local dx = x2 - x1
local angle = math.deg(math.atan2(dy, dx))
if (angle < 0) then
angle = 360 + angle
end
The reason you want to use this is because atan2 in lua will give you a number between -180 and 180. It will be correct until you hit 180 then as it should go beyond 180 (i.e. 187) it will invert it to a negative number going down from -180 to 0 as you get closer to 360. To correct for this we check to see if the angle is less than 0 and if it is we add 360 to give us the correct angle.
According this reference:
Returns the arc tangent of y/x (in radians), but uses the signs of
both parameters to find the quadrant of the result. (It also handles
correctly the case of x being zero.)
So I guess you can use math.tan to invert it also.
As atan2 works as tan-1, so the inverse could be tan, taking into consideration conversion between radian and degree