Connect spy with tangent lines

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
4
down vote

favorite












I am using TikZ spy library to magnify part of my plot, and I would like to connect the spy point and the magnifying glass with two tangents to both circles (see second example). I found and implemented an algorithm to compute such lines (or, better, the four interesting points in the two circles), but I cannot understand how to pass to it the coordinates and radii of spy's circles. It seems to me that there is a mismatch between numbers, point and centimeters.



Is there a way to get what I described?



documentclass[crop,tikz,margin=10pt]standalone
usepackagetikz
usetikzlibraryintersections
usetikzlibraryspy
usepackagepgfplots
begindocument
begintikzpicture[
spy using outlines = circle,size=3cm,magnification=5,connect spies,
]
beginaxis
addplot+[domain = 0:2*pi] expression sin(deg(x));
coordinate (spy point) at (axis cs: 0, 0);
coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
endaxis

spy on (spy point) in node at (magnifying glass);
endtikzpicture
begintikzpicture
defradiusa0.3
defradiusb3

defxa5
defya3

defxb0
defyb0

coordinate (magnifying glass) at (xa, ya);
coordinate (spy point) at (xb, yb);

pgfmathsetmacroxp(xb * radiusa - xa * radiusb) / (radiusa - radiusb)
pgfmathsetmacroyp(yb * radiusa - ya * radiusb) / (radiusa - radiusb)
pgfmathsetmacrodistanceasqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa))
pgfmathsetmacrodistancebsqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb))
pgfmathsetmacrodenoma(xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
pgfmathsetmacrodenomb(xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)

pgfmathsetmacroxc(radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
pgfmathsetmacroyc(radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya

pgfmathsetmacroxe(radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
pgfmathsetmacroye(radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya

pgfmathsetmacroxd(radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
pgfmathsetmacroyd(radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb

pgfmathsetmacroxf(radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
pgfmathsetmacroyf(radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb


draw (magnifying glass) circle(radiusa);
draw (spy point) circle(radiusb);

% draw (xa, ya) node[scale=3, green] .;
% draw (xb, yb) node[scale=3, green] .;
% draw (xp, yp) node[scale=3, blue] .;
% draw (xc, yc) node[scale=3, red] .;
% draw (xd, yd) node[scale=3, red] .;
% draw (xe, ye) node[scale=3, red] .;
% draw (xf, yf) node[scale=3, red] .;

% draw (xa, ya) -- (xp, yp);
% draw (xb, yb) -- (xp, yp);

draw (xc, yc) -- (xd, yd);
draw (xe, ye) -- (xf, yf);
endtikzpicture
enddocument


enter image description here










share|improve this question

























    up vote
    4
    down vote

    favorite












    I am using TikZ spy library to magnify part of my plot, and I would like to connect the spy point and the magnifying glass with two tangents to both circles (see second example). I found and implemented an algorithm to compute such lines (or, better, the four interesting points in the two circles), but I cannot understand how to pass to it the coordinates and radii of spy's circles. It seems to me that there is a mismatch between numbers, point and centimeters.



    Is there a way to get what I described?



    documentclass[crop,tikz,margin=10pt]standalone
    usepackagetikz
    usetikzlibraryintersections
    usetikzlibraryspy
    usepackagepgfplots
    begindocument
    begintikzpicture[
    spy using outlines = circle,size=3cm,magnification=5,connect spies,
    ]
    beginaxis
    addplot+[domain = 0:2*pi] expression sin(deg(x));
    coordinate (spy point) at (axis cs: 0, 0);
    coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
    endaxis

    spy on (spy point) in node at (magnifying glass);
    endtikzpicture
    begintikzpicture
    defradiusa0.3
    defradiusb3

    defxa5
    defya3

    defxb0
    defyb0

    coordinate (magnifying glass) at (xa, ya);
    coordinate (spy point) at (xb, yb);

    pgfmathsetmacroxp(xb * radiusa - xa * radiusb) / (radiusa - radiusb)
    pgfmathsetmacroyp(yb * radiusa - ya * radiusb) / (radiusa - radiusb)
    pgfmathsetmacrodistanceasqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa))
    pgfmathsetmacrodistancebsqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb))
    pgfmathsetmacrodenoma(xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
    pgfmathsetmacrodenomb(xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)

    pgfmathsetmacroxc(radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
    pgfmathsetmacroyc(radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya

    pgfmathsetmacroxe(radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
    pgfmathsetmacroye(radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya

    pgfmathsetmacroxd(radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
    pgfmathsetmacroyd(radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb

    pgfmathsetmacroxf(radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
    pgfmathsetmacroyf(radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb


    draw (magnifying glass) circle(radiusa);
    draw (spy point) circle(radiusb);

    % draw (xa, ya) node[scale=3, green] .;
    % draw (xb, yb) node[scale=3, green] .;
    % draw (xp, yp) node[scale=3, blue] .;
    % draw (xc, yc) node[scale=3, red] .;
    % draw (xd, yd) node[scale=3, red] .;
    % draw (xe, ye) node[scale=3, red] .;
    % draw (xf, yf) node[scale=3, red] .;

    % draw (xa, ya) -- (xp, yp);
    % draw (xb, yb) -- (xp, yp);

    draw (xc, yc) -- (xd, yd);
    draw (xe, ye) -- (xf, yf);
    endtikzpicture
    enddocument


    enter image description here










    share|improve this question























      up vote
      4
      down vote

      favorite









      up vote
      4
      down vote

      favorite











      I am using TikZ spy library to magnify part of my plot, and I would like to connect the spy point and the magnifying glass with two tangents to both circles (see second example). I found and implemented an algorithm to compute such lines (or, better, the four interesting points in the two circles), but I cannot understand how to pass to it the coordinates and radii of spy's circles. It seems to me that there is a mismatch between numbers, point and centimeters.



      Is there a way to get what I described?



      documentclass[crop,tikz,margin=10pt]standalone
      usepackagetikz
      usetikzlibraryintersections
      usetikzlibraryspy
      usepackagepgfplots
      begindocument
      begintikzpicture[
      spy using outlines = circle,size=3cm,magnification=5,connect spies,
      ]
      beginaxis
      addplot+[domain = 0:2*pi] expression sin(deg(x));
      coordinate (spy point) at (axis cs: 0, 0);
      coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
      endaxis

      spy on (spy point) in node at (magnifying glass);
      endtikzpicture
      begintikzpicture
      defradiusa0.3
      defradiusb3

      defxa5
      defya3

      defxb0
      defyb0

      coordinate (magnifying glass) at (xa, ya);
      coordinate (spy point) at (xb, yb);

      pgfmathsetmacroxp(xb * radiusa - xa * radiusb) / (radiusa - radiusb)
      pgfmathsetmacroyp(yb * radiusa - ya * radiusb) / (radiusa - radiusb)
      pgfmathsetmacrodistanceasqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa))
      pgfmathsetmacrodistancebsqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb))
      pgfmathsetmacrodenoma(xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
      pgfmathsetmacrodenomb(xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)

      pgfmathsetmacroxc(radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
      pgfmathsetmacroyc(radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya

      pgfmathsetmacroxe(radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
      pgfmathsetmacroye(radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya

      pgfmathsetmacroxd(radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
      pgfmathsetmacroyd(radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb

      pgfmathsetmacroxf(radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
      pgfmathsetmacroyf(radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb


      draw (magnifying glass) circle(radiusa);
      draw (spy point) circle(radiusb);

      % draw (xa, ya) node[scale=3, green] .;
      % draw (xb, yb) node[scale=3, green] .;
      % draw (xp, yp) node[scale=3, blue] .;
      % draw (xc, yc) node[scale=3, red] .;
      % draw (xd, yd) node[scale=3, red] .;
      % draw (xe, ye) node[scale=3, red] .;
      % draw (xf, yf) node[scale=3, red] .;

      % draw (xa, ya) -- (xp, yp);
      % draw (xb, yb) -- (xp, yp);

      draw (xc, yc) -- (xd, yd);
      draw (xe, ye) -- (xf, yf);
      endtikzpicture
      enddocument


      enter image description here










      share|improve this question













      I am using TikZ spy library to magnify part of my plot, and I would like to connect the spy point and the magnifying glass with two tangents to both circles (see second example). I found and implemented an algorithm to compute such lines (or, better, the four interesting points in the two circles), but I cannot understand how to pass to it the coordinates and radii of spy's circles. It seems to me that there is a mismatch between numbers, point and centimeters.



      Is there a way to get what I described?



      documentclass[crop,tikz,margin=10pt]standalone
      usepackagetikz
      usetikzlibraryintersections
      usetikzlibraryspy
      usepackagepgfplots
      begindocument
      begintikzpicture[
      spy using outlines = circle,size=3cm,magnification=5,connect spies,
      ]
      beginaxis
      addplot+[domain = 0:2*pi] expression sin(deg(x));
      coordinate (spy point) at (axis cs: 0, 0);
      coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
      endaxis

      spy on (spy point) in node at (magnifying glass);
      endtikzpicture
      begintikzpicture
      defradiusa0.3
      defradiusb3

      defxa5
      defya3

      defxb0
      defyb0

      coordinate (magnifying glass) at (xa, ya);
      coordinate (spy point) at (xb, yb);

      pgfmathsetmacroxp(xb * radiusa - xa * radiusb) / (radiusa - radiusb)
      pgfmathsetmacroyp(yb * radiusa - ya * radiusb) / (radiusa - radiusb)
      pgfmathsetmacrodistanceasqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa))
      pgfmathsetmacrodistancebsqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb))
      pgfmathsetmacrodenoma(xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
      pgfmathsetmacrodenomb(xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)

      pgfmathsetmacroxc(radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
      pgfmathsetmacroyc(radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya

      pgfmathsetmacroxe(radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
      pgfmathsetmacroye(radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya

      pgfmathsetmacroxd(radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
      pgfmathsetmacroyd(radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb

      pgfmathsetmacroxf(radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
      pgfmathsetmacroyf(radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb


      draw (magnifying glass) circle(radiusa);
      draw (spy point) circle(radiusb);

      % draw (xa, ya) node[scale=3, green] .;
      % draw (xb, yb) node[scale=3, green] .;
      % draw (xp, yp) node[scale=3, blue] .;
      % draw (xc, yc) node[scale=3, red] .;
      % draw (xd, yd) node[scale=3, red] .;
      % draw (xe, ye) node[scale=3, red] .;
      % draw (xf, yf) node[scale=3, red] .;

      % draw (xa, ya) -- (xp, yp);
      % draw (xb, yb) -- (xp, yp);

      draw (xc, yc) -- (xd, yd);
      draw (xe, ye) -- (xf, yf);
      endtikzpicture
      enddocument


      enter image description here







      tikz-pgf spy






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 5 hours ago









      Claudio

      560415




      560415




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          2
          down vote













          I ended up implementing the algorithm in a short Python script and manually extracting the points' coordinated from TikZ source.



          Note that I used an inner scope otherwise the tangent lines itself were visible inside the magnifying glass. There is also a visible difference in line width between the tangents and the spy circle, so the figure needs to be tuned a bit.



          It is still less convenient than having everything implemented in TikZ.



          documentclass[crop,tikz,margin=10pt]standalone
          usepackagetikz
          usetikzlibraryintersections
          usetikzlibraryspy
          usepackagepgfplots
          makeatletter
          newcommandxcoord[2][center]%
          pgfpointanchor#2#1%
          pgfmathparsepgf@x/pgf@xx%
          pgfmathprintnumberpgfmathresult%

          newcommandycoord[2][center]%
          pgfpointanchor#2#1%
          pgfmathparsepgf@y/pgf@yy%
          pgfmathprintnumberpgfmathresult%

          makeatother
          begindocument
          begintikzpicture
          beginscope[
          spy using outlines = circle,size=3cm,magnification=5,
          ]
          beginaxis
          addplot+[domain = 0:2*pi] expression sin(deg(x));
          coordinate (spy point) at (axis cs: 0, 0);
          coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
          coordinate (a) at (rel axis cs: 0.5, 1.1);
          endaxis
          node at (a) spy point: xcoordspy point, ycoordspy point, glass: xcoordmagnifying glass, ycoordmagnifying glass;

          spy on (spy point) in node at (magnifying glass);
          endscope
          coordinate (c) at (-1.6589690159337693, 0.10010961563788023);
          coordinate (d) at (0.7862061968132461, 2.6420219231275763);
          coordinate (e) at (-2.962541913303562, 2.6233998438799935);
          coordinate (f) at (0.5254916173392875, 3.1466799687759988);
          draw (c) -- (d);
          draw (e) -- (f);
          endtikzpicture
          enddocument


          enter image description here



          from math import sqrt
          import matplotlib.pyplot as plt


          def main():
          radiusa = 1.5
          radiusb = 1.5 / 5
          xa = -2.74
          ya = 1.14
          xb = 0.57
          yb = 2.85

          figure, ax = plt.subplots()
          circlea = plt.Circle((xa, ya), radiusa, color='C0')
          circleb = plt.Circle((xb, yb), radiusb, color='C0')
          ax.add_artist(circlea)
          ax.add_artist(circleb)

          (xc, yc), (xd, yd), (xe, ye), (xf, yf) = compute(xa, ya, radiusa, xb, yb, radiusb)

          ax.plot([xc, xd], [yc, yd], color='C0')
          ax.plot([xe, xf], [ye, yf], color='C0')

          ax.set_xlim(
          min(xa - radiusa, xb - radiusb),
          max(xa + radiusa, xb + radiusb),
          )
          ax.set_ylim(
          min(ya - radiusa, yb - radiusb),
          max(ya + radiusa, yb + radiusb),
          )

          print("\coordinate (c) at (, );".format(xc, yc))
          print("\coordinate (d) at (, );".format(xd, yd))
          print("\coordinate (e) at (, );".format(xe, ye))
          print("\coordinate (f) at (, );".format(xf, yf))

          plt.show()


          def compute(xa, ya, radiusa, xb, yb, radiusb):
          xp = (xb * radiusa - xa * radiusb) / (radiusa - radiusb)
          yp = (yb * radiusa - ya * radiusb) / (radiusa - radiusb)
          distancea = sqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa)
          distanceb = sqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb)
          denoma = (xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
          denomb = (xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)

          xc = (radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
          yc = (radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya

          xe = (radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
          ye = (radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya

          xd = (radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
          yd = (radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb

          xf = (radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
          yf = (radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb

          return (xc, yc), (xd, yd), (xe, ye), (xf, yf)


          if __name__ == '__main__':
          main()





          share|improve this answer



























            up vote
            2
            down vote













            Here is a proposal without external programs. I am using your methods to compute the tangents but would like to remark that this has also been done in this answer. The coordinates of the relevant nodes are extracted with calc, and the conversion to cm is as simple as a multiplication by 1pt/1cm.



            documentclass[crop,tikz,margin=10pt]standalone
            usepackagetikz
            usetikzlibraryintersections,calc
            usetikzlibraryspy
            usepackagepgfplots
            begindocument
            begintikzpicture[
            spy using outlines = circle,size=3cm,magnification=5,connect spies,
            get coords/.code=xdefxan1xdefyan2
            xdefxbn3xdefybn4
            ]
            beginaxis
            addplot+[domain = 0:2*pi] expression sin(deg(x));
            coordinate (spy point) at (axis cs: 0, 0);
            coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
            endaxis

            spy[spy connection path=
            defradiusa0.3
            defradiusb1.5
            path let p1=(tikzspyonnode),p2=(tikzspyinnode),
            n1=x1*1pt/1cm,n2=y1*1pt/1cm,n3=x2*1pt/1cm,n4=y2*1pt/1cm in [get coords];
            pgfmathsetmacroxp(xb * radiusa - xa * radiusb) / (radiusa - radiusb)
            pgfmathsetmacroyp(yb * radiusa - ya * radiusb) / (radiusa - radiusb)
            pgfmathsetmacrodistanceasqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa))
            pgfmathsetmacrodistancebsqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb))
            pgfmathsetmacrodenoma(xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
            pgfmathsetmacrodenomb(xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)
            pgfmathsetmacroxc(radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
            pgfmathsetmacroyc(radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya
            pgfmathsetmacroxe(radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
            pgfmathsetmacroye(radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya
            pgfmathsetmacroxd(radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
            pgfmathsetmacroyd(radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb
            pgfmathsetmacroxf(radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
            pgfmathsetmacroyf(radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb
            draw (xc, yc) -- (xd, yd);
            draw (xe, ye) -- (xf, yf);]
            on (spy point) in node at (magnifying glass);
            endtikzpicture
            enddocument


            enter image description here






            share|improve this answer




















              Your Answer







              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "85"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              convertImagesToLinks: false,
              noModals: false,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );













               

              draft saved


              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f455365%2fconnect-spy-with-tangent-lines%23new-answer', 'question_page');

              );

              Post as a guest






























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              2
              down vote













              I ended up implementing the algorithm in a short Python script and manually extracting the points' coordinated from TikZ source.



              Note that I used an inner scope otherwise the tangent lines itself were visible inside the magnifying glass. There is also a visible difference in line width between the tangents and the spy circle, so the figure needs to be tuned a bit.



              It is still less convenient than having everything implemented in TikZ.



              documentclass[crop,tikz,margin=10pt]standalone
              usepackagetikz
              usetikzlibraryintersections
              usetikzlibraryspy
              usepackagepgfplots
              makeatletter
              newcommandxcoord[2][center]%
              pgfpointanchor#2#1%
              pgfmathparsepgf@x/pgf@xx%
              pgfmathprintnumberpgfmathresult%

              newcommandycoord[2][center]%
              pgfpointanchor#2#1%
              pgfmathparsepgf@y/pgf@yy%
              pgfmathprintnumberpgfmathresult%

              makeatother
              begindocument
              begintikzpicture
              beginscope[
              spy using outlines = circle,size=3cm,magnification=5,
              ]
              beginaxis
              addplot+[domain = 0:2*pi] expression sin(deg(x));
              coordinate (spy point) at (axis cs: 0, 0);
              coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
              coordinate (a) at (rel axis cs: 0.5, 1.1);
              endaxis
              node at (a) spy point: xcoordspy point, ycoordspy point, glass: xcoordmagnifying glass, ycoordmagnifying glass;

              spy on (spy point) in node at (magnifying glass);
              endscope
              coordinate (c) at (-1.6589690159337693, 0.10010961563788023);
              coordinate (d) at (0.7862061968132461, 2.6420219231275763);
              coordinate (e) at (-2.962541913303562, 2.6233998438799935);
              coordinate (f) at (0.5254916173392875, 3.1466799687759988);
              draw (c) -- (d);
              draw (e) -- (f);
              endtikzpicture
              enddocument


              enter image description here



              from math import sqrt
              import matplotlib.pyplot as plt


              def main():
              radiusa = 1.5
              radiusb = 1.5 / 5
              xa = -2.74
              ya = 1.14
              xb = 0.57
              yb = 2.85

              figure, ax = plt.subplots()
              circlea = plt.Circle((xa, ya), radiusa, color='C0')
              circleb = plt.Circle((xb, yb), radiusb, color='C0')
              ax.add_artist(circlea)
              ax.add_artist(circleb)

              (xc, yc), (xd, yd), (xe, ye), (xf, yf) = compute(xa, ya, radiusa, xb, yb, radiusb)

              ax.plot([xc, xd], [yc, yd], color='C0')
              ax.plot([xe, xf], [ye, yf], color='C0')

              ax.set_xlim(
              min(xa - radiusa, xb - radiusb),
              max(xa + radiusa, xb + radiusb),
              )
              ax.set_ylim(
              min(ya - radiusa, yb - radiusb),
              max(ya + radiusa, yb + radiusb),
              )

              print("\coordinate (c) at (, );".format(xc, yc))
              print("\coordinate (d) at (, );".format(xd, yd))
              print("\coordinate (e) at (, );".format(xe, ye))
              print("\coordinate (f) at (, );".format(xf, yf))

              plt.show()


              def compute(xa, ya, radiusa, xb, yb, radiusb):
              xp = (xb * radiusa - xa * radiusb) / (radiusa - radiusb)
              yp = (yb * radiusa - ya * radiusb) / (radiusa - radiusb)
              distancea = sqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa)
              distanceb = sqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb)
              denoma = (xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
              denomb = (xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)

              xc = (radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
              yc = (radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya

              xe = (radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
              ye = (radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya

              xd = (radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
              yd = (radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb

              xf = (radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
              yf = (radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb

              return (xc, yc), (xd, yd), (xe, ye), (xf, yf)


              if __name__ == '__main__':
              main()





              share|improve this answer
























                up vote
                2
                down vote













                I ended up implementing the algorithm in a short Python script and manually extracting the points' coordinated from TikZ source.



                Note that I used an inner scope otherwise the tangent lines itself were visible inside the magnifying glass. There is also a visible difference in line width between the tangents and the spy circle, so the figure needs to be tuned a bit.



                It is still less convenient than having everything implemented in TikZ.



                documentclass[crop,tikz,margin=10pt]standalone
                usepackagetikz
                usetikzlibraryintersections
                usetikzlibraryspy
                usepackagepgfplots
                makeatletter
                newcommandxcoord[2][center]%
                pgfpointanchor#2#1%
                pgfmathparsepgf@x/pgf@xx%
                pgfmathprintnumberpgfmathresult%

                newcommandycoord[2][center]%
                pgfpointanchor#2#1%
                pgfmathparsepgf@y/pgf@yy%
                pgfmathprintnumberpgfmathresult%

                makeatother
                begindocument
                begintikzpicture
                beginscope[
                spy using outlines = circle,size=3cm,magnification=5,
                ]
                beginaxis
                addplot+[domain = 0:2*pi] expression sin(deg(x));
                coordinate (spy point) at (axis cs: 0, 0);
                coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
                coordinate (a) at (rel axis cs: 0.5, 1.1);
                endaxis
                node at (a) spy point: xcoordspy point, ycoordspy point, glass: xcoordmagnifying glass, ycoordmagnifying glass;

                spy on (spy point) in node at (magnifying glass);
                endscope
                coordinate (c) at (-1.6589690159337693, 0.10010961563788023);
                coordinate (d) at (0.7862061968132461, 2.6420219231275763);
                coordinate (e) at (-2.962541913303562, 2.6233998438799935);
                coordinate (f) at (0.5254916173392875, 3.1466799687759988);
                draw (c) -- (d);
                draw (e) -- (f);
                endtikzpicture
                enddocument


                enter image description here



                from math import sqrt
                import matplotlib.pyplot as plt


                def main():
                radiusa = 1.5
                radiusb = 1.5 / 5
                xa = -2.74
                ya = 1.14
                xb = 0.57
                yb = 2.85

                figure, ax = plt.subplots()
                circlea = plt.Circle((xa, ya), radiusa, color='C0')
                circleb = plt.Circle((xb, yb), radiusb, color='C0')
                ax.add_artist(circlea)
                ax.add_artist(circleb)

                (xc, yc), (xd, yd), (xe, ye), (xf, yf) = compute(xa, ya, radiusa, xb, yb, radiusb)

                ax.plot([xc, xd], [yc, yd], color='C0')
                ax.plot([xe, xf], [ye, yf], color='C0')

                ax.set_xlim(
                min(xa - radiusa, xb - radiusb),
                max(xa + radiusa, xb + radiusb),
                )
                ax.set_ylim(
                min(ya - radiusa, yb - radiusb),
                max(ya + radiusa, yb + radiusb),
                )

                print("\coordinate (c) at (, );".format(xc, yc))
                print("\coordinate (d) at (, );".format(xd, yd))
                print("\coordinate (e) at (, );".format(xe, ye))
                print("\coordinate (f) at (, );".format(xf, yf))

                plt.show()


                def compute(xa, ya, radiusa, xb, yb, radiusb):
                xp = (xb * radiusa - xa * radiusb) / (radiusa - radiusb)
                yp = (yb * radiusa - ya * radiusb) / (radiusa - radiusb)
                distancea = sqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa)
                distanceb = sqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb)
                denoma = (xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
                denomb = (xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)

                xc = (radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
                yc = (radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya

                xe = (radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
                ye = (radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya

                xd = (radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
                yd = (radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb

                xf = (radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
                yf = (radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb

                return (xc, yc), (xd, yd), (xe, ye), (xf, yf)


                if __name__ == '__main__':
                main()





                share|improve this answer






















                  up vote
                  2
                  down vote










                  up vote
                  2
                  down vote









                  I ended up implementing the algorithm in a short Python script and manually extracting the points' coordinated from TikZ source.



                  Note that I used an inner scope otherwise the tangent lines itself were visible inside the magnifying glass. There is also a visible difference in line width between the tangents and the spy circle, so the figure needs to be tuned a bit.



                  It is still less convenient than having everything implemented in TikZ.



                  documentclass[crop,tikz,margin=10pt]standalone
                  usepackagetikz
                  usetikzlibraryintersections
                  usetikzlibraryspy
                  usepackagepgfplots
                  makeatletter
                  newcommandxcoord[2][center]%
                  pgfpointanchor#2#1%
                  pgfmathparsepgf@x/pgf@xx%
                  pgfmathprintnumberpgfmathresult%

                  newcommandycoord[2][center]%
                  pgfpointanchor#2#1%
                  pgfmathparsepgf@y/pgf@yy%
                  pgfmathprintnumberpgfmathresult%

                  makeatother
                  begindocument
                  begintikzpicture
                  beginscope[
                  spy using outlines = circle,size=3cm,magnification=5,
                  ]
                  beginaxis
                  addplot+[domain = 0:2*pi] expression sin(deg(x));
                  coordinate (spy point) at (axis cs: 0, 0);
                  coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
                  coordinate (a) at (rel axis cs: 0.5, 1.1);
                  endaxis
                  node at (a) spy point: xcoordspy point, ycoordspy point, glass: xcoordmagnifying glass, ycoordmagnifying glass;

                  spy on (spy point) in node at (magnifying glass);
                  endscope
                  coordinate (c) at (-1.6589690159337693, 0.10010961563788023);
                  coordinate (d) at (0.7862061968132461, 2.6420219231275763);
                  coordinate (e) at (-2.962541913303562, 2.6233998438799935);
                  coordinate (f) at (0.5254916173392875, 3.1466799687759988);
                  draw (c) -- (d);
                  draw (e) -- (f);
                  endtikzpicture
                  enddocument


                  enter image description here



                  from math import sqrt
                  import matplotlib.pyplot as plt


                  def main():
                  radiusa = 1.5
                  radiusb = 1.5 / 5
                  xa = -2.74
                  ya = 1.14
                  xb = 0.57
                  yb = 2.85

                  figure, ax = plt.subplots()
                  circlea = plt.Circle((xa, ya), radiusa, color='C0')
                  circleb = plt.Circle((xb, yb), radiusb, color='C0')
                  ax.add_artist(circlea)
                  ax.add_artist(circleb)

                  (xc, yc), (xd, yd), (xe, ye), (xf, yf) = compute(xa, ya, radiusa, xb, yb, radiusb)

                  ax.plot([xc, xd], [yc, yd], color='C0')
                  ax.plot([xe, xf], [ye, yf], color='C0')

                  ax.set_xlim(
                  min(xa - radiusa, xb - radiusb),
                  max(xa + radiusa, xb + radiusb),
                  )
                  ax.set_ylim(
                  min(ya - radiusa, yb - radiusb),
                  max(ya + radiusa, yb + radiusb),
                  )

                  print("\coordinate (c) at (, );".format(xc, yc))
                  print("\coordinate (d) at (, );".format(xd, yd))
                  print("\coordinate (e) at (, );".format(xe, ye))
                  print("\coordinate (f) at (, );".format(xf, yf))

                  plt.show()


                  def compute(xa, ya, radiusa, xb, yb, radiusb):
                  xp = (xb * radiusa - xa * radiusb) / (radiusa - radiusb)
                  yp = (yb * radiusa - ya * radiusb) / (radiusa - radiusb)
                  distancea = sqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa)
                  distanceb = sqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb)
                  denoma = (xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
                  denomb = (xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)

                  xc = (radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
                  yc = (radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya

                  xe = (radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
                  ye = (radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya

                  xd = (radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
                  yd = (radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb

                  xf = (radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
                  yf = (radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb

                  return (xc, yc), (xd, yd), (xe, ye), (xf, yf)


                  if __name__ == '__main__':
                  main()





                  share|improve this answer












                  I ended up implementing the algorithm in a short Python script and manually extracting the points' coordinated from TikZ source.



                  Note that I used an inner scope otherwise the tangent lines itself were visible inside the magnifying glass. There is also a visible difference in line width between the tangents and the spy circle, so the figure needs to be tuned a bit.



                  It is still less convenient than having everything implemented in TikZ.



                  documentclass[crop,tikz,margin=10pt]standalone
                  usepackagetikz
                  usetikzlibraryintersections
                  usetikzlibraryspy
                  usepackagepgfplots
                  makeatletter
                  newcommandxcoord[2][center]%
                  pgfpointanchor#2#1%
                  pgfmathparsepgf@x/pgf@xx%
                  pgfmathprintnumberpgfmathresult%

                  newcommandycoord[2][center]%
                  pgfpointanchor#2#1%
                  pgfmathparsepgf@y/pgf@yy%
                  pgfmathprintnumberpgfmathresult%

                  makeatother
                  begindocument
                  begintikzpicture
                  beginscope[
                  spy using outlines = circle,size=3cm,magnification=5,
                  ]
                  beginaxis
                  addplot+[domain = 0:2*pi] expression sin(deg(x));
                  coordinate (spy point) at (axis cs: 0, 0);
                  coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
                  coordinate (a) at (rel axis cs: 0.5, 1.1);
                  endaxis
                  node at (a) spy point: xcoordspy point, ycoordspy point, glass: xcoordmagnifying glass, ycoordmagnifying glass;

                  spy on (spy point) in node at (magnifying glass);
                  endscope
                  coordinate (c) at (-1.6589690159337693, 0.10010961563788023);
                  coordinate (d) at (0.7862061968132461, 2.6420219231275763);
                  coordinate (e) at (-2.962541913303562, 2.6233998438799935);
                  coordinate (f) at (0.5254916173392875, 3.1466799687759988);
                  draw (c) -- (d);
                  draw (e) -- (f);
                  endtikzpicture
                  enddocument


                  enter image description here



                  from math import sqrt
                  import matplotlib.pyplot as plt


                  def main():
                  radiusa = 1.5
                  radiusb = 1.5 / 5
                  xa = -2.74
                  ya = 1.14
                  xb = 0.57
                  yb = 2.85

                  figure, ax = plt.subplots()
                  circlea = plt.Circle((xa, ya), radiusa, color='C0')
                  circleb = plt.Circle((xb, yb), radiusb, color='C0')
                  ax.add_artist(circlea)
                  ax.add_artist(circleb)

                  (xc, yc), (xd, yd), (xe, ye), (xf, yf) = compute(xa, ya, radiusa, xb, yb, radiusb)

                  ax.plot([xc, xd], [yc, yd], color='C0')
                  ax.plot([xe, xf], [ye, yf], color='C0')

                  ax.set_xlim(
                  min(xa - radiusa, xb - radiusb),
                  max(xa + radiusa, xb + radiusb),
                  )
                  ax.set_ylim(
                  min(ya - radiusa, yb - radiusb),
                  max(ya + radiusa, yb + radiusb),
                  )

                  print("\coordinate (c) at (, );".format(xc, yc))
                  print("\coordinate (d) at (, );".format(xd, yd))
                  print("\coordinate (e) at (, );".format(xe, ye))
                  print("\coordinate (f) at (, );".format(xf, yf))

                  plt.show()


                  def compute(xa, ya, radiusa, xb, yb, radiusb):
                  xp = (xb * radiusa - xa * radiusb) / (radiusa - radiusb)
                  yp = (yb * radiusa - ya * radiusb) / (radiusa - radiusb)
                  distancea = sqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa)
                  distanceb = sqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb)
                  denoma = (xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
                  denomb = (xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)

                  xc = (radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
                  yc = (radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya

                  xe = (radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
                  ye = (radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya

                  xd = (radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
                  yd = (radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb

                  xf = (radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
                  yf = (radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb

                  return (xc, yc), (xd, yd), (xe, ye), (xf, yf)


                  if __name__ == '__main__':
                  main()






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 1 hour ago









                  Claudio

                  560415




                  560415




















                      up vote
                      2
                      down vote













                      Here is a proposal without external programs. I am using your methods to compute the tangents but would like to remark that this has also been done in this answer. The coordinates of the relevant nodes are extracted with calc, and the conversion to cm is as simple as a multiplication by 1pt/1cm.



                      documentclass[crop,tikz,margin=10pt]standalone
                      usepackagetikz
                      usetikzlibraryintersections,calc
                      usetikzlibraryspy
                      usepackagepgfplots
                      begindocument
                      begintikzpicture[
                      spy using outlines = circle,size=3cm,magnification=5,connect spies,
                      get coords/.code=xdefxan1xdefyan2
                      xdefxbn3xdefybn4
                      ]
                      beginaxis
                      addplot+[domain = 0:2*pi] expression sin(deg(x));
                      coordinate (spy point) at (axis cs: 0, 0);
                      coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
                      endaxis

                      spy[spy connection path=
                      defradiusa0.3
                      defradiusb1.5
                      path let p1=(tikzspyonnode),p2=(tikzspyinnode),
                      n1=x1*1pt/1cm,n2=y1*1pt/1cm,n3=x2*1pt/1cm,n4=y2*1pt/1cm in [get coords];
                      pgfmathsetmacroxp(xb * radiusa - xa * radiusb) / (radiusa - radiusb)
                      pgfmathsetmacroyp(yb * radiusa - ya * radiusb) / (radiusa - radiusb)
                      pgfmathsetmacrodistanceasqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa))
                      pgfmathsetmacrodistancebsqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb))
                      pgfmathsetmacrodenoma(xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
                      pgfmathsetmacrodenomb(xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)
                      pgfmathsetmacroxc(radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
                      pgfmathsetmacroyc(radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya
                      pgfmathsetmacroxe(radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
                      pgfmathsetmacroye(radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya
                      pgfmathsetmacroxd(radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
                      pgfmathsetmacroyd(radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb
                      pgfmathsetmacroxf(radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
                      pgfmathsetmacroyf(radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb
                      draw (xc, yc) -- (xd, yd);
                      draw (xe, ye) -- (xf, yf);]
                      on (spy point) in node at (magnifying glass);
                      endtikzpicture
                      enddocument


                      enter image description here






                      share|improve this answer
























                        up vote
                        2
                        down vote













                        Here is a proposal without external programs. I am using your methods to compute the tangents but would like to remark that this has also been done in this answer. The coordinates of the relevant nodes are extracted with calc, and the conversion to cm is as simple as a multiplication by 1pt/1cm.



                        documentclass[crop,tikz,margin=10pt]standalone
                        usepackagetikz
                        usetikzlibraryintersections,calc
                        usetikzlibraryspy
                        usepackagepgfplots
                        begindocument
                        begintikzpicture[
                        spy using outlines = circle,size=3cm,magnification=5,connect spies,
                        get coords/.code=xdefxan1xdefyan2
                        xdefxbn3xdefybn4
                        ]
                        beginaxis
                        addplot+[domain = 0:2*pi] expression sin(deg(x));
                        coordinate (spy point) at (axis cs: 0, 0);
                        coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
                        endaxis

                        spy[spy connection path=
                        defradiusa0.3
                        defradiusb1.5
                        path let p1=(tikzspyonnode),p2=(tikzspyinnode),
                        n1=x1*1pt/1cm,n2=y1*1pt/1cm,n3=x2*1pt/1cm,n4=y2*1pt/1cm in [get coords];
                        pgfmathsetmacroxp(xb * radiusa - xa * radiusb) / (radiusa - radiusb)
                        pgfmathsetmacroyp(yb * radiusa - ya * radiusb) / (radiusa - radiusb)
                        pgfmathsetmacrodistanceasqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa))
                        pgfmathsetmacrodistancebsqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb))
                        pgfmathsetmacrodenoma(xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
                        pgfmathsetmacrodenomb(xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)
                        pgfmathsetmacroxc(radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
                        pgfmathsetmacroyc(radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya
                        pgfmathsetmacroxe(radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
                        pgfmathsetmacroye(radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya
                        pgfmathsetmacroxd(radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
                        pgfmathsetmacroyd(radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb
                        pgfmathsetmacroxf(radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
                        pgfmathsetmacroyf(radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb
                        draw (xc, yc) -- (xd, yd);
                        draw (xe, ye) -- (xf, yf);]
                        on (spy point) in node at (magnifying glass);
                        endtikzpicture
                        enddocument


                        enter image description here






                        share|improve this answer






















                          up vote
                          2
                          down vote










                          up vote
                          2
                          down vote









                          Here is a proposal without external programs. I am using your methods to compute the tangents but would like to remark that this has also been done in this answer. The coordinates of the relevant nodes are extracted with calc, and the conversion to cm is as simple as a multiplication by 1pt/1cm.



                          documentclass[crop,tikz,margin=10pt]standalone
                          usepackagetikz
                          usetikzlibraryintersections,calc
                          usetikzlibraryspy
                          usepackagepgfplots
                          begindocument
                          begintikzpicture[
                          spy using outlines = circle,size=3cm,magnification=5,connect spies,
                          get coords/.code=xdefxan1xdefyan2
                          xdefxbn3xdefybn4
                          ]
                          beginaxis
                          addplot+[domain = 0:2*pi] expression sin(deg(x));
                          coordinate (spy point) at (axis cs: 0, 0);
                          coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
                          endaxis

                          spy[spy connection path=
                          defradiusa0.3
                          defradiusb1.5
                          path let p1=(tikzspyonnode),p2=(tikzspyinnode),
                          n1=x1*1pt/1cm,n2=y1*1pt/1cm,n3=x2*1pt/1cm,n4=y2*1pt/1cm in [get coords];
                          pgfmathsetmacroxp(xb * radiusa - xa * radiusb) / (radiusa - radiusb)
                          pgfmathsetmacroyp(yb * radiusa - ya * radiusb) / (radiusa - radiusb)
                          pgfmathsetmacrodistanceasqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa))
                          pgfmathsetmacrodistancebsqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb))
                          pgfmathsetmacrodenoma(xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
                          pgfmathsetmacrodenomb(xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)
                          pgfmathsetmacroxc(radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
                          pgfmathsetmacroyc(radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya
                          pgfmathsetmacroxe(radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
                          pgfmathsetmacroye(radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya
                          pgfmathsetmacroxd(radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
                          pgfmathsetmacroyd(radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb
                          pgfmathsetmacroxf(radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
                          pgfmathsetmacroyf(radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb
                          draw (xc, yc) -- (xd, yd);
                          draw (xe, ye) -- (xf, yf);]
                          on (spy point) in node at (magnifying glass);
                          endtikzpicture
                          enddocument


                          enter image description here






                          share|improve this answer












                          Here is a proposal without external programs. I am using your methods to compute the tangents but would like to remark that this has also been done in this answer. The coordinates of the relevant nodes are extracted with calc, and the conversion to cm is as simple as a multiplication by 1pt/1cm.



                          documentclass[crop,tikz,margin=10pt]standalone
                          usepackagetikz
                          usetikzlibraryintersections,calc
                          usetikzlibraryspy
                          usepackagepgfplots
                          begindocument
                          begintikzpicture[
                          spy using outlines = circle,size=3cm,magnification=5,connect spies,
                          get coords/.code=xdefxan1xdefyan2
                          xdefxbn3xdefybn4
                          ]
                          beginaxis
                          addplot+[domain = 0:2*pi] expression sin(deg(x));
                          coordinate (spy point) at (axis cs: 0, 0);
                          coordinate (magnifying glass) at (rel axis cs: -0.4, 0.2);
                          endaxis

                          spy[spy connection path=
                          defradiusa0.3
                          defradiusb1.5
                          path let p1=(tikzspyonnode),p2=(tikzspyinnode),
                          n1=x1*1pt/1cm,n2=y1*1pt/1cm,n3=x2*1pt/1cm,n4=y2*1pt/1cm in [get coords];
                          pgfmathsetmacroxp(xb * radiusa - xa * radiusb) / (radiusa - radiusb)
                          pgfmathsetmacroyp(yb * radiusa - ya * radiusb) / (radiusa - radiusb)
                          pgfmathsetmacrodistanceasqrt((xp - xa) * (xp - xa) + (yp - ya) * (yp - ya) - radiusa * radiusa))
                          pgfmathsetmacrodistancebsqrt((xp - xb) * (xp - xb) + (yp - yb) * (yp - yb) - radiusb * radiusb))
                          pgfmathsetmacrodenoma(xp - xa)*(xp - xa) + (yp - ya)*(yp - ya)
                          pgfmathsetmacrodenomb(xp - xb)*(xp - xb) + (yp - yb)*(yp - yb)
                          pgfmathsetmacroxc(radiusa * radiusa * (xp - xa) + radiusa * (yp - ya) * distancea) / denoma + xa
                          pgfmathsetmacroyc(radiusa * radiusa * (yp - ya) - radiusa * (xp - xa) * distancea) / denoma + ya
                          pgfmathsetmacroxe(radiusa * radiusa * (xp - xa) - radiusa * (yp - ya) * distancea) / denoma + xa
                          pgfmathsetmacroye(radiusa * radiusa * (yp - ya) + radiusa * (xp - xa) * distancea) / denoma + ya
                          pgfmathsetmacroxd(radiusb * radiusb * (xp - xb) + radiusb * (yp - yb) * distanceb) / denomb + xb
                          pgfmathsetmacroyd(radiusb * radiusb * (yp - yb) - radiusb * (xp - xb) * distanceb) / denomb + yb
                          pgfmathsetmacroxf(radiusb * radiusb * (xp - xb) - radiusb * (yp - yb) * distanceb) / denomb + xb
                          pgfmathsetmacroyf(radiusb * radiusb * (yp - yb) + radiusb * (xp - xb) * distanceb) / denomb + yb
                          draw (xc, yc) -- (xd, yd);
                          draw (xe, ye) -- (xf, yf);]
                          on (spy point) in node at (magnifying glass);
                          endtikzpicture
                          enddocument


                          enter image description here







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered 32 mins ago









                          marmot

                          65.7k471142




                          65.7k471142



























                               

                              draft saved


                              draft discarded















































                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f455365%2fconnect-spy-with-tangent-lines%23new-answer', 'question_page');

                              );

                              Post as a guest













































































                              Comments

                              Popular posts from this blog

                              What does second last employer means? [closed]

                              List of Gilmore Girls characters

                              Confectionery