给定:两个圆圈的中心和半径
我的问题是我无法弄清楚如何使用数值方法找到圆圈切线。使用http://mathworld.wolfram.com/Circle-CircleTangents.html我会想到如何手动解决它,但不知道如何使用matlab / octave这样做。
正在设置导致我困难的问题。即创建方程组。在上面的网站上,他们使用从中心到切点的线之间的点积垂直于切线的事实。但是,我不知道如何将其转换为我的模型。如果我使用matlab" dot"功能,我如何设置雅可比矩阵?
答案 0 :(得分:1)
使用MATLAB内置函数
最简单的方法是按原样定义函数,然后使用fsolve()
函数。例如(代码未经过测试):
function y = cctang(t)
%t is a 1-by-4 line vector (first two members = t1, last two members = t2)
%y is a 1-by-4 vector
%Initialization of centers and radii
x1 = [0 0]; r1=4;
x2 = [1 1]; r2=0.5;
y= zeros(1, 4);
y(1) = ( t(3:4) - x2) * ( t(3:4) - t(1:2))';
y(2) = ( t(1:2) - x1) * ( t(3:4) - t(1:2))';
y(3) = norm(t(1:2)-x1)^2 - r1^2;
y(4) = norm(t(3:4)-x2)^2 - r2^2;
end
然后执行:
t0 = [0 0 1 1];
solution = fsolve(@cctang,t0);
使用自定义迭代功能
如果您想从头开始构建所有内容,可以构建自定义雅可比函数并将其输入到您在问题中给出的求解函数。雅可比函数应如下所示:
function J = myJacobian(t)
%returns a 4-by-4 matrix
x1 = [0 0]; r1=4;
x2 = [1 1]; r2=0.5;
J = zeros(4,4);
J(1,:) = [ x2(1)-t(3), x2(2)-t(4), 2*t(3)-x2(1), 2*t(4)-x2(2)];
%etc...
end
使用符号工具箱
大部分"努力工作"在前一种方法中,您需要以数字和手动方式计算导数。
使用符号工具箱,您可以象征性地定义函数,然后使用built-in jacobian()
function计算雅可比矩阵。
这些将是您的自定义数值求解函数的输入。在每次迭代时,您应该使用实际数值替换符号变量(请参阅subs()
)。
这将使您的代码更加通用,对人为错误不那么敏感(例如,我在最后一段代码中计算的一个派生词中出错的概率是多少?)
答案 1 :(得分:1)
作为Yellow解决方案的替代方案,我想指出问题可以通过迭代的更几何风格来解决。此解决方案适用于任何平滑曲线,而不仅仅是圆形。
让我们分别使用中心C[A]
和C[B]
以及半径A
和B
来呼叫圈子R[A]
和R[B]
。方括号表示下标。
您还可以对线路端点进行一些初步估算,可能来自用户选择。请将这些积分称为P[A][0]
和P[B][0]
。
对于P[A][i]
和P[B][i]
,请按以下方式计算P[A][i+1]
和P[B][i+1]
:
L[i]
和P[A][i]
投影到圈子上来创建一行P[B][i]
。Q[A][i]
成为L[i]
与A
的最近点。Q[B][i]
同样是L[i]
到B
的最近点。P[A][i+1]
成为Q[A][i]
C[A]
的投影。P[B][i+1]
成为Q[B][i]
C[B]
的投影。||P[A][i+1] - Q[A][i]|| + ||P[A][i+1] - Q[A][i]|| < epsilon
,则线段P[A][i+1], P[B][i+1]
是您的解决方案。答案 2 :(得分:1)
“缩小”两个圆圈,直到一个圆圈成为一个点。在放气期间,外切线保持相同的方向。
要从距离中心距离R
的点找到半径为D
的圆的两条切线,就足以求解一个直角三角形。特别是,接触点与中心线的位置角由sin(phi)=R/D
给出。
通过类似地给较大的圆圈充气,可以发现两个内部切线。
更新:简单的分析解决方案。
不失一般性,让放气圆以单位半径为中心(应用平移和缩放)。让(U, V)
外部点和(X, Y)
圆圈上的一个点(例如X²+Y²=1
)。
我们用点积U . (U - X) + Y . (V - Y) = 0, i.e. U . X + V . Y = 1
表示与半径矢量的正切的正交性。
让我们通过除以√(U² + V²)
来生成u . X + v . Y = t
,然后重写(v . Y)² = (t - u . X)²
或X² - 2 u . t . X + t² - v² = 0
来规范化。
解决方案就是
X = u . t +/- v . √(1 - t²)
Y = v . t -/+ u . √(1 - t²)
乘以两个原始圆的半径,可以获得从中心到接触点的向量。