Sign in to follow this  
markww

angle in a circle

Recommended Posts

markww    122
Hi, I have a circle, I know its radius. I have a point on its edge. Is there anyway to figure out what angle in degrees that is?
           |
        ---|----
      /    |     \     
     P     |      \  
     |     |      |
 ----------O------X--------          
     |     |      |
      \    |     /
       \---|--- /
           |
           |
yeah that's a fine ascii circle, so anyway, I'm interested in the angle formed between P, O, X. I know the coordinates of all 3, I just want to know the angle between them. Thanks for any help p.s. - the formatting keeps messing up the circle (not that it was that great to begin with, hope it's understandable)

Share this post


Link to post
Share on other sites
SiCrane    11839
Assuming a programming language with an atan2() function the functions like the C math library function, atan2() should be able to give you the angle.

Share this post


Link to post
Share on other sites
markww    122
I'm using C++:

#include <math.h>
double atan2( double y, double x );

What am I feeding it though? I know the radius, and the two edge points,

Thanks

Share this post


Link to post
Share on other sites
Tom    352
You're feeding it the coordinates of your point relative to the circle's origin, so you need to adjust the coordinates: X = O.x - P.x, Y = O.y - P.y. I don't know if they need to be inverted along the Y-axis, but this will become evident very quickly when you first test it.

Share this post


Link to post
Share on other sites
markww    122
Hi Tom,

My circle will always be at (0,0), so the edge points should always be relative to the center. I don't get how giving this atan2 function one set of (x,y) points will give you the proper angle - wouldn't it need to the second set of points to determine the angle formed between them?

Thanks

Share this post


Link to post
Share on other sites
OrenGL    228
You know I really like these questions. Every few months I run into it again and realize I totally forgot how to solve it... After scratching my head for a bit here it is.

Let a = x-o
Let b = p-o
Let alpha be the angle you are trying to find

a cross b = ||a||*||b||*sin(alpha)
a dot b = ||a||*||b||*cos(alpha)

so

(a cross b) / (a dot b) = sin(alpha)/cos(alpha) = tan(alpha)

So alpha = atan( (a cross b) / (a dot b) )

Edit:

a cross b is a vector and you need a scalar. There is a 2d version of the cross product that gives a scalar... Oh my rusty brain...

Share this post


Link to post
Share on other sites
jyk    2094
Quote:
I don't get how giving this atan2 function one set of (x,y) points will give you the proper angle - wouldn't it need to the second set of points to determine the angle formed between them?
By 'second set of points', do you mean a 'second set of coordinates', i.e. a second x-y pair?

In any case, the angle returned by atan2() is always relative to the positive x axis (with positive angles being in the counter-clockwise direction), so only one input vector is required.

Share this post


Link to post
Share on other sites
markww    122
@jyk:
Yeah if atan2() gives the result relative to the positive x-axis that's perfect, exactly what I want. So if P = (-5,2) I would just do:

double Angle = atan2(2, -5);

and that's it?


@Oren:

I'm trying to remember by math from back in the day. I remember how to do cross products ok but the final formula confuses me:

alpha = atan( (a cross b) / (a dot b) )

I thought dot product returns a single value, while cross product leaves you with (in my case) 2 components - how do I feed that to atan after the (a cross b) / (a dot b) statement?


Sorry I'm rusty, I just want my airplane to rotate the right way!

Thanks

Share this post


Link to post
Share on other sites
jyk    2094
Quote:
Original post by OrenGL
You know I really like these questions. Every few months I run into it again and realize I totally forgot how to solve it... After scratching my head for a bit here it is.

Let a = x-o
Let b = p-o
Let alpha be the angle you are trying to find

a cross b = ||a||*||b||*sin(alpha)
a dot b = ||a||*||b||*cos(alpha)

so

(a cross b) / (a dot b) = sin(alpha)/cos(alpha) = tan(alpha)

So alpha = atan( (a cross b) / (a dot b) )
I think you mean ||aXb|| in the above derivation, not aXb.

Also, it's best to use the 'atan2' function when you have it available, as it will handle gracefully the cases where the cosine is (near) zero. This then leaves you with:
angle = atan2(||aXb||,a.b)
Which is indeed an effective way to compute the angle between two 3-d vectors of arbitrary (but non-zero) length.

However, note that the returned angle will always be positive, so this can only be used to compute the unsigned angle between two vectors in 3-d.

Computing the signed angle between two 3-d vectors requires a frame of reference of some sort, but you'll note that the OP's problem is actually 2-d. Using similar logic to the derivation you posted above, we can compute the (signed) angle between two 2-d vectors of arbitrary (but non-zero) length as follows:
angle = atan2(perp(a).b,a.b)
Of course since the OP is asking for an absolute rather than relative angle, atan2(y,x) will do the trick, as previously noted.

Share this post


Link to post
Share on other sites
markww    122
Hmm if it's from the positive x-axis, then shouldn't:


atan2(4.0, -0.3);


be greater than 90 degrees since it is already in quadrant II? I'm probably mis-using it -

Thanks

Share this post


Link to post
Share on other sites
jyk    2094
Quote:
Original post by markww
Hmm if it's from the positive x-axis, then shouldn't:


atan2(4.0, -0.3);


be greater than 90 degrees since it is already in quadrant II? I'm probably mis-using it -
Remember that (in C++ at least), the return value of atan2() is in radians.

Share this post


Link to post
Share on other sites
Verminox    166
For two vectors a and b,
a dot b = |a| * |b| * cos(angle)
And you know the lengths of the vectors (=radius).


Therefore,
cos(angle) = (a dot b) / r2
So you can find the angle using the acos() function.


Edit: Sorry didn't notice that one of the vectors is always along the X axis. In that case the atan2() methods are perfect. You can use the above method using cosines if you need to find the angle between any two points on the circle.

[Edited by - Verminox on October 15, 2007 9:00:55 AM]

Share this post


Link to post
Share on other sites
alvaro    21246
The "acos of the dot product" solution has the advantage that it works for vectors in more dimensions. It has the disadvantage that it doesn't give you a sign.

If you are familiar with complex numbers, you can represent both points by complex numbers (representing point (x,y) as x+iy) and then the ratio of both numbers is a complex number whose argument is the angle you are looking for. Again, use atan2() to extract the argument.

Oh, and you should get in the habit of using radians for everything, at least internally in your programs. If you ever need to display the angle for a user to see, then you can multiply it by 180/PI before you show it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this