InteractiveMind
asked on
Calculate angle of line, relative to a vertical
Hi :)
Okay, I have a graph, with (for example) the following two lines:
a = (0, 0) to (0, 4)
b = (0, 0) to (4, 4)
Line 'a' will always be vertical.
Now, I need to calculate the angle (clockwise) between these two lines (ultimately, I need either an equation or algorithm).
I came up with this:
angle = tan^-1 ( 1 / m )
where m = the gradient of line 'b'
But, this equation only applies when 'm' is positive. Whereas I require the equation to function correctly even when the m is negative.
I've tried using a combination of vector's and the Cosine rule, but I can't get it to work.
I know this is rather easy stuff (for you lot at least), but I just can't get it to work lol -- it's soo frustrating. Anyone got a solution please?
Thanks in advance,
>> IM
Okay, I have a graph, with (for example) the following two lines:
a = (0, 0) to (0, 4)
b = (0, 0) to (4, 4)
Line 'a' will always be vertical.
Now, I need to calculate the angle (clockwise) between these two lines (ultimately, I need either an equation or algorithm).
I came up with this:
angle = tan^-1 ( 1 / m )
where m = the gradient of line 'b'
But, this equation only applies when 'm' is positive. Whereas I require the equation to function correctly even when the m is negative.
I've tried using a combination of vector's and the Cosine rule, but I can't get it to work.
I know this is rather easy stuff (for you lot at least), but I just can't get it to work lol -- it's soo frustrating. Anyone got a solution please?
Thanks in advance,
>> IM
drawing these lines then clearly tan(theta) is clearly 1, ie the angle is 45o
ASKER
Yes, I came to that conclusion.. but I need an equation/algorithm which can calculate the angle between 'a' and another line (with any gradient)..
So, if 'b' = (0,0) to (3,-2)
the equation:
tan(theta) = 1 / (m = -0.666666 )
doesn't work.
I need an equation that works for *all* possible vectors of 'b'.. including: b = (0,0) to (5,0)
Cheers,
So, if 'b' = (0,0) to (3,-2)
the equation:
tan(theta) = 1 / (m = -0.666666 )
doesn't work.
I need an equation that works for *all* possible vectors of 'b'.. including: b = (0,0) to (5,0)
Cheers,
Forget about slopes and arctangents. You have to deal with infinites and ambiguities.
Convert your b vector to polar coordinates: (X, Y) = (r, theta)
That will give you an unambiguous angle, measured counterclockwise from the X-axis.
Then you can just do a subtraction.
Convert your b vector to polar coordinates: (X, Y) = (r, theta)
That will give you an unambiguous angle, measured counterclockwise from the X-axis.
Then you can just do a subtraction.
ASKER
I've tried using Vectors and the Cosine rule together, like so:
Example
-----------
'a' and 'b' are both vectors (expressed as column vectors)
a = 0
~ 5
b = -3
~ -2
The tail of vector 'a' is in contact with the tail of vector 'b'.
Now, I've decided to create a triangle, so that I can use the Cosine rule to calculate the angle.. So, I've got to add a third Vector, from the nose of vector 'a' to the nose of vector 'b':
c = b - a
~ ~ ~
From those vectors, we can calculate their lengths:
a = 5
~
b = 3^2 + 2^2 = 13
~
c = b - a = 13 - 5 = 8
~ ~ ~
Without even moving onto the Cosine stuff, I can see that this is wrong; because vector 'c' has to be longer than vector 'a' and 'b' (because if you draw vectors 'a' and 'b', you can see that the angle 'ab' is greater than 90 degrees).
But even if I were to work with those figures, like below, it gives a result which is clearly incorrect:
theta = cos^-1 ( ( 5^2 + 13^2 - 8^2) / 2(5)(13) ) = 0
I'm puzzled.
>> IM
Example
-----------
'a' and 'b' are both vectors (expressed as column vectors)
a = 0
~ 5
b = -3
~ -2
The tail of vector 'a' is in contact with the tail of vector 'b'.
Now, I've decided to create a triangle, so that I can use the Cosine rule to calculate the angle.. So, I've got to add a third Vector, from the nose of vector 'a' to the nose of vector 'b':
c = b - a
~ ~ ~
From those vectors, we can calculate their lengths:
a = 5
~
b = 3^2 + 2^2 = 13
~
c = b - a = 13 - 5 = 8
~ ~ ~
Without even moving onto the Cosine stuff, I can see that this is wrong; because vector 'c' has to be longer than vector 'a' and 'b' (because if you draw vectors 'a' and 'b', you can see that the angle 'ab' is greater than 90 degrees).
But even if I were to work with those figures, like below, it gives a result which is clearly incorrect:
theta = cos^-1 ( ( 5^2 + 13^2 - 8^2) / 2(5)(13) ) = 0
I'm puzzled.
>> IM
ASKER
Ah, let me just read your comment d-glitch...
ASKER
Hmm.. I'm a little unclear..
In: (X, Y) = (r, theta)
What does the 'r' represent? And could you please provide an example to demonstrate this?
Cheers :)
>> IM
In: (X, Y) = (r, theta)
What does the 'r' represent? And could you please provide an example to demonstrate this?
Cheers :)
>> IM
A = (0, 4) ==> rA=4
unit vector = (0, 1) ==> thetaA=90
B = (4, 4) ==> rB= sqrt(32)
unit vector (1/sqrt(2), 1/sqrt(2)) ==> thetaB=45
The unit vector is always (X/mag, Y/mag)
arccos( theta) = X/mag has two solutions.
arcsin( theta) = Y/mag has ttwo solutions.
One of the solutions will work for both.
unit vector = (0, 1) ==> thetaA=90
B = (4, 4) ==> rB= sqrt(32)
unit vector (1/sqrt(2), 1/sqrt(2)) ==> thetaB=45
The unit vector is always (X/mag, Y/mag)
arccos( theta) = X/mag has two solutions.
arcsin( theta) = Y/mag has ttwo solutions.
One of the solutions will work for both.
Your algorithm should check the value m, it must not be zero or infinite.
If m = zero, you know the angle is Pi/2,
If m = infinite, you know the angle is 0 or Pi
(if b= (0,Y(b)) where Y(b) is positive, then the angle is 0),
otherwise, you can use
angle = (Pi/2)*{[(m-abs(m)]/2m)} + arctan[abs(1/m)]
If m = zero, you know the angle is Pi/2,
If m = infinite, you know the angle is 0 or Pi
(if b= (0,Y(b)) where Y(b) is positive, then the angle is 0),
otherwise, you can use
angle = (Pi/2)*{[(m-abs(m)]/2m)} + arctan[abs(1/m)]
A vector can be expressed in Cartesian coordiantes (x, y)
or in polar coordinates (r, theta) (magnitude, direction)
direction has to be a vector of length=1 (a unit vector)
[ cos(theta), sin(theta)] is the standard unit vector.
It points in direction theta and it is one unit long since cos^2 + sin^2 = 1
r is the magnitude of the vector r = sqrt( x^2 + y^2)
or in polar coordinates (r, theta) (magnitude, direction)
direction has to be a vector of length=1 (a unit vector)
[ cos(theta), sin(theta)] is the standard unit vector.
It points in direction theta and it is one unit long since cos^2 + sin^2 = 1
r is the magnitude of the vector r = sqrt( x^2 + y^2)
ASKER
> "r = sqrt( x^2 + y^2)"
what happens when x and y are negative? (r = sqrt( x^2 + y^2) = sqrt(-3^2 - 2^2) = sqrt(-13) = ?)
what happens when x and y are negative? (r = sqrt( x^2 + y^2) = sqrt(-3^2 - 2^2) = sqrt(-13) = ?)
(-3, -2) ==> r = sqrt( -3^2 + -2^2) = sqrt( 9 +4) = sqrt( 13)
Magnitude is always guranteed to be positve. That's the great thing about it.
You will find the direction of the unit vector between 180 a 270 degrees.
Magnitude is always guranteed to be positve. That's the great thing about it.
You will find the direction of the unit vector between 180 a 270 degrees.
ASKER
lol Ah yeah, of course! When I type it into my calculator, it says "Math Error" (...and that's what caused me to think so stupidly).
lol -- I'll get back to you all on this later.
Cheers,
>> IM
lol -- I'll get back to you all on this later.
Cheers,
>> IM
a = (0, 0) to (0, 4)
b = (0, 0) to (4, 4)
the angle between to vectors is
arccos(a dot b / sqrt(a dot a * b dot b))
the dot product of two vectors is (ax*bx+ay*by)
a = (0-0,4-0)
b = (4-0,4-0)
a dot b = 4*0 + 4*4 = 16
a dot a = 0*0 + 4*4 = 16
b dot b = 4*4 + 4*4 = 32
16/sqrt(16*32) = 1/sqrt(2)
arccos(1/sqrt(2)) = pi/4
b = (0, 0) to (4, 4)
the angle between to vectors is
arccos(a dot b / sqrt(a dot a * b dot b))
the dot product of two vectors is (ax*bx+ay*by)
a = (0-0,4-0)
b = (4-0,4-0)
a dot b = 4*0 + 4*4 = 16
a dot a = 0*0 + 4*4 = 16
b dot b = 4*4 + 4*4 = 32
16/sqrt(16*32) = 1/sqrt(2)
arccos(1/sqrt(2)) = pi/4
My former equation works for for 0-Pi.
angle = (Pi/2)*{[(m-abs(m)]/2m)} + arctan[abs(1/m)] + (Pi)*{[(X(b)-abs(X(b))]/2X (b))}
works for all angles around the circle where m is not zero or infinite.
If m = zero, the angle is Pi/2 or 3Pi/2 (Check X(b)).
If m = infinite, the angle is 0 or Pi (Check Y(b)).
You can use many methods,
any methods you use, you can not avoid checking some variables to check conditions.
angle = (Pi/2)*{[(m-abs(m)]/2m)} + arctan[abs(1/m)] + (Pi)*{[(X(b)-abs(X(b))]/2X
works for all angles around the circle where m is not zero or infinite.
If m = zero, the angle is Pi/2 or 3Pi/2 (Check X(b)).
If m = infinite, the angle is 0 or Pi (Check Y(b)).
You can use many methods,
any methods you use, you can not avoid checking some variables to check conditions.
Hi IM,
angle = tan^-1(y/x) + (180 if y is negative)
Bye
---
Harish
angle = tan^-1(y/x) + (180 if y is negative)
Bye
---
Harish
InteractiveMind,
You require the dirfference between the angles of each line.
Req. Ang. =(tan^-1(by/bx) + (180 if by is negative))-(tan^-1(ay/ax) + (180 if ay is negative))
You require the dirfference between the angles of each line.
Req. Ang. =(tan^-1(by/bx) + (180 if by is negative))-(tan^-1(ay/ax) + (180 if ay is negative))
ASKER
Thanks very much everyone.
the Java Math class doesn't seem to contain a an inverse tan method (/function). Is there a way that I can combine tan, and some other function to recreate the inverse tan function?
>> IM
the Java Math class doesn't seem to contain a an inverse tan method (/function). Is there a way that I can combine tan, and some other function to recreate the inverse tan function?
>> IM
I don't know Java. But I am sure, it will have something like
arctan(x) or atan(x)
arctan(x) or atan(x)
ASKER
Yes. I'll use that then... But is arctan the same as inverse tan? :o\
Yes
ASKER
Oh right. I never knew that. lol :)
Strange. The link you posted about the Math Engine states that it contains the arctan() function, whereas according to my IDE, and the official API spec (http://java.sun.com/j2se/1.5.0/docs/api/), the Math class only contains an atan() function; (which obviously is the same thing - so it doesn't really matter; I just wonder why that links states otherwise).
Ah well.
Cheers, Harish.
I'll get back to you all.
>> IM
Strange. The link you posted about the Math Engine states that it contains the arctan() function, whereas according to my IDE, and the official API spec (http://java.sun.com/j2se/1.5.0/docs/api/), the Math class only contains an atan() function; (which obviously is the same thing - so it doesn't really matter; I just wonder why that links states otherwise).
Ah well.
Cheers, Harish.
I'll get back to you all.
>> IM
IM have you checked my algorithm? You can use directly
Req. Ang. =(arctan(by/bx) + (180° if by is negative)) - 90°
Note that the result of arctan may be in radians, in which case you will have to change that to degrees...
Req. Ang. =(arctan(by/bx)*180°/PI + (180° if by is negative)) - 90°
Req. Ang. =(arctan(by/bx) + (180° if by is negative)) - 90°
Note that the result of arctan may be in radians, in which case you will have to change that to degrees...
Req. Ang. =(arctan(by/bx)*180°/PI + (180° if by is negative)) - 90°
As I have told already, I don't know Java :(
ASKER
Cheers.
Okay, getting there.. I've tried this:
double by = 4;
double bx = 4;
double bn = 0;
if ( isNegative(by) )
bn = 180;
double angle = ( Math.toDegrees( Math.atan(by/bx) ) + bn) - 90;
Now, it should (at least, I want it to) set the 'angle' variable to 45.0; instead, it's setting it to -45.0.
Why is this?
BTW: I can do some C++ as well, so if you can do C++, and can demonstrate it in that, then I can 'translate' it into Java (although, for what we're doing here, Java is almost completely identical to C++).
Cheers,
>> IM
Okay, getting there.. I've tried this:
double by = 4;
double bx = 4;
double bn = 0;
if ( isNegative(by) )
bn = 180;
double angle = ( Math.toDegrees( Math.atan(by/bx) ) + bn) - 90;
Now, it should (at least, I want it to) set the 'angle' variable to 45.0; instead, it's setting it to -45.0.
Why is this?
BTW: I can do some C++ as well, so if you can do C++, and can demonstrate it in that, then I can 'translate' it into Java (although, for what we're doing here, Java is almost completely identical to C++).
Cheers,
>> IM
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Fantastic.
Cheers, everyone! :)
>> IM
Cheers, everyone! :)
>> IM
In C++....
#include <math.h>
main()
{
double by = 4;
double bx = 4;
double bn = 0;
if (by < 0)
bn = 180;
double angle = 90 - (atan(by/bx) * 180 / M_PI + bn);
}
You may have to check for the condition bx!=0
#include <math.h>
main()
{
double by = 4;
double bx = 4;
double bn = 0;
if (by < 0)
bn = 180;
double angle = 90 - (atan(by/bx) * 180 / M_PI + bn);
}
You may have to check for the condition bx!=0
You have already accepted the answer !
Thanks :)
Thanks :)
ASKER
^_^
If you're working in Java, you should have an atan2(by,bx) function
This would eliminate problems when by or bx is zero, and properly handle negative bx or by over the full range of the circle.
This would eliminate problems when by or bx is zero, and properly handle negative bx or by over the full range of the circle.