3

I am looking to replicate the figure shown in the image below. What is the simplest way to create the infinity-like curves and gray filled region of (c) using TikZ? Any tips would be appreciated! Thank you for your time.

enter image description here

Spahn711
  • 287
  • 1
    There is obviously a formula describing these shapes, so knowing that formula would be much better than just faking it. – John Kormylo May 26 '15 at 04:18

2 Answers2

6

I think faking it is just fine...

\documentclass[border=5]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,math}
\tikzmath{
  \x1 = -1/2;  \x2 = 1/2;
  \r1 = 1/3; \r2 = 1/6;
  \R1 = 1/2; \R2 = 1/4;
  \q1 = \R2 / (\R1 + \R2);
  \q2 = \R1 / (\R1 + \R2);
  \s = 1/12;
}
\begin{document}
\begin{tikzpicture}
\draw [fill=gray] (\x1, 0) circle [radius=\r1];
\draw [fill=gray] (\x2, 0) circle [radius=\r2];

\draw (\x1,\R1) 
  arc (90:270:\R1) cos (\x1*\q1+\x2*\q2, 0) sin (\x2,\R2) 
  arc (90:-90:\R2) cos (\x1*\q1+\x2*\q2, 0) sin cycle;

\tikzset{shift=(270:2)}

\fill [gray] (\x1,\R1) 
  arc (90:270:\R1) cos (\x1*\q1+\x2*\q2, 0) sin cycle;
\draw [fill=gray] (\x1, 0) circle [radius=\r1];
\draw [fill=gray] (\x2, 0) circle [radius=\r2];

\draw (\x1,\R1) 
  arc (90:270:\R1) cos (\x1*\q1+\x2*\q2, 0) sin (\x2,\R2) 
  arc (90:-90:\R2) cos (\x1*\q1+\x2*\q2, 0) sin cycle;

\tikzset{shift=(270:2)}

\fill [gray] (\x1,\R1+\s) 
  arc ( 90:270:\R1+\s) cos (\x1*\q1+\x2*\q2, -\s*4/3) sin (\x2,-\R2-\s)
  arc (270:450:\R2+\s) cos (\x1*\q1+\x2*\q2, \s*4/3) sin cycle; 

\draw [fill=gray] (\x1, 0) circle [radius=\r1];
\draw [fill=gray] (\x2, 0) circle [radius=\r2];

\draw (\x1,\R1) 
  arc (90:270:\R1) cos (\x1*\q1+\x2*\q2, 0) sin (\x2,\R2) 
  arc (90:-90:\R2) cos (\x1*\q1+\x2*\q2, 0) sin cycle;

\end{tikzpicture}
\end{document}

enter image description here

Mark Wibrow
  • 70,437
6

This one makes an interesting exercise in managing subpaths in Metapost.

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);

path C, c, loop;

C = fullcircle scaled 42;
c = fullcircle scaled 14 shifted 72 right;

loop = subpath (1,7) of C scaled 2
    .. subpath (3,-3) of fullcircle scaled 28 shifted center c
    .. cycle;

picture detached, semidetached, contact;

defaultfont := "ptmr8r";
color grey; grey = 0.8 white;

detached = image(
  fill C withcolor grey;
  fill c withcolor grey;
  draw C;
  draw c;
  draw loop;
  label("(a)",    point 3 of loop shifted 15 left);
  label.rt("Detached", point 10 of loop shifted 5 right);
);  

semidetached = image(
  (s,t) = subpath(6,7) of loop intersectiontimes subpath (13,14) of loop;
  fill subpath (t-1,6+s) of loop ..cycle withcolor grey;
  fill c withcolor grey;
  draw C;
  draw c;
  draw loop;
  label("(b)",    point 3 of loop shifted 15 left);
  label.rt("Semi-detached", point 10 of loop shifted 5 right);
  label.top("Secondary", point 1 of loop);
  label.top("Primary",   point 8 of loop);
  );

contact = image(
  filldraw subpath(-.6,6.6) of loop
        .. subpath(13.1,6.9) of loop .. cycle
  withpen pencircle scaled 5 withcolor grey;
  draw C;
  draw c;
  draw loop;
  label("(c)",    point 3 of loop shifted 15 left);
  label.rt("Contact", point 10 of loop shifted 5 right);

);

draw detached;
draw semidetached shifted 104 down;
draw contact shifted 208 down;

endfig;
end.

If you are struggling to see how it works, try adding this

for i=1 upto length loop: dotlabel.top(decimal i, point i of loop); endfor

to one of the images so you can see where the points are on loop.

Thruston
  • 42,268