Tikz:绘制 RGB 立方体

Tikz:绘制 RGB 立方体

我正在尝试使用 Tikz 绘制一个 RGB 立方体。到目前为止,我设法用颜色渐变创建了这个立方体:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{3d}
\usetikzlibrary{shadings}
\definecolor{mypurple}{rgb}{1.0,0.0,1.0}
\begin{document}

    \begin{tikzpicture}[x  = {(0.5cm,0.5cm)},
    y  = {(0.95cm,-0.25cm)},
    z  = {(0cm,0.9cm)}]
    \begin{scope}[canvas is yz plane at x=-1]
    \shade[lower right=mypurple, lower left=blue, upper right=white, upper left=cyan] (-1,-1) rectangle (1,1);
    \end{scope}
    \begin{scope}[canvas is xz plane at y=1]
    \shade[lower right=red, lower left=mypurple, upper right=yellow, upper left=white] (-1,-1) rectangle (1,1);
    \end{scope}
    \begin{scope}[canvas is yx plane at z=1]
    \shade[lower right=white, lower left=cyan, upper right=yellow, upper left=green] (-1,-1) rectangle (1,1);
    \end{scope}
    \end{tikzpicture}
\end{document}

结果:

似乎参考点的上/下/左/右被解释为相对于特定矩形的边界矩形。

我如何将角落设置为参考点?

答案1

不幸的是,你不能,正如手册所述

此阴影使用在矩形四个角的颜色之间进行双线性插值的颜色来填充矩形。

此处,矩形似乎表示“边与页面边缘平行的形状”。幸运的是,您可以自己插入阴影。

一些提示:

  • 我使用了\colorlet{<name>}[<model>]{<definition>}。如果省略<model>,则有时会选择不同的模型,从而产生奇怪的色彩效果。
  • 瓷砖画得比应有的稍大一些(第二个坐标中的(\x+0.1)(\y+0.1)部分)。如果使用精确的尺寸,您会看到瓷砖之间有微小的间隙。这也是我\clip在每个瓷砖的开头添加的原因scope,否则面会太大。
  • 对于更好的分辨率来说,它相当慢。如果您在经常更改的文档中使用它,请考虑使用这些externalize功能。
  • \makeatletter和之间的代码\makeatother修复canvas is xy plane at z=3D库。此补丁由杰克这个答案

代码

\documentclass[tikz, border=2mm]{standalone}
\usetikzlibrary{3d}
\usetikzlibrary{shadings}
\definecolor{mypurple}{RGB}{255,0,255}

\makeatletter
    \tikzoption{canvas is xy plane at z}[]%
    {   \def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
        \def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
        \def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
        \tikz@canvas@is@plane
    }
\makeatother 

\begin{document}

\pgfmathtruncatemacro{\Divisions}{50}
\pgfmathsetmacro{\Cube}{5}

