使用 TikZ 制作彩色棱镜

使用 TikZ 制作彩色棱镜

全部。

我使用 TikZ 的 3d 库绘制了一个五角柱。代码如下:

\documentclass[tikz,border=1cm]{standalone}
\colorlet{blu}{blue!10}
\usetikzlibrary{3d,
%   arrows
}

\begin{document}

\begin{tikzpicture}[opacity=0.8]
\newdimen\len
\len=2cm
%\foreach 
\begin{scope}[canvas is zx plane at y=0]
    \pgfmathsetmacro{\angle}{360/5}
    \draw[fill=blu] %
    (0:\len) coordinate (a0)
    \foreach \i in {1,...,4} {
        -- (\angle*\i:\len) coordinate (a\i) 
    } 
    -- cycle;
\end{scope}
\begin{scope}[canvas is zx plane at y=3]
\pgfmathsetmacro{\angle}{360/5}
\draw[fill=blu] %
(0:\len) coordinate (b0)
\foreach \i in {1,...,4} {
    -- (\angle*\i:\len) coordinate (b\i) 
} 
-- cycle;
\end{scope}
\draw (a3) -- (b3);
\draw[fill=blu] (a0) -- node [midway,anchor=north] {$l$} (a4) -- node[midway,anchor=east] {$h$} (b4) -- (b0);
\foreach \q in {0,1}{
    \pgfmathsetmacro{\s}{\q + 1}
    \draw[fill=blu] (a\s) -- (a\q) -- (b\q) -- (b\s) ;
}
\draw (a2) -- (b2);
\pgfmathsetmacro{\R}{5}
%\coordinate (O) at (0,0,0);
%\foreach \a/\pos in {x/north,y/east,z/west}
%   \draw[very thin,->] (O) -- (xyz cs: \a=\R) node[anchor=\pos] {$\a$};
\end{tikzpicture}

尽管它可以工作并且看起来可以接受,但我想使用循环来优化此代码。这是另一个 MWE:

\documentclass[tikz,border=1cm]{standalone}
\colorlet{blu}{blue!10}
\usetikzlibrary{3d}

\begin{document}

\begin{tikzpicture}
\newdimen\len
\len=2cm
\foreach \i in {1,...,5} {
    \begin{scope}[canvas is xz plane at y=0] 
        \coordinate (a\i) at (\i*360/5:\len);
    \end{scope}
    \begin{scope}[canvas is xz plane at y=3]
        \coordinate (b\i) at (\i*360/5:\len);
    \end{scope}
    \draw (a\i) -- (b\i);
}
\foreach \q in {a,b}{
    \foreach \j in {1,...,4} {
        \pgfmathsetmacro\k{\j+1}
        \draw (\q\j) -- (\q\k);
    } 
    \draw (\q5) -- (\q1); %LOOP
}
\end{tikzpicture}

\end{document}

这很好。我现在不知道该怎么做的是如何填充它;我也非常想循环绘制底面五边形(这就是我添加“%LOOP”注释的原因)。在第一个例子中,我注释了生成轴的代码,但它们最终会出现在这个图中。看到这个帖子,我想指出的是,我希望棱柱像这样画,而不是以五边形作为前景和背景(这是我正在写的一组笔记,像这样画棱柱很重要)。

我知道每篇帖子应该问一个问题,所以我真正想首先解决的是填充部分:如何填充第二个图形的表面(按原样绘制)?

谢谢!

答案1

我不认为这个3d图书馆能给你带来很大的优势,但这里有一个使用它的答案。

\documentclass[tikz,border=1cm]{standalone}
\colorlet{blu}{blue!10}
\usetikzlibrary{3d,backgrounds,perspective}

\begin{document}

\begin{tikzpicture}[3d view={65}{25}]
\newdimen\len
\len=2cm
\foreach \i in {1,...,6} {
    \begin{scope}[canvas is xy plane at z=0] 
        \coordinate (a\i) at (\i*360/5:\len);
    \end{scope}
    \begin{scope}[canvas is xy plane at z=3]
        \coordinate (b\i) at (\i*360/5:\len);
    \end{scope}
    \ifnum\i>1
    \draw[fill=blue!20,fill opacity=0.5]
      (b\the\numexpr\i-1) -- (a\the\numexpr\i-1) -- (a\i) -- (b\i) -- cycle;
    \fi
}
\begin{scope}[on background layer]
 \draw[fill=blue!20,fill opacity=0.5] plot[samples at={1,...,5}] (a\x);
