Asymptote 在绘制三维图形时确实会给出 3D 箭头(它们甚至有阴影!)。我们能用 TikZ 伪造它吗?这是一个手写的示例,只有一个箭头:
\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{tikzpicture}[->,scale=2]
\draw[>={Triangle[width=3pt,length=5pt]}] (0,0,0) -- (1,0,0);
\draw[>={Triangle[width=3pt,length=5pt]}] (0,0,0) -- (0,1,0);
\draw[>={Circle[sep=-.9pt,width=3.08pt,length=2pt]Triangle[width=3pt,length=5pt]}] (0,0,0) -- (0,0,1);
\end{tikzpicture}
\end{document}
但这是(错误地)通过反复试验手动计算出来的(除了它并不完美之外,看看其他两个轴 — x 和 y — 的方向,它应该有一定的倾斜度)。如果有一个像其他箭头一样的界面就好了
>={3D[length=⟨real length⟩,width=⟨real width of the base⟩]}
然后根据这些值进行计算(当然,也会考虑到x=⟨x vect⟩,y=⟨y vect⟩,z=⟨z vect⟩
)
Circle[sep=⟨value⟩,width=⟨value⟩,length=⟨value⟩,slant=⟨value⟩]
Triangle[width=⟨value⟩,length=⟨value⟩] % And I'm not sure if `slant=⟨value⟩`
% is necessary in this Triangle case
例子
使用答案中的代码(感谢 Symbol1),例如,此代码(从另一个问题中获取想法,链接在评论中)
\begin{tikzpicture}[x={(0cm,1cm)},
y={({cos(30)*1cm},{sin(30)*-1cm})},
z={({cos(20)*1cm},{sin(20)*1cm})},
thick,
scale=3]
\pgfmathsetmacro{\ax}{.4}
\pgfmathsetmacro{\ay}{.6}
\pgfmathsetmacro{\az}{-.6}
\pgfmathsetmacro{\bx}{.4}
\pgfmathsetmacro{\by}{-.7}
\pgfmathsetmacro{\bz}{-.8}
\draw[densely dotted,thin] (\ax,\ay,\az) -- (\ax,0,\az);
\draw[densely dotted,thin] (\ax,\ay,\az) -- (0,\ay,\az);
\draw[densely dotted,thin] (\ax,0,0) -- (\ax,0,\az) -- (0,0,\az);
\draw[densely dotted,thin] (0,0,\az) -- (0,\ay,\az) -- (0,\ay,0);
\draw[densely dotted,thin] (\bx,\by,\bz) -- (\bx,0,\bz);
\draw[densely dotted,thin] (\bx,\by,\bz) -- (0,\by,\bz);
\draw[densely dotted,thin] (\bx,0,0) -- (\bx,0,\bz) -- (0,0,\bz);
\draw[densely dotted,thin] (0,0,\bz) -- (0,\by,\bz) -- (0,\by,0);
\draw[-{Cone3}] (0,0,0) -- (1,0,0) node[right] {$x$};
\draw[-{Cone3}] (0,0,0) -- (0,1,0) node[above right] {$y$};
\draw[-{Cone3}] (0,0,0) -- (0,0,1) node[below right] {$z$};
\draw[-{Cone3}] (0,0,0) -- (0,0,-1) node[above left] {$-z$};
\draw[thin] (0,0,0) -- (0,-.9,0);
\draw[-{Cone3}] (0,0,0) -- (\ax,\ay,\az) node[below left] {source};
\draw[-{Cone3}] (0,0,0) -- (\bx,\by,\bz) node[above right] {sim};
\end{tikzpicture}
给出了这个数字
答案1
这种方法允许您分配一个沥青从0
到90
,其中0
表示位于屏幕上,90
表示垂直于屏幕。(当然你可以分配91.1
或5566
或任何好的数。目前abs
代码中的 消除了所有有趣的情况。)
一旦你修复了间距,部件drawing code
就会进行一些必要的计算,例如切点的位置。请注意,虽然预定义的箭头提示有一些附加选项,例如open
和harpoon
,但我的提示没有实现它们。我甚至用fill
它来摆脱线宽问题。
\documentclass[tikz,border=9]{standalone}
\usepgflibrary{arrows.meta}
\makeatletter
\pgfkeys{
/pgf/arrow keys/.cd,
pitch/.code={%
\pgfmathsetmacro\pgfarrowpitch{#1}
\pgfmathsetmacro\pgfarrowsinpitch{abs(sin(\pgfarrowpitch))}
\pgfmathsetmacro\pgfarrowcospitch{abs(cos(\pgfarrowpitch))}
},
}
\pgfdeclarearrow{
name = Cone,
defaults = { % inherit from Kite
length = +3.6pt +5.4,
width' = +0pt +0.5,
line width = +0pt 1 1,
pitch = +0, % lie on screen
},
cache = false, % no need cache
setup code = {}, % so no need setup
drawing code = { % but still need math
% draw the base
\pgfmathsetmacro\pgfarrowhalfwidth{.5\pgfarrowwidth}
\pgfmathsetmacro\pgfarrowhalfwidthsin{\pgfarrowhalfwidth*\pgfarrowsinpitch}
\pgfpathellipse{\pgfpointorigin}{\pgfqpoint{\pgfarrowhalfwidthsin pt}{0pt}}{\pgfqpoint{0pt}{\pgfarrowhalfwidth pt}}
\pgfusepath{fill}
% test if the cone part visible
\pgfmathsetmacro\pgfarrowlengthcos{\pgfarrowlength*\pgfarrowcospitch}
\pgfmathparse{\pgfarrowlengthcos>\pgfarrowhalfwidthsin}
\ifnum\pgfmathresult=1
% it is visible, so draw
\pgfmathsetmacro\pgfarrowlengthtemp{\pgfarrowhalfwidthsin*\pgfarrowhalfwidthsin/\pgfarrowlengthcos}
\pgfmathsetmacro\pgfarrowwidthtemp{\pgfarrowhalfwidth/\pgfarrowlengthcos*sqrt(\pgfarrowlengthcos*\pgfarrowlengthcos-\pgfarrowhalfwidthsin*\pgfarrowhalfwidthsin)}
\pgfpathmoveto{\pgfqpoint{\pgfarrowlengthcos pt}{0pt}}
\pgfpathlineto{\pgfqpoint{\pgfarrowlengthtemp pt}{ \pgfarrowwidthtemp pt}}
\pgfpathlineto{\pgfqpoint{\pgfarrowlengthtemp pt}{-\pgfarrowwidthtemp pt}}
\pgfpathclose
\pgfusepath{fill}
\fi
\pgfpathmoveto{\pgfpointorigin}
}
}
\begin{document}
\begin{tikzpicture}[line width=5]
\draw[-{Cone }](0,0,0)--(1,0,0);
\draw[-{Cone }](0,0,0)--(0,1,0);
\draw[-{Cone[pitch=60]}](0,0,0)--(0,0,1);
\path(2,0,0)(0,2,0)(0,0,2);
\end{tikzpicture}
\foreach\theta in{0,10,...,350}{
\tikz[line width=5]\draw[-{Cone[pitch=\theta]}](-2,0)(2,0)(0,0)--({cos(\theta)},0);
}
\foreach\theta in{0,10,...,350}{
\tikz[line width=5,opacity=.5]\draw[-{Cone[pitch=\theta]}](-2,0)(2,0)(0,0)--({cos(\theta)},0);
}
\end{document}
更新
我写了三条提示Cone1
,,Cone2
和Cone3
。
Cone1
它用沥青与上述类似Cone
,只是现在检查是否sin(pitch)
为阳性。如果是,它假定箭头指向你的眼睛,因此添加一个白点。(同时,cos(pitch)
必须为阳性。)
说到点,很难确定正确的尺寸和颜色。目前Cone1
读取设置line width
并填充一个白色圆圈,其直径就是宽度。这是一个好主意,因为线宽在其他地方没有用到,但如果你真的关心代码的可读性,这也是一个坏主意。
Cone2
本提示接受切线选项,tangent={(1,2,3)}
以便它可以计算音高(实际上是它的正弦和余弦)。
问题是,在 Ti 的世界里钾Z 从来没有人关心过垂直于屏幕的 3D 向量投影。如果我们足够幸运,当前投影到屏幕上是正交类型,这可能是由 指定的tikz-3dplot
,那么垂直于屏幕的投影在数学上定义得很好,直到一个符号。(我们无法区分进入屏幕和屏幕外将其投影到屏幕上。
不幸的是,在大多数情况下,如果您手动分配x=
、y=
和,z=
它将不是正交投影。
在这里,我简单地使用叉积来计算缺失的投影,条件是结果将是正确的如果有人用来tikz-3dplot
分配投影。
更准确地说,\tikz@scan@one@point
是 Ti 中使用的命令钾Z 来解析坐标,例如(1,2)
、(3:4)
、(A)
或(5,6,7)
。当我写
\tikz@scan@one@point\pgfarrowtangenttosincos#1
并且#1
,例如(5,6,7)
,Ti钾Z 最终将得到
\pgfarrowtangenttosincos{\pgfpointxyz{5}{6}{7}}
然后,根据 的定义\pgfarrowtangenttosincos
,PGF 将执行
\pgfpointxyz{5}{6}{7}
\tdplotcrossprod(\pgf@xx,\pgf@yx,\pgf@zx)(\pgf@xy,\pgf@yy,\pgf@zy)
现在
(\pgftemp@x,\pgftemp@y,\pgftemp@z)
是(5,6,7)
。(\pgf@x,\pgf@y)
(5,6,7)
是屏幕上的投影。(\tdplotresx,\tdplotresy,\tdplotresz)
是叉积的结果。
所以
sqrt(\pgf@x*\pgf@x+\pgf@y*\pgf@y)
屏幕上的长度(\tdplotresx,\tdplotresy,\tdplotresz)
和的内积(\tdplotresx,\tdplotresy,\tdplotresz)
是长度屏幕外- 以上两个的平方根就是整个向量的长度。
所以
- 正弦是
a/c
- 余弦是
b/c
此后,一切都正常Cone1
。
Cone3
我做了些改动\pgfpointxyz
,让它缓冲两个最近的 3D 坐标。在绘制箭头时,我假设旧的缓冲坐标是终点,而更早的缓冲坐标是起点。因此切线应该是这两个坐标的差。
代码
\documentclass[tikz]{standalone}
\usepgflibrary{arrows.meta}
\usepackage{tikz-3dplot}
\begin{document}
\makeatletter
\pgfkeys{
/pgf/arrow keys/.cd,
pitch/.code={%
\pgfmathsetmacro\pgfarrowpitch{#1}
\pgfmathsetmacro\pgfarrowcospitch{abs(cos(\pgfarrowpitch))}
\pgfmathsetmacro\pgfarrowsinpitch{ sin(\pgfarrowpitch)}
}
}
\pgfdeclarearrow{
name = Cone1,
defaults = { % inherit from Kite
length = +3.6pt +5.4,
width' = +0pt +0.5,
line width = +0pt 1 1,
pitch = +0, % lie on screen
},
cache = false, % no need cache
setup code = {}, % so no need setup
drawing code = { % but still need math
% draw the base
\pgfmathsetmacro\pgfarrowhalfwidth{.5\pgfarrowwidth}
\pgfmathsetmacro\pgfarrowhalfwidthsin{\pgfarrowhalfwidth*abs(\pgfarrowsinpitch)}
\pgfpathellipse{\pgfpointorigin}{\pgfqpoint{\pgfarrowhalfwidthsin pt}{0pt}}{\pgfqpoint{0pt}{\pgfarrowhalfwidth pt}}
\pgfusepath{fill}
% test if the cone part visible
\pgfmathsetmacro\pgfarrowlengthcos{\pgfarrowlength*\pgfarrowcospitch}
\ifdim\pgfarrowlengthcos pt>\pgfarrowhalfwidthsin pt
% it is visible, so draw
\pgfmathsetmacro\pgfarrowlengthtemp{\pgfarrowhalfwidthsin*\pgfarrowhalfwidthsin/\pgfarrowlengthcos}
\pgfmathsetmacro\pgfarrowwidthtemp{\pgfarrowhalfwidth/\pgfarrowlengthcos*sqrt(\pgfarrowlengthcos*\pgfarrowlengthcos-\pgfarrowhalfwidthsin*\pgfarrowhalfwidthsin)}
\pgfpathmoveto{\pgfqpoint{\pgfarrowlengthcos pt}{0pt}}
\pgfpathlineto{\pgfqpoint{\pgfarrowlengthtemp pt}{ \pgfarrowwidthtemp pt}}
\pgfpathlineto{\pgfqpoint{\pgfarrowlengthtemp pt}{-\pgfarrowwidthtemp pt}}
\pgfpathclose
\pgfusepath{fill}
\else
% it is invisible, check in pointing your eye
\ifdim\pgfarrowsinpitch pt>0pt
\pgfpathcircle{\pgfqpoint{\pgfarrowlengthcos pt}{0pt}}{.5\pgfarrowlinewidth}
\pgfsetcolor{white}
\pgfusepath{fill}
\fi
\fi
\pgfpathmoveto{\pgfpointorigin}
}
}
%\begin{tikzpicture}[line width=5]
% \draw[-{Cone1 }](0,0,0)--(1,0,0);
% \draw[-{Cone1 }](0,0,0)--(0,1,0);
% \draw[-{Cone1[pitch=60]}](0,0,0)--(0,0,1);
% \path(3,0,0)(0,3,0)(0,0,3);
%\end{tikzpicture}
%\foreach\theta in{0,10,...,350}{
% \tikz[line width=5]\draw[-{Cone1[width'=0 1,pitch=\theta]}](-2,-.5)(2,.5)(0,0)--({cos(\theta)},0);
%}
%\foreach\theta in{0,10,...,350}{
% \tikz[line width=5,opacity=.5]\draw[-{Cone1[width'=0 1,pitch=\theta]}](-2,-.5)(2,.5)(0,0)--({cos(\theta)},0);
%}
\def\pgfarrowtangenttosincos#1{
#1
\tdplotcrossprod(\pgf@xx,\pgf@yx,\pgf@zx)(\pgf@xy,\pgf@yy,\pgf@zy)
\pgfmathsetmacro\pgfarrowtangentxxyy{\pgf@x*\pgf@x+\pgf@y*\pgf@y}
\pgfmathsetmacro\pgfarrowtangentxy{sqrt(\pgfarrowtangentxxyy)}
\pgfmathsetmacro\pgfarrowtangentz{(\pgftemp@x*\tdplotresx+\pgftemp@y*\tdplotresy+\pgftemp@z*\tdplotresz)/72.27*2.54}
%\message{^^J^^J(\tdplotresx,\tdplotresy,\tdplotresz)(\pgfarrowtangentxy,\pgfarrowtangentz)}\show\\
\pgfmathsetmacro\pgfarrowtangentxyz{sqrt(\pgfarrowtangentxxyy+\pgfarrowtangentz*\pgfarrowtangentz)}
\pgfmathsetmacro\pgfarrowcospitch{\pgfarrowtangentxy/\pgfarrowtangentxyz}
\pgfmathsetmacro\pgfarrowsinpitch{\pgfarrowtangentz/\pgfarrowtangentxyz}
}
\pgfkeys{
/pgf/arrow keys/.cd,
tangent/.code={%
\tikz@scan@one@point\pgfarrowtangenttosincos#1
}
}
\pgfdeclarearrow{
name = Cone2,
defaults = { % inherit from Kite
length = +3.6pt +5.4,
width' = +0pt +0.5,
line width = +0pt 1 1,
tangent = {(1,0,0)} % lie on x-axis
},
cache = false, % no need cache
setup code = {}, % so no need setup
drawing code = { % but still need math
% draw the base
\pgfmathsetmacro\pgfarrowhalfwidth{.5\pgfarrowwidth}
\pgfmathsetmacro\pgfarrowhalfwidthsin{\pgfarrowhalfwidth*abs(\pgfarrowsinpitch)}
\pgfpathellipse{\pgfpointorigin}{\pgfqpoint{\pgfarrowhalfwidthsin pt}{0pt}}{\pgfqpoint{0pt}{\pgfarrowhalfwidth pt}}
\pgfusepath{fill}
% test if the cone part visible
\pgfmathsetmacro\pgfarrowlengthcos{\pgfarrowlength*\pgfarrowcospitch}
\ifdim\pgfarrowlengthcos pt>\pgfarrowhalfwidthsin pt
% it is visible, so draw
\pgfmathsetmacro\pgfarrowlengthtemp{\pgfarrowhalfwidthsin*\pgfarrowhalfwidthsin/\pgfarrowlengthcos}
\pgfmathsetmacro\pgfarrowwidthtemp{\pgfarrowhalfwidth/\pgfarrowlengthcos*sqrt(\pgfarrowlengthcos*\pgfarrowlengthcos-\pgfarrowhalfwidthsin*\pgfarrowhalfwidthsin)}
\pgfpathmoveto{\pgfqpoint{\pgfarrowlengthcos pt}{0pt}}
\pgfpathlineto{\pgfqpoint{\pgfarrowlengthtemp pt}{ \pgfarrowwidthtemp pt}}
\pgfpathlineto{\pgfqpoint{\pgfarrowlengthtemp pt}{-\pgfarrowwidthtemp pt}}
\pgfpathclose
\pgfusepath{fill}
\else
% it is invisible, check in pointing your eye
\ifdim\pgfarrowsinpitch pt>0pt
\pgfpathcircle{\pgfqpoint{\pgfarrowlengthcos pt}{0pt}}{.5\pgfarrowlinewidth}
\pgfsetcolor{white}
\pgfusepath{fill}
\fi
\fi
\pgfpathmoveto{\pgfpointorigin}
}
}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[line width=5,tdplot_main_coords]
\draw[-{Cone2[tangent={(1,0,0)}]}](0,0,0)--(1,0,0)node[cyan]{X};
\draw[-{Cone2[tangent={(0,1,0)}]}](0,0,0)--(0,1,0)node[cyan]{Y};
\draw[-{Cone2[tangent={(0,0,1)}]}](0,0,0)--(0,0,1)node[cyan]{Z};
\path(-2cm,-2cm)(2cm,2cm);
\end{tikzpicture}
\foreach\theta in{0,10,...,350}{
\tdplotsetrotatedcoords{\theta}{30}{30}
\tikz[line width=5,line cap=round,tdplot_rotated_coords]{
\draw[-{Cone2[tangent={(1,0,0)}]}](0,0,0)--(1,0,0)node[cyan]{X};
\draw[-{Cone2[tangent={(0,1,0)}]}](0,0,0)--(0,1,0)node[cyan]{Y};
\draw[-{Cone2[tangent={(0,0,1)}]}](0,0,0)--(0,0,1)node[cyan]{Z};
\path(-2cm,-2cm)(2cm,2cm);
}
}
\def\pgfpointxyz#1#2#3{%
\pgfmathparse{#1}%
\let\pgftemp@x=\pgfmathresult%
\pgfmathparse{#2}%
\let\pgftemp@y=\pgfmathresult%
\pgfmathparse{#3}%
\let\pgftemp@z=\pgfmathresult%
\pgf@x=\pgftemp@x\pgf@xx%
\advance\pgf@x by \pgftemp@y\pgf@yx%
\advance\pgf@x by \pgftemp@z\pgf@zx%
\pgf@y=\pgftemp@x\pgf@xy%
\advance\pgf@y by \pgftemp@y\pgf@yy%
\advance\pgf@y by \pgftemp@z\pgf@zy%
% ↑↑↑old definition↑↑↑ ↓↓↓new code↓↓↓
\global\let\pgfolderpointx\pgfoldpointx
\global\let\pgfolderpointy\pgfoldpointy
\global\let\pgfolderpointz\pgfoldpointz
\global\let\pgfoldpointx\pgftemp@x
\global\let\pgfoldpointy\pgftemp@y
\global\let\pgfoldpointz\pgftemp@z
}
\pgfdeclarearrow{
name = Cone3,
defaults = { % inherit from Kite
length = +3.6pt +5.4,
width' = +0pt +0.5,
line width = +0pt 1 1,
tangent = {(1,0,0)} % lie on x-axis
},
cache = false, % no need cache
setup code = {}, % so no need setup
drawing code = { % but still need math
% calculate the tangent
\pgfkeys{pgf/arrow keys/tangent={(\pgfoldpointx-\pgfolderpointx,\pgfoldpointy-\pgfolderpointy,\pgfoldpointz-\pgfolderpointz)}}
% draw the base
\pgfmathsetmacro\pgfarrowhalfwidth{.5\pgfarrowwidth}
\pgfmathsetmacro\pgfarrowhalfwidthsin{\pgfarrowhalfwidth*abs(\pgfarrowsinpitch)}
\pgfpathellipse{\pgfpointorigin}{\pgfqpoint{\pgfarrowhalfwidthsin pt}{0pt}}{\pgfqpoint{0pt}{\pgfarrowhalfwidth pt}}
\pgfusepath{fill}
% test if the cone part visible
\pgfmathsetmacro\pgfarrowlengthcos{\pgfarrowlength*\pgfarrowcospitch}
\ifdim\pgfarrowlengthcos pt>\pgfarrowhalfwidthsin pt
% it is visible, so draw
\pgfmathsetmacro\pgfarrowlengthtemp{\pgfarrowhalfwidthsin*\pgfarrowhalfwidthsin/\pgfarrowlengthcos}
\pgfmathsetmacro\pgfarrowwidthtemp{\pgfarrowhalfwidth/\pgfarrowlengthcos*sqrt(\pgfarrowlengthcos*\pgfarrowlengthcos-\pgfarrowhalfwidthsin*\pgfarrowhalfwidthsin)}
\pgfpathmoveto{\pgfqpoint{\pgfarrowlengthcos pt}{0pt}}
\pgfpathlineto{\pgfqpoint{\pgfarrowlengthtemp pt}{ \pgfarrowwidthtemp pt}}
\pgfpathlineto{\pgfqpoint{\pgfarrowlengthtemp pt}{-\pgfarrowwidthtemp pt}}
\pgfpathclose
\pgfusepath{fill}
\else
% it is invisible, check in pointing your eye
\ifdim\pgfarrowsinpitch pt>0pt
\pgfpathcircle{\pgfqpoint{\pgfarrowlengthcos pt}{0pt}}{.5\pgfarrowlinewidth}
\pgfsetcolor{white}
\pgfusepath{fill}
\fi
\fi
\pgfpathmoveto{\pgfpointorigin}
}
}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[line width=5,tdplot_main_coords]
\draw[-{Cone2[tangent={(1,0,0)}]}](0,0,0)--(1,0,0)node[cyan]{X};
\draw[-{Cone2[tangent={(0,1,0)}]}](0,0,0)--(0,1,0)node[cyan]{Y};
\draw[-{Cone2[tangent={(0,0,1)}]}](0,0,0)--(0,0,1)node[cyan]{Z};
\path(-2cm,-2cm)(2cm,2cm);
\end{tikzpicture}
\foreach\theta in{0,5,...,355}{
\tdplotsetrotatedcoords{\theta}{2*\theta}{3*\theta}
\tikz[line width=5,line cap=round,tdplot_rotated_coords]{
\draw[-Cone3](0,0,0)--(1,0,0)node[cyan]{X};
\draw[-Cone3](0,0,0)--(0,1,0)node[cyan]{Y};
\draw[-Cone3](0,0,0)--(0,0,1)node[cyan]{Z};
\path(-2cm,-2cm)(2cm,2cm);
}
}
\end{document}
答案2
这个如何?
\documentclass[margin=10pt]{standalone}
\usepackage[svgnames]{xcolor}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[scale=3]
\def\opaque{0.035} % rendering opacity
\def\prop{1.3} % variable of rendering opacity
\def\R{2} % % cone slant height
\def\theta{21} % 2*\theta is the angle of expanded by the tip of the cone
\def\range{100} % number of interaction for smooth rending effect
\def\ratio{0.4} % ellipse b/a for cone lower edge
\def\aratio{0.35} % a_rod / a_cone
\def\height{0.8} % rod height
\def\fraction{0.375} % ellipse b/a for rod edge
\def\angle{12} % angle extended by rod edge
\def\total{60} % number of interaction for smooth rending effect
\def\conecolor{red!\range!black!40!red} % cone color
\foreach \i in {0,...,\range}
{
\fill[\conecolor, opacity={\opaque+\prop*\opaque*(\range-2*\i)/\range}] (0, {\R*cos(\theta)}) -- ({\R*sin(\theta)*cos(270+90*\i/\range)},{\ratio*\R*sin(\theta)*sin(270+90*\i/\range)}) arc({270+90*\i/\range}:360: {\R*sin(\theta)} and {\ratio*\R*sin(\theta)} ) -- cycle;
\fill[\conecolor, opacity={\opaque+\prop*\opaque*(\range-\i)/\range}] (0, {\R*cos(\theta)}) -- ({\R*sin(\theta)*cos(270-90*\i/\range)},{\ratio*\R*sin(\theta)*sin(270-90*\i/\range)}) arc({270-90*\i/\range}:180: {\R*sin(\theta)} and {\ratio*\R*sin(\theta)} ) -- cycle;
}
\definecolor{conered}{RGB}{255,114,114}
\definecolor{conegreen}{RGB}{37,146,37}
\definecolor{coneblue}{RGB}{107,107,236}
\fill[conered] (-0.7167,0) arc (180:360: 0.7167 and 0.2867) arc (0:180: 0.7167 and 0.2867) -- cycle ;
\pgfmathparse{\R*sin(\theta)*\aratio}
\fill[conered] (-0.251, -{sqrt(1-0.251*0.251/(0.7167*0.7167) )*0.2867}) arc ({360-acos(-0.251/0.7167) )}:{360-acos(0.251/0.7167 )}: 0.7167 and 0.2867 ) -- (0.251,-\height) arc (360:180:0.251 and 0.0941) --cycle ;
\foreach \i in {0,...,\total}
{
\fill[\conecolor, opacity={2*\opaque+\prop*\opaque*(\total-1*\i)/\total}] ({\pgfmathresult*\i/\total}, {\pgfmathresult*\ratio*sqrt(1-\i/\total*\i/\total) } ) arc ( {acos(\i/\total)}:0: {\R*sin(\theta)*\aratio} and {\R*sin(\theta)*\aratio*\ratio} ) -- ++(0,-\height) arc (360: {360-acos(\i/\total)}: {\R*sin(\theta)*\aratio} and {\R*sin(\theta)*\aratio*\ratio} ) -- cycle;
\fill[\conecolor, opacity={2*\opaque+\prop*\opaque*(\total-1*\i)/\total}] ({-\R*sin(\theta)*\aratio*\i/\total}, {\R*sin(\theta)*\aratio*\ratio*sqrt(1-\i/\total*\i/\total) } ) arc ( {acos(-\i/\total)}:180: {\R*sin(\theta)*\aratio} and {\R*sin(\theta)*\aratio*\ratio} ) -- ++(0,-\height) arc (180: {360-acos(-\i/\total)}: {\R*sin(\theta)*\aratio} and {\R*sin(\theta)*\aratio*\ratio} ) -- cycle;
}
\draw[thick, conered, yshift=-0.8cm] (-0.251,0.8) -- (-0.251,0) arc (180:360:0.251 and 0.0941) -- (0.251,0.8);
\end{tikzpicture}
\end{document}