# How can I draw sphere cut by plane by using tikz-3dplot?

Based on the equation at here, I use another way to draw. My code

\documentclass[border=2mm,12pt,tikz]{standalone}
\usepackage{tikz-3dplot-circleofsphere}
\usepackage{fouriernc}
\makeatletter
\tikzset{
reuse path/.code={\pgfsyssoftpath@setcurrentpath{#1}}
}
\tikzset{even odd clip/.code={\pgfseteorule},
protect/.code={
\clip[overlay,even odd clip,reuse path=#1]
(-6383.99999pt,-6383.99999pt) rectangle (6383.99999pt,6383.99999pt);
}}
\makeatother
\begin{document}
\tdplotsetmaincoords{70}{80}
\begin{tikzpicture}[tdplot_main_coords,scale=1,line join = round, line cap = round,declare function={R=5;r=4;h=sqrt(R^2 - r^2);myx= 2; myy=sqrt(R*R-h*h- myx*myx); k=-1; Angle=k*acos(r/R);}]
\path
(0,0,0) coordinate (O)
(0,0,k*h) coordinate (H)
(myx,myy,k*h) coordinate (M)
;
\begin{scope}
\draw[save path=\sphere,thick,tdplot_screen_coords] (O) circle (R);
\end{scope}
\begin{scope} [canvas is xy plane at z=k*h]
\path[save path=\rectA] (-R,-R) rectangle (R,R);
\begin{scope}
\clip[use path=\sphere];
\draw[dashed,use path=\rectA];
\end{scope}
\tikzset{protect=\sphere}
\draw[thick,use path=\rectA];
\end{scope}
\begin{scope}[shift={(O)}]
\tdplotCsDrawLatCircle[blue, thick]{R}{{Angle}}
\end{scope}
\foreach \p in {H,M,O}
{\draw[fill=black] (\p) circle (1.5pt);}
\foreach \p/\g in {M/90,O/-135,H/30}
{\path (\p)+(\g:3mm) node{$\p$}; }
\draw[dashed] (O) -- (H) -- (M) --cycle;
\end{tikzpicture}
\end{document}


I get

How can I get like this picture by using \usepackage{tikz-3dplot} to get result

You can "hack" the macros from tikz-3dplot-circleofsphere. Here I "hack" \tdplotCsDrawLatCircle by storing the foreground arc in a macro called \pathFG:

 \tdplotCsDrawLatCircle[tdplotCsFront/.style={draw=none,save path=\pathFG},
tdplotCsBack/.style={draw=none}]{R}{Angle}


This gives us access to this stretch for clipping utilizing reuse path=\pathFG. (Note that use path does not do what we want here.) Then one can clip and protect the relevant areas.

\documentclass[border=2mm,12pt,tikz]{standalone}
\usepackage{tikz-3dplot-circleofsphere}
\usepackage{fouriernc}
\makeatletter
\tikzset{
reuse path/.code={\pgfsyssoftpath@setcurrentpath{#1}}
}
\tikzset{even odd clip/.code={\pgfseteorule},
protect/.code={
\clip[overlay,even odd clip,reuse path=#1]
(-6383.99999pt,-6383.99999pt) rectangle (6383.99999pt,6383.99999pt);
}}
\makeatother
\begin{document}
\tdplotsetmaincoords{70}{80}
\begin{tikzpicture}[tdplot_main_coords,scale=1,line join = round,
line cap = round,
declare function={R=5;r=4;h=sqrt(R^2 - r^2);%
myx= 2; myy=sqrt(R*R-h*h- myx*myx); k=-1; Angle=k*acos(r/R);}]
\path
(0,0,0) coordinate (O)
(0,0,k*h) coordinate (H)
(myx,myy,k*h) coordinate (M)
;
\tdplotCsDrawLatCircle[tdplotCsFront/.style={draw=none,save path=\pathFG},
tdplotCsBack/.style={draw=none}]{R}{Angle}
\begin{scope}
\end{scope}
\begin{scope} [canvas is xy plane at z=k*h]
\path[save path=\rectA] (-R,-R) rectangle (R,R);
\begin{scope}
\clip[reuse path=\pathFG,save path=\pathFGB] -- (R,R)  -- (R,-R) -- cycle;
\draw[dashed,use path=\sphere];
\end{scope}
\begin{scope}
\clip[use path=\sphere];
\draw[dashed,use path=\rectA];
\end{scope}
\begin{scope}
\tikzset{protect=\pathFGB}
\draw[thick,use path=\sphere];
\end{scope}
\draw[thick] (R,R)  -- (R,-R);
\tikzset{protect=\sphere}
\draw[thick,use path=\rectA];
\end{scope}
\tdplotCsDrawLatCircle[blue, thick]{R}{Angle}
\foreach \p in {H,M,O}
{\draw[fill=black] (\p) circle (1.5pt);}
\foreach \p/\g in {M/90,O/-135,H/30}
{\path (\p)+(\g:3mm) node{$\p$}; }
\draw[dashed] (O) -- (H) -- (M) --cycle;
\end{tikzpicture}
\end{document}


Note that this trick is not limited to tikz-3dplot-circleofsphere. Whenever a package draws a path with a macro we can access and use it this way. For instance, one can hack the tikzlings package to provide our friends with cloths.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikzlings}
\newcounter{savedpath}
\makeatletter
\tikzset{reuse path/.code={\pgfsyssoftpath@setcurrentpath{#1}},
save paths/.code={\setcounter{savedpath}{0}%
\edef\tikz@path@name{#1}%
\tikzset{every path/.append style={autosave path}}},
autosave path/.code={\stepcounter{savedpath}%
\edef\temp{\noexpand\tikzset{save path=\csname\tikz@path@name\roman{savedpath}\endcsname}}%
\temp
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\begin{scope}[save paths=mpath]
\marmot
\end{scope}
\begin{scope}
\clip[reuse path=\mpathvii];
\fill[blue] (-1,1.4) to[bend right=10] (1,1.4) -- (1,0.5) to[bend left=10] (-1,0.5) --
cycle;
\fill[brown!30!black,reuse path=\mpathix];
\fill[brown!30!black,reuse path=\mpathx];
\end{scope}
\end{tikzpicture}
\end{document}


As can be seen, these reused paths can be used for clipping and filling. They can also be used for drawing. For some reason they cannot be used for shading, though, even though you can use them to clip some shading which yields the equivalent result. One can also combine them. It is conceivable that these are some steps towards solving this issue.

ADDENDUM: Some animation. No, this does not work for arbitrary view angles but for some nontrivial subset of them.

\documentclass[border=2mm,12pt,tikz]{standalone}
\usepackage{tikz-3dplot-circleofsphere}
\usepackage{fouriernc}
\makeatletter
\tikzset{
reuse path/.code={\pgfsyssoftpath@setcurrentpath{#1}}
}
\tikzset{even odd clip/.code={\pgfseteorule},
protect/.code={
\clip[overlay,even odd clip,reuse path=#1]
(-6383.99999pt,-6383.99999pt) rectangle (6383.99999pt,6383.99999pt);
}}
\makeatother
\begin{document}
\foreach \Angle in {5,15,...,355}
{\tdplotsetmaincoords{70}{\Angle}
\begin{tikzpicture}[tdplot_main_coords,scale=1,line join = round,
line cap = round,
declare function={R=5;L=5.5;r=4;h=sqrt(R^2 - r^2);%
myx= 2; myy=sqrt(R*R-h*h- myx*myx); k=-1; Angle=k*acos(r/R);}]
\path[tdplot_screen_coords,use as bounding box] (-9,-9) rectangle (9,9);
\path
(0,0,0) coordinate (O)
(0,0,k*h) coordinate (H)
(myx,myy,k*h) coordinate (M)
;
\pgfmathtruncatemacro{\itest}{(abs(sin(\tdplotmainphi)*cos(\tdplotmainphi))<0.3 ? 0 : 1)}
\tdplotCsDrawLatCircle[tdplotCsFront/.style={draw=none,save path=\pathFG},
tdplotCsBack/.style={draw=none}]{R}{Angle}
\begin{scope}
\end{scope}
\begin{scope} [canvas is xy plane at z=k*h]
\path[save path=\rectA] (-L,-L) rectangle (L,L);
\begin{scope}
\path ({(cos(\tdplotmainphi)<0 ? -1 : 1)*L},
{(sin(\tdplotmainphi)<0 ? -1 : 1)*L}) coordinate (p1)
({(cos(\tdplotmainphi-90+0)<0 ? -1 : 1)*L},
{(sin(\tdplotmainphi-90+0)<0 ? -1 : 1)*L})  coordinate (p2)
({(cos(\tdplotmainphi-180+0)<0 ? -1 : 1)*L},
{(sin(\tdplotmainphi-180+0)<0 ? -1 : 1)*L})
coordinate (p3);
\clip[overlay,reuse path=\pathFG,save path=\pathFGB]
--(p1) -- (p2)  -- (p3) -- cycle;
\draw[dashed,use path=\sphere];
\end{scope}
\begin{scope}
\clip[use path=\sphere];
\draw[dashed,use path=\rectA];
\end{scope}
\begin{scope}
\tikzset{protect=\pathFGB}
\draw[thick,use path=\sphere];
\end{scope}
\draw[thick] (p1) -- (p2)  -- (p3);
\tikzset{protect=\sphere}
\draw[thick,use path=\rectA];
\end{scope}
\tdplotCsDrawLatCircle[blue, thick]{R}{Angle}
\foreach \p in {H,M,O}
{\draw[fill=black] (\p) circle (1.5pt);}
\foreach \p/\g in {M/90,O/-135,H/30}
{\path (\p)+(\g:3mm) node{$\p$}; }
\draw[dashed] (O) -- (H) -- (M) --cycle;
\end{tikzpicture}}
\end{document}


And here is another animation.

\documentclass[border=2mm,12pt,tikz]{standalone}
\usepackage{tikz-3dplot-circleofsphere}
\usepackage{fouriernc}
\makeatletter
\tikzset{
reuse path/.code={\pgfsyssoftpath@setcurrentpath{#1}}
}
\tikzset{even odd clip/.code={\pgfseteorule},
protect/.code={
\clip[overlay,even odd clip,reuse path=#1]
(-6383.99999pt,-6383.99999pt) rectangle (6383.99999pt,6383.99999pt);
}}
\makeatother
\begin{document}
\foreach \Z in {4,3,...,-4,-3,-2,...,3}
{\tdplotsetmaincoords{70}{80}
\begin{tikzpicture}[tdplot_main_coords,scale=1,line join = round,
line cap = round,
declare function={R=5;L=5.5;h=abs(\Z);r=sqrt(R*R-\Z*\Z);%
myx= 2; myy=sqrt(R*R-h*h- myx*myx); k=sign(\Z); Angle=k*acos(r/R);}]
\path[tdplot_screen_coords,use as bounding box] (-9,-9) rectangle (9,9);
\path
(0,0,0) coordinate (O)
(0,0,k*h) coordinate (H)
(myx,myy,k*h) coordinate (M)
;
\pgfmathtruncatemacro{\itest}{(abs(sin(\tdplotmainphi)*cos(\tdplotmainphi))<0.3 ? 0 : 1)}
\tdplotCsDrawLatCircle[tdplotCsFront/.style={draw=none,save path=\pathFG},
tdplotCsBack/.style={draw=none}]{R}{Angle}
\begin{scope}
\end{scope}
\begin{scope} [canvas is xy plane at z=k*h]
\path[save path=\rectA] (-L,-L) rectangle (L,L);
\begin{scope}
\path ({(cos(\tdplotmainphi)<0 ? -1 : 1)*L},
{(sin(\tdplotmainphi)<0 ? -1 : 1)*L}) coordinate (p1)
({(cos(\tdplotmainphi-90+0)<0 ? -1 : 1)*L},
{(sin(\tdplotmainphi-90+0)<0 ? -1 : 1)*L})  coordinate (p2)
({(cos(\tdplotmainphi-180+0)<0 ? -1 : 1)*L},
{(sin(\tdplotmainphi-180+0)<0 ? -1 : 1)*L})
coordinate (p3);
\clip[overlay,reuse path=\pathFG,save path=\pathFGB]
--(p1) -- (p2)  -- (p3) -- cycle;
\draw[dashed,use path=\sphere];
\end{scope}
\begin{scope}
\clip[use path=\sphere];
\draw[dashed,use path=\rectA];
\end{scope}
\begin{scope}
\tikzset{protect=\pathFGB}
\draw[thick,use path=\sphere];
\end{scope}
\draw[thick] (p1) -- (p2)  -- (p3);
\tikzset{protect=\sphere}
\draw[thick,use path=\rectA];
\end{scope}
\tdplotCsDrawLatCircle[blue, thick]{R}{Angle}
\foreach \p in {H,M,O}
{\draw[fill=black] (\p) circle (1.5pt);}
\foreach \p/\g in {M/90,O/-135,H/30}
{\path (\p)+(\g:3mm) node{$\p$}; }
\draw[dashed] (O) -- (H) -- (M) --cycle;
\end{tikzpicture}}
\end{document}


• How about anamination of the plane and the circle? Commented Apr 22, 2020 at 5:33
• @ThuyNguyen It is difficult because there are so many cases. If you vary the angles only moderately, you can use this code, but for strong variations it does not work without distinguishing many cases. Maybe the animation here will do.
– user194703
Commented Apr 22, 2020 at 5:44
• @minhthien_2016 Yes, of course. It is just that this has been done several times already and there is a lot of repetition. That's why I am interested in more general solutions.
– user194703
Commented Apr 22, 2020 at 6:02
• @ThuyNguyen It is not a particularly well-defined statement to say that the plane is parallel to Oxy since, given a plane, you can always choose your coordinate axis in such a way that this is the case. What is more important is the information in which domains the view angles will be varied.
– user194703
Commented Apr 24, 2020 at 2:48