3

I want to draw the following picture using tikz?

enter image description here

For this I used the code of

https://tex.stackexchange.com/a/597008/241755

post but I want x-axes to be from origin to right. It is not just a matter of drawing axes, but also calculations in these coordinates. (I don't need the top cylinder of the linked post)

p.s. I am aware that my post is kind of please-do-it-for-me. Sorry for this.

enter image description here

C.F.G
  • 552
  • In the example you quote, the ratio of cylinder and sphere radii are tuned in such a way that for the chosen view angle the the upper circle of the cylinder touch the top-most point of the sphere. Do you wish to maintain this tuning? –  Jul 04 '23 at 17:44
  • @user23623: I don't need the top-cylinder. – C.F.G Jul 04 '23 at 18:04
  • Maybe asymptote would be a better choice here. – projetmbc Jul 04 '23 at 18:58

1 Answers1

7

As I tried to explain in my comment, the parameters used in the answer you link to are tuned in such a way that, in screen coordinates, the top-most point of the circle coincides with the top-most point of the sphere. More specifically, the answer dials the ratio of cylinder and sphere radii in such a way that these points coincide in the isometric view. The following tunes the view angle in such a way that these points coincide for a given cylinder radius r and sphere radius R. This allows you to have the x-axis point in any direction you want.

\documentclass[tikz,border=2mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\begin{tikzpicture}[declare function={R=3;% radius of sphere
        r=1.5;% radius of cylinder
    }]
    \pgfmathsetmacro{\myalpha}{asin(r/R)}
    \pgfmathsetmacro{\myh}{R*cos(\myalpha)}
    \tdplotsetmaincoords{90-\myalpha}{0}
    \begin{scope}[tdplot_main_coords]
      \begin{scope}  
        \clip (0,0,\myh) circle[radius=r];
        \path[left color=gray!50!black,right color=gray,middle color=gray!20] (r/2,0,\myh) circle[radius=1.5*r];;  
      \end{scope}
      \draw[ball color=gray,even odd rule]  (0,0,\myh) circle[radius=r]
        [tdplot_screen_coords] (0,0) circle[radius=R];  
    \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

However, it is clear that this is not the most general situation, in which you can choose the radii and view angles independently of each other. This is what the following code does.

\documentclass[tikz,border=2mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\begin{tikzpicture}[declare function={R=3;% radius of sphere
        r=1.5;% radius of cylinder
        theta=75;% view angle
    }]
    \pgfmathsetmacro{\myalpha}{asin(r/R)}
    \pgfmathsetmacro{\myh}{R*cos(\myalpha)}
    \pgfmathtruncatemacro{\iflag}{ifthenelse(theta>90-\myalpha,1,0)}
    \ifnum\iflag=0\relax
        \path[ball color=gray] (0,0) circle[radius=R];          
    \else
        \pgfmathsetmacro{\myhprime}{\myh*sin(theta)+r*cos(theta)}
        \pgfmathsetmacro{\mytcrit}{-asin((r*cos(theta)*\myhprime)/(r*r-\myhprime*\myhprime))}
        \pgfmathsetmacro{\mybeta}{90-atan2(\myhprime+r*cos(theta)*sin(\mytcrit),r*cos(\mytcrit))}
        \pgfmathsetmacro{\mytcrit}{\mytcrit/cos(theta)}
        \path[ball color=gray]  (90-\mybeta:R) arc[start angle=90-\mybeta,end angle=-270+\mybeta,radius=R];
    \fi
    \tdplotsetmaincoords{theta}{0}
    \begin{scope}[tdplot_main_coords]
        \draw[dashed] (0,0,-\myh) circle[radius=r] (-r,0,\myh) edge (-r,0,-\myh) (r,0,\myh) edge (r,0,-\myh);
        \clip (0,0,\myh) circle[radius=r];
        \path[left color=gray!50!black,right color=gray,middle color=gray!20] (r/2,0,\myh) circle[radius=1.5*r];
        \fill (0,0,-\myh) circle[radius=r];  
    \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

You can set the view angle theta to change the view. The other view angle is redundant because of the rotational symmetry about the z-axis. This version also truncates the sphere at the bottom.

\documentclass{article}
\usepackage[margin=1cm]{geometry}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\newcommand{\DrawSphereInCylinder}[1]{\begin{tikzpicture}[declare function={R=3;% radius of sphere
        r=1.5;% radius of cylinder
        theta=#1;% view angle
    }]
    \pgfmathsetmacro{\myalpha}{asin(r/R)}
    \pgfmathsetmacro{\myh}{R*cos(\myalpha)}
    \pgfmathtruncatemacro{\iflag}{ifthenelse(theta>90-\myalpha,1,0)}
    \tdplotsetmaincoords{theta}{0}
    \ifnum\iflag=0\relax
        \path[ball color=gray] (0,0) circle[radius=R];          
    \else
        \pgfmathsetmacro{\myhprime}{\myh*sin(theta)+r*cos(theta)}
        \pgfmathsetmacro{\mytcrit}{-asin((r*cos(theta)*\myhprime)/(r*r-\myhprime*\myhprime))}
        \pgfmathsetmacro{\mybeta}{90-atan2(\myhprime+r*cos(theta)*sin(\mytcrit),r*cos(\mytcrit))}
        \pgfmathsetmacro{\mytcrit}{asin((cos(theta)*\myhprime)/(r*sin(theta)*sin(theta)))}
        \path[ball color=gray]  (90-\mybeta:R) arc[start angle=90-\mybeta,end angle=-90+\mybeta,radius=R]
        [tdplot_main_coords] 
        -- ({r*cos(-\mytcrit)},{-r*sin(\mytcrit)},-\myh)
        arc[start angle=-\mytcrit,end angle=-180+\mytcrit,radius=r]
        [tdplot_screen_coords]
        -- (-90-\mybeta:R) arc[start angle=-90-\mybeta,end angle=-270+\mybeta,radius=R];
    \fi
    \begin{scope}[tdplot_main_coords]
        \ifnum\iflag=0\relax
            \draw[dashed] (0,0,-\myh) circle[radius=r] (-r,0,\myh) edge (-r,0,-\myh) (r,0,\myh) edge (r,0,-\myh);
        \else 
            \draw[dashed] ({r*cos(-\mytcrit)},{-r*sin(\mytcrit)},-\myh)
            arc[start angle=-\mytcrit,end angle=180+\mytcrit,radius=r]
            (-r,0,\myh) edge (-r,0,-\myh) (r,0,\myh) edge (r,0,-\myh);
        \fi    
        \clip (0,0,\myh) circle[radius=r];
        \path[left color=gray!50!black,right color=gray,middle color=gray!20] (r/2,0,\myh) circle[radius=1.5*r];
        \fill[white] (0,0,-\myh) circle[radius=r];  
    \end{scope}
    \path (current bounding box.north) node[above]{$\theta={#1}^\circ$};
\end{tikzpicture}}
\begin{document}
\begin{tabular}{cc}
    \DrawSphereInCylinder{85} & \DrawSphereInCylinder{70}\\    
    \DrawSphereInCylinder{55} & \DrawSphereInCylinder{40}\\    
    \DrawSphereInCylinder{25} & \DrawSphereInCylinder{10}\\    
\end{tabular}
\end{document}

enter image description here

  • Thank you very much. – minhthien_2016 Jul 05 '23 at 00:56
  • In the 85 angle view, shouldn't the lower part of the sphere be removed like the upper part? – C.F.G Jul 05 '23 at 03:06
  • Also, how can I automatically rotate the y-axis to match with the angular view? this is my y-axes: \draw[red, dashed] (0,0,0)--(0,\myh,0); \draw[->] (0,\myh,0)--(0,1.5*R,0)node[left]{$y$}; – C.F.G Jul 05 '23 at 04:18
  • 1
    @C.F.G I modified the last version to truncate the sphere at the bottom as well, now the three codes do somewhat different things. You can draw the coordinate systems in new "main" coordinates with the same theta but an arbitrary second argument. Note, however, that it is impossible to have an orthographic projection in which one axis points (typically the z-axis) to the top, one to the right on the screen, and theta is nontrivial. The only situation in which this happens is when the projection of the third axis is just a point. –  Jul 05 '23 at 05:12
  • @user23623 Thanks a lot. Tikz is really powerful. But it is the user (you) who gives it life. – C.F.G Jul 05 '23 at 05:23
  • @user23623 so happy to read you again :) – JeT Jul 05 '23 at 20:06