Points (A) (B) (A') and (B') are not the edges of the cylinder, but rather the points where the visible edge of the sphere (circle) and the visible edge of of the cylinder (ellipse) intersect, which depend on the viewing angles.
Points (C) and (D) represent the visible right and left edges.
\documentclass[12pt,border=3mm]{standalone}
\usepackage{fouriernc}
\usepackage{tikz}
\usepackage{tkz-euclide}
\usetkzobj{all}
\usepackage{tikz-3dplot}
\usetikzlibrary{calc,backgrounds}
\begin{document}
\def\myangle{70}%
\tdplotsetmaincoords{\myangle}{0}%
\begin{tikzpicture}[scale=1,tdplot_main_coords]
\pgfmathsetmacro{\r}{2*sqrt(3)}% sphere radius=4, cylendar height=4
\path% common coordinates
(0,0,-2) coordinate (O)
(0,0,0) coordinate (I)
(0,0,2) coordinate (O')
(O) ++(0:\r) coordinate (C)% right edge
(O) ++(180:\r) coordinate (D);% left edge
\draw[dashed,thick] (C)-- ++(0,0,4) (D)-- ++(0,0,4);
\draw[dashed] (O)--(O');
\begin{scope}[tdplot_screen_coords, on background layer]
\fill[ball color=orange!70, opacity=1.0] (I) circle (4);
\end{scope}
\pgfmathsetmacro{\mynumer}{2*cos(\myangle)}
\pgfmathsetmacro{\mydenom}{\r*sin(\myangle)}
\pgfmathsetmacro{\quadrant}{ifthenelse(abs(\mynumer)<abs(\mydenom), 0,
ifthenelse(\mynumer>0, 1, 2))}% 0=side, 1=top, 2=bottom
\ifcase\quadrant
\pgfmathsetmacro{\intercept}{asin(\mynumer/\mydenom)}
\path
(O) ++(-\intercept:\r) coordinate (A)
(O) ++(-180+\intercept:\r) coordinate (B)
(O') ++(\intercept:\r) coordinate (A')
(O') ++(180-\intercept:\r) coordinate (B');
\draw [thick] (B) arc (-180+\intercept:-\intercept:\r);
\draw [thick, dashed] (A) arc (-\intercept:180+\intercept:\r);
\draw [thick] (B') arc (-180-\intercept:\intercept:\r);
\draw [thick, dashed] (A') arc (\intercept:180-\intercept:\r);
\foreach \v/\position in {I/left,O/below,O'/above,A/below,B/below,A'/left,B'/left} {
\draw[draw =black, fill=black] (\v) circle (1.2pt) node [\position=0.2mm] {$\v$};
}
\or% top
\path
(C) coordinate (A)
(D) coordinate (B)
(A) ++(0,0,4) coordinate (A')
(B) ++((0,0,4) coordinate (B');
\draw [thick] (O') circle (\r);
\draw [thick, dashed] (O) circle (\r);
\foreach \v/\position in {I/left,O/below,O'/above,A/below,B/below,A'/left,B'/left} {
\draw[draw =black, fill=black] (\v) circle (1.2pt) node [\position=0.2mm] {$\v$};
}
\or% bottom
\path
(C) coordinate (A)
(D) coordinate (B)
(A) ++(0,0,4) coordinate (A')
(B) ++((0,0,4) coordinate (B');
\draw [thick,dashed] (O') circle (\r);
\draw [thick] (O) circle (\r);
\foreach \v/\position in {I/left,O/below,O'/above,A/below,B/below,A'/left,B'/left} {
\draw[draw =black, fill=black] (\v) circle (1.2pt) node [\position=0.2mm] {$\v$};
}
\fi
\draw[dashed] (O)--(A) (I) --(A);
\tkzMarkRightAngle[size = 0.3](I,O,A);
\end{tikzpicture}
\end{document}
You can you 3dtools. Some calculations can be found by 3dtools
.
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3dtools,calc}% https://github.com/marmotghost/tikz-3dtools
\begin{document}
\begin{tikzpicture}[3d/install view={phi=70,theta=80},line cap=butt,
line join=round,c/.style={circle,fill,inner sep=1pt},declare function={a=4;}]
\path
(0,0,0) coordinate (D)
(a,0,0) coordinate (B)
(0, a,0) coordinate (C)
(0,0,a) coordinate (A);
\path[3d/circumcircle center={A={(A)},B={(B)},C={(C)}}] coordinate (J);
;
\draw[3d/hidden] (D) --(A) (D) -- (J) (D) --(C);
\draw[3d/visible] (A) --(B)--(C) --cycle (D) -- (B);
\pgfmathsetmacro{\R}{tddistance("(J)","(B)")}
\pgfmathsetmacro{\h}{tddistance("(J)","(D)")}
\tikzset{3d/define orthonormal dreibein={A={(A)},B={(C)},C={(B)}}}
\path[x={(ex)},y={(ey)},z={(ez)}]
(J) pic{3d/cone={r=\R,h=\h}};
\path foreach \p/\g in {A/90,D/-90,B/-30,C/0,J/-90}{(\p)node[c]{}+(\g:2.5mm) node{$\p$}};
\end{tikzpicture}
\end{document}
With phi=5
,
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3dtools,calc}% https://github.com/marmotghost/tikz-3dtools
\begin{document}
\begin{tikzpicture}[3d/install view={phi=5,theta=80},line cap=butt,
line join=round,c/.style={circle,fill,inner sep=1pt},declare function={a=4;}]
\path
(0,0,0) coordinate (D)
(a,0,0) coordinate (B)
(0, a,0) coordinate (C)
(0,0,a) coordinate (A);
\path[3d/circumcircle center={A={(A)},B={(B)},C={(C)}}] coordinate (J);
;
\draw[3d/hidden] (D) -- (J) (D) --(C) (A) -- (B) -- (C) --cycle ;
\draw[3d/visible] (D) --(A) (D) -- (B);
\pgfmathsetmacro{\R}{tddistance("(J)","(B)")}
\pgfmathsetmacro{\h}{tddistance("(J)","(D)")}
\tikzset{3d/define orthonormal dreibein={A={(A)},B={(C)},C={(B)}}}
\path[x={(ex)},y={(ey)},z={(ez)}]
(J) pic{3d/cone={r=\R,h=\h}};
\path foreach \p/\g in {A/90,D/-90,B/-30,C/50,J/-90}{(\p)node[c]{}+(\g:2.5mm) node{$\p$}};
\end{tikzpicture}
\end{document}
Best Answer
Here is a little tool box that allows you to
protect
some (closed) path. It is based on the links mentioned in the code (and possibly more). The important pieces arewhere the paths
\rectA
,\rectB
and\lineA
have been used before and saved withsave path
.\tikzset{protect=\rectA}
"protects" the interior of the\rectA
path, and likewise for\rectB
.It turns out that for some (to me obscure) reasons it can happen in some cases that the insanely large bounding box is too large. However, for most practical applications something more "modest" like
will be more than sufficient.