Найти касательные точки окружности и две линии в первом квадранте - PullRequest
0 голосов
/ 17 ноября 2018

Мне нужно определить явные выражения, чтобы найти точки (x1, y1) и (x2, y2), которые являются двумя касательными точками окружности с радиусом r (известный) и двумя линиями (известные уравнения).Центр круга (x0, y0) не знаю и не требуется.См. Рисунок ниже.

enter image description here

В моем случае у меня есть следующие условия:

  1. проблема в первом квадранте: x> 0, y> 0
  2. строка y = m1 * x + b1 с m1 <= 0, b1> = 0
  3. строка y = m2 * x + b2 с m2 b1
  4. центр круга выше y = m1 * x + b1, поэтому y0> y1
  5. центр круга в правой части y = m2 * x + b2, поэтому x0> x2
  6. окружность, касательная к линии y = m1 * x + b1, поэтому (y1-y0) / (x1-x0) = - 1 / m1
  7. окружность, касающаяся линии y = m2 * x + b2, поэтому(y2-y0) / (x2-x0) = - 1 / м2

Я вычислил следующее:

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)

Почему этого недостаточно для определения проблемы?

Ответы [ 3 ]

0 голосов
/ 17 ноября 2018

Параллели с двумя данными линиями на расстоянии 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)
0 голосов
/ 17 ноября 2018

Вычисления 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 - Srrt [1 + 1 / m2 ^ 2] m2 r) / (m1 - m2)

y0 = FullSimplify[m1 x0 + b1 + (s1 (-(1/m1)) - s1 m1)]

(b2 м1 - м2 (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]]

(р + м1 м2 р - Sqrt [1 + 1 / m1 ^ 2] m1 (b1 - b2 + Sqrt [1 + 1 / m2 ^ 2] m2 r)) / (Sqrt [ 1 + 1 / м1 ^ 2] м1 (м1 - м2))

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 + м2 (b2 м2 - (м2 [1 + 1 / м2 ^ 2] + m1 (-Sqrt [1 + 1 / m1 ^ 2] + Sqrt [1 + 1 / m2 ^ 2]) m2) r)) / ((m1 - м2) (1 + м2 ^ 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]]]

enter image description here

0 голосов
/ 17 ноября 2018

Я не знаю ни деталей Sage (в котором, я думаю, ваш код), ни Mathematica, но я могу указать на некоторые трудности.

Во-первых, я считаю, что вам нужно "поймать" математикупеременные, которые вы определяете в переменных языка.Таким образом, вам может понадобиться

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, чтобы сделать это для вас?

...