需要帮助从 TikZ 中的一组 2D 节点创建 3D 立方体

需要帮助从 TikZ 中的一组 2D 节点创建 3D 立方体

我正在制作一个需要 3D 立方体的图形。我的计划是创建一组 2D 节点,然后绘制立方体的顶部和右侧,最后绘制缺失的线条。我做到了这一点,直到我遇到麻烦:

在此处输入图片描述

我无法让立方体的侧面与立方体的表面正确对齐。另外,我对如何绘制线条有一个模糊的想法,但我敢打赌,我也会遇到问题。

代码如下:

\documentclass[a4paper, 11pt]{article}

\usepackage[rgb]{xcolor}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}

\definecolor{shade0}{named}{white}
\definecolor{shade1}{rgb}{0.9, 0.9, 0.9}
\definecolor{shade2}{rgb}{0.8, 0.8, 0.8}
\definecolor{shade3}{rgb}{0.65, 0.65, 0.65}
\definecolor{shade4}{rgb}{0.45, 0.45, 0.45}

\newlength{\gpgpuElemSize}
\setlength{\gpgpuElemSize}{8mm}
\newlength{\gpgpuElemSep}
\setlength{\gpgpuElemSep}{1mm}

\begin{document}
\begin{tikzpicture}[%
    auto,
    box/.style={%
      draw,
      rectangle,
      semithick,
    },
    thread-s/.style={
      draw,
      semithick,
      fill=shade1,
    },
    thread/.style={%
      box,
      thread-s,
      minimum size=0.5\gpgpuElemSize,
      inner sep=0,
      node distance=0pt,
    },
  ]

  % Draw boxes
  \foreach \i in {1, ..., 4} {%
    \foreach \j in {1, ..., 4} {%
      \ifnum \j=1
        \ifnum \i=1
          \node [thread] (thread\i-\j) {};
        \else
          \pgfmathtruncatemacro\prevI{\i-1}
          \node [thread, below=of thread\prevI-1, yshift=\pgflinewidth]
            (thread\i-\j) {};
        \fi
      \else
        \pgfmathtruncatemacro\prevJ{\j-1}
        \node [thread, right=of thread\i-\prevJ, xshift=-\pgflinewidth]
          (thread\i-\j) {};
      \fi
    }
  }

  % Create 3D perspective
  \path let \p1 = (thread4-4.south east),
            \p2 = (thread1-4.north east)
         in
           [thread-s]
           (thread1-4.north east) -- ++(30:0.5\gpgpuElemSize)
           -- ++(0, \y1-\y2-\pgflinewidth) -- (thread4-4.south east) --   
           cycle;
\end{tikzpicture}
\end{document}

答案1

\foreach在坐标中使用具有不同用途的单个循环要容易得多:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\foreach \x in{0,...,4}
{   \draw (0,\x ,4) -- (4,\x ,4);
    \draw (\x ,0,4) -- (\x ,4,4);
    \draw (4,\x ,4) -- (4,\x ,0);
    \draw (\x ,4,4) -- (\x ,4,0);
    \draw (4,0,\x ) -- (4,4,\x );
    \draw (0,4,\x ) -- (4,4,\x );
}
\end{tikzpicture}

\end{document}

在此处输入图片描述


编辑1:我稍微概括了一下,现在您可以通过简单地指定尺寸和比例来绘制长方体(以及大小为 n 的立方体):

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}

