12

I'm trying to depict Viviani's curve with tikz. Ideally my picture would look like this one:

enter image description here

(source)

My code is

\documentclass[]{standalone}

\usepackage{pgfplots}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
  \begin{axis}[axis lines=center, ticks=none, view/h=120, view/v=5]
    \addplot3+[domain=0:4*pi, samples=100, samples y=0, no marks, smooth, ultra thick,black](
    {1+cos(deg(x))},
    {sin(deg(x))},
    {2*sin(deg(x)/2)}
    );% node[blue,circle,fill,pos=0.3]{} node[red,draw,pos=0.65,thick]{};
    \addplot3[%
    opacity = 0.1,
    mesh,
    blue,
    z buffer = sort,
    samples = 50,
    variable = \u,
    variable y = \v,
    domain = 0:180,
    y domain = 0:360,
    ]
    ({2*cos(u)*sin(v)}, {2*sin(u)*sin(v)}, {2*cos(v)});
    \addplot3[%
    opacity = .1,
    mesh,
    red,
    z buffer = sort,
    samples = 50,
    variable = \u,
    variable y = \v,
    domain = 0:360,
    y domain = -2:2,
    ]
    ({1+cos(u)}, {sin(u)}, {v});
  \end{axis}
\end{tikzpicture}

\end{document}

This produces

enter image description here

The plot doesn't convey the intersection very well. Is my code salvageable?

  • What do you want to see? To me the only difference is that the opacitiy of your cylinder is lower (more transparent) than in the original picture. – Douwe66 Feb 29 '16 at 7:30
  • @Douwe66 It's not clear in my picture where the cylinder is "outside" of the sphere. The first picture depicts this quite well. – Brian Fitzpatrick Feb 29 '16 at 7:32
  • Have you found this post: tex.stackexchange.com/questions/73922/… It seems not possible to get it right without coding what should be in front... – Douwe66 Feb 29 '16 at 7:54
  • Perhaps the view does not help... – mirkom Feb 29 '16 at 13:08
  • I have found another hack that allows to plot an arbitrary number of surfaces correctly, without doing anything manually: tex.stackexchange.com/a/394066/38641. – iavr Oct 1 '17 at 10:48
8

As tikz cannot properly do the intersection to draw part of the cylinder inside the sphere and part of it outside, you can best draw it yourself in parts. In the example below, I did this using min() and max()

So cut the cylinder in pieces to show the outside. Furthermore, it helps to use a surface instead of the grid plot.

enter image description here

\documentclass[]{standalone}

\usepackage{pgfplots}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
  \begin{axis}[axis lines=center, ticks=none, view/h=110, view/v=10]

    \addplot3[%
    opacity = 1,
    surf,
        faceted color=blue,
    white,
    z buffer = sort,
    samples = 30,
    variable = \u,
    variable y = \v,
    domain = 0:180,
    y domain = 0:360,
    ]
    ({2*cos(u)*sin(v)}, {2*sin(u)*sin(v)}, {2*cos(v)});

    \addplot3+[domain=0:4*pi, samples=50, samples y=0, no marks, smooth, ultra thick,black](
    {1+cos(deg(x))},
    {sin(deg(x))},
    {2*sin(deg(x)/2)}
    );% node[blue,circle,fill,pos=0.3]{} node[red,draw,pos=0.65,thick]{};

    \addplot3[%
    opacity = 1,
    surf,
        faceted color=red,
    white,
    z buffer = sort,
    samples = 30,
    variable = \u,
    variable y = \v,
    domain = 0:360,
    y domain = 0:2,
    ]
    ({1+cos(u)}, {sin(u)}, {max(sqrt(2*(2-x)),v)});

    \addplot3[%
    opacity = 1,
    surf,
        faceted color=red,
    white,
    z buffer = sort,
    samples = 30,
    variable = \u,
    variable y = \v,
    domain = 0:360,
    y domain = -2:0,
    ]
    ({1+cos(u)}, {sin(u)}, {min(-sqrt(2*(2-x)),v)});



  \end{axis}
\end{tikzpicture}

\end{document}
  • Wow! This is a great answer! – Brian Fitzpatrick Mar 1 '16 at 16:12
  • I liked your question as I could also learn a lot from it! In addition to my answer, I just found axis equal that might help to get the ratio right (because the sphere looks a bit blown up in the xy-plane). – Douwe66 Mar 5 '16 at 12:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.