我怎样才能绘制如下图所示的横截面?

我怎样才能绘制如下图所示的横截面?

如何绘制如下图所示的横截面?在此处输入图片描述

答案1

因为这是这个网站上反复出现的问题,而且有些说法我并不完全同意,所以作为概念证明:是的,一个使用 pgfplots 绘制此类图。您只需要有一点耐心(或拥有一台超快的计算机)。如果您有多个表面,则有两个有用的(甚至是必要的?)成分:

  1. 手动进行一些 3D 排序。(这对于 patchplots 来说不是必需的,但对于这类图来说,我认为是必需的。)
  2. 使用图层。

图表的实际排序并不重要,重要的是图层。动画也许可以最好地说明“手动 3D 排序”的含义。

在此处输入图片描述

请注意,动画上的奇怪线条是转换为动画 gif 的产物。实际的 pdf 没有这个问题。

在此处输入图片描述

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{3d}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=1.16}
\begin{document}
\foreach \X in {3} %{1,2,3}%   % <-for animation
{\pgfmathsetmacro{\v}{0.3}
\pgfmathsetmacro{\u}{1.5}
\begin{tikzpicture}[declare function={radius(\x)=sqrt(1.5^2-(\x-1.5)*(\x-1.5));
funky(\x)=(1+\v*cos(4*deg(\x)));},x={(3.2*\u cm,0.0cm)}, 
   y={(0cm,\u cm)},z={(-\u*0.3535cm,-\u*0.3535cm)},]
\begin{axis}[set layers,colormap/cool,hide axis,
   x={(3.2*\u cm,0.0cm)}, 
   y={(0cm,\u cm)},
   z={(-\u*0.3535cm,-\u*0.3535cm)},
   ymin=-2.5,ymax=2.5,xmin=-0.1,xmax=3
   ]
  \addplot3[draw=none] coordinates {(0.3,-2,-2) (0.3,2,-2) (0.3,2,2)
  (2.7,2,2) (2.7,2,-2) (2.7,-2,-2)};
  \path[name path=plane] (1.5,-2.25,-2.25) coordinate (z1)
  -- (1.5,-2.25,2.25) coordinate (z2) -- (1.5,2.25,2.25)  coordinate (z3)
  -- (1.5,2.25,-2.25) coordinate (z4) -- cycle;
  \draw[-latex] (0,-2.25,0) -- (3,-2.25,0) node[below left]{$x$};
  \draw[-latex] (0,-2.5,0) -- (0,2.5,0) node[below left]{$y$};
  \addplot3[smooth,opacity=0.3,surf,shader=interp,on layer=axis background,
  samples=30,
  domain=0.3:2.7,y domain=pi:2*pi,
  z buffer=sort]
  (x,{cos(deg(y))*radius(x)*funky(y)}, 
  {sin(deg(y))*radius(x)*funky(y)});
  %
  \ifnum\X>1
  \path[on layer=main,thick,purple,fill=purple,fill opacity=0.3] 
  plot[smooth,samples=59,domain=0:2*pi]
  (1.5,{cos(deg(\x))*radius(1.5)*funky(\x)}, 
  {sin(deg(\x))*radius(1.5)*funky(\x)});
  \draw[on layer=axis background,thick,purple,purple,thick,dashed] 
  plot[smooth,samples=59,domain=pi:2*pi]
  (1.5,{cos(deg(\x))*radius(1.5)*funky(\x)}, 
  {sin(deg(\x))*radius(1.5)*funky(\x)});
  \draw[on layer=axis foreground,thick,purple,purple,thick] 
  plot[smooth,samples=59,domain=0:pi]
  (1.5,{cos(deg(\x))*radius(1.5)*funky(\x)}, 
  {sin(deg(\x))*radius(1.5)*funky(\x)});
  \draw[blue,thick,dashed,on layer=main,fill=blue!70!green,fill opacity=0.3] 
  plot[smooth,samples=59,domain=0:2*pi]
  (0.3,{cos(deg(\x))*radius(0.3)*funky(\x)}, 
  {sin(deg(\x))*radius(0.3)*funky(\x)});
  \draw[blue,thick,on layer=main,fill=blue!70!green,fill opacity=0.3] 
  plot[smooth,samples=59,domain=0:2*pi]
  (2.7,{cos(deg(\x))*radius(0.3)*funky(\x)}, 
  {sin(deg(\x))*radius(0.3)*funky(\x)});
  \fi
  %
  \ifnum\X>2
  \addplot3[smooth,opacity=0.3,surf,shader=interp,on layer=axis foreground,
  samples=30,
  domain=0.3:2.7,y domain=0:pi,
  z buffer=sort]
  (x,{cos(deg(y))*radius(x)*funky(y)}, 
  {sin(deg(y))*radius(x)*(1+\v*cos(4*deg(y)))});
  \path[thick,name path=upper] plot[smooth,variable=\x,samples=30,domain=0.3:2.7]
  (\x,{cos(deg(0))*radius(\x)*funky(0)}, 
  {sin(deg(0))*radius(\x)*funky(0)});
  \path[thick,name path=lower] plot[smooth,variable=\x,samples=30,domain=0.3:2.7]
  (\x,{cos(deg(pi))*radius(\x)*funky(pi)}, 
  {sin(deg(pi))*radius(\x)*funky(pi)});
  \path [name intersections={of=plane and upper,by={x1,x2}}];
  \path [name intersections={of=plane and lower,by={y1,y2}}];
  \draw (y1) -- (z2) -- (z3) -- (z4) -- (x2);
  \draw[dashed] (y1) -- (z1)  -- (x2);
  \fill (1.5,-2.25,0) circle(1pt) node[below] {$x$};
  \fill (0.3,-2.25,0) circle(1pt) node[below] {$a$};
  \fill (2.7,-2.25,0) circle(1pt) node[below] {$b$};
  \begin{scope}[on layer=main]
   \begin{scope}[canvas is zy plane at x=1.5,transform shape,xscale=-1]
    \node at (0,0) {$A(x)$};
    \node at (1.8,1.8) {$P_x$};
   \end{scope}
   \begin{scope}[canvas is zy plane at x=0.3,transform shape,xscale=-1]
    \node at (0,0) {$A(a)$};
   \end{scope}
   \begin{scope}[canvas is zy plane at x=2.7,transform shape,xscale=-1]
    \node at (0,0) {$A(b)$};
   \end{scope}
  \end{scope}
  \draw[on layer=axis foreground,thick,blue] 
  plot[smooth,samples=59,domain=0.3:2.7]
  (\x,{cos(deg(pi/4))*radius(\x)*funky(pi/4)}, 
  {sin(deg(pi/4))*radius(\x)*funky(pi/4)});
  \draw[on layer=axis background,thick,blue,dashed] 
  plot[smooth,samples=59,domain=0.3:2.7]
  (\x,{cos(deg(pi/4+pi))*radius(\x)*funky(pi/4+pi)}, 
  {sin(deg(pi/4+pi))*radius(\x)*funky(pi/4+pi)});
  \fi
 \end{axis}
\end{tikzpicture}
}
\end{document}

请注意,我的 3D 排序远非完美。我将域分为0:pipi:2*pi。这并不完全正确,但在这种情况下是一个合理的近似值。还请注意,3d库在这里没有任何问题。

相关内容