\newcommand{\tikzcuboid}[4]{% width, height, depth, scale
\begin{tikzpicture}[scale=#4]
\foreach \x in {0,...,#1}
{   \draw (\x ,0  ,#3 ) -- (\x ,#2 ,#3 );
    \draw (\x ,#2 ,#3 ) -- (\x ,#2 ,0  );
}
\foreach \x in {0,...,#2}
{   \draw (#1 ,\x ,#3 ) -- (#1 ,\x ,0  );
    \draw (0  ,\x ,#3 ) -- (#1 ,\x ,#3 );
}
\foreach \x in {0,...,#3}
{   \draw (#1 ,0  ,\x ) -- (#1 ,#2 ,\x );
    \draw (0  ,#2 ,\x ) -- (#1 ,#2 ,\x );
}
\end{tikzpicture}
}

\newcommand{\tikzcube}[2]{% length, scale
\tikzcuboid{#1}{#1}{#1}{#2}
}

\begin{document}

\tikzcuboid{11}{7}{5}{0.5}

\tikzcube{13}{0.25}

\end{document}

此外,还可以通过以下方式改进:

  • 指定每个维度的线密度
  • 旋转长方体
  • 定义坐标轴(例如为每个坐标轴指定一个角度)
  • 使用彩色/粗/虚线
  • 在范围内使用它,而不是在tikzpicture环境中,以便它可以与其他东西一起使用
  • X 和 Y 方向的参数(再次与其他内容一起使用tikzpicture

也有可能:

  • 使用四边形代替线条,这样就可以使用填充、阴影等。
  • 指定阴影图案(针对整个面或每个单独的四边形)

也许我会做到这一点,但我不敢打赌;)

在此处输入图片描述


编辑2:事实证明我今天有一些空闲时间;)

完毕:

  • 移位
  • 狡猾的
  • 迪克斯
  • 迪米
  • 暗色
  • 规模
  • 密度x
  • 密度
  • 密度
  • 回转

遗迹:

  • 安莱克斯
  • 安格尔利
  • 安格尔兹
  • 缩放比例
  • 鳞状
  • 缩放比例
  • 前线
  • 线顶
  • 右线
  • 填充前沿
  • 填充顶部
  • 填充权
  • 新库兹
  • 阴影

newcoordsshaded是开关(目前尚未使用)。请注意,density对于自然数 K,s 必须满足 K/densityA = dimensionA,否则会出现奇怪的效果(基本上,这意味着每个面必须分成整数个段;对于 dimension=3 和 density=0.5,每 2 厘米画一条线,因此将是 1.5 个段,这不太好)

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm,landscape]{geometry}
\usepackage{tikz}
\usepackage{keyval}
\usepackage{ifthen}

\makeatletter
% Standard Values for Parameters
\newcommand{\tikzcuboid@shiftx}{0}
\newcommand{\tikzcuboid@shifty}{0}
\newcommand{\tikzcuboid@dimx}{4}
\newcommand{\tikzcuboid@dimy}{4}
\newcommand{\tikzcuboid@dimz}{4}
\newcommand{\tikzcuboid@scale}{1}
\newcommand{\tikzcuboid@densityx}{1}
\newcommand{\tikzcuboid@densityy}{1}
\newcommand{\tikzcuboid@densityz}{1}
\newcommand{\tikzcuboid@rotation}{0}
\newcommand{\tikzcuboid@anglex}{0}
\newcommand{\tikzcuboid@angley}{90}
\newcommand{\tikzcuboid@anglez}{225}
\newcommand{\tikzcuboid@scalex}{1}
\newcommand{\tikzcuboid@scaley}{1}
\newcommand{\tikzcuboid@scalez}{1}
\newcommand{\tikzcuboid@linefront}{}
\newcommand{\tikzcuboid@linetop}{}
\newcommand{\tikzcuboid@lineright}{}
\newcommand{\tikzcuboid@fillfront}{}
\newcommand{\tikzcuboid@filltop}{}
\newcommand{\tikzcuboid@fillright}{}
\newcommand{\tikzcuboid@newcoords}{N}
\newcommand{\tikzcuboid@filled}{N}
\newcommand{\tikzcuboid@shaded}{N}
% Definition of Keys
\define@key{tikzcuboid}{shiftx}[\tikzcuboid@shiftx]{\renewcommand{\tikzcuboid@shiftx}{#1}}
\define@key{tikzcuboid}{shifty}[\tikzcuboid@shifty]{\renewcommand{\tikzcuboid@shifty}{#1}}
\define@key{tikzcuboid}{dimx}[\tikzcuboid@dimx]{\renewcommand{\tikzcuboid@dimx}{#1}}
\define@key{tikzcuboid}{dimy}[\tikzcuboid@dimy]{\renewcommand{\tikzcuboid@dimy}{#1}}
\define@key{tikzcuboid}{dimz}[\tikzcuboid@dimz]{\renewcommand{\tikzcuboid@dimz}{#1}}
\define@key{tikzcuboid}{scale}[\tikzcuboid@scale]{\renewcommand{\tikzcuboid@scale}{#1}}
\define@key{tikzcuboid}{densityx}[\tikzcuboid@densityx]{\renewcommand{\tikzcuboid@densityx}{#1}}
\define@key{tikzcuboid}{densityy}[\tikzcuboid@densityy]{\renewcommand{\tikzcuboid@densityy}{#1}}
\define@key{tikzcuboid}{densityz}[\tikzcuboid@densityz]{\renewcommand{\tikzcuboid@densityz}{#1}}
\define@key{tikzcuboid}{rotation}[\tikzcuboid@rotation]{\renewcommand{\tikzcuboid@rotation}{#1}}
\define@key{tikzcuboid}{anglex}[\tikzcuboid@anglex]{\renewcommand{\tikzcuboid@anglex}{#1}}
\define@key{tikzcuboid}{angley}[\tikzcuboid@angley]{\renewcommand{\tikzcuboid@angley}{#1}}
\define@key{tikzcuboid}{anglez}[\tikzcuboid@anglez]{\renewcommand{\tikzcuboid@anglez}{#1}}
\define@key{tikzcuboid}{scalex}[\tikzcuboid@scalex]{\renewcommand{\tikzcuboid@scalex}{#1}}
\define@key{tikzcuboid}{scaley}[\tikzcuboid@scaley]{\renewcommand{\tikzcuboid@scaley}{#1}}
\define@key{tikzcuboid}{scalez}[\tikzcuboid@scalez]{\renewcommand{\tikzcuboid@scalez}{#1}}
\define@key{tikzcuboid}{linefront}[\tikzcuboid@linefront]{\renewcommand{\tikzcuboid@linefront}{#1}}
\define@key{tikzcuboid}{linetop}[\tikzcuboid@linetop]{\renewcommand{\tikzcuboid@linetop}{#1}}
\define@key{tikzcuboid}{lineright}[\tikzcuboid@lineright]{\renewcommand{\tikzcuboid@lineright}{#1}}
\define@key{tikzcuboid}{fillfront}[\tikzcuboid@fillfront]{\renewcommand{\tikzcuboid@fillfront}{#1}}
\define@key{tikzcuboid}{filltop}[\tikzcuboid@filltop]{\renewcommand{\tikzcuboid@filltop}{#1}}
\define@key{tikzcuboid}{fillright}[\tikzcuboid@fillright]{\renewcommand{\tikzcuboid@fillright}{#1}}
\define@key{tikzcuboid}{newcoords}[\tikzcuboid@newcoords]{\renewcommand{\tikzcuboid@newcoords}{#1}}
\define@key{tikzcuboid}{filled}[\tikzcuboid@filled]{\renewcommand{\tikzcuboid@filled}{#1}}
\define@key{tikzcuboid}{shaded}[\tikzcuboid@shaded]{\renewcommand{\tikzcuboid@shaded}{#1}}
% Commands
\newcommand{\tikzcuboid}[1]{
    \setkeys{tikzcuboid}{#1} % Process Keys passed to command
    \begin{scope}[xshift=\tikzcuboid@shiftx,yshift=\tikzcuboid@shifty,scale=\tikzcuboid@scale,rotate=\tikzcuboid@rotation]
    \pgfmathsetmacro{\steppingx}{1/\tikzcuboid@densityx}
    \pgfmathsetmacro{\steppingy}{1/\tikzcuboid@densityy}
    \pgfmathsetmacro{\steppingz}{1/\tikzcuboid@densityz}
    \newcommand{\dimx}{\tikzcuboid@dimx}
    \newcommand{\dimy}{\tikzcuboid@dimy}
    \newcommand{\dimz}{\tikzcuboid@dimz}
    \pgfmathsetmacro{\secondx}{2*\steppingx}
    \pgfmathsetmacro{\secondy}{2*\steppingy}
    \pgfmathsetmacro{\secondz}{2*\steppingz}
    \foreach \x in {\steppingx,\secondx,...,\dimx}
    {   \foreach \y in {\steppingy,\secondy,...,\dimy}
        {   \pgfmathsetmacro{\lowx}{(\x-\steppingx)}
            \pgfmathsetmacro{\lowy}{(\y-\steppingy)}
            \filldraw[fill=orange,draw=blue] (\lowx,\lowy,\dimz) -- (\lowx,\y,\dimz) -- (\x,\y,\dimz) -- (\x,\lowy,\dimz) -- cycle;

        }
    }
    \foreach \x in {\steppingx,\secondx,...,\dimx}
    {   \foreach \z in {\steppingz,\secondz,...,\dimz}
        {   \pgfmathsetmacro{\lowx}{(\x-\steppingx)}
            \pgfmathsetmacro{\lowz}{(\z-\steppingz)}
            \filldraw[fill=green,draw=red] (\lowx,\dimy,\lowz) -- (\lowx,\dimy,\z) -- (\x,\dimy,\z) -- (\x,\dimy,\lowz) -- cycle;
        }
    }
    \foreach \y in {\steppingy,\secondy,...,\dimy}
    {   \foreach \z in {\steppingz,\secondz,...,\dimz}
        {   \pgfmathsetmacro{\lowy}{(\y-\steppingy)}
            \pgfmathsetmacro{\lowz}{(\z-\steppingz)}
            \filldraw[fill=red!50!blue,draw=yellow] (\dimx,\lowy,\lowz) -- (\dimx,\lowy,\z) -- (\dimx,\y,\z) -- (\dimx,\y,\lowz) -- cycle;
        }
    }
    \end{scope}

    % Write parameters to log file, just for checking       
%   \typeout{=============================}
%   \typeout{*****************************}
%   \typeout{tikzcuboid shiftx = \tikzcuboid@shiftx}
%   \typeout{tikzcuboid shifty = \tikzcuboid@shifty}
%   \typeout{tikzcuboid dimx = \tikzcuboid@dimx}
%   \typeout{tikzcuboid dimy = \tikzcuboid@dimy}
%   \typeout{tikzcuboid dimz = \tikzcuboid@dimz}
%   \typeout{tikzcuboid scale = \tikzcuboid@scale}
%   \typeout{tikzcuboid densityx = \tikzcuboid@densityx}
%   \typeout{tikzcuboid densityy = \tikzcuboid@densityy}
%   \typeout{tikzcuboid densityz = \tikzcuboid@densityz}
%   \typeout{tikzcuboid rotation = \tikzcuboid@rotation}
%   \typeout{tikzcuboid anglex = \tikzcuboid@anglex}
%   \typeout{tikzcuboid angley = \tikzcuboid@angley}
%   \typeout{tikzcuboid anglez = \tikzcuboid@anglez}
%   \typeout{tikzcuboid scalex = \tikzcuboid@scalex}
%   \typeout{tikzcuboid scaley = \tikzcuboid@scaley}
%   \typeout{tikzcuboid scalez = \tikzcuboid@scalez}
%   \typeout{tikzcuboid linefront = \tikzcuboid@linefront}
%   \typeout{tikzcuboid linetop = \tikzcuboid@linetop}
%   \typeout{tikzcuboid lineright = \tikzcuboid@lineright}
%   \typeout{tikzcuboid fillfront = \tikzcuboid@fillfront}
%   \typeout{tikzcuboid filltop = \tikzcuboid@filltop}
%   \typeout{tikzcuboid fillright = \tikzcuboid@fillright}
%   \typeout{tikzcuboid newcoords = \tikzcuboid@newcoords}
%   \typeout{tikzcuboid filled = \tikzcuboid@filled}
%   \typeout{tikzcuboid shaded = \tikzcuboid@shaded}
%   \typeout{*****************************}
%   \typeout{=============================}
}

\makeatother

\begin{document}

\begin{tikzpicture}
    \tikzcuboid{shiftx=0cm,%
        shifty=0cm,%
        scale=1.00,%
        rotation=30,%
        densityx=1,%
        densityy=2,%
        densityz=3%
    }
    \tikzcuboid{%
        shiftx=0cm,%
        shifty=8cm,%
        scale=1.00,%
        rotation=60,%
        densityx=3,%
        densityy=2,%
        densityz=5%
    }
    \tikzcuboid{%
        shiftx=8cm,%
        shifty=8cm,%
        scale=1.00,%
        rotation=45,%
        densityx=0.5,%
        densityy=1,%
        densityz=2%
    }
    \tikzcuboid{%
        shiftx=8cm,%
        shifty=0cm,%
        scale=1.00,%
        rotation=75,%
        densityx=2,%
        densityy=7,%
        densityz=2%
    }
\end{tikzpicture}

\end{document}

最后,一些输出(颜色只是为了展示):

在此处输入图片描述


编辑3:现在除了阴影之外我已经拥有了一切:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm,landscape]{geometry}
\usepackage{tikz}
\usepackage{keyval}
\usepackage{ifthen}
%====================================
%emphasize vertices --> switch and emph style (e.g. thick,black)
%====================================
\makeatletter
% Standard Values for Parameters
\newcommand{\tikzcuboid@shiftx}{0}
\newcommand{\tikzcuboid@shifty}{0}
\newcommand{\tikzcuboid@dimx}{3}
\newcommand{\tikzcuboid@dimy}{3}
\newcommand{\tikzcuboid@dimz}{3}
\newcommand{\tikzcuboid@scale}{1}
\newcommand{\tikzcuboid@densityx}{1}
\newcommand{\tikzcuboid@densityy}{1}
\newcommand{\tikzcuboid@densityz}{1}
\newcommand{\tikzcuboid@rotation}{0}
\newcommand{\tikzcuboid@anglex}{0}
\newcommand{\tikzcuboid@angley}{90}
\newcommand{\tikzcuboid@anglez}{225}
\newcommand{\tikzcuboid@scalex}{1}
\newcommand{\tikzcuboid@scaley}{1}
\newcommand{\tikzcuboid@scalez}{sqrt(0.5)}
\newcommand{\tikzcuboid@linefront}{black}
\newcommand{\tikzcuboid@linetop}{black}
\newcommand{\tikzcuboid@lineright}{black}
\newcommand{\tikzcuboid@fillfront}{white}
\newcommand{\tikzcuboid@filltop}{white}
\newcommand{\tikzcuboid@fillright}{white}
\newcommand{\tikzcuboid@shaded}{N}
\newcommand{\tikzcuboid@shadecolor}{black}
\newcommand{\tikzcuboid@shadeperc}{25}
\newcommand{\tikzcuboid@emphedge}{N}
\newcommand{\tikzcuboid@emphstyle}{thick}

% Definition of Keys
\define@key{tikzcuboid}{shiftx}[\tikzcuboid@shiftx]{\renewcommand{\tikzcuboid@shiftx}{#1}}
\define@key{tikzcuboid}{shifty}[\tikzcuboid@shifty]{\renewcommand{\tikzcuboid@shifty}{#1}}
\define@key{tikzcuboid}{dimx}[\tikzcuboid@dimx]{\renewcommand{\tikzcuboid@dimx}{#1}}
\define@key{tikzcuboid}{dimy}[\tikzcuboid@dimy]{\renewcommand{\tikzcuboid@dimy}{#1}}
\define@key{tikzcuboid}{dimz}[\tikzcuboid@dimz]{\renewcommand{\tikzcuboid@dimz}{#1}}
\define@key{tikzcuboid}{scale}[\tikzcuboid@scale]{\renewcommand{\tikzcuboid@scale}{#1}}
\define@key{tikzcuboid}{densityx}[\tikzcuboid@densityx]{\renewcommand{\tikzcuboid@densityx}{#1}}
\define@key{tikzcuboid}{densityy}[\tikzcuboid@densityy]{\renewcommand{\tikzcuboid@densityy}{#1}}
\define@key{tikzcuboid}{densityz}[\tikzcuboid@densityz]{\renewcommand{\tikzcuboid@densityz}{#1}}
\define@key{tikzcuboid}{rotation}[\tikzcuboid@rotation]{\renewcommand{\tikzcuboid@rotation}{#1}}
\define@key{tikzcuboid}{anglex}[\tikzcuboid@anglex]{\renewcommand{\tikzcuboid@anglex}{#1}}
\define@key{tikzcuboid}{angley}[\tikzcuboid@angley]{\renewcommand{\tikzcuboid@angley}{#1}}
\define@key{tikzcuboid}{anglez}[\tikzcuboid@anglez]{\renewcommand{\tikzcuboid@anglez}{#1}}
\define@key{tikzcuboid}{scalex}[\tikzcuboid@scalex]{\renewcommand{\tikzcuboid@scalex}{#1}}
\define@key{tikzcuboid}{scaley}[\tikzcuboid@scaley]{\renewcommand{\tikzcuboid@scaley}{#1}}
\define@key{tikzcuboid}{scalez}[\tikzcuboid@scalez]{\renewcommand{\tikzcuboid@scalez}{#1}}
\define@key{tikzcuboid}{linefront}[\tikzcuboid@linefront]{\renewcommand{\tikzcuboid@linefront}{#1}}
\define@key{tikzcuboid}{linetop}[\tikzcuboid@linetop]{\renewcommand{\tikzcuboid@linetop}{#1}}
\define@key{tikzcuboid}{lineright}[\tikzcuboid@lineright]{\renewcommand{\tikzcuboid@lineright}{#1}}
\define@key{tikzcuboid}{fillfront}[\tikzcuboid@fillfront]{\renewcommand{\tikzcuboid@fillfront}{#1}}
\define@key{tikzcuboid}{filltop}[\tikzcuboid@filltop]{\renewcommand{\tikzcuboid@filltop}{#1}}
\define@key{tikzcuboid}{fillright}[\tikzcuboid@fillright]{\renewcommand{\tikzcuboid@fillright}{#1}}
\define@key{tikzcuboid}{shaded}[\tikzcuboid@shaded]{\renewcommand{\tikzcuboid@shaded}{#1}}
\define@key{tikzcuboid}{shadecolor}[\tikzcuboid@shadecolor]{\renewcommand{\tikzcuboid@shadecolor}{#1}}
\define@key{tikzcuboid}{shadeperc}[\tikzcuboid@shadeperc]{\renewcommand{\tikzcuboid@shadeperc}{#1}}
\define@key{tikzcuboid}{emphedge}[\tikzcuboid@emphedge]{\renewcommand{\tikzcuboid@emphedge}{#1}}
\define@key{tikzcuboid}{emphstyle}[\tikzcuboid@emphstyle]{\renewcommand{\tikzcuboid@emphstyle}{#1}}
% Commands
\newcommand{\tikzcuboid}[1]{
    \setkeys{tikzcuboid}{#1} % Process Keys passed to command
    \pgfmathsetmacro{\vectorxx}{\tikzcuboid@scalex*cos(\tikzcuboid@anglex)}
    \pgfmathsetmacro{\vectorxy}{\tikzcuboid@scalex*sin(\tikzcuboid@anglex)}
    \pgfmathsetmacro{\vectoryx}{\tikzcuboid@scaley*cos(\tikzcuboid@angley)}
    \pgfmathsetmacro{\vectoryy}{\tikzcuboid@scaley*sin(\tikzcuboid@angley)}
    \pgfmathsetmacro{\vectorzx}{\tikzcuboid@scalez*cos(\tikzcuboid@anglez)}
    \pgfmathsetmacro{\vectorzy}{\tikzcuboid@scalez*sin(\tikzcuboid@anglez)}
    \begin{scope}[xshift=\tikzcuboid@shiftx, yshift=\tikzcuboid@shifty, scale=\tikzcuboid@scale, rotate=\tikzcuboid@rotation, x={(\vectorxx,\vectorxy)}, y={(\vectoryx,\vectoryy)}, z={(\vectorzx,\vectorzy)}]
    \pgfmathsetmacro{\steppingx}{1/\tikzcuboid@densityx}
    \pgfmathsetmacro{\steppingy}{1/\tikzcuboid@densityy}
    \pgfmathsetmacro{\steppingz}{1/\tikzcuboid@densityz}
    \newcommand{\dimx}{\tikzcuboid@dimx}
    \newcommand{\dimy}{\tikzcuboid@dimy}
    \newcommand{\dimz}{\tikzcuboid@dimz}
    \pgfmathsetmacro{\secondx}{2*\steppingx}
    \pgfmathsetmacro{\secondy}{2*\steppingy}
    \pgfmathsetmacro{\secondz}{2*\steppingz}
    \foreach \x in {\steppingx,\secondx,...,\dimx}
    {   \foreach \y in {\steppingy,\secondy,...,\dimy}
        {   \pgfmathsetmacro{\lowx}{(\x-\steppingx)}
            \pgfmathsetmacro{\lowy}{(\y-\steppingy)}
            \filldraw[fill=\tikzcuboid@fillfront,draw=\tikzcuboid@linefront] (\lowx,\lowy,\dimz) -- (\lowx,\y,\dimz) -- (\x,\y,\dimz) -- (\x,\lowy,\dimz) -- cycle;

        }
    }
    \foreach \x in {\steppingx,\secondx,...,\dimx}
    {   \foreach \z in {\steppingz,\secondz,...,\dimz}
        {   \pgfmathsetmacro{\lowx}{(\x-\steppingx)}
            \pgfmathsetmacro{\lowz}{(\z-\steppingz)}
            \filldraw[fill=\tikzcuboid@filltop,draw=\tikzcuboid@linetop] (\lowx,\dimy,\lowz) -- (\lowx,\dimy,\z) -- (\x,\dimy,\z) -- (\x,\dimy,\lowz) -- cycle;
        }
    }
    \foreach \y in {\steppingy,\secondy,...,\dimy}
    {   \foreach \z in {\steppingz,\secondz,...,\dimz}
        {   \pgfmathsetmacro{\lowy}{(\y-\steppingy)}
            \pgfmathsetmacro{\lowz}{(\z-\steppingz)}
            \filldraw[fill=\tikzcuboid@fillright,draw=\tikzcuboid@lineright] (\dimx,\lowy,\lowz) -- (\dimx,\lowy,\z) -- (\dimx,\y,\z) -- (\dimx,\y,\lowz) -- cycle;
        }
    }
    \ifthenelse{\equal{\tikzcuboid@emphedge}{Y}}%
        {\draw[\tikzcuboid@emphstyle](0,\dimy,0) -- (\dimx,\dimy,0) -- (\dimx,\dimy,\dimz) -- (0,\dimy,\dimz) -- cycle;%
        \draw[\tikzcuboid@emphstyle] (0,0,\dimz) -- (0,\dimy,\dimz) -- (\dimx,\dimy,\dimz) -- (\dimx,0,\dimz) -- cycle;%
        \draw[\tikzcuboid@emphstyle](\dimx,0,0) -- (\dimx,\dimy,0) -- (\dimx,\dimy,\dimz) -- (\dimx,0,\dimz) -- cycle;%
        }%
        {}
    \end{scope}
}

\makeatother

\begin{document}

\begin{tikzpicture}
    \tikzcuboid{shiftx=0cm,%
        shifty=0cm,%
        scale=1.00,%
        rotation=30,%
        densityx=1,%
        densityy=2,%
        densityz=3,%
        dimx=4,%
        dimy=5,%
        dimy=2,%
        linefront=yellow!30!black,%
        linetop=red!30!black,%
        lineright=blue!30!black,%
        fillfront=yellow!30!white,%
        filltop=red!30!white,%
        fillright=blue!30!white%
    }
    \tikzcuboid{%
        shiftx=0cm,%
        shifty=8cm,%
        scale=1.00,%
        rotation=60,%
        densityx=3,%
        densityy=2,%
        densityz=5,%
        dimx=4,%
        dimy=4,%
        dimy=4,%
        linefront=orange!75!black,%
        linetop=green!75!black,%
        lineright=violet!75!black,%
        fillfront=orange!75!white,%
        filltop=green!75!white,%
        fillright=violet!75!white%
    }
    \tikzcuboid{%
        shiftx=8cm,%
        shifty=8cm,%
        scale=1.00,%
        rotation=45,%
        densityx=1,%
        densityy=(2/3),%
        densityz=2,%
        dimx=3,%
        dimy=3,%
        dimy=3,%
        linefront=white!15!black,%
        linetop=white!30!black,%
        lineright=white!45!black,%
        fillfront=black!15!white,%
        filltop=black!30!white,%
        fillright=black!45!white%
    }
    \tikzcuboid{%
        shiftx=8cm,%
        shifty=0cm,%
        scale=1.00,%
        rotation=75,%
        densityx=2,%
        densityy=3,%
        densityz=2,%
        dimx=6,%
        dimy=8,%
        dimy=1,%
        linefront=red!75!black,%
        linetop=red!50!black,%
        lineright=red!25!black,%
        fillfront=red!25!white,%
        filltop=red!50!white,%
        fillright=red!75!white%
    }
    \tikzcuboid{%
        shiftx=16cm,%
        shifty=8cm,%
        scale=1.00,%
        rotation=0,%
        densityx=2,%
        densityy=2,%
        densityz=2,%
        dimx=4,%
        dimy=4,%
        dimy=4,%
        linefront=green!75!black,%
        linetop=green!50!black,%
        lineright=green!25!black,%
        fillfront=green!25!white,%
        filltop=green!50!white,%
        fillright=green!75!white,%
        emphedge=Y,%
        emphstyle=very thick,
    }
    \tikzcuboid{%
        shiftx=16cm,%
        shifty=0cm,%
        scale=1.00,%
        rotation=0,%
        densityx=1,%
        densityy=1,%
        densityz=1,%
        dimx=4,%
        dimy=4,%
        dimy=4,%
        linefront=blue!75!black,%
        linetop=blue!50!black,%
        lineright=blue!25!black,%
        fillfront=blue!25!white,%
        filltop=blue!50!white,%
        fillright=blue!75!white,%
        anglex=15,%
        angley=135,%
        anglez=225,%
        scalex=1,%
        scaley=1,%
        scalez=1,%
        emphedge=N,%
    }
\end{tikzpicture}

\end{document}

还有一些样本:

在此处输入图片描述

另外,你可以稍微玩一下:

在此处输入图片描述

仍然存在一些问题(某些轴变换不起作用,只能emphstyle传递一个选项...),而且我还不确定如何进行阴影处理,我会进行更多的实验。


编辑4:最后我得到了一切,特别感谢阿尔特蒙杜斯安德鲁·史黛西帮助我一些问题。我终于整合了所有选项并切换到pgfkeys,现在我正在写手册,CTAN包裹即将推出!

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm,landscape]{geometry}
\usepackage{tikz}

\newif\ifcuboidshade
\newif\ifcuboidemphedge

\tikzset{
  cuboid/.is family,
  cuboid,
  shiftx/.initial=0,
  shifty/.initial=0,
  dimx/.initial=3,
  dimy/.initial=3,
  dimz/.initial=3,
  scale/.initial=1,
  densityx/.initial=1,
  densityy/.initial=1,
  densityz/.initial=1,
  rotation/.initial=0,
  anglex/.initial=0,
  angley/.initial=90,
  anglez/.initial=225,
  scalex/.initial=1,
  scaley/.initial=1,
  scalez/.initial=0.5,
  front/.style={draw=black,fill=white},
  top/.style={draw=black,fill=white},
  right/.style={draw=black,fill=white},
  shade/.is if=cuboidshade,
  shadecolordark/.initial=black,
  shadecolorlight/.initial=white,
  shadeopacity/.initial=0.15,
  shadesamples/.initial=16,
  emphedge/.is if=cuboidemphedge,
  emphstyle/.style={thick},
}

\newcommand{\tikzcuboidkey}[1]{\pgfkeysvalueof{/tikz/cuboid/#1}}

% Commands
\newcommand{\tikzcuboid}[1]{
    \tikzset{cuboid,#1} % Process Keys passed to command
  \pgfmathsetlengthmacro{\vectorxx}{\tikzcuboidkey{scalex}*cos(\tikzcuboidkey{anglex})*28.452756}
  \pgfmathsetlengthmacro{\vectorxy}{\tikzcuboidkey{scalex}*sin(\tikzcuboidkey{anglex})*28.452756}
  \pgfmathsetlengthmacro{\vectoryx}{\tikzcuboidkey{scaley}*cos(\tikzcuboidkey{angley})*28.452756}
  \pgfmathsetlengthmacro{\vectoryy}{\tikzcuboidkey{scaley}*sin(\tikzcuboidkey{angley})*28.452756}
  \pgfmathsetlengthmacro{\vectorzx}{\tikzcuboidkey{scalez}*cos(\tikzcuboidkey{anglez})*28.452756}
  \pgfmathsetlengthmacro{\vectorzy}{\tikzcuboidkey{scalez}*sin(\tikzcuboidkey{anglez})*28.452756}
  \begin{scope}[xshift=\tikzcuboidkey{shiftx}, yshift=\tikzcuboidkey{shifty}, scale=\tikzcuboidkey{scale}, rotate=\tikzcuboidkey{rotation}, x={(\vectorxx,\vectorxy)}, y={(\vectoryx,\vectoryy)}, z={(\vectorzx,\vectorzy)}]
    \pgfmathsetmacro{\steppingx}{1/\tikzcuboidkey{densityx}}
  \pgfmathsetmacro{\steppingy}{1/\tikzcuboidkey{densityy}}
  \pgfmathsetmacro{\steppingz}{1/\tikzcuboidkey{densityz}}
  \newcommand{\dimx}{\tikzcuboidkey{dimx}}
  \newcommand{\dimy}{\tikzcuboidkey{dimy}}
  \newcommand{\dimz}{\tikzcuboidkey{dimz}}
  \pgfmathsetmacro{\secondx}{2*\steppingx}
  \pgfmathsetmacro{\secondy}{2*\steppingy}
  \pgfmathsetmacro{\secondz}{2*\steppingz}
  \foreach \x in {\steppingx,\secondx,...,\dimx}
  { \foreach \y in {\steppingy,\secondy,...,\dimy}
    {   \pgfmathsetmacro{\lowx}{(\x-\steppingx)}
      \pgfmathsetmacro{\lowy}{(\y-\steppingy)}
      \filldraw[cuboid/front] (\lowx,\lowy,\dimz) -- (\lowx,\y,\dimz) -- (\x,\y,\dimz) -- (\x,\lowy,\dimz) -- cycle;
    }
    }
  \foreach \x in {\steppingx,\secondx,...,\dimx}
  { \foreach \z in {\steppingz,\secondz,...,\dimz}
    {   \pgfmathsetmacro{\lowx}{(\x-\steppingx)}
      \pgfmathsetmacro{\lowz}{(\z-\steppingz)}
      \filldraw[cuboid/top] (\lowx,\dimy,\lowz) -- (\lowx,\dimy,\z) -- (\x,\dimy,\z) -- (\x,\dimy,\lowz) -- cycle;
        }
    }
    \foreach \y in {\steppingy,\secondy,...,\dimy}
  { \foreach \z in {\steppingz,\secondz,...,\dimz}
    {   \pgfmathsetmacro{\lowy}{(\y-\steppingy)}
      \pgfmathsetmacro{\lowz}{(\z-\steppingz)}
      \filldraw[cuboid/right] (\dimx,\lowy,\lowz) -- (\dimx,\lowy,\z) -- (\dimx,\y,\z) -- (\dimx,\y,\lowz) -- cycle;
    }
  }
  \ifcuboidemphedge
    \draw[cuboid/emphstyle] (0,\dimy,0) -- (\dimx,\dimy,0) -- (\dimx,\dimy,\dimz) -- (0,\dimy,\dimz) -- cycle;%
    \draw[cuboid/emphstyle] (0,\dimy,\dimz) -- (0,0,\dimz) -- (\dimx,0,\dimz) -- (\dimx,\dimy,\dimz);%
    \draw[cuboid/emphstyle] (\dimx,\dimy,0) -- (\dimx,0,0) -- (\dimx,0,\dimz);%
    \fi

    \ifcuboidshade
    \pgfmathsetmacro{\cstepx}{\dimx/\tikzcuboidkey{shadesamples}}
    \pgfmathsetmacro{\cstepy}{\dimy/\tikzcuboidkey{shadesamples}}
    \pgfmathsetmacro{\cstepz}{\dimz/\tikzcuboidkey{shadesamples}}
    \foreach \s in {1,...,\tikzcuboidkey{shadesamples}}
    {   \pgfmathsetmacro{\lows}{\s-1}
        \pgfmathsetmacro{\cpercent}{(\lows)/(\tikzcuboidkey{shadesamples}-1)*100}
        \fill[opacity=\tikzcuboidkey{shadeopacity},color=\tikzcuboidkey{shadecolorlight}!\cpercent!\tikzcuboidkey{shadecolordark}] (0,\s*\cstepy,\dimz) -- (\s*\cstepx,\s*\cstepy,\dimz) -- (\s*\cstepx,0,\dimz) -- (\lows*\cstepx,0,\dimz) -- (\lows*\cstepx,\lows*\cstepy,\dimz) -- (0,\lows*\cstepy,\dimz) -- cycle;
        \fill[opacity=\tikzcuboidkey{shadeopacity},color=\tikzcuboidkey{shadecolorlight}!\cpercent!\tikzcuboidkey{shadecolordark}] (0,\dimy,\s*\cstepz) -- (\s*\cstepx,\dimy,\s*\cstepz) -- (\s*\cstepx,\dimy,0) -- (\lows*\cstepx,\dimy,0) -- (\lows*\cstepx,\dimy,\lows*\cstepz) -- (0,\dimy,\lows*\cstepz) -- cycle;
        \fill[opacity=\tikzcuboidkey{shadeopacity},color=\tikzcuboidkey{shadecolorlight}!\cpercent!\tikzcuboidkey{shadecolordark}] (\dimx,0,\s*\cstepz) -- (\dimx,\s*\cstepy,\s*\cstepz) -- (\dimx,\s*\cstepy,0) -- (\dimx,\lows*\cstepy,0) -- (\dimx,\lows*\cstepy,\lows*\cstepz) -- (\dimx,0,\lows*\cstepz) -- cycle;
    }
    \fi 

  \end{scope}
}

\makeatother

\begin{document}

\begin{tikzpicture}
    \tikzcuboid{%
    shiftx=0cm,%
    shifty=8cm,%
    scale=1.00,%
    rotation=0,%
    densityx=2,%
    densityy=2,%
    densityz=2,%
    dimx=3,%
    dimy=3,%
    dimz=3,%
    scalex=1,%
    scaley=1,%
    scalez=1,%
    anglex=-30,%
    angley=90,%
    anglez=210,%
    front/.style={draw=green!50!black,fill=green!50!white},%
    top/.style={draw=green!50!black,fill=green!50!white},%
    right/.style={draw=green!50!black,fill=green!50!white},%
    emphedge,%
    emphstyle/.style={line width=1pt, green!12!black,densely dashed},
    shade,%
    shadesamples=64,%
    shadeopacity=0.15,%
    }
    \tikzcuboid{%
    shiftx=8cm,%
    shifty=8cm,%
    shadeopacity=0.30,%
    }   
    \tikzcuboid{%
    shiftx=16cm,%
    shifty=8cm,%
    shadeopacity=0.60,%
    }   
    \tikzcuboid{%
    shiftx=0cm,%
    shifty=0cm,%
    scale=1.00,%
    rotation=0,%
    densityx=1,%
    densityy=1,%
    densityz=1,%
    dimx=4,%
    dimy=4,%
    dimz=4,%
    front/.style={draw=blue!75!black,fill=blue!25!white},%
    right/.style={draw=blue!25!black,fill=blue!75!white},%
    top/.style={draw=blue!50!black,fill=blue!50!white},%
    anglex=-7,%
    angley=90,%
    anglez=221.5,%
    scalex=1,%
    scaley=1,%
    scalez=0.5,%
    emphedge=false,%
    shade,%
    shadeopacity=0.15,%
    }
    \tikzcuboid{%
    shiftx=8cm,%
    shifty=0cm,%
    shadeopacity=0.30,%
    }
    \tikzcuboid{%
    shiftx=16cm,%
    shifty=0cm,%
    shadeopacity=0.60,%
    }
\end{tikzpicture}

\end{document}

以下是一些示例:第一条线是等距的,第二条线是等距投影,从左到右,阴影不透明度分别为 0.15、0.30 和 0.60

在此处输入图片描述

答案2

这是针对维度等于 1 的 Bombadil 代码的固定版本。

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm,landscape]{geometry}
\usepackage{tikz}
\usepackage{ifthen}
%-------------------
\newif\ifcuboidshade
\newif\ifcuboidemphedge

\tikzset{
  cuboid/.is family,
  cuboid,
  shiftx/.initial=0,
  shifty/.initial=0,
  dimx/.initial=3,
  dimy/.initial=3,
  dimz/.initial=3,
  scale/.initial=1,
  densityx/.initial=1,
  densityy/.initial=1,
  densityz/.initial=1,
  rotation/.initial=0,
  anglex/.initial=0,
  angley/.initial=90,
  anglez/.initial=225,
  scalex/.initial=1,
  scaley/.initial=1,
  scalez/.initial=0.5,
  front/.style={draw=black,fill=white},
  top/.style={draw=black,fill=white},
  right/.style={draw=black,fill=white},
  shade/.is if=cuboidshade,
  shadecolordark/.initial=black,
  shadecolorlight/.initial=white,
  shadeopacity/.initial=0.15,
  shadesamples/.initial=16,
  emphedge/.is if=cuboidemphedge,
  emphstyle/.style={thick},
}

\newcommand{\tikzcuboidkey}[1]{\pgfkeysvalueof{/tikz/cuboid/#1}}

% Commands
\newcommand{\tikzcuboid}[1]{
    \tikzset{cuboid,#1} % Process Keys passed to command
  \pgfmathsetlengthmacro{\vectorxx}{\tikzcuboidkey{scalex}*cos(\tikzcuboidkey{anglex})*28.452756}
  \pgfmathsetlengthmacro{\vectorxy}{\tikzcuboidkey{scalex}*sin(\tikzcuboidkey{anglex})*28.452756}
  \pgfmathsetlengthmacro{\vectoryx}{\tikzcuboidkey{scaley}*cos(\tikzcuboidkey{angley})*28.452756}
  \pgfmathsetlengthmacro{\vectoryy}{\tikzcuboidkey{scaley}*sin(\tikzcuboidkey{angley})*28.452756}
  \pgfmathsetlengthmacro{\vectorzx}{\tikzcuboidkey{scalez}*cos(\tikzcuboidkey{anglez})*28.452756}
  \pgfmathsetlengthmacro{\vectorzy}{\tikzcuboidkey{scalez}*sin(\tikzcuboidkey{anglez})*28.452756}
  \begin{scope}[xshift=\tikzcuboidkey{shiftx}, yshift=\tikzcuboidkey{shifty}, scale=\tikzcuboidkey{scale}, rotate=\tikzcuboidkey{rotation}, x={(\vectorxx,\vectorxy)}, y={(\vectoryx,\vectoryy)}, z={(\vectorzx,\vectorzy)}]
    \pgfmathsetmacro{\steppingx}{1/\tikzcuboidkey{densityx}}
  \pgfmathsetmacro{\steppingy}{1/\tikzcuboidkey{densityy}}
  \pgfmathsetmacro{\steppingz}{1/\tikzcuboidkey{densityz}}
  \newcommand{\dimx}{\tikzcuboidkey{dimx}}
  \newcommand{\dimy}{\tikzcuboidkey{dimy}}
  \newcommand{\dimz}{\tikzcuboidkey{dimz}}
  \pgfmathsetmacro{\secondx}{2*\steppingx}
  \pgfmathsetmacro{\secondy}{2*\steppingy}
  \pgfmathsetmacro{\secondz}{2*\steppingz}
  \ifthenelse{\equal{\dimx}{1}}
    {\foreach \x in {\steppingx,...,\dimx}}
    {\foreach \x in {\steppingx,\secondx,...,\dimx}}
  {     \ifthenelse{\equal{\dimy}{1}}
    {\foreach \y in {\steppingy,...,\dimy}}
    {\foreach \y in {\steppingy,\secondy,...,\dimy}}
    {   \pgfmathsetmacro{\lowx}{(\x-\steppingx)}
      \pgfmathsetmacro{\lowy}{(\y-\steppingy)}
      \filldraw[cuboid/front] (\lowx,\lowy,\dimz) -- (\lowx,\y,\dimz) -- (\x,\y,\dimz) -- (\x,\lowy,\dimz) -- cycle;
    }
    }
    \ifthenelse{\equal{\dimx}{1}}
    {\foreach \x in {\steppingx,...,\dimx}}
    {\foreach \x in {\steppingx,\secondx,...,\dimx}}
  { \ifthenelse{\equal{\dimz}{1}}
    {\foreach \z in {\steppingz,...,\dimz}}
    {\foreach \z in {\steppingz,\secondz,...,\dimz}}
    {   \pgfmathsetmacro{\lowx}{(\x-\steppingx)}
      \pgfmathsetmacro{\lowz}{(\z-\steppingz)}
      \filldraw[cuboid/top] (\lowx,\dimy,\lowz) -- (\lowx,\dimy,\z) -- (\x,\dimy,\z) -- (\x,\dimy,\lowz) -- cycle;
        }
    }
    \ifthenelse{\equal{\dimy}{1}}
    {\foreach \y in {\steppingy,...,\dimy}}
    {\foreach \y in {\steppingy,\secondy,...,\dimy}}
  { \ifthenelse{\equal{\dimz}{1}}
    {\foreach \z in {\steppingz,...,\dimz}}
    {\foreach \z in {\steppingz,\secondz,...,\dimz}}
    {   \pgfmathsetmacro{\lowy}{(\y-\steppingy)}
      \pgfmathsetmacro{\lowz}{(\z-\steppingz)}
      \filldraw[cuboid/right] (\dimx,\lowy,\lowz) -- (\dimx,\lowy,\z) -- (\dimx,\y,\z) -- (\dimx,\y,\lowz) -- cycle;
    }
  }
  \ifcuboidemphedge
    \draw[cuboid/emphstyle] (0,\dimy,0) -- (\dimx,\dimy,0) -- (\dimx,\dimy,\dimz) -- (0,\dimy,\dimz) -- cycle;%
    \draw[cuboid/emphstyle] (0,\dimy,\dimz) -- (0,0,\dimz) -- (\dimx,0,\dimz) -- (\dimx,\dimy,\dimz);%
    \draw[cuboid/emphstyle] (\dimx,\dimy,0) -- (\dimx,0,0) -- (\dimx,0,\dimz);%
    \fi

    \ifcuboidshade
    \pgfmathsetmacro{\cstepx}{\dimx/\tikzcuboidkey{shadesamples}}
    \pgfmathsetmacro{\cstepy}{\dimy/\tikzcuboidkey{shadesamples}}
    \pgfmathsetmacro{\cstepz}{\dimz/\tikzcuboidkey{shadesamples}}
    \foreach \s in {1,...,\tikzcuboidkey{shadesamples}}
    {   \pgfmathsetmacro{\lows}{\s-1}
        \pgfmathsetmacro{\cpercent}{(\lows)/(\tikzcuboidkey{shadesamples}-1)*100}
        \fill[opacity=\tikzcuboidkey{shadeopacity},color=\tikzcuboidkey{shadecolorlight}!\cpercent!\tikzcuboidkey{shadecolordark}] (0,\s*\cstepy,\dimz) -- (\s*\cstepx,\s*\cstepy,\dimz) -- (\s*\cstepx,0,\dimz) -- (\lows*\cstepx,0,\dimz) -- (\lows*\cstepx,\lows*\cstepy,\dimz) -- (0,\lows*\cstepy,\dimz) -- cycle;
        \fill[opacity=\tikzcuboidkey{shadeopacity},color=\tikzcuboidkey{shadecolorlight}!\cpercent!\tikzcuboidkey{shadecolordark}] (0,\dimy,\s*\cstepz) -- (\s*\cstepx,\dimy,\s*\cstepz) -- (\s*\cstepx,\dimy,0) -- (\lows*\cstepx,\dimy,0) -- (\lows*\cstepx,\dimy,\lows*\cstepz) -- (0,\dimy,\lows*\cstepz) -- cycle;
        \fill[opacity=\tikzcuboidkey{shadeopacity},color=\tikzcuboidkey{shadecolorlight}!\cpercent!\tikzcuboidkey{shadecolordark}] (\dimx,0,\s*\cstepz) -- (\dimx,\s*\cstepy,\s*\cstepz) -- (\dimx,\s*\cstepy,0) -- (\dimx,\lows*\cstepy,0) -- (\dimx,\lows*\cstepy,\lows*\cstepz) -- (\dimx,0,\lows*\cstepz) -- cycle;
    }
    \fi 

  \end{scope}
}

\makeatother
%-------------------
\begin{document}   
\begin{tikzpicture}   

\tikzcuboid{dimx=1,dimy=1,dimz=1};
\tikzcuboid{dimx=1,dimy=2,dimz=3,shiftx=100};
\tikzcuboid{dimx=3,dimy=1,dimz=2,shiftx=0,shifty=80};
\tikzcuboid{dimx=2,dimy=3,dimz=1,shiftx=100,shifty=80};

\end{tikzpicture}
\end{document}

输出如下

维度等于 1 个示例

主要的变化是 ifthenelse 黑客检查 dim{x,y,z} 是否等于 1,如果是,则取消每个步进。

  \ifthenelse{\equal{\dimx}{1}}
    {\foreach \x in {\steppingx,...,\dimx}}
    {\foreach \x in {\steppingx,\secondx,...,\dimx}}

答案3

从 Stefan Kottwitz 的“数独 3D 立方体”示例开始(http://www.texample.net/tikz/examples/sudoku-3d-cube/ 使用 yslant 和 xslant 来实现类似 3D 外观的想法),我为 Pasigraphy Rhapsody 开发了一种替代可视化方法,https://gitlab.com/nbatfai/pasigraphy-rhapsody/blob/master/para/docs/prelpara.lua 我认为它可以轻松地用于以下目的:

在此处输入图片描述

\begin{tikzpicture}[thick, scale=2, every node/.style={scale=2}]
\prelparaIIID{1}{"1:3:3:0:1:2:2:3:4:10:2:0:9:9:0:1:0"}
\end{tikzpicture}

在此处输入图片描述

 \begin{tikzpicture}[thick, scale=2, every node/.style={scale=2}]
 \prelparaIIID{1}{"1:3:3:0:1:2:2:3:4:10:2:0:9:9:0:8:2:1:6:6:1"}
 \end{tikzpicture}

在此处输入图片描述

 \begin{tikzpicture}[thick, scale=2, every node/.style={scale=2}]
 \prelparaIIID{1}{"3:4:3:0:1:2:2:3:4:10:2:0:9:9:0:8:2:1:6:6:1:6:2:1:5:5:1:8:2:1:7:7:1:4:2:1:3:3:1:4:2:1:3:3:1:10:2:1:7:7:1:6:2:1:5:5:1"}
 \prelparaIIID{2} {"4:4:3:1:2:2:2:3:4:10:2:0:9:9:0:8:2:1:6:6:1:6:2:1:5:5:1:8:2:1:7:7:1:4:2:1:3:3:1:4:2:1:3:3:1:2:1:1:1:6:2:1:5:5:1:4:1:1:1:8:2:2:2:4:4:2:1:1:1"}
 \prelparaIIID{1}{"3:4:3:0:1:2:2:3:4:10:2:0:9:9:0:8:2:1:6:6:1:6:2:1:5:5:1:8:2:1:7:7:1:4:2:1:3:3:1:4:2:1:3:3:1:10:2:1:7:7:1:6:2:1:5:5:1"}
 \end{tikzpicture}

根据@siracusa的建议,我附上了一个完整的例子

演示文本

\documentclass[a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{t1enc}
\usepackage{luacode}
\directlua{require('prelpara')}
\usepackage{tikz}

\newcommand\N[1]{\directlua{N(#1) }} 
\newcommand\D[3]{\directlua{D(#1,#2,#3) }} 
\newcommand\prelparaIID[1]{\directlua{para2D(#1)}}
\newcommand\prelparaIIID[2]{\directlua{para3D(#1,#2)}}

\begin{document}

\begin{tikzpicture}[thick, scale=2, every node/.style={scale=2}]
\prelparaIIID{1}{"3:4:3:0:1:2:2:3:4:10:2:0:9:9:0:8:2:1:6:6:1:6:2:1:5:5:1:8:2:1:7:7:1:4:2:1:3:3:1:4:2:1:3:3:1:10:2:1:7:7:1:6:2:1:5:5:1"}
\prelparaIIID{2} {"4:4:3:1:2:2:2:3:4:10:2:0:9:9:0:8:2:1:6:6:1:6:2:1:5:5:1:8:2:1:7:7:1:4:2:1:3:3:1:4:2:1:3:3:1:2:1:1:1:6:2:1:5:5:1:4:1:1:1:8:2:2:2:4:4:2:1:1:1"}
\prelparaIIID{1}{"3:4:3:0:1:2:2:3:4:10:2:0:9:9:0:8:2:1:6:6:1:6:2:1:5:5:1:8:2:1:7:7:1:4:2:1:3:3:1:4:2:1:3:3:1:10:2:1:7:7:1:6:2:1:5:5:1"}
\end{tikzpicture}

\end{document}

准备程序

--[[

% Esport Language (PaRa) , first experiments 
% This is a rapid prototype for planning Pasigraphy Rhapsody (Paszigráfia Rapszódia, PaRa)
%
% prelpara.lua
%
% Copyright (C) 2019 Norbert Bátfai, [email protected], [email protected]
%
%  This program is free software: you can redistribute it and/or modify
%  it under the terms of the GNU General Public License as published by
%  the Free Software Foundation, either version 3 of the License, or
%  (at your option) any later version.
%
%  This program is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%  GNU General Public License for more details.
%
%  You should have received a copy of the GNU General Public License
%  along with this program.  If not, see <https://www.gnu.org/licenses/>.
%
% Version history
%
% Initial hack
%
% for vis_prel_para.tex
% Working title: Visualization of the Language of the Esports Culture: A Preliminary Study
% 
% A LuaLaTeX based visualization experiment for Pasigraphy Rhapsody
%
% The idea of using yslant and xslant to achieve a 3D effect like appearance 
% comes from Stefan Kottwitz's example http://www.texample.net/tikz/examples/sudoku-3d-cube/
% 
%
--]]
function para2D(fmts)
        local sntnc = fmts:split(":")
        r=sntnc[1]
        fmts_shift = 1
        for i = 0, r-1 do
            fmts_shift = fmts_shift +1
            n=sntnc[fmts_shift]
            fmts_shift = fmts_shift +1
            nod=sntnc[fmts_shift]
            tex.sprint(
                    "\\tikzstyle{shifting}=[xshift=", i,"cm]"                   
                    ,"\\shade[shifting, left color=gray!10, right color=black!80] (0,0) rectangle +(1,1);"
                    ,"\\draw[shifting, step=\\N{",n,"}cm, cyan] (0,0) grid (1,1);")     
            for j = 1, nod do
                fmts_shift = fmts_shift +1
                x=sntnc[fmts_shift]
                fmts_shift = fmts_shift +1
                y=sntnc[fmts_shift]+1
                tex.sprint(
                    "\\node[shifting, fill=orange, anchor=north west,  inner sep=0pt,minimum size=\\N{",n,"}cm-\\pgflinewidth] at \\D{",n,"}{",x,"}{",y,"} {};")
            end
        end
    end

function para3D(direct, fmts)
        dir=tonumber(direct)
        d={{2,1,2,-1,1,-1}, {1,0,1,-1,0,-1}}
        local sntnc = fmts:split(":")
        r=sntnc[1]
        fmts_shift = 1
        for i = 0, r-1 do
            fmts_shift = fmts_shift +1
            n=sntnc[fmts_shift]
            fmts_shift = fmts_shift +1
            nod=sntnc[fmts_shift]
            tex.sprint(
            "\\tikzstyle{leftslant}=[yslant=-.5, xshift=",-1+i*d[dir][1],"cm, yshift=",-1+i*d[dir][2],"cm]"
            ,"\\tikzstyle{rightslant}=[yslant=0.5, xshift=",i*d[dir][3],"cm, yshift=",-1+i*d[dir][4],"cm]"
            ,"\\tikzstyle{topslant}=[yslant=0.5, xslant=-1, xshift=", i*d[dir][5],"cm, yshift=", i*d[dir][6],"cm]"
            ,"\\shade[leftslant, right color=gray!10,left color=black!80] (0,0) rectangle +(1,1);"
            ,"\\draw[leftslant, step=\\N{",n,"}cm, cyan] (0,0) grid (1,1);")
            for j = 1, nod do
                fmts_shift = fmts_shift +1
                x=sntnc[fmts_shift]
                fmts_shift = fmts_shift +1
                y=sntnc[fmts_shift]+1
                tex.sprint(
                "\\node[leftslant, fill=orange, anchor=north west,  inner sep=0pt,minimum size=\\N{",n,"}cm-\\pgflinewidth] at \\D{",n,"}{",x,"}{",y,"-.5*",x,"} {};")
            end    
            fmts_shift = fmts_shift +1    
            n=sntnc[fmts_shift]
            fmts_shift = fmts_shift +1
            nod=sntnc[fmts_shift]
            tex.sprint(
                "\\shade[rightslant, right color=black!70,left color=gray!20] (0,0) rectangle +(1,1);",
                "\\draw[rightslant, step=\\N{",n,"}cm, pink](0,0) grid (1,1);")
            for j = 1, nod do
                fmts_shift = fmts_shift +1
                x=sntnc[fmts_shift]
                fmts_shift = fmts_shift +1
                y=sntnc[fmts_shift]
                tex.sprint(
                    "\\node[rightslant, fill=cyan, anchor=south west,  inner sep=0pt,minimum size=\\N{",n,"}cm-\\pgflinewidth] at \\D{",n,"}{",x,"}{",y,"+.5*",x,"} {};")
            end    
            fmts_shift = fmts_shift +1
            n=sntnc[fmts_shift]
            fmts_shift = fmts_shift +1
            nod=sntnc[fmts_shift]       
            tex.sprint(
                "\\shade[topslant, bottom color=gray!10,top color=black!80] (0,0) rectangle +(1,1);",
                "\\draw[topslant, step=\\N{",n,"}cm, orange] (0,0) grid (1,1);")
            for j = 1, nod do
                fmts_shift = fmts_shift +1
                x=sntnc[fmts_shift]
                fmts_shift = fmts_shift +1
                y=sntnc[fmts_shift]     
                tex.sprint(
                    "\\node[topslant, fill=yellow, anchor=south west,  inner sep=0pt,minimum size=\\N{",n,"}cm-\\pgflinewidth] at \\D{",n,"}{",y,"-",x,"}{",tonumber(y)/2,"+.5*",x,"} {};")
           end    
    end
end

function N(n) 
            tex.sprint(1/n)
end 

function D(n, x, y) 
            tex.sprint("(",       (1/n)*x,     ", ",   (1/n)*y,       ")")
end 

相关内容