3

Using this as a [reference][1]: Find a tangent point on circle?

cx = 0;
cy = 0;

px = -3;
py = -8;

dx = cx - px;
dy = cy - py;

a = asin(5 / ((dx*dx + dy*dy)^0.5));
b = atan2(dy, dx);

t_1 = deg2rad(180) + b - a;
t_2 = deg2rad(180) + b + a;

For a point (7,6) the angles are 7.9572/73.4434 and for (-3, -8) are 213.6264/285.2615. So for the first quadrant, the angles do not make sense, but for third quadrant they do. What I am doing wrong?

4

4 回答 4

2

Your formula for a is wrong. You should use

a = acos(5 / ((dx*dx + dy*dy)^0.5))

instead of

a = asin(5 / ((dx*dx + dy*dy)^0.5))

i.e. use acos(...) instead of asin(...). The reason is shown in the image below. The formula for angle a is a=acos(r/H), where r is the radius of the circle and H is the length of the hypotenuse of the right angle triangle. So this has nothing to do with the fact that asin(...) has no way to know which of the two possible quadrants the value that is passed in lies. the argument of the asin is always positive, and you always want the answer in the range 0 to 90 degrees.

image of circle with two tangents from an external point

So the answer for the two angles that you want are b+a and b-a. Using acos instead of asin in your two cases produces 97.7592 & -16.5566 (or equivalently 343.4434) for your first quadrant example, and -164.7385 & -56.3736 (or equivalently 195.2615 and 303.6264) for your third quadrant example. (NB: instead of adding 180 degrees in the formula for t_1 and t-2, you could just switch the signs of dx and dy)

于 2013-06-09T23:14:34.830 回答
2

First -- I spent like 10 minutes figuring out what the heck you're trying to do (which in the end, I got from a comment in one of the answers), while solving your problem took 2 minutes. So, for future reference, please give a description of your problem as clear as you can first.

Now, I think you just have your signs messed up. Try the following:

%// difference vector
%// NOTE: these go the other way around for the atan2 to come out right
dx = px - cx;
dy = py - cy;

%// tip angle of the right triangle
a = asin( 5 / sqrt(dx*dx + dy*dy) );
%// angle between the (local) X-axis and the line of interest
b = atan2(dy, dx);
%// the third angle in the right triangle
%// NOTE: minus a here instead of plus b
g = pi/2 - a;

%// Angles of interest
%// NOTE1: signs are flipped; this automatically takes care of overshoots
%// NOTE2: don't forget to mod 360
t_1 = mod( rad2deg(b - g), 360)
t_2 = mod( rad2deg(b + g), 360)

Alternatively, you could skip computing the intermediate angle a by using acos instead of asin:

%// difference vector    
dx = px - cx;
dy = py - cy;

%// Directly compute the third angle of the right triangle 
%// (that is, the angle "at the origin")
g = acos( 5 / sqrt(dx*dx + dy*dy) );
%// angle between the (local) X-axis and the line of interest
b = atan2(dy, dx);

%// Angles of interest
t_1 = mod( rad2deg(b - g), 360)
t_2 = mod( rad2deg(b + g), 360)

Just another wayto re-discover the trigonometric identity acos(x) = pi/2 - asin(x) :)

于 2013-06-10T07:20:17.147 回答
0

Alright, it looks like you are not accounting for the fact that asin, atan, ( any a-trig function ) has no way to know which of the two possible quadrants the value you passed in lies. To make up for that, a-trig function will assume that your point is in the first or fourth quadrant ( northeast / southeast ). Therefore, if you call atan function and your original point was in the second or third quadrant, you need to add 180 degrees / pi radians onto whatever value it returns.

See the documentation here stating that asin returns a value from [-pi/2, pi/2] : http://www.mathworks.com/help/matlab/ref/asin.html

Hope that helps :)

EDIT I misunderstood the situation originally

Here is what I think you have calculated : t_1 and t_2 represent the angles you would travel at if you started on the circle from the tangent point and wanted to travel to your original starting point.

Viewed with this perspective your angles are correct.

For the point (7,6)

If you started on the circle at approx. (0,5) and traveled at 7 degrees, you would hit the point. If you started on the circle at approx. (5,0) and traveled at 70 degrees, you would hit the point.

Now, what is going to be more useful and less confusing than angles, will be to know the slope of the line. To get this from the angle, do the following with angle in degrees:

angle = (angle + 90 + 360) % 180 - 90 // this gives us the angle as it would be in quad 1 or 4
slope = tan( deg2rad( angle ) )
于 2013-06-09T18:45:44.313 回答
0

This MathWorld entry is what you want: http://mathworld.wolfram.com/CircleTangentLine.html.

于 2013-06-09T19:35:06.510 回答