11

I have code worked for drawing common tangent lines to two circles(http://en.wikipedia.org/wiki/Tangent_lines_to_circles), now I want to delete the inner common tangent lines, how?

Manipulate[Block[{t1, t2, v1, v2, pts},
  t1 = {xm, ym};
  t2 = {xn, yn};
  {v1, v2} = p;
  pts = {t1, t2} /. NSolve[{(t2 - v2).(t2 - t1) == 0, (t1 - v1).(t2 - t1) == 0, 
    (t1 - v1).(t1 - v1) == r1^2, (t2 - v2).(t2 - v2) == r2^2}, {xm, ym, xn, yn}, Reals];
  If[pts == {t1, t2}, pts = {}];
  Graphics[{Circle[v1, r1], Circle[v2, r2], Line[pts]}, 
   PlotRange -> 6, Frame -> 1]
  ], {{p, {{-3, 1}, {3, 0}}}, Locator}, {{r1, 1}, 1, 3}, {{r2, 2}, 1, 
  3}]

enter image description here

matrix42
  • 6,996
  • 2
  • 26
  • 62

5 Answers5

13

Here is one way:

  Manipulate[Block[{t1, t2, v1, v2, pt, pts}, t1 = {xm, ym};
  t2 = {xn, yn};
  {v1, v2} = p;
  pt = {t1, t2} /. 
    NSolve[{(t2 - v2).(t2 - t1) == 0, (t1 - v1).(t2 - t1) == 0,
      (t1 - v1).(t1 - v1) == r1^2, (t2 - v2).(t2 - v2) == r2^2}, {xm, 
      ym, xn, yn}, Reals];
  pts = Select[pt, Sign[(#[[1]] - v1).(#[[2]] - v2)] == 1 &];
  If[pts == {t1, t2}, pts = {}];
  Graphics[{Circle[p[[1]], r1], Circle[p[[2]], r2], Line@pts}, 
   PlotRange -> 6, Frame -> 1]], {{p, {{-3, 1}, {3, 0}}}, 
  Locator}, {{r1, 1}, 1, 3}, {{r2, 2}, 1, 3}]

enter image description here

EDIT: Pickett's suggestion

Putting constraint in NSolve:

  Manipulate[Block[{t1, t2, v1, v2, pts}, t1 = {xm, ym};
  t2 = {xn, yn};
  {v1, v2} = p;
  pts = {t1, t2} /. 
    NSolve[{(t2 - v2).(t2 - t1) == 0, (t1 - v1).(t2 - t1) == 
       0, (t1 - v1).(t1 - v1) == r1^2, (t2 - v2).(t2 - v2) == 
       r2^2, (t1 - v1).(t2 - v2) > 0}, {xm, ym, xn, yn}, Reals];
  If[pts == {t1, t2}, pts = {}];
  Graphics[{Circle[p[[1]], r1], Circle[p[[2]], r2], Line[pts]}, 
   PlotRange -> 6, Frame -> 1]], {{p, {{-3, 1}, {3, 0}}}, 
  Locator}, {{r1, 1}, 1, 3}, {{r2, 2}, 1, 3}]
ubpdqn
  • 60,617
  • 3
  • 59
  • 148
6
Manipulate[Block[{x1, y1, x2, y2},
  {{x1, y1}, {x2, y2}} = p;
  Show[Graphics[{Circle[{x1, y1}, r1], Circle[{x2, y2}, r2]}, 
    PlotRange -> 6, Frame -> 1], 
   ContourPlot[
    r1^2*((x - x2)^2 + (y - y2)^2) - 
      2*r1*r2*((x - x1)*(x - x2) + (y - y1)*(y - y2)) + 
      r2^2*((x - x1)^2 + (y - y1)^2) - (-x*y1 + x*y2 + x1*y - x1*y2 - 
         x2*y + x2*y1)^2 == 0, {x, -6, 6}, {y, -6, 6}, 
    PerformanceGoal -> "Quality"]]], {{p, {{-3, 1}, {3, 0}}}, 
  Locator}, {{r1, 1}, 1, 3}, {{r2, 2}, 1, 3}]

enter image description here

matrix42
  • 6,996
  • 2
  • 26
  • 62
2
circles = MapThread[Circle, {##}] &;

tangentLines = If[Or[RegionWithin[##], RegionWithin[#2, #]]& @@ MapThread[Disk, {##}],
   {}, InfiniteLine @@@ MaximalBy[MeshPrimitives[#, 1], ArcLength, 2] & @
    ConvexHullMesh[Join @@ MapThread[CirclePoints[##, 100] &, {##}]]] &; 

Manipulate[Graphics[{circles[p, {r1, r2}], Red, tangentLines[p, {r1, r2}]}, 
   PlotRange -> 6, Frame -> True], 
 {{p, {{-3, 1}, {3, 0}}}, Locator},
 {{r1, 1}, 1, 3},
 {{r2, 2}, 1, 3}]

enter image description here

kglr
  • 394,356
  • 18
  • 477
  • 896
1
center1 = {0, 0};
center2 = {4, 5};
sol = SolveValues[{x1, y1} \[Element] 
     Circle[center1] && {x2, y2} \[Element] Circle[center2, 2] && 
    GeometricTest[{Circle[], 
      InfiniteLine[{{x1, y1}, {x2, y2}}]}, {"Tangent", {x1, y1}}] && 
    GeometricTest[{Circle[center2, 2], 
      InfiniteLine[{{x1, y1}, {x2, y2}}]}, {"Tangent", {x2, y2}}] && 
    GeometricTest[{Point[{x1, y1}], Point[{x2, y2}]}, {"SameSide", 
      InfiniteLine[{center1, center2}]}], {x1, y1, x2, y2}];
Graphics[{Circle[center1], Circle[center2, 2], Red, 
  InfiniteLine /@ ArrayReshape[sol, {2, 2, 2}]}]

enter image description here

yode
  • 26,686
  • 4
  • 62
  • 167
1

There are two ways for two arbitrary regions, the easy one is by the convenient of ConvexHullRegion.

Manipulate[
 Graphics[{{EdgeForm[Red], FaceForm[], 
    ConvexHullRegion[
     RegionUnion[Disk[p[[1]], r1], Disk[p[[2]], r2]]]}, {EdgeForm[
     Blue], FaceForm[], Disk[p[[1]], r1], Disk[p[[2]], r2]}}, 
  PlotRange -> 10, Frame -> True], {{p, {{-3, 1}, {3, 0}}}, 
  Locator}, {r1, {2, 1}, {4, 4}}, {r2, {2, 3}, {8, 8}}]

enter image description here

cvgmt
  • 72,231
  • 4
  • 75
  • 133