tikz add tag
Anonymous 1123
At [here](https://tex.stackexchange.com/questions/505731/how-to-get-trace-to-get-a-cylinder-when-i-rotate-a-rectangle), I get a cylinder when I rotate a rectangle. How can I get two cones when I rotate triangle `ABC` where `A(a,0,0), B(0,b,0), C(0,0,c)` around one side of triangle. Ingeneral, how to get a solid when I rotate a convex polygon around a line?
Top Answer
marmot
Here is some proof of principle for triangles. It computes the envelope of the rotation of a triangle around one of its edges. The critical angles are the same as [here](https://topanswers.xyz/tex?q=1218#a1447), only for a constant slope. I am not convinced that Ti*k*Z is made for such tasks, let alone for generalizations to arbitrary polygons. These codes require the newest version of [3dtools](https://github.com/marmotghost/tikz-3dtools) because I decided to add (a user interface to) the components of the normal to the library as they are getting used in various applications.

```
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3dtools}% https://github.com/marmotghost/tikz-3dtools
\begin{document}
\foreach \AnglePhi in {5,15,...,355}
{\begin{tikzpicture}[line cap=butt,line join=round,
declare function={%
a=4.5;b=3;c=4;
tmpc(\u)=nscreenx*\u;%
sv1(\u)=-((-1*nscreenz*tmpc(\u)+sqrt(nscreeny*nscreeny+nscreenz*nscreenz-tmpc(\u)*tmpc(\u))*abs(nscreeny))%
	/(nscreeny*nscreeny+nscreenz*nscreenz));% 
sv2(\u)=(-(-1*nscreenz*tmpc(\u))+sqrt(nscreeny*nscreeny+nscreenz*nscreenz-tmpc(\u)*tmpc(\u))*abs(nscreeny))%
	/(nscreeny*nscreeny+nscreenz*nscreenz);% 
cv1(\u)=-((-1*nscreeny*tmpc(\u)+sqrt(nscreeny*nscreeny+nscreenz*nscreenz-tmpc(\u)*tmpc(\u))*abs(nscreenz))/(nscreeny*nscreeny+nscreenz*nscreenz));% 
cv2(\u)=(-(-1*nscreeny*tmpc(\u))+sqrt(nscreeny*nscreeny+nscreenz*nscreenz-tmpc(\u)*tmpc(\u))*abs(nscreenz))/(nscreeny*nscreeny+nscreenz*nscreenz);%
tmpdisc(\u)=nscreeny*nscreeny+nscreenz*nscreenz-tmpc(\u)*tmpc(\u);%
}]
 \path[use as bounding box] (-7,-6) rectangle (7,6) coordinate (TR);
 %\path (6,-5) node[above left]{$\phi=\AnglePhi$};
 \begin{scope}[3d/install view={phi=\AnglePhi,psi=0,theta=70}]
  \path (a,0,0) coordinate (A) (0,b,0) coordinate (B) (0,0,c) coordinate (C)
   [3d/define orthonormal dreibein];
  \draw[blue] (A) -- (B) -- (C) -- cycle; 
  % height of the point (C) of the triangle
  \pgfmathsetmacro{\myr}{TD("(C)-(A)o(ey)")} 
  % projection of (C) on line (A)--(B), i.e. distance from (A)
  \pgfmathsetmacro{\myx}{TD("(C)-(A)o(ex)")} 
  \begin{scope}[x={(ex)},y={(ey)},z={(ez)},shift={(A)}]
   \draw[thin,densely dashed,variable=\u,domain=0:360,samples=61,smooth cycle]
     plot (\myx,{\myr*cos(\u)},{\myr*sin(\u)});
   % slope of the first stretch	
   \pgfmathsetmacro{\myslope}{\myr/\myx}
   \pgfmathtruncatemacro{\itest}{sign(tmpdisc(\myslope))}
   \ifnum\itest>-1\relax   
	\pgfmathsetmacro{\angA}{Mod(720+atan2(sv1(\myslope),cv1(\myslope)),360)}
	\pgfmathsetmacro{\angB}{Mod(720+atan2(sv2(\myslope),cv2(\myslope)),360)}
	\pgfmathsetmacro{\angC}{min(\angA,\angB)}
	\pgfmathsetmacro{\angD}{max(\angA,\angB)}
	\pgfmathtruncatemacro{\jtest}{(screendepth(-1,0,0)>0)*((\angD-\angC)<180)}
	\ifnum\jtest=1
	 \pgfmathsetmacro{\angC}{\angC+360}
	\fi	
	\pgfmathtruncatemacro{\jtest}{(screendepth(-1,0,0)<0)*((\angD-\angC)>180)}
	\ifnum\jtest=1
	 \pgfmathsetmacro{\angD}{\angD-360}
	\fi	
	\draw[thick,variable=\u,domain=\angC:\angD,samples=61,smooth]
	 (A) -- plot (\myx,{\myr*cos(\u)},{\myr*sin(\u)}) -- cycle;
   \else
    \pgfmathtruncatemacro{\jtest}{sign(screendepth(-1,0,0))}
	\ifnum\jtest=1
     \draw[thick,variable=\u,domain=0:360,samples=61,smooth cycle]
      plot (\myx,{\myr*cos(\u)},{\myr*sin(\u)});	  
	\fi 
   \fi
   \pgfmathsetmacro{\myL}{sqrt(a*a+b*b)-\myx}
   \pgfmathsetmacro{\myslope}{-\myr/\myL}	
   \pgfmathtruncatemacro{\itest}{sign(tmpdisc(\myslope))}
   \ifnum\itest>-1\relax   
	\pgfmathsetmacro{\angA}{Mod(720+atan2(sv1(\myslope),cv1(\myslope)),360)}
	\pgfmathsetmacro{\angB}{Mod(720+atan2(sv2(\myslope),cv2(\myslope)),360)}
	\pgfmathsetmacro{\angC}{min(\angA,\angB)}
	\pgfmathsetmacro{\angD}{max(\angA,\angB)}
	\pgfmathtruncatemacro{\jtest}{(screendepth(1,0,0)<0)*((\angD-\angC)<180)}
	\ifnum\jtest<1
	 \pgfmathsetmacro{\angC}{\angC+360}
	\fi	
	\pgfmathtruncatemacro{\jtest}{(screendepth(1,0,0)>0)*((\angD-\angC)>180)}
	\ifnum\jtest=1
	 \pgfmathsetmacro{\angD}{\angD-360}
	\fi	
	\draw[thick,variable=\u,domain=\angC:\angD,samples=61,smooth]
	 (B) -- plot (\myx,{\myr*cos(\u)},{\myr*sin(\u)}) -- cycle;
   \else
    \pgfmathtruncatemacro{\jtest}{sign(screendepth(1,0,0))}
	\ifnum\jtest=1
     \draw[thick,variable=\u,domain=0:360,samples=61,smooth cycle]
      plot (\myx,{\myr*cos(\u)},{\myr*sin(\u)});	  
	\fi 
   \fi	
  \end{scope}
 \end{scope}
\end{tikzpicture}}
\end{document}
```
![ani.gif](/image?hash=5f75eb61393a7bb94396b31c4a56e0c05e500f7398fc6003d217cbed4c1225d6)

You can make it more solid-like by filling the contour.
```
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3dtools}% https://github.com/marmotghost/tikz-3dtools
\begin{document}
\foreach \AnglePhi in {5,15,...,355}
{\begin{tikzpicture}[line cap=butt,line join=round,
declare function={%
a=4.5;b=3;c=4;
tmpc(\u)=nscreenx*\u;%
sv1(\u)=-((-1*nscreenz*tmpc(\u)+sqrt(nscreeny*nscreeny+nscreenz*nscreenz-tmpc(\u)*tmpc(\u))*abs(nscreeny))%
	/(nscreeny*nscreeny+nscreenz*nscreenz));% 
sv2(\u)=(-(-1*nscreenz*tmpc(\u))+sqrt(nscreeny*nscreeny+nscreenz*nscreenz-tmpc(\u)*tmpc(\u))*abs(nscreeny))%
	/(nscreeny*nscreeny+nscreenz*nscreenz);% 
cv1(\u)=-((-1*nscreeny*tmpc(\u)+sqrt(nscreeny*nscreeny+nscreenz*nscreenz-tmpc(\u)*tmpc(\u))*abs(nscreenz))/(nscreeny*nscreeny+nscreenz*nscreenz));% 
cv2(\u)=(-(-1*nscreeny*tmpc(\u))+sqrt(nscreeny*nscreeny+nscreenz*nscreenz-tmpc(\u)*tmpc(\u))*abs(nscreenz))/(nscreeny*nscreeny+nscreenz*nscreenz);%
tmpdisc(\u)=nscreeny*nscreeny+nscreenz*nscreenz-tmpc(\u)*tmpc(\u);%
}]
 \path[use as bounding box] (-7,-6) rectangle (7,6) coordinate (TR);
 %\path (6,-5) node[above left]{$\phi=\AnglePhi$};
 \begin{scope}[3d/install view={phi=\AnglePhi,psi=0,theta=70}]
  \path (a,0,0) coordinate (A) (0,b,0) coordinate (B) (0,0,c) coordinate (C)
   [3d/define orthonormal dreibein];
  \draw[blue] (A) -- (B) -- (C) -- cycle; 
  % height of the point (C) of the triangle
  \pgfmathsetmacro{\myr}{TD("(C)-(A)o(ey)")} 
  % projection of (C) on line (A)--(B), i.e. distance from (A)
  \pgfmathsetmacro{\myx}{TD("(C)-(A)o(ex)")} 
  \begin{scope}[x={(ex)},y={(ey)},z={(ez)},shift={(A)}]
   \draw[thin,densely dashed,variable=\u,domain=0:360,samples=61,smooth cycle]
     plot (\myx,{\myr*cos(\u)},{\myr*sin(\u)});
   % slope of the first stretch	
   \pgfmathsetmacro{\myslope}{\myr/\myx}
   \pgfmathtruncatemacro{\itest}{sign(tmpdisc(\myslope))}
   \ifnum\itest>-1\relax   
	\pgfmathsetmacro{\angA}{Mod(720+atan2(sv1(\myslope),cv1(\myslope)),360)}
	\pgfmathsetmacro{\angB}{Mod(720+atan2(sv2(\myslope),cv2(\myslope)),360)}
	\pgfmathsetmacro{\angC}{min(\angA,\angB)}
	\pgfmathsetmacro{\angD}{max(\angA,\angB)}
	\pgfmathtruncatemacro{\jtest}{(screendepth(-1,0,0)>0)*((\angD-\angC)<180)}
	\ifnum\jtest=1
	 \pgfmathsetmacro{\angC}{\angC+360}
	\fi	
	\pgfmathtruncatemacro{\jtest}{(screendepth(-1,0,0)<0)*((\angD-\angC)>180)}
	\ifnum\jtest=1
	 \pgfmathsetmacro{\angD}{\angD-360}
	\fi	
	\draw[thick,variable=\u,domain=\angC:\angD,samples=61,smooth,
		fill=gray,fill opacity=0.5]
	 (A) -- plot (\myx,{\myr*cos(\u)},{\myr*sin(\u)}) -- cycle;
   \else
    \pgfmathtruncatemacro{\jtest}{sign(screendepth(-1,0,0))}
	\ifnum\jtest=1
     \draw[thick,variable=\u,domain=0:360,samples=61,smooth cycle,
	 	fill=gray,fill opacity=0.5]
      plot (\myx,{\myr*cos(\u)},{\myr*sin(\u)});	  
	\fi 
   \fi
   \pgfmathsetmacro{\myL}{sqrt(a*a+b*b)-\myx}
   \pgfmathsetmacro{\myslope}{-\myr/\myL}	
   \pgfmathtruncatemacro{\itest}{sign(tmpdisc(\myslope))}
   \ifnum\itest>-1\relax   
	\pgfmathsetmacro{\angA}{Mod(720+atan2(sv1(\myslope),cv1(\myslope)),360)}
	\pgfmathsetmacro{\angB}{Mod(720+atan2(sv2(\myslope),cv2(\myslope)),360)}
	\pgfmathsetmacro{\angC}{min(\angA,\angB)}
	\pgfmathsetmacro{\angD}{max(\angA,\angB)}
	\pgfmathtruncatemacro{\jtest}{(screendepth(1,0,0)<0)*((\angD-\angC)<180)}
	\ifnum\jtest<1
	 \pgfmathsetmacro{\angC}{\angC+360}
	\fi	
	\pgfmathtruncatemacro{\jtest}{(screendepth(1,0,0)>0)*((\angD-\angC)>180)}
	\ifnum\jtest=1
	 \pgfmathsetmacro{\angD}{\angD-360}
	\fi	
	\draw[thick,variable=\u,domain=\angC:\angD,samples=61,smooth,
		fill=gray,fill opacity=0.5]
	 (B) -- plot (\myx,{\myr*cos(\u)},{\myr*sin(\u)}) -- cycle;
   \else
    \pgfmathtruncatemacro{\jtest}{sign(screendepth(1,0,0))}
	\ifnum\jtest=1
     \draw[thick,variable=\u,domain=0:360,samples=61,smooth cycle,
	 	fill=gray,fill opacity=0.5]
      plot (\myx,{\myr*cos(\u)},{\myr*sin(\u)});
	\fi 
   \fi	
  \end{scope}
 \end{scope}
\end{tikzpicture}}
\end{document}
```
![ani.gif](/image?hash=4d769c15c63b7864df0169f8fc84139edecf71a4d6ed19d1b1fe90b5b369d1bd)

Unfortunately I do not know of a good way to add realistic shading.

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.