我想生成这个图表。有人能帮忙吗?我做不到。我尝试使用以下代码来做到这一点,但无法获得所需的输出。
\documentclass[tikz, border=20pt]{standalone}
\usepackage{tikz,tikz-3dplot}
\tdplotsetmaincoords{80}{45}
\tdplotsetrotatedcoords{+90}{180}{+90}
\tikzset{surface/.style={draw=blue!70, fill=blue!40!white, fill opacity=.6}}
\newcommand{\coneback}[4][]{
%% start at the correct point on the circle, draw the arc, then draw to the origin of the diagram, then close the path
\draw[canvas is xy plane at z=#2, #1] (45-#4:#3) arc (45-#4:225+#4:#3) -- (O) --cycle;
}
\newcommand{\conefront}[4][]{
\draw[canvas is xy plane at z=#2, #1] (45-#4:#3) arc (45-#4:-135+#4:#3) -- (O) --cycle;
}
\begin{document}{\LARGE {\tiny }}
\begin{tikzpicture}[tdplot_main_coords]
\coordinate (O) at (0,0,0);
%% make sure to draw everything from back to front
\draw[thick,color=green!100] (0,0,-5) -- (O);
\draw[thick,->,color=green!100] (O) -- (0,0,5) node[left] {$x$};
\draw[thick,->,color=red!100] (0,-6,0) -- (0,6,0) node[] {$y$};
\conefront[surface]{3}{2}{10}
\coneback[surface]{3}{2}{10}
\end{tikzpicture}
\end{document}
答案1
\documentclass[tikz, border=1cm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}
\pgfplotsset{colormap={violet}{rgb255=(25,25,122) rgb255=(238,140,238) color=(white)}}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
view={10}{5},
mesh/interior colormap name=violet,
colormap/viridis,
xmin=-1, xmax=5,
ymin=-3, ymax=3,
zmin=-3, zmax=3,
axis lines=center, axis equal,
axis on top,
x axis line style={draw=none, insert path={(axis cs:-1,0,0) edge[-] (axis cs:0,0,0) (axis cs:0,0,0) edge[densely dashed, -, opacity=0.5] (axis cs:2.5,0,0) (axis cs:2.5,0,0) edge (axis cs:6,0,0)}},
y axis line style={draw=none, insert path={(axis cs:0,-3,0) edge[-] (axis cs:0,0,0) (axis cs:0,0,0) edge[opacity=0.3] (axis cs:0,3,0)}},
xtick distance=1, ztick distance=1,
ytick=\empty,
]
\addplot3[
surf, shader=faceted interp,
domain=0:3, samples=10,
domain y=0:360, samples y=37,
z buffer=sort,
] (x,{x*cos(y)},{x*sin(y)});
\end{axis}
\end{tikzpicture}
\end{document}
答案2
在这种情况下,我尝试调整我为这个问题开发的代码阴影 3D 箭头。有两个问题需要处理:
- 开口锥体(内表面和外表面)
- 圆锥体内的坐标轴。
我尝试获取一张可以改变观察者位置和光源位置的图像。例如,下面是从略微不同的角度拍摄的同一幅图像。
主要pic
对象是 ,gen o-cone
它取决于六个参数。此对象生成一个带有一些标线的圆锥体。它由 所用,oo-cone
它通过依次绘制 来生成带有标线和平面部分(圆)的圆锥体gen o-cone
。首先给出代码;它使用文件tikzCone.sty
。该文件包含两个对象的定义pic
、视点和太阳位置。它出现在最后。
代码
\documentclass[margin=10pt]{standalone}
\usepackage[rgb]{xcolor}
\usepackage{tikz}
\usetikzlibrary{math}
\usepackage{tikzCone}
\begin{document}
\begin{tikzpicture}[view={33}{26}, sun={-90}{70}{.9}]
\pgfdeclarelayer{background}
\pgfdeclarelayer{middleground}
\pgfsetlayers{background, middleground, main}
\begin{pgfonlayer}{middleground}
\begin{scope}[blue!50!black, line width=1.2pt]
\draw[red, ->] (0, 0, 0) -- (6, 0, 0)
node[shift={(.2, 0, 0)}, above] {$x$};
\draw[->] (0, 0, 0) -- (0, 4, 0) node[shift={(-.1, .2, 0)}] {$y$};
\draw[->] (0, 0, 0) -- (0, 0, 4) node[shift={(-.1, 0, .3)}] {$z$};
\end{scope}
\end{pgfonlayer}
\draw pic[blue!40!gray]
{oo-cone={B=(0, 0, 0), T=(3, 0, 0), rB=0, rT=3.5, ng=11, ns=4}};
\end{tikzpicture}
\end{document}
tikxCone.sty
\tikzset{%
view/.style 2 args={% observer longitude and latitude (y upwards)
% Remark. lomg=0 means x=0
z={({-sin(#1)}, {-cos(#1)*sin(#2)})},
x={({cos(#1)}, {-sin(#1)*sin(#2)})},
y={(0, {cos(#2)})},
evaluate={%
\tox={sin(#1)*cos(#2)};
\toy={sin(#2)};
\toz={cos(#1)*cos(#2)};
},
longitude = #1,
latitude = #2
},
sun/.style n args={3}{% longitude, latitude, light contrast in [0, 1]
sun longitude = #1,
sun latitude = #2,
contrast = #3,
evaluate={%
real \sunx, \suny, \sunz, \lightC;
\sunx = sin(\sLongit)*cos(\sLatit);
\suny = sin(\sLatit);
\sunz = cos(\sLongit)*cos(\sLatit);
}
}
}
\pgfkeys{/tikz/.cd,
latitude/.store in=\aLatit, % observer's latitude
latitude=0
}
\pgfkeys{/tikz/.cd,
longitude/.store in=\aLongit, % observer's longitude
longitude=0 % corresponds to x=0
}
\pgfkeys{/tikz/.cd,
sun latitude/.store in=\sLatit,
sun latitude = 80
}
\pgfkeys{/tikz/.cd,
sun longitude/.store in=\sLongit,
sun longitude=90
}
\pgfkeys{/tikz/.cd,
contrast/.store in=\lightC, % light contrast \in [0, 1]
contrast=.5
}
\tikzmath{%
function coneFaceIsSeen(\j, \M) {%
\t = 360*((\j-.5)/\M);
\ux = \vx*cos(\t) +\wx*sin(\t);
\uy = \vy*cos(\t) +\wy*sin(\t);
\uz = \vz*cos(\t) +\wz*sin(\t);
% modification needed when the radii are different
\ang = atan2(\coneBR -\coneTR, \tmpBT);
\ux = \ux*cos(\ang) +\nx*sin(\ang);
\uy = \uy*cos(\ang) +\ny*sin(\ang);
\uz = \uz*cos(\ang) +\nz*sin(\ang);
\res = \ux*\tox + \uy*\toy + \uz*\toz;
if \res >= 0 then { return 1;} else {return 0;};
};
function coneFaceColor(\j, \M) {
% Verifies if seen when the cone has no base; the color number is
% modified by -2000.
real \ang;
\t = 360*((\j-.5)/\M);
\ux = \vx*cos(\t) +\wx*sin(\t);
\uy = \vy*cos(\t) +\wy*sin(\t);
\uz = \vz*cos(\t) +\wz*sin(\t);
% modification needed when the radii are different
\ang = atan2(\coneBR -\coneTR, \tmpBT);
\ux = \ux*cos(\ang) +\nx*sin(\ang);
\uy = \uy*cos(\ang) +\ny*sin(\ang);
\uz = \uz*cos(\ang) +\nz*sin(\ang);
\res = \ux*\tox + \uy*\toy + \uz*\toz;
\tmp = int(100*\lightC*(\ux*\sunx + \uy*\suny + \uz*\sunz));
if \res>0 then {% if seen
return \tmp;
} else {return {-2000 +\tmp};};
};
}
\tikzset{%
pics/gen o-cone/.style args={B=(#1), T=(#2), rB=#3, rT=#4, ng=#5, np=#6}{%
% x, y, z of the bottom and top centers: #1 and #2
% bottom and top radius: #3 and #4
% number of generatrices to be drawn and of global points: #5 and #6
code={%
\colorlet{mainColor}{.}
\colorlet{innerColor}{-mainColor!90!gray}
\colorlet{lineRGB}{mainColor!30!black}
\colorlet{leftRGB{0}}{mainColor!70!black} % shade outside
\colorlet{leftRGB{1}}{white} % light outside
\colorlet{leftRGB{2}}{innerColor!70!black}
\colorlet{leftRGB{3}}{white}
\colorlet{rightRGB{0}}{mainColor} % shade outside
\colorlet{rightRGB{1}}{mainColor} % light outside
\colorlet{rightRGB{2}}{innerColor} % shade inside
\colorlet{rightRGB{3}}{innerColor} % light inside
\tikzmath{% B, T, rB, rT, and construction of the orthonormal basis
integer \coneN, \k, \j, \prevj, \i, \ng, \ntmp;
real \Bx, \By, \Bz, \Tx, \Ty, \Tz, \coneBR, \coneTR;
\j = 0;
for \c in {#1}{%
\j = \j +1;
\B{\j} = \c;
};
\j = 0;
for \c in {#2}{%
\j = \j +1;
\T{\j} = \c;
};
\Bx = \B{1};
\By = \B{2};
\Bz = \B{3};
\Tx = \T{1};
\Ty = \T{2};
\Tz = \T{3};
\coneBR = #3;
\coneTR = #4;
\ng = #5;
\ntmp = int(#6/\ng);
\coneN = \ntmp*\ng;
real \tmpBT, \tmpx, \tmpy, \tmpz, \tmpcst, \cstForColor;
real \nx, \ny, \nz, \vx, \vy, \vz, \wx, \wy, \wz;
\tmpx = \Tx -\Bx;
\tmpy = \Ty -\By;
\tmpz = \Tz -\Bz;
\tmpBT = sqrt(\tmpx*\tmpx +\tmpy*\tmpy +\tmpz*\tmpz);
\nx = \tmpx/\tmpBT;
\ny = \tmpy/\tmpBT;
\nz = \tmpz/\tmpBT;
if abs(\ny)>=abs(\nz) then {%
\tmpcst = sqrt(\nx*\nx +\ny*\ny);
\vx = -\ny/\tmpcst;
\vy = \nx/\tmpcst;
\vz = 0;
\wx = -\vy*\nz;
\wy = \vx*\nz;
\wz = (1 -\nz*\nz)/\tmpcst;
} else {%
\tmpcst = sqrt(\nx*\nx +\nz*\nz);
\vx = -\nz/\tmpcst;
\vy = 0;
\vz = \nx/\tmpcst;
\wx = \vz*\ny;
\wy = (\ny*\ny -1)/\tmpcst;
\wz = -\vx*\ny;
};
%% points \P {1,\j} for bottom, \P {2,\j} for top
for \j in {0, ..., \coneN}{%
\t = \j/\coneN*360;
\Px{1,\j} = \Bx +\coneBR*\vx*cos(\t) +\coneBR*\wx*sin(\t);
\Py{1,\j} = \By +\coneBR*\vy*cos(\t) +\coneBR*\wy*sin(\t);
\Pz{1,\j} = \Bz +\coneBR*\vz*cos(\t) +\coneBR*\wz*sin(\t);
\Px{2,\j} = \Tx +\coneTR*\vx*cos(\t) +\coneTR*\wx*sin(\t);
\Py{2,\j} = \Ty +\coneTR*\vy*cos(\t) +\coneTR*\wy*sin(\t);
\Pz{2,\j} = \Tz +\coneTR*\vz*cos(\t) +\coneTR*\wz*sin(\t);
};
%% lateral faces
for \j in {1, ..., \coneN}{%
\prevj = \j -1;
\cstForColor = coneFaceColor(\j, \coneN);
if \cstForColor>-999 then {%
if \cstForColor>=0. then {%
\i = 1;
} else {%
\i = 0; % in shade
\cstForColor = int(abs(\cstForColor));
};
{%
\fill[leftRGB{\i}!\cstForColor!rightRGB{\i}]
(\Px{1,\prevj}, \Py{1,\prevj}, \Pz{1,\prevj})
-- (\Px{1,\j}, \Py{1,\j}, \Pz{1,\j})
-- (\Px{2,\j}, \Py{2,\j}, \Pz{2,\j})
-- (\Px{2,\prevj}, \Py{2,\prevj}, \Pz{2,\prevj})
-- cycle;
\draw[lineRGB, line width=.1pt]
(\Px{1,\prevj}, \Py{1,\prevj}, \Pz{1,\prevj})
-- (\Px{1,\j}, \Py{1,\j}, \Pz{1,\j});
\draw[lineRGB, line width=.1pt]
(\Px{2,\j}, \Py{2,\j}, \Pz{2,\j})
-- (\Px{2,\prevj}, \Py{2,\prevj}, \Pz{2,\prevj});
};
if int(\prevj/\ntmp)*\ntmp==\prevj then {%
{%
\draw[lineRGB]
(\Px{1,\j}, \Py{1,\j}, \Pz{1,\j})
-- (\Px{2,\j}, \Py{2,\j}, \Pz{2,\j});
};
} else {%
{%
\draw[leftRGB{\i}!\cstForColor!rightRGB{\i}]
(\Px{1,\j}, \Py{1,\j}, \Pz{1,\j})
-- (\Px{2,\j}, \Py{2,\j}, \Pz{2,\j});
};
};
} else {%
\cstForColor = -(\cstForColor +2000); % back to -value
if \cstForColor>=0. then {%
\i = 3;
} else {%
\i = 2; % in the shade for leftRGB{}
\cstForColor = int(abs(\cstForColor));
};
{%
\begin{pgfonlayer}{background}
\fill[leftRGB{\i}!\cstForColor!rightRGB{\i}]
(\Px{1,\prevj}, \Py{1,\prevj}, \Pz{1,\prevj})
-- (\Px{1,\j}, \Py{1,\j}, \Pz{1,\j})
-- (\Px{2,\j}, \Py{2,\j}, \Pz{2,\j})
-- (\Px{2,\prevj}, \Py{2,\prevj}, \Pz{2,\prevj})
-- cycle;
\draw[lineRGB, line width=.1pt]
(\Px{1,\prevj}, \Py{1,\prevj}, \Pz{1,\prevj})
-- (\Px{1,\j}, \Py{1,\j}, \Pz{1,\j});
\draw[lineRGB, line width=.1pt]
(\Px{2,\j}, \Py{2,\j}, \Pz{2,\j})
-- (\Px{2,\prevj}, \Py{2,\prevj}, \Pz{2,\prevj});
\end{pgfonlayer}
};
if int(\prevj/\ntmp)*\ntmp==\prevj then {%
{%
\begin{pgfonlayer}{background}
\draw[lineRGB, line width=.1pt]
(\Px{1,\j}, \Py{1,\j}, \Pz{1,\j})
-- (\Px{2,\j}, \Py{2,\j}, \Pz{2,\j});
\end{pgfonlayer}
};
} else {%
{%
\begin{pgfonlayer}{background}
\draw[leftRGB{\i}!\cstForColor!rightRGB{\i}]
(\Px{1,\j}, \Py{1,\j}, \Pz{1,\j})
-- (\Px{2,\j}, \Py{2,\j}, \Pz{2,\j});
\end{pgfonlayer}
};
};
};
};
} % end tikzmath
}
},
pics/oo-cone/.style args={B=(#1), T=(#2), rB=#3, rT=#4, ng=#5, ns=#6}{%
% cone surface with a mesh of generatrices and sections
% x, y, z of the bottom and top centers: #1 and #2
% bottom and top radius: #3 and #4
% number of generatrices to be drawn and of sections: #5 and #6
code={%
\tikzmath{%
integer \previ, \j, \prevj, \i, \ng, \ns, \nextNs, \ntmp;
real \Bx, \By, \Bz, \Tx, \Ty, \Tz, \coneBR, \coneTR;
\ns = #6;
\j = 0;
for \c in {#1}{%
\j = \j +1;
\P{0,\j} = \c;
};
\j = 0;
for \c in {#2}{%
\j = \j +1;
\P{\ns,\j} = \c;
};
\P{0,4} = #3;
\P{\ns,4} = #4;
for \j in {1, ..., 4}{%
\d{\j} = (\P{\ns,\j} -\P{0,\j})/\ns;
};
\ng = #5;
for \i in {1, ..., \ns}{%
\previ = \i -1;
for \j in {1, 2, 3, 4}{%
\P{\i,\j} = \P{\previ,\j} +\d{\j};
};
{%
\path pic[.]
{gen o-cone={B=(\P{\previ,1}, \P{\previ,2}, \P{\previ,3}),
T=(\P{\i,1}, \P{\i,2}, \P{\i,3}),
rB=\P{\previ,4}, rT=\P{\i,4}, ng=12, np=240}};
};
};
}
}
}
}