How can I draw these cones properly without the base exceeding the lines?
It is not too difficult to compute the angle of the intersection from your inputs.
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[fill opacity=0.2,text opacity=1]
\def\h{2}
\def\r{2}
\def\p{0.5}
% compute the aspect of the cylinder/cone
\pgfmathsetmacro{\mytheta}{atan2(\p,\r)}
% compute the critical angle at which the mantle intersects the base
\pgfmathsetmacro{\alphacrit}{90-acos(\p/\h)}%
% lower cone
\path (0,\h) + (-\alphacrit:\r cm and \p cm) coordinate (br)
(0,\h) + (180+\alphacrit:\r cm and \p cm) coordinate (bl);
\draw[left color=gray!50!black, right color=gray!50!black, middle color=gray!50,
line width = 0.6pt]
(bl) arc[start angle=180+\alphacrit,end angle=360-\alphacrit,
x radius=\r*1cm,y radius=\p*1cm]
-- (0,0) -- cycle;
% cylinder base
\fill[gray] (0,\h) circle[x radius=\r,y radius=\p];
\draw[dashed,line width = 0.6pt] (\r,\h)
arc[start angle=0,end angle=180,x radius=\r*1cm,y radius=\p*1cm];
\fill[fill=black,fill opacity=1] (0,\h) circle[radius=1.2pt];
% cylinder mantle
\draw[line width = 0.6pt,left color=gray!50!black, right
color=gray!50!black, middle color=gray!50]
(\r,\h) arc[start angle=0,end angle=-180,x radius=\r*1cm,y radius=\p*1cm]
-- (-\r,3*\h) arc[start angle=180,end angle=360,x radius=\r*1cm,y radius=\p*1cm]
-- cycle;
% cylinder top
\fill[gray] (0,3*\h) circle[x radius=\r,y radius=\p];
\draw[dashed,line width = 0.6pt] (\r,3*\h)
arc[start angle=0,end angle=180,x radius=\r*1cm,y radius=\p*1cm];
\fill[fill=black,fill opacity=1] (0,3*\h) circle[radius=1.2pt];
% upper cone
\path (0,3*\h) + (\alphacrit:\r cm and \p cm) coordinate (tr)
(0,3*\h) + (180-\alphacrit:\r cm and \p cm) coordinate (tl);
\draw[left color=gray!50!black, right color=gray!50!black, middle color=gray!50,
line width = 0.6pt]
(tl) arc[start angle=180-\alphacrit,end angle=360+\alphacrit,
x radius=\r*1cm,y radius=\p*1cm]
-- (0,4*\h) -- cycle;
% annotations
\draw[|-|] (\r+0.3,0) -- node[right] {$1.5$} (\r+0.3,\h);
\draw[|-|] (-\r-0.3,\h) -- node[left] {$3.0$} (-\r-0.3,3*\h);
\draw[|-|] (\r+0.3,3*\h) -- node[right] {$1.5$} (\r+0.3,4*\h);
\draw[dashed] (0,3*\h) -- node[above=-1.5pt] {$1.5$} (\r,3*\h);
\end{tikzpicture}
\end{document}
There is a chance that my other post on this is wrong...
It's quite flexible to make pic
with the following kind of pgfkeys
code (credit to whom? Schrodinger's cat?)
\tikzset{pics/ZZZZZ/.style={code={
\tikzset{ZZZZZ/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/ZZZZZ/##1}}%
.....
This is my first try. The code for pic cylinder
is straight.
\begin{tikzpicture}[thick]
\path
(0,0) pic[brown]{cylinder}
(7,0) pic[cyan]{cylinder={major=3,minor=.75,height=4}};
\end{tikzpicture}
For pic cone
, I add the boolean key upside down
via boolean comparison\newif\ifupsidedown
with setting
upside down/.initial=false, % Initially, cylinder is upside
upside down/.is if=upsidedown
\begin{tikzpicture}[thick]
\path
(0,0) pic[blue]{cone}
(7,0) pic[red]{cone={major=3,minor=.75,height=2.5,upside down=true}};
\end{tikzpicture}
Here is the final picture.
Full code is as follows.
\documentclass[tikz,border=5mm]{standalone}
\begin{document}
%%%%%%%% CYLINDER %%%%%%%%%%%%%%%%%%%%%
\tikzset{pics/cylinder/.style={code={
\tikzset{cylinder/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/cylinder/##1}}%
\draw[fill=white]
(\pv{major},\pv{height})--(\pv{major},0)
arc(0:-180:{\pv{major}} and {\pv{minor}})
--(-\pv{major},\pv{height})
arc(180:-180:{\pv{major}} and {\pv{minor}});
\draw[dashed]
(\pv{major},0) arc(0:180:{\pv{major}} and {\pv{minor}});
}},
cylinder/.cd,
major/.initial=1.5,
minor/.initial=.7,
height/.initial=3,
}% end of the pic: cylinder
%%%%%%%% CONE %%%%%%%%%%%%%%%%%%%%%%%%%
\newif\ifupsidedown
\tikzset{pics/cone/.style={code={
\tikzset{cone/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/cone/##1}}%
\pgfmathsetmacro{\t}{asin(\pv{minor}/\pv{height})}
\ifupsidedown
\draw
(-\t:{\pv{major}} and {\pv{minor}})--(0,-\pv{height})--(180+\t:{\pv{major}} and {\pv{minor}})
(\pv{major},0) arc(0:360:{\pv{major}} and {\pv{minor}});
\else
\draw[fill=white]
(\t:{\pv{major}} and {\pv{minor}})--(0,\pv{height})--(180-\t:{\pv{major}} and {\pv{minor}})
arc(180-\t:360+\t:{\pv{major}} and {\pv{minor}});
\draw[dashed]
(\t:{\pv{major}} and {\pv{minor}}) arc(\t:180-\t:{\pv{major}} and {\pv{minor}});
\fi
}},
cone/.cd,
major/.initial=3,
minor/.initial=1,
height/.initial=3,
upside down/.initial=false,
upside down/.is if=upsidedown
} % end of the pic: cone
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{tikzpicture}[thick]
\path
(0,0) pic[brown]{cylinder}
(7,0) pic[cyan]{cylinder={major=3,minor=.75,height=4}}
;
\end{tikzpicture}
\begin{tikzpicture}[thick]
\path
(0,0) pic[blue]{cone}
(7,0) pic[red]{cone={major=3,minor=.75,height=2.5,upside down=true}}
;
\end{tikzpicture}
\begin{tikzpicture}
\def\a{1.5} \def\b{.5} \def\hcy{3} \def\hco{1.5}
\path[thick]
(0,0)
pic{cone={major=\a,minor=\b,height=\hco,upside down=true}}
pic{cylinder={major=\a,minor=\b,height=\hcy}}
(0,3)
pic{cone={major=\a,minor=\b,height=\hco}}
;
% for legends
\begin{scope}[magenta,nodes={midway,scale=.8}]
\draw[dashed] (\a,\hcy)--(0,\hcy) node[above]{1.5};
\draw[|-|] (\a+.3,\hcy)--+(90:\hco) node[right]{1.5};
\draw[|-|] (\a+.3,0)--+(-90:\hco) node[right]{1.5};
\draw[|-|] (-\a-.3,0)--+(90:\hcy) node[left]{3};
\fill (0,0) circle(1.5pt) (0,\hcy) circle(1.5pt);
\end{scope}
\end{tikzpicture}
\end{document}
You can try this code
\documentclass[12pt,a4paper,border=2mm]{standalone}
\usepackage{tikz, tikz-3dplot}
\usetikzlibrary{calc,backgrounds}
\usepackage{pgfplots}
\begin{document}
\pgfmathsetmacro\th{70}
\pgfmathsetmacro\az{70}
\tdplotsetmaincoords{\th}{\az}
\pgfmathsetmacro\h{3} %height of cylinder
\pgfmathsetmacro\R{3} %radius of base
\pgfmathsetmacro\v{\h + 3}
\pgfmathsetmacro\t{-\h}
\begin{tikzpicture} [scale=1, tdplot_main_coords, axis/.style={blue,thick}]
\path
(0,0,0) coordinate (O)
(0,0,\v) coordinate (B)
(0,0,\t) coordinate (A);
\pgfmathsetmacro\cott{{cot(\th)}}
\pgfmathsetmacro\fraction{\R*\cott/(\v-\h)}
\pgfmathsetmacro\fractionTwo{\R*\cott/\t}
\pgfmathsetmacro\fraction{\fraction<1 ? \fraction : 1}
\pgfmathsetmacro\angle{{acos(\fraction)}}
\pgfmathsetmacro\angleTwo{{acos(\fractionTwo)}}
\pgfmathsetmacro\PhiOne{180+(\az-90)+\angle}
\pgfmathsetmacro\PhiTwo{180+(\az-90)-\angle}
\pgfmathsetmacro\PhiOneBis{180+(\az-90)+\angleTwo}
\pgfmathsetmacro\PhiTwoBis{180+(\az-90)-\angleTwo}
\pgfmathsetmacro\sinPhiOne{{sin(\PhiOne)}}
\pgfmathsetmacro\cosPhiOne{{cos(\PhiOne)}}
\pgfmathsetmacro\sinPhiTwo{{sin(\PhiTwo)}}
\pgfmathsetmacro\cosPhiTwo{{cos(\PhiTwo)}}
\pgfmathsetmacro\sinPhiOneBis{{sin(\PhiOneBis)}}
\pgfmathsetmacro\cosPhiOneBis{{cos(\PhiOneBis)}}
\pgfmathsetmacro\sinPhiTwoBis{{sin(\PhiTwoBis)}}
\pgfmathsetmacro\cosPhiTwoBis{{cos(\PhiTwoBis)}}
\pgfmathsetmacro\sinazp{{sin(\az-90)}}
\pgfmathsetmacro\cosazp{{cos(\az-90)}}
\pgfmathsetmacro\sinazm{{sin(90-\az)}}
\pgfmathsetmacro\cosazm{{cos(90-\az)}}
%\tdplotdrawarc[tdplot_main_coords,thick]{(O)}{\R}{\PhiOne}{360+\PhiTwo}{anchor=north}{}
\draw[dashed] (\tdplotmainphi:\R) arc(\tdplotmainphi:\tdplotmainphi+180:\R);
\draw[thick] (\tdplotmainphi:\R) arc(\tdplotmainphi:\tdplotmainphi-180:\R);
\tdplotdrawarc[tdplot_main_coords,thick]{(0,0,\h)}{\R}{\PhiOne}{360+\PhiTwo}{anchor=north}{}
\tdplotdrawarc[tdplot_main_coords,dashed]{(0,0,\h)}{\R}{\PhiTwo}{\PhiOne}{anchor=north}{}
\draw[thick] ({\R*cos(\tdplotmainphi)},{\R*sin(\tdplotmainphi)},0 ) -- ({\R*cos(\tdplotmainphi)},{\R*sin(\tdplotmainphi)},\h );
\draw[thick] ({\R*cos(\tdplotmainphi-180)},{\R*sin(\tdplotmainphi-180)},0 ) -- ({\R*cos(\tdplotmainphi-180)},{\R*sin(\tdplotmainphi-180)},\h );
\draw[thick] (B) -- (\R*\cosPhiOne,\R*\sinPhiOne,\h);
\draw[thick] (B) -- (\R*\cosPhiTwo,\R*\sinPhiTwo,\h);
\draw[thick] (A) -- (\R*\cosPhiOneBis,\R*\sinPhiOneBis,0);
\draw[thick] (A) -- (\R*\cosPhiTwoBis,\R*\sinPhiTwoBis,0);
\foreach \p in {O,B,A}
\draw[fill=black] (\p) circle (1pt);
\foreach \p/\g in {O/-45,B/90,A/-90}
\path (\p)+(\g:3mm) node{$\p$};
\draw[dashed] (A)--(B) (-\R*\sinazm,-\R*\cosazm,0) -- (-\R*\sinazp,+\R*\cosazp,0) ;
\end{tikzpicture}
\end{document}
You can try
\documentclass[12pt,a4paper,border=2mm]{standalone}
\usepackage{tikz, tikz-3dplot}
\usetikzlibrary{calc,backgrounds}
\usepackage{pgfplots}
\begin{document}
\pgfmathsetmacro\th{80}
\pgfmathsetmacro\az{70}
\tdplotsetmaincoords{\th}{\az}
\pgfmathsetmacro\h{3} %height of cylinder
\pgfmathsetmacro\R{8} %radius of base
\pgfmathsetmacro\v{\h + 3}
\pgfmathsetmacro\t{-8}
\begin{tikzpicture} [scale=1, tdplot_main_coords, axis/.style={blue,thick}]
\path
(0,0,0) coordinate (O)
(0,0,\v) coordinate (B)
(0,0,\t) coordinate (A);
\pgfmathsetmacro\cott{{cot(\th)}}
\pgfmathsetmacro\fraction{\R*\cott/(\v-\h)}
\pgfmathsetmacro\fractionTwo{\R*\cott/\t}
\pgfmathsetmacro\fraction{\fraction<1 ? \fraction : 1}
\pgfmathsetmacro\angle{{acos(\fraction)}}
\pgfmathsetmacro\angleTwo{{acos(\fractionTwo)}}
\pgfmathsetmacro\PhiOne{180+(\az-90)+\angle}
\pgfmathsetmacro\PhiTwo{180+(\az-90)-\angle}
\pgfmathsetmacro\PhiOneBis{180+(\az-90)+\angleTwo}
\pgfmathsetmacro\PhiTwoBis{180+(\az-90)-\angleTwo}
\pgfmathsetmacro\sinPhiOne{{sin(\PhiOne)}}
\pgfmathsetmacro\cosPhiOne{{cos(\PhiOne)}}
\pgfmathsetmacro\sinPhiTwo{{sin(\PhiTwo)}}
\pgfmathsetmacro\cosPhiTwo{{cos(\PhiTwo)}}
\pgfmathsetmacro\sinPhiOneBis{{sin(\PhiOneBis)}}
\pgfmathsetmacro\cosPhiOneBis{{cos(\PhiOneBis)}}
\pgfmathsetmacro\sinPhiTwoBis{{sin(\PhiTwoBis)}}
\pgfmathsetmacro\cosPhiTwoBis{{cos(\PhiTwoBis)}}
\pgfmathsetmacro\sinazp{{sin(\az-90)}}
\pgfmathsetmacro\cosazp{{cos(\az-90)}}
\pgfmathsetmacro\sinazm{{sin(90-\az)}}
\pgfmathsetmacro\cosazm{{cos(90-\az)}}
\draw[dashed] (\tdplotmainphi:\R) arc(\tdplotmainphi:\tdplotmainphi+180:\R);
\draw[thick] (\tdplotmainphi:\R) arc(\tdplotmainphi:\tdplotmainphi-180:\R);
\tdplotdrawarc[tdplot_main_coords,thick]{(0,0,\h)}{\R}{\PhiOne}{360+\PhiTwo}{anchor=north}{}
\tdplotdrawarc[tdplot_main_coords,dashed]{(0,0,\h)}{\R}{\PhiTwo}{\PhiOne}{anchor=north}{}
\draw[thick] ({\R*cos(\tdplotmainphi)},{\R*sin(\tdplotmainphi)},0 ) -- ({\R*cos(\tdplotmainphi)},{\R*sin(\tdplotmainphi)},\h );
\draw[thick] ({\R*cos(\tdplotmainphi-180)},{\R*sin(\tdplotmainphi-180)},0 ) -- ({\R*cos(\tdplotmainphi-180)},{\R*sin(\tdplotmainphi-180)},\h );
\draw[thick] (B) -- (\R*\cosPhiOne,\R*\sinPhiOne,\h);
\draw[thick] (B) -- (\R*\cosPhiTwo,\R*\sinPhiTwo,\h);
\draw[thick] (A) -- (\R*\cosPhiOneBis,\R*\sinPhiOneBis,0);
\draw[thick] (A) -- (\R*\cosPhiTwoBis,\R*\sinPhiTwoBis,0);
\foreach \p in {O,B,A}
\draw[fill=black] (\p) circle (1pt);
\foreach \p/\g in {O/-45,B/90,A/-90}
\path (\p)+(\g:3mm) node{$\p$};
\draw[dashed] (A)--(B) (-\R*\sinazm,-\R*\cosazm,0) -- (-\R*\sinazp,+\R*\cosazp,0) ;
\end{tikzpicture}
\end{document}