如何生成绕x轴旋转平面曲线得到的三维图形?

如何生成绕x轴旋转平面曲线得到的三维图形?

在此处输入图片描述

我想生成这个图表。有人能帮忙吗?我做不到。我尝试使用以下代码来做到这一点,但无法获得所需的输出。

\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}

坐标系中的 3D 阴影锥体

答案2

23-16

在这种情况下,我尝试调整我为这个问题开发的代码阴影 3D 箭头。有两个问题需要处理:

  1. 开口锥体(内表面和外表面)
  2. 圆锥体内的坐标轴。

我尝试获取一张可以改变观察者位置和光源位置的图像。例如,下面是从略微不同的角度拍摄的同一幅图像。

在此处输入图片描述

主要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}};
          };
        };
      }
    }
  }
}

相关内容