markww 122 Report post Posted October 13, 2007 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) 0 Share this post Link to post Share on other sites
SiCrane 11839 Report post Posted October 13, 2007 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. 0 Share this post Link to post Share on other sites
markww 122 Report post Posted October 13, 2007 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 0 Share this post Link to post Share on other sites
Tom 352 Report post Posted October 13, 2007 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. 0 Share this post Link to post Share on other sites
markww 122 Report post Posted October 13, 2007 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 0 Share this post Link to post Share on other sites
OrenGL 228 Report post Posted October 13, 2007 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-oLet b = p-oLet alpha be the angle you are trying to finda 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... 0 Share this post Link to post Share on other sites
jyk 2094 Report post Posted October 13, 2007 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. 0 Share this post Link to post Share on other sites
markww 122 Report post Posted October 13, 2007 @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 0 Share this post Link to post Share on other sites
jyk 2094 Report post Posted October 13, 2007 Quote:Original post by OrenGLYou 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-oLet b = p-oLet alpha be the angle you are trying to finda 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. 0 Share this post Link to post Share on other sites
markww 122 Report post Posted October 13, 2007 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 0 Share this post Link to post Share on other sites
jyk 2094 Report post Posted October 13, 2007 Quote:Original post by markwwHmm 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. 0 Share this post Link to post Share on other sites
JohnBolton 1372 Report post Posted October 14, 2007 Quote:Original post by OrenGLThere is a 2d version of the cross product that gives a scalar... Oh my rusty brain...It's called "perpdot". 0 Share this post Link to post Share on other sites
Verminox 166 Report post Posted October 15, 2007 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) / r^{2}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] 0 Share this post Link to post Share on other sites
alvaro 21246 Report post Posted October 15, 2007 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. 0 Share this post Link to post Share on other sites