# How can I draw a frustum like this?

I am trying to draw a frustum with centers of two bases A, C and two radii SA and CD, height of frustum AC.

I tried

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{60}{70}
\begin{tikzpicture}[tdplot_main_coords,declare function={a=2;
}]
\path
(0,0,0) coordinate (A)
(a,0,0) coordinate (B)
(a,a,0) coordinate (C)
(0,2*a,0) coordinate (D)
(0,0,2*a)  coordinate (S)
;
\draw (A)--(B)--(C)--(D)--(S) -- cycle (S) -- (B) (S) --(C);
\draw [dashed] (D) -- (A) -- (C);
\path foreach \p/\g in {A/-90,B/-90,C/0,D/0,S/90}{(\p)node{}+(\g:2.5mm) node{$\p$}};

\end{tikzpicture}
\end{document}


I got

How can I draw it?

• What are the centers of a frustum? Commented Sep 19, 2021 at 11:36
• @Bernard Updated. Commented Sep 19, 2021 at 14:07
• I'm sorry, but I still don't understand what you're trying to achieve. Could you post a hand-made sketch? Commented Sep 19, 2021 at 14:20

You can use 3dtools

\documentclass[border=3mm,tikz]{standalone}
\usetikzlibrary{3dtools,calc}% https://github.com/marmotghost/tikz-3dtools
\begin{document}
\begin{tikzpicture}[3d/install view={phi=55,psi=0,theta=70},
line join = round, line cap = round,
c/.style={circle,fill,inner sep=1pt},
declare function={a=2;r=a*sqrt(2);R=2*a;}]
\path
(0,0,0) coordinate (A)
(a,0,0) coordinate (B)
(a,a,0) coordinate (C)
(0,2*a,0) coordinate (D)
(0,0,2*a) coordinate (S)
[3d coordinate={(S')=(C)-(D) +(A)}];
\tikzset{3d/define orthonormal dreibein={A={(A)},B={(S)},C={(S')}}}
\path[x={(ex)},y={(ey)},z={(ez)}](A) pic{3d/frustum={r=r,R=R,h=r}};
\draw[3d/visible](C) -- (D);
\draw[3d/hidden](S) --(A) -- (B) -- (C) (S) -- (C) (S) -- (D) (A) -- (C) (A) -- (D) (S) -- (B);
\path foreach \p/\g in {A/180,B/-90,C/-90,D/0,S/90}
{(\p)node[c]{}+(\g:2.5mm) node{$\p$}};
\end{tikzpicture}
\end{document}


Or

\documentclass[border=3mm,12pt,tikz]{standalone}
\usetikzlibrary{3dtools,calc}% https://github.com/marmotghost/tikz-3dtools
\begin{document}
\foreach \Angle in {5,15,...,355}
{\begin{tikzpicture}[3d/install view={phi=\Angle,psi=0,theta=70},
line join = round, line cap = round,same bounding box=A,
c/.style={circle,fill,inner sep=1pt},
declare function={a=2;r=a*sqrt(2);R=2*a;}]
\path
(0,0,0) coordinate (A)
(a,0,0) coordinate (B)
(a,a,0) coordinate (C)
(0,2*a,0) coordinate (D)
(0,0,2*a) coordinate (S)
[3d coordinate={(S')=(C)-(D) +(A)}];
\pgfmathsetmacro{\myB}{TD("(C)")}
\pgfmathtruncatemacro{\itest}{screendepth(\myB)>0?1:0}
\ifnum\itest=1
\draw[3d/visible] (C) -- (D);
\draw[3d/hidden] (S) -- (A);
\else
\draw[3d/hidden] (D) -- (C);
\draw[3d/visible] (S) -- (A);
\fi
\draw[3d/hidden] (A) -- (C)  (A) -- (D) -- (S)
(A) -- (B) -- (C) (S) -- (B)  -- (C) -- cycle
;
\tikzset{3d/define orthonormal dreibein={A={(A)},B={(S)},C={(S')}}}
\path[x={(ex)},y={(ey)},z={(ez)}](A) pic{3d/frustum={r=r,R=R,h=r}};
\path foreach \p/\g in {A/180,B/-90,C/-90,D/0,S/90}
{(\p)node[c]{}+(\g:2.5mm) node{$\p$}};
\end{tikzpicture}}
\end{document}


Update and finish.

import three;
import solids;

size(8cm);
currentprojection=orthographic((1,-.2,.3));

real a=2;
triple A=O,B=(a,0,0),C=(a,a,0),D=(0,2a,0),S=(0,0,2a);
triple D_=rotate(-90,C,A)*D;

draw(C--D);
draw(A--S--B--cycle,dashed);
draw(A--C^^A--D,dashed);

revolution R=revolution(A,D_--S,C);
draw(C--D_,Arrow3);
//draw(surface(R),green+opacity(.5));
draw(R,linewidth(0.6bp));

path3 c=circle(C,abs(C-D),A-C);
// draw(c,Arrow3); // To specify the direction of circle
path c_=project(c);

draw(subpath(c,reltime(c,0.3),reltime(c,0.5)),green+0.8bp,Arrow3);
dot(relpoint(c,0.3));
dot(relpoint(c,0.5));

path pvisib1 = cut(project(D--S--C),c_,1).before;
path pvisib2 = cut(project(D--S--C),c_,2).after;
path pcache = cut(cut(project(D--S--C),c_,1).after,c_,1).before;
path BCdashed = cut(project(C--B),c_,1).after;
path BC = cut(project(C--B),c_,1).before;

// three.asy, line 1163
draw(invert(pvisib1),blue);
draw(invert(pvisib2),blue);
draw(invert(BC),blue);
draw(invert(pcache)^^invert(BCdashed),red+dashed);

dot("$A$",A,dir(-135));
dot("$B$",B,dir(-90));
dot("$C$",C,dir(-35));
dot("$D$",D,dir(0));
dot("$S$",S,dir(90));


import graph;
import solids;
currentprojection=orthographic(3,3,1.5);
//currentlight=Viewport;
currentlight.background = gray(.7);

picture pic1,pic2;
size(pic1,200);
size(pic2,200);
path g= (0, 0.65){right}
..{up}(0.45, 1)
--(0.5, 1){down}
..{left}(0.1,0.6)
{right}..{down}(0.15,0.55)
..{down}(0.075,0.35){down}
..{down}(0.075, 0.2)
..(0.15,0.15){down}
..{left}(0.1,0.1){right}
..{right}(0.4,0.05)
--(0.4,0){left}
..{left}(0,0.05);
pen[] colors={red,green,blue};
colors.cyclic=true;

for(int i=0;i<length(g);++i){

draw(pic1,subpath(g,i,i+1),colors[i]+1bp);
path3 p=path3(subpath(g,i,i+1),YZplane);
revolution R=revolution(p,Z,0,300);
draw(pic2,surface(R),colors[i],meshpen=black+0.55bp);

}
xaxis(pic1,"$x$",Arrow());
yaxis(pic1,"$y$",Arrow());

picture pic;
picture pic3;
draw(pic3,(-15,0)--(15,0),Arrow);


Animation.

import graph;
import solids;

currentprojection=orthographic(3,3,1.5);
//currentlight.background = gray(.7);

size(8cm);

path g= (0, 0.65){right}
..{up}(0.45, 1)
--(0.5, 1){down}
..{left}(0.1,0.6)
{right}..{down}(0.15,0.55)
..{down}(0.075,0.35){down}
..{down}(0.075, 0.2)
..(0.15,0.15){down}
..{left}(0.1,0.1){right}
..{right}(0.4,0.05)
--(0.4,0){left}
..{left}(0,0.05);

pen[] colors={red,green,blue};
colors.cyclic=true;

int numberofframes=72;
string[] files;

// Optional arguments and "normal" is always coincide with orthographic(3,3,1.5)
path3 boundingbox = circle((3,3,2), r=0.7, normal=(3,3,1.5));

for (int j=37; j<=numberofframes; ++j)
{
files[j]="T"+(string) j;
picture pic;
draw(pic, boundingbox, invisible);
for(int i=0;i<length(g);++i)
{
path3 p=path3(subpath(g,i,i+1),YZplane);
revolution R=revolution(p,Z,0,j*5);
draw(pic,surface(R),colors[i],meshpen=black+0.51bp);
}
shipout(files[j],bbox(invisible));
erase();
}


Compile with Asymptote.

Compile at http://asymptote.ualberta.ca/

From solids.asy

// A surface of revolution generated by rotating a planar path3 g
// from angle1 to angle2 about c--c+axis.
revolution revolution(triple c=O, path3 g, triple axis=Z, real angle1=0, real angle2=360);


Code

import three;
import solids;

size(8cm);
currentprojection=orthographic((1,-.2,.3));

real a=2;
triple A=O,B=(a,0,0),C=(a,a,0),D=(0,2a,0),S=(0,0,2a);
triple D_=rotate(-90,C,A)*D;

draw(A--B--C--D);
draw(A--S--B^^C--S--D);
draw(A--C^^A--D,dashed);

revolution R=revolution(A,D_--S,C);
draw(C--D_,Arrow3);
//draw(surface(R),green+opacity(.5));
draw(R,linewidth(0.6bp));

dot("$A$",A,dir(-135));
dot("$B$",B,dir(-90));
dot("$C$",C,dir(-35));
dot("$D$",D,dir(0));
dot("$S$",S,dir(90));


with D_--S is a generatrix and A--C is the directrix.

• How can I put this code between \begin{document} ... \end{document} ? Commented Sep 19, 2021 at 14:39
• I try your code at asymptote.ualberta.ca and try rotate by hand, dashed line of the circle incorrect. Commented Sep 19, 2021 at 14:47
• @ThuyNguyen Be patient! You will get a tikz-3dplot or3dtools from experienced users. Commented Sep 19, 2021 at 14:53
• @NguyenVanChi1998: Do you know anything about the status of 3dtools or the author? What made you suggest it? Commented Sep 20, 2021 at 1:16
• @hpekristiansen :-)), marmot is not on this, and he(she) also left topanswers.xyz/tex. I don't know tikz-3dplot or 3dtools and relative things but I see many good answers with them, so I think experienced users will not ignore this question. Commented Sep 20, 2021 at 2:15
\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3d}
\begin{document}
\tdplotsetmaincoords{60}{70}
\begin{tikzpicture}[tdplot_main_coords,declare function={a=2;}]
\coordinate (A) at (0,0,0);
\coordinate (B) at (a,0,0);
\coordinate (C) at (a,a,0);
\coordinate (D) at (0,2*a,0);
\coordinate (S) at (0,0,2*a);
\draw (A)--(B)--(C)--(D)--(S) -- cycle (S) -- (B) (S) --(C);
\draw [dashed] (A) -- (D)  (A) -- (C);
\path foreach \p/\g in {A/-90,B/-90,C/0,D/0,S/90}{(\p)node{}+(\g:2.5mm) node{$\p$}};
\begin{scope}[plane origin={(0,0,0)}, plane x={(1,-1,0)}, plane y={(0,0,1)}, canvas is plane]
\draw (0,0) circle (2*a);
\end{scope}
\begin{scope}[plane origin={(a,a,0)}, plane x={(a+1,a-1,0)}, plane y={(a,a,1)}, canvas is plane]
\draw (0,0) circle (a);
\end{scope}
\end{tikzpicture}
\end{document}


\tdplotsetmaincoords{80}{50} :

\tdplotsetmaincoords{80}{100} :