Connect spy with tangent lines
Clash 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
tikz-pgf spy
add a comment |Â
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
tikz-pgf spy
add a comment |Â
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
tikz-pgf spy
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
tikz-pgf spy
tikz-pgf spy
asked 5 hours ago
Claudio
560415
560415
add a comment |Â
add a comment |Â
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
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()
add a comment |Â
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
add a comment |Â
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
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()
add a comment |Â
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
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()
add a comment |Â
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
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()
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
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()
answered 1 hour ago
Claudio
560415
560415
add a comment |Â
add a comment |Â
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
add a comment |Â
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
add a comment |Â
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
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
answered 32 mins ago


marmot
65.7k471142
65.7k471142
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password