\begin{tikzpicture}
[   x={(0.5cm,0.5cm)},
    y={(0.95cm,-0.25cm)},
    z={(0cm,0.9cm)}
]
    \begin{scope}[canvas is yz plane at x=-\Cube/2]
        \shade[lower right=mypurple, lower left=blue, upper right=white, upper left=cyan] (-1,-1) rectangle (1,1);
        \clip (-\Cube/2,-\Cube/2) rectangle (\Cube/2,\Cube/2);
        \colorlet{BL}[RGB]{blue}
        \colorlet{BR}[RGB]{mypurple}
        \colorlet{TL}[RGB]{cyan}
        \colorlet{TR}[RGB]{white}
        \foreach \x in {1,...,\Divisions}
        {   \pgfmathtruncatemacro{\px}{(\x-1)/(\Divisions-1)*100}
            \colorlet{B}[RGB]{BR!\px!BL}
            \colorlet{T}[RGB]{TR!\px!TL}
            \foreach \y in {1,...,\Divisions}
            {   \pgfmathtruncatemacro{\py}{(\y-1)/(\Divisions-1)*100}
                \fill[T!\py!B] ({-\Cube/2+\Cube*(\x-1)/\Divisions},{-\Cube/2+\Cube*(\y-1)/\Divisions}) rectangle ({-\Cube/2+\Cube*(\x+0.1)/\Divisions},{-\Cube/2+\Cube*(\y+0.1)/\Divisions});
            }
        }
        \draw[thick] (-\Cube/2,-\Cube/2) rectangle (\Cube/2,\Cube/2);
    \end{scope}

    \begin{scope}[canvas is xz plane at y=\Cube/2]
        \clip (-\Cube/2,-\Cube/2) rectangle (\Cube/2,\Cube/2);
        \colorlet{BL}[RGB]{mypurple}
        \colorlet{BR}[RGB]{red}
        \colorlet{TL}[RGB]{white}
        \colorlet{TR}[RGB]{yellow}
        \foreach \x in {1,...,\Divisions}
        {   \pgfmathtruncatemacro{\px}{(\x-1)/(\Divisions-1)*100}
            \colorlet{B}[RGB]{BR!\px!BL}
            \colorlet{T}[RGB]{TR!\px!TL}
            \foreach \y in {1,...,\Divisions}
            {   \pgfmathtruncatemacro{\py}{(\y-1)/(\Divisions-1)*100}
                \fill[T!\py!B] ({-\Cube/2+\Cube*(\x-1)/\Divisions},{-\Cube/2+\Cube*(\y-1)/\Divisions}) rectangle ({-\Cube/2+\Cube*(\x+0.1)/\Divisions},{-\Cube/2+\Cube*(\y+0.1)/\Divisions});
            }
        }
        \draw[thick] (-\Cube/2,-\Cube/2) rectangle (\Cube/2,\Cube/2);
    \end{scope}

    \begin{scope}[canvas is xy plane at z=\Cube/2]
        \clip (-\Cube/2,-\Cube/2) rectangle (\Cube/2,\Cube/2);
        \colorlet{BL}[RGB]{cyan}
        \colorlet{BR}[RGB]{green}
        \colorlet{TL}[RGB]{white}
        \colorlet{TR}[RGB]{yellow}
        \foreach \x in {1,...,\Divisions}
        {   \pgfmathtruncatemacro{\px}{(\x-1)/(\Divisions-1)*100}
            \colorlet{B}[RGB]{BR!\px!BL}
            \colorlet{T}[RGB]{TR!\px!TL}
            \foreach \y in {1,...,\Divisions}
            {   \pgfmathtruncatemacro{\py}{(\y-1)/(\Divisions-1)*100}
                \fill[T!\py!B] ({-\Cube/2+\Cube*(\x-1)/\Divisions},{-\Cube/2+\Cube*(\y-1)/\Divisions}) rectangle ({-\Cube/2+\Cube*(\x+0.1)/\Divisions},{-\Cube/2+\Cube*(\y+0.1)/\Divisions});
            }
        }
        \draw[thick] (-\Cube/2,-\Cube/2) rectangle (\Cube/2,\Cube/2);
    \end{scope}
\end{tikzpicture}

\end{document}

输出

在此处输入图片描述

答案2

这是一个剪切和折叠的解决方案。

\documentclass[tikz]{standalone}
\usetikzlibrary{shadings}
\begin{document}
\begin{tikzpicture}[line join=round]
  \shade[draw,upper left=black,upper right=red,
  lower left=blue,lower right=magenta]
  (0,0) rectangle (1,1);

  \shade[draw,upper left=red,upper right=yellow,
  lower left=magenta,lower right=white]
  (1,0) rectangle (2,1);

  \shade[draw,upper left=blue,upper right=magenta,
  lower left=cyan,lower right=white]
  (0,-1) rectangle (1,0);

  \shade[draw,upper left=cyan,upper right=white,
  lower left=green,lower right=yellow]
  (0,-2) rectangle (1,-1);

  \shade[draw,upper left=green,upper right=black,
  lower left=cyan,lower right=blue]
  (-1,0) rectangle (0,1);

  \shade[draw,upper left=green,upper right=yellow,
  lower left=black,lower right=red]
  (0,1) rectangle (1,2);

  \draw (0,1) -- ++(-.1,.1) -- ++(-.8,0) -- ++(-.1,-.1) -- cycle;
  \draw (2,1) -- ++(-.1,.1) -- ++(-.8,0) -- ++(-.1,-.1) -- cycle;
  \draw (1,2) -- ++(-.1,.1) -- ++(-.8,0) -- ++(-.1,-.1) -- cycle;

  \draw (0,0) -- ++(-.1,-.1) -- ++(0,-.8) -- ++(.1,-.1) -- cycle;
  \draw (0,-1) -- ++(-.1,-.1) -- ++(0,-.8) -- ++(.1,-.1) -- cycle;

  \draw (1,0) -- ++(.1,-.1) -- ++(0,-.8) -- ++(-.1,-.1) -- cycle;
  \draw (1,-1) -- ++(.1,-.1) -- ++(0,-.8) -- ++(-.1,-.1) -- cycle;
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容