在第一象限中找到圆和两条直线的切点
Find Tangent Points of Circle and Two Lines in First Quadrant
我需要定义明确的表达式来找到点 (x1,y1) 和 (x2,y2),它们是半径为 r(已知)的圆和两条线(已知方程)的两个切点。圆心 (x0,y0) not 知道并且 not 不需要。见下图。
以我为例,我有以下条件:
- 第一象限问题:x>0,y>0
- 行 y=m1*x+b1,m1<=0,b1>=0
- 行 y=m2*x+b2,m2 < m1,b2>b1
- 圆心在y=m1*x+b1之上,所以y0>y1
- 圆心在 r.h.s。 y=m2*x+b2,所以 x0>x2
- 圆与直线 y=m1*x+b1 相切,所以 (y1-y0)/(x1-x0)=-1/m1
- 圆与直线 y=m2*x+b2 相切,所以 (y2-y0)/(x2-x0)=-1/m2
我计算了以下内容:
x1, y1, x2, y2 = var('x1, y1, x2, y2') # tangent points
m1, b1, m2, b2 = var('m1, b1, m2, b2') # lines' eqn
x0, y0, r = var('x0, y0, r') # cirsle's eqn
eq1 = (x1 - x0)^2 + (y1 - y0)^2 - r^2 == 0
eq2 = (x2 - x0)^2 + (y2 - y0)^2 - r^2 == 0
eq3 = y1 - m1*x1 - b1 == 0
eq4 = y2 - m2*x2 - b2 == 0
eq5 = (y1-y0)/(x1-x0) == -1/m1
eq6 = (y2-y0)/(x2-x0) == -1/m2
# unknown: x0,y0,x1,y1,x2,y2
# known: m1,b1,m2,b2,r
solve([eq1,eq2,eq3,eq4,eq5,eq6,
x1>0,y1>0,x2>0,y2>0,
m1<=0,b1>=0,m2<m1,b2>b1,
x0>x2,y0>y1,r>0],x0,y0,x1,y1,x2,y2)
为什么这还不足以定义问题?
我完全不知道 Sage(我认为你的代码在其中)或 Mathematica 的细节,但我可以指出一些困难。
首先,我认为您需要 "catch" 将您定义的数学变量放入语言的变量中。所以你可能需要
x1, y1, x2, y2 = var('x1, y1, x2, y2') # tangent points
m1, b1, m2, b2 = var('m1, b1, m2, b2') # lines' eqn
x0, y0, r = var('x0, y0, r') # cirsle's eqn
接下来,您将所有方程式放入一个 solve
命令中。从图表中可以看出,圆上和两条线上都没有点,但是您尝试找到同时满足所有方程式的所有点。您应该将单个 solve
分成两个命令,每行一个。
接下来,您的要求中没有任何内容可以使您的直线与给定曲线相切。对于一个几乎任意的圆和线,可能没有、一个或两个交点,而且完全出现一个点的可能性极小。您需要限制每条线都与曲线相切。该限制的编程难度适中,似乎并不比找到交点容易。您确定您使用的方法适合您的问题吗?
确保切点在第一象限中还有其他困难,但这不如其他困难重要。
最后,您的代码中没有任何内容表明您的已知值为 m1, b1, m2, b2, r
并且您希望 x0, y0
从最终表达式中删除。 (你确实声明你想要 x1, y1, x2, y2
的表达式。)我不知道如何在 Sage 或 Mathematica 中做到这一点。
所涉及的数学问题并不难。点 (x0, y0)
必须位于与给定直线平行的直线上,并且与直线的距离为 r
。 (x0, y0)
得到四分。对于其中的每一个,您都可以找到给定线上最接近这些点 (x0, y0)
的点。总共产生四分,然后你只需选择第一象限中的那些。另一种更快的三角函数方法是找到两条给定线之间的角度,然后您可以使用三角函数找到所需点与交点的距离,然后找到这些点。
您确定需要 Sage/Mathematica 为您做这件事吗?
距离为 R 的两条给定直线的平行线相交于圆心。找到这个点后,将其投影到原来的两条直线上。
这些操作有简单的解析表达式。
让这两行成为 a'x+b'y+c'=0
,a"x+b"y+c"=0
其中 a'²+b'²=1, a"²+b"²=1
(这是比你的方程式稍微更一般的形式)。
平行线的交点就是系统的解
a'x+b'y+c'-r=0
a"x+b"y+c"-r=0,
由克拉默法则给出
|c'-r b'| / |a' b'| |a' c'-r| / |a' b'|
u = |c"-r b"| / |a" b"|, v = |a" c"-r| / |a" b"|
并且投影的坐标简单地由
给出
x' = x - a (a'u+b'v+c)
y' = y - b (a'u+b'v+c)
x" = x - a (a"u+b"v+c)
y" = y - b (a"u+b"v+c)
计算 x1
、y1
、x2
和 y2
作为未知数
Clear[m1, x1, b1, m2, x2, b2, r, x0]
y1 = m1 x1 + b1;
y2 = m2 x2 + b2;
s1 = r/Sqrt[1 + 1/m1^2];
s2 = r/Sqrt[1 + 1/m2^2];
x0 = x0 /. FullSimplify@Solve[
m1 x0 + b1 + (s1 (-(1/m1)) - s1 m1) ==
m2 x0 + b2 + (s2 (-(1/m2)) - s2 m2), x0][[1]]
(-b1 + b2 + Sqrt[1 + 1/m1^2] m1 r - Sqrt[1 + 1/m2^2] m2 r)/(m1 - m2)
y0 = FullSimplify[m1 x0 + b1 + (s1 (-(1/m1)) - s1 m1)]
(b2 m1 - m2 (b1 +
m1 (-Sqrt[1 + 1/m1^2] + Sqrt[1 + 1/m2^2]) r))/(m1 - m2)
x1 = x1 /. FullSimplify@
Solve[{(x1 - x0)^2 + (y1 - y0)^2 == r^2}, x1][[1]]
(r + m1 m2 r -
Sqrt[1 + 1/m1^2] m1 (b1 - b2 + Sqrt[1 + 1/m2^2] m2 r))/(Sqrt[
1 + 1/m1^2] m1 (m1 - m2))
x2 = x2 /. FullSimplify@
Solve[{(x2 - x0)^2 + (y2 - y0)^2 == r^2}, x2][[1]]
(b2 - b1 (1 + m2^2) + Sqrt[1 + 1/m1^2] m1 r +
m2 (b2 m2 - (Sqrt[1 + 1/m2^2] +
m1 (-Sqrt[1 + 1/m1^2] + Sqrt[1 + 1/m2^2]) m2) r))/((m1 -
m2) (1 + m2^2))
使用值进行测试
m1 = -0.28; b1 = 1.64; m2 = -1.08; b2 = 3.84;
r = 3.9062658021579098;
{x1, y1}
{x2, y2}
{3.81302, 0.572355}
{2., 1.68}
Show[Plot[
{m1 x + b1,
m1 x + b1 + (s1 (-(1/m1)) - s1 m1),
m2 x + b2,
m2 x + b2 + (s2 (-(1/m2)) - s2 m2)}, {x, 0, 10},
PlotRange -> {{0, 10}, {0, 10}}, AspectRatio -> 1],
Graphics[Circle[{x0, y0}, r]]]
我需要定义明确的表达式来找到点 (x1,y1) 和 (x2,y2),它们是半径为 r(已知)的圆和两条线(已知方程)的两个切点。圆心 (x0,y0) not 知道并且 not 不需要。见下图。
以我为例,我有以下条件:
- 第一象限问题:x>0,y>0
- 行 y=m1*x+b1,m1<=0,b1>=0
- 行 y=m2*x+b2,m2 < m1,b2>b1
- 圆心在y=m1*x+b1之上,所以y0>y1
- 圆心在 r.h.s。 y=m2*x+b2,所以 x0>x2
- 圆与直线 y=m1*x+b1 相切,所以 (y1-y0)/(x1-x0)=-1/m1
- 圆与直线 y=m2*x+b2 相切,所以 (y2-y0)/(x2-x0)=-1/m2
我计算了以下内容:
x1, y1, x2, y2 = var('x1, y1, x2, y2') # tangent points
m1, b1, m2, b2 = var('m1, b1, m2, b2') # lines' eqn
x0, y0, r = var('x0, y0, r') # cirsle's eqn
eq1 = (x1 - x0)^2 + (y1 - y0)^2 - r^2 == 0
eq2 = (x2 - x0)^2 + (y2 - y0)^2 - r^2 == 0
eq3 = y1 - m1*x1 - b1 == 0
eq4 = y2 - m2*x2 - b2 == 0
eq5 = (y1-y0)/(x1-x0) == -1/m1
eq6 = (y2-y0)/(x2-x0) == -1/m2
# unknown: x0,y0,x1,y1,x2,y2
# known: m1,b1,m2,b2,r
solve([eq1,eq2,eq3,eq4,eq5,eq6,
x1>0,y1>0,x2>0,y2>0,
m1<=0,b1>=0,m2<m1,b2>b1,
x0>x2,y0>y1,r>0],x0,y0,x1,y1,x2,y2)
为什么这还不足以定义问题?
我完全不知道 Sage(我认为你的代码在其中)或 Mathematica 的细节,但我可以指出一些困难。
首先,我认为您需要 "catch" 将您定义的数学变量放入语言的变量中。所以你可能需要
x1, y1, x2, y2 = var('x1, y1, x2, y2') # tangent points
m1, b1, m2, b2 = var('m1, b1, m2, b2') # lines' eqn
x0, y0, r = var('x0, y0, r') # cirsle's eqn
接下来,您将所有方程式放入一个 solve
命令中。从图表中可以看出,圆上和两条线上都没有点,但是您尝试找到同时满足所有方程式的所有点。您应该将单个 solve
分成两个命令,每行一个。
接下来,您的要求中没有任何内容可以使您的直线与给定曲线相切。对于一个几乎任意的圆和线,可能没有、一个或两个交点,而且完全出现一个点的可能性极小。您需要限制每条线都与曲线相切。该限制的编程难度适中,似乎并不比找到交点容易。您确定您使用的方法适合您的问题吗?
确保切点在第一象限中还有其他困难,但这不如其他困难重要。
最后,您的代码中没有任何内容表明您的已知值为 m1, b1, m2, b2, r
并且您希望 x0, y0
从最终表达式中删除。 (你确实声明你想要 x1, y1, x2, y2
的表达式。)我不知道如何在 Sage 或 Mathematica 中做到这一点。
所涉及的数学问题并不难。点 (x0, y0)
必须位于与给定直线平行的直线上,并且与直线的距离为 r
。 (x0, y0)
得到四分。对于其中的每一个,您都可以找到给定线上最接近这些点 (x0, y0)
的点。总共产生四分,然后你只需选择第一象限中的那些。另一种更快的三角函数方法是找到两条给定线之间的角度,然后您可以使用三角函数找到所需点与交点的距离,然后找到这些点。
您确定需要 Sage/Mathematica 为您做这件事吗?
距离为 R 的两条给定直线的平行线相交于圆心。找到这个点后,将其投影到原来的两条直线上。
这些操作有简单的解析表达式。
让这两行成为 a'x+b'y+c'=0
,a"x+b"y+c"=0
其中 a'²+b'²=1, a"²+b"²=1
(这是比你的方程式稍微更一般的形式)。
平行线的交点就是系统的解
a'x+b'y+c'-r=0
a"x+b"y+c"-r=0,
由克拉默法则给出
|c'-r b'| / |a' b'| |a' c'-r| / |a' b'|
u = |c"-r b"| / |a" b"|, v = |a" c"-r| / |a" b"|
并且投影的坐标简单地由
给出x' = x - a (a'u+b'v+c)
y' = y - b (a'u+b'v+c)
x" = x - a (a"u+b"v+c)
y" = y - b (a"u+b"v+c)
计算 x1
、y1
、x2
和 y2
作为未知数
Clear[m1, x1, b1, m2, x2, b2, r, x0]
y1 = m1 x1 + b1;
y2 = m2 x2 + b2;
s1 = r/Sqrt[1 + 1/m1^2];
s2 = r/Sqrt[1 + 1/m2^2];
x0 = x0 /. FullSimplify@Solve[
m1 x0 + b1 + (s1 (-(1/m1)) - s1 m1) ==
m2 x0 + b2 + (s2 (-(1/m2)) - s2 m2), x0][[1]]
(-b1 + b2 + Sqrt[1 + 1/m1^2] m1 r - Sqrt[1 + 1/m2^2] m2 r)/(m1 - m2)
y0 = FullSimplify[m1 x0 + b1 + (s1 (-(1/m1)) - s1 m1)]
(b2 m1 - m2 (b1 + m1 (-Sqrt[1 + 1/m1^2] + Sqrt[1 + 1/m2^2]) r))/(m1 - m2)
x1 = x1 /. FullSimplify@
Solve[{(x1 - x0)^2 + (y1 - y0)^2 == r^2}, x1][[1]]
(r + m1 m2 r - Sqrt[1 + 1/m1^2] m1 (b1 - b2 + Sqrt[1 + 1/m2^2] m2 r))/(Sqrt[ 1 + 1/m1^2] m1 (m1 - m2))
x2 = x2 /. FullSimplify@
Solve[{(x2 - x0)^2 + (y2 - y0)^2 == r^2}, x2][[1]]
(b2 - b1 (1 + m2^2) + Sqrt[1 + 1/m1^2] m1 r + m2 (b2 m2 - (Sqrt[1 + 1/m2^2] + m1 (-Sqrt[1 + 1/m1^2] + Sqrt[1 + 1/m2^2]) m2) r))/((m1 - m2) (1 + m2^2))
使用值进行测试
m1 = -0.28; b1 = 1.64; m2 = -1.08; b2 = 3.84;
r = 3.9062658021579098;
{x1, y1}
{x2, y2}
{3.81302, 0.572355}
{2., 1.68}
Show[Plot[
{m1 x + b1,
m1 x + b1 + (s1 (-(1/m1)) - s1 m1),
m2 x + b2,
m2 x + b2 + (s2 (-(1/m2)) - s2 m2)}, {x, 0, 10},
PlotRange -> {{0, 10}, {0, 10}}, AspectRatio -> 1],
Graphics[Circle[{x0, y0}, r]]]