我正在制作一个需要 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
- 密度
- 密度
- 回转
遗迹:
- 安莱克斯
- 安格尔利
- 安格尔兹
- 缩放比例
- 鳞状
- 缩放比例
- 前线
- 线顶
- 右线
- 填充前沿
- 填充顶部
- 填充权
- 新库兹
- 阴影
newcoords
和shaded
是开关(目前尚未使用)。请注意,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}
输出如下
主要的变化是 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