![简化 PSTricks 代码](https://linux22.com/image/446323/%E7%AE%80%E5%8C%96%20PSTricks%20%E4%BB%A3%E7%A0%81.png)
考虑以下代码:
\documentclass{article}
\usepackage[
a4paper,
landscape,
margin = 4cm
]{geometry}
\usepackage{xfp}
\usepackage{pstricks}
\psset{dimen = m}
\usepackage{multido}
\begin{document}
\begin{pspicture}(21,8)
\multido
{\i = 0+6}
{4}
{\psframe(\i,0)(\fpeval{\i+3},2)}
\multido
{\i = 3+6}
{3}
{\psframe(\i,2)(\fpeval{\i+3},4)
\psframe[fillstyle = solid, fillcolor = gray](\i,0)(\fpeval{\i+3},2)
\rput(\fpeval{\i+1.5},1){\Large $+$}
\psline{->}(\fpeval{\i-0.2},1.8)(\fpeval{\i+0.2},2.2)
\psline{->}(\fpeval{\i+3.2},1.8)(\fpeval{\i+2.8},2.2)}
\multido
{\i = 6+6}
{2}
{\psframe(\i,4)(\fpeval{\i+3},6)
\psframe[fillstyle = solid, fillcolor = gray](\i,2)(\fpeval{\i+3},4)
\rput(\fpeval{\i+1.5},3){\Large $+$}
\psline{->}(\fpeval{\i-0.2},3.8)(\fpeval{\i+0.2},4.2)
\psline{->}(\fpeval{\i+3.2},3.8)(\fpeval{\i+2.8},4.2)}
\multido
{\i = 9+6}
{1}
{\psframe(\i,6)(\fpeval{\i+3},8)
\psframe[fillstyle = solid, fillcolor = gray](\i,4)(\fpeval{\i+3},6)
\rput(\fpeval{\i+1.5},5){\Large $+$}
\psline{->}(\fpeval{\i-0.2},5.8)(\fpeval{\i+0.2},6.2)
\psline{->}(\fpeval{\i+3.2},5.8)(\fpeval{\i+2.8},6.2)}
\end{pspicture}
\end{document}
\multido
我确信通过在 a 中使用 a 可以更“优雅”地完成此操作,\multido
但我做不到。我该怎么做?
更新
这是我最终得到的结果,感谢 user187802 的出色回答:
\documentclass[a4paper]{article}
\usepackage[margin = 1cm]{geometry}
\usepackage{pstricks}
\psset{dimen = m}
\usepackage{multido}
\usepackage{xfp}
% Parameters
\def\pilStr{0.2} % arrow size
\def\klodsBredde{2.5} % block width
\def\klodsHoejde{1.6} % block height
\def\pyramideStr{4} % pyramide size (natural number)
\newcommand*\pil{
\psline{->}(-\pilStr,-\pilStr)(\pilStr,\pilStr)
}
\def\kasseTom(#1,#2){
\psframe(#1,#2)
}
\def\kassePlus(#1,#2){
\psframe[
fillstyle = solid,
fillcolor = gray!75
](#1,#2)
\rput(\fpeval{#1/2},\fpeval{#2/2}){\large$+$}
\rput(0,#2){\pil}
\rput{90}(#1,#2){\pil}
}
\newcommand*\pyramideBredde{\fpeval{(2*\pyramideStr-1)*\klodsBredde}}
\newcommand*\pyramideHoejde{\fpeval{\klodsHoejde*\pyramideStr}}
\makeatletter
\newcommand*\pyramide{
\@ifnextchar(\psPyramide{\psPyramide(2,1)}
}
\def\psPyramide(#1,#2)#3{
\multido
{\rX = 0+#1,
\rY = 0+#2,
\iZ = 0+1}
{#3}
{\multido
{\rA = \rX+\fpeval{2*#1}}
{\fpeval{#3-\iZ}}
{\rput(\rA,\rY){\kasseTom(#1,#2)}}
\multido
{\rB = \fpeval{\rX+#1}+\fpeval{2*#1}}
{\fpeval{#3-\iZ-1}}
{\rput(\rB,\rY){\kassePlus(#1,#2)}}}
}
\makeatother
\def\udtryk(#1,#2)#3{
\rput(\fpeval{(2*#1+#2-2.5)*\klodsBredde},\fpeval{(#2-0.5)*\klodsHoejde}){#3}
}
\begin{document}
\begin{figure}
\centering
\begin{pspicture}(\pyramideBredde,\pyramideHoejde)
\pyramide(\klodsBredde,\klodsHoejde){\pyramideStr}
\udtryk(1,1){$x$}
\udtryk(2,1){$x$}
\udtryk(3,1){$y$}
\udtryk(4,1){$y$}
\udtryk(1,2){\textcolor{red}{$2x$}}
\udtryk(2,2){$x + y$}
\udtryk(3,2){\textcolor{red}{$2y$}}
\udtryk(1,3){\textcolor{red}{$3x + y$}}
\udtryk(2,3){\textcolor{red}{$x + 3y$}}
\udtryk(1,4){\textcolor{red}{$4x + 4y$}}
\end{pspicture}
\caption{An addition pyramide.}
\label{fig:add-pyramide}
\end{figure}
\end{document}
答案1
运行lualatex
:
\documentclass{article}
\usepackage[a4paper,margin = 1cm]{geometry}
\usepackage{pstricks}
\psset{dimen = m}
\usepackage{multido}
\def\Arrow{\psline{->}(-0.2,-0.2)(0.2,0.2)}
\def\Frame#1(#2,#3){%
\psframe#1[linecolor=black!50](#2,#3)%
\if$#1$\else\rput(!#2 2 div #3 2 div){+}\rput(0,#3){\Arrow}\rput{90}(#2,#3){\Arrow}\fi}
\makeatletter
\def\Bricks{\@ifnextchar(\psBricks{\psBricks(2,1)}}%
\def\psBricks(#1,#2)#3{%
\begin{pspicture}[calcframe]
\edef\dX{\numexpr2*#1}%
\edef\dY{\numexpr2*#2}%
\multido{\iX=0+#1,\iY=0+#2,\iZ=0+1}{#3}{%
\multido{\iA=\iX+\dX}{\numexpr#3-\iZ}{\rput(\iA,\iY){\Frame(#1,#2)}}%
\multido{\iB={\numexpr\iX+#1}+\dX}{\numexpr#3-\iZ-1}{\rput(\iB,\iY){\Frame*(#1,#2)}}%
}
\end{pspicture}}
\makeatother
\begin{document}
\psset{unit=0.5}
\Bricks(2,1){4}
\Bricks(3,2){4}
\Bricks{6}
\Bricks(1,1){4}
\end{document}