点与圆相切

时间:2013-06-09 18:34:58

标签: matlab geometry latitude-longitude angle

将其用作[参考] [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;

对于点(7,6),角度为7.9572 / 73.4434,而(-3,-8)为213.6264 / 285.2615。 因此,对于第一象限,角度没有意义,但对于第三象限,它们会这样做。我做错了什么?

4 个答案:

答案 0 :(得分:2)

a的公式错误。你应该使用

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

而不是

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

即。使用acos(...)代替asin(...)。原因如下图所示。角度a的公式为a=acos(r/H),其中r是圆的半径,H是直角三角形的斜边长度。所以这与asin(...)无法知道传递的值的两个可能象限中的哪一个的事实无关。 asin的参数总是正的,你总是希望答案在0到90度的范围内。

image of circle with two tangents from an external point

所以你想要的两个角度的答案是b+ab-a。在两种情况下使用acos代替asin会产生97.7592&您的第一个象限示例为-16.5566(或等效343.4434),-164.7385&您的第三象限示例为-56.3736(或等效195.2615和303.6264)。 (注意:代替在t_1t-2的公式中添加180度,您只需切换dxdy的符号

答案 1 :(得分:2)

首先 - 我花了10分钟时间搞清楚你想要做什么(最后,我从其中一个答案中得到评论),同时解决你的问题问题花了2分钟。因此,为了将来参考,请尽可能明确地说明您的问题,首先

现在,我想你的标志搞砸了。请尝试以下方法:

%// 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)

或者,您可以使用a代替acos来跳过计算中间角度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)

另一种方法是重新发现trigonometric identity acos(x) = pi/2 - asin(x):)

答案 2 :(得分:0)

好吧,看起来你没有考虑到asin,atan,(任何a-trig函数)无法知道你传递的两个可能象限中的哪一个的事实。为了弥补这一点,a-trig函数将假设您的点位于第一或第四象限(东北/东南)。因此,如果您调用atan函数并且原始点位于第二或第三象限,则需要将180度/ pi弧度添加到它返回的任何值上。

请参阅此处的文档,说明asin从[-pi / 2,pi / 2]返回一个值: http://www.mathworks.com/help/matlab/ref/asin.html

希望有所帮助:)

修改 我误解了原来的情况

以下是我认为您计算的内容: t_1和t_2表示如果从切点开始在圆上并想要前往原始起点,则将要行进的角度。

从这个角度来看,你的角度是正确的。

关于点(7,6)

如果你开始在大约的圈子。 (0,5)并且在7度旅行,你会达到这一点。 如果你开始在大约圈。 (5,0)并且以70度的速度旅行,你会达到目的。

现在,比角度更有用且更少混淆的是知道线的斜率。要从角度获得此值,请使用以度为单位的角度执行以下操作:

angle = (angle + 90 + 360) % 180 - 90 // this gives us the angle as it would be in quad 1 or 4
slope = tan( deg2rad( angle ) )

答案 3 :(得分:0)

此MathWorld条目符合您的要求:http://mathworld.wolfram.com/CircleTangentLine.html