\end{scope}
\draw[fill=blue!20,fill opacity=0.5] plot[samples at={1,...,5}] (b\x);
\end{tikzpicture}

\end{document}

在此处输入图片描述

正如你所看到的,我忍不住添加了一个正交投影。

使其完全可旋转的一种方法是使用这个帖子,这需要3D 工具库。(这个库的开发陷入停滞,因为似乎没有办法在 GitHub 上维护它。)

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3dtools}
\begin{document}
\newcommand\GetProj[2]{\begingroup
\foreach \Coord [count=\nCoord] in #1
  {\ifnum\nCoord=1
  \xdef\temp{\Coord}
  \else
  \xdef\temp{\temp+\Coord}
  \fi}
  \edef\ntemp{\noexpand\path[overlay,3d coordinate={(tmp)=\temp}];}
  \ntemp
  \pgfmathsetmacro{#2}{TD("(n)o(tmp)")}
  \pgfmathsmuggle#2\endgroup}
\newcounter{tdorder}
\foreach \X in {1,...,20}
{\pgfdeclarelayer{layer\X}
\ifnum\X=1
\xdef\LstLayers{layer\X}
\else
\xdef\LstLayers{\LstLayers,layer\X}
\fi}
\pgfsetlayers\LstLayers
\tikzset{closed polygon/.style={insert path={foreach \Coord [count=\nCoord] in {#1}
 {\ifnum\nCoord=1
  \Coord
 \else
  -- \Coord
 \fi} -- cycle}},polygon/.style={insert path={foreach \Coord [count=\nCoord] in {#1}
 {\ifnum\nCoord=1
  \Coord
 \else
  -- \Coord
 \fi}}}}
%
\foreach \X in {5,15,...,355}
{\tdplotsetmaincoords{90-30*cos(\X)}{\X}
\begin{tikzpicture}[tdplot_main_coords,font=\sffamily,fill opacity=1]
  \path[tdplot_screen_coords,use as bounding box] (-5,-5) rectangle (5,5);
  \path foreach \X [count=\cX] in {b,t}
   {foreach \Y [count=\cY] in {A,B,C,D,E}
   {({2*cos(72*\cY)},{2*sin(72*\cY)},-4.5+3*\cX) coordinate(\X\Y)}};
  \def\PlaneData{%
  {draw,fill=blue!20}/closed polygon/{(bA),(tA),(tB),(bB)},%
  {draw,fill=blue!20}/closed polygon/{(bB),(tB),(tC),(bC)},%
  {draw,fill=blue!20}/closed polygon/{(bC),(tC),(tD),(bD)},%
  {draw,fill=blue!20}/closed polygon/{(bD),(tD),(tE),(bE)},%
  {draw,fill=blue!20}/closed polygon/{(bE),(tE),(tA),(bA)},%
  {draw,fill=blue!20}/closed polygon/{(tA),(tB),(tC),(tD),(tE)},%
  {draw,fill=blue!20}/closed polygon/{(bA),(bB),(bC),(bD),(bE)}}
  % normal of screen 
  \path[overlay] ({sin(\tdplotmaintheta)*sin(\tdplotmainphi)},
       {-1*sin(\tdplotmaintheta)*cos(\tdplotmainphi)},
       {cos(\tdplotmaintheta)}) coordinate (n); 
  % build up the list of projections       
  \foreach \Style/\Poly/\CoordLst [count=\nC] in \PlaneData
  {%
  \GetProj{\CoordLst}{\currproj}
  \ifnum\nC=1
    \xdef\LstProj{\currproj}
  \else
    \xdef\LstProj{\LstProj,\currproj}
  \fi}
  % draw the planes in appropriate layers
  \foreach \Style/\Poly/\CoordLst [count=\nC] in \PlaneData
  {%
  \GetProj{\CoordLst}{\currproj}
  \setcounter{tdorder}{1}
  \foreach \Proj in \LstProj
  {\pgfmathtruncatemacro{\itest}{ifthenelse(\Proj<\currproj,1,0)}
  \ifnum\itest=1
  \stepcounter{tdorder}
  \fi}
  \begin{pgfonlayer}{layer\number\value{tdorder}}
  \edef\temp{\noexpand\path[\Style,\Poly={\CoordLst}];}
  \temp
  \end{pgfonlayer}
  }
%   
\end{tikzpicture}}
\end{document}

在此处输入图片描述

相关内容