搬去新问题
我正在用 tikz 编写一个包来绘制 3d 块,并已使其绘制网格块。
\documentclass[tikz, border=4mm]{standalone}
\usepackage{dnnplot}
\begin{document}
\begin{tikzpicture}
\node[block={scale=1, x=30mm, y=30mm, z=30mm, grid={(4,3,3)}, back plot}, anchor=back south west] (a) at (0, 0) {};
\end{tikzpicture}
\end{document}
现在,当我想制作一个网格块以在网格点处有锚点时,我遇到了一些麻烦。这有点像matrix
在 tikz 中所做的,但实际上这些锚点是在形状的定义中声明的。我参考了这个答案。但我的情况稍微复杂一些,我自己也搞错了。我唯一意识到的是,当我尝试\declareshape{...}
直接在 而不是 在等 中获取密钥的值时\anchor{...}
,\saveddimen{...}
该值就是它们最初设置的值。这不是我预期的结果。
非常抱歉,我把所有的代码都放在这里,没有做任何简化……注释的代码是我糟糕的尝试。关于选项的一些解释在https://github.com/ZhiyuanLck/dnnplot。
dnnplot.sty
\ProvidesPackage{dnnplot}
\RequirePackage{pdftexcmds}
\RequirePackage{tikz}
\makeatletter
\newif\ifback@plot
\newif\ifplane@block
% #1 parse mode #2 + or -
\def\grid@parse@temp#1#2{
\long\expandafter\def\csname grid@parse@#1@temp\endcsname##1##2{
\pgfmathparse{##1comp(##2)}
\expandafter\pgfmathtruncatemacro\csname
grid@#1@temp##1\endcsname{ifthenelse(\pgfmathresult #2 1, \pgfmathresult #2 1, 0)}
}
}
\grid@parse@temp{line}{-}
\long\def\grid@parse@line(#1){
\grid@parse@line@temp{x}{#1}
\grid@parse@line@temp{y}{#1}
\grid@parse@line@temp{z}{#1}
}
\grid@parse@temp{anchor}{+}
\long\def\grid@parse@anchor(#1){
\grid@parse@anchor@temp{x}{#1}
\grid@parse@anchor@temp{y}{#1}
\grid@parse@anchor@temp{z}{#1}
}
\pgfmathdeclarefunction{xcomp}{3}{
\begingroup
\pgfmathparse{#1}
\pgfmathsmuggle\pgfmathresult
\endgroup
}
\pgfmathdeclarefunction{ycomp}{3}{
\begingroup
\pgfmathparse{#2}
\pgfmathsmuggle\pgfmathresult
\endgroup
}
\pgfmathdeclarefunction{zcomp}{3}{
\begingroup
\pgfmathparse{#3}
\pgfmathsmuggle\pgfmathresult
\endgroup
}
\pgfkeys{/block plot/.cd,
x/.store in=\block@xcoordinate, x=0cm,
y/.store in=\block@ycoordinate, y=0cm,
z/.store in=\block@zcoordinate, z=0cm,
scale/.store in=\block@scale, scale=.5,
pre/.store in=\block@pre, pre=,
back plot/.is if=back@plot,
plane/.is if=plane@block,
zshift/.store in=\block@zshift, zshift=0,
front/.store in=\block@front, front=,
align axis/.store in=\block@align@axis, align axis=x,
hfactor/.store in=\block@hfactor, hfactor=.5,
vfactor/.store in=\block@vfactor, vfactor=.5,
align/.store in=\block@align, align=center,
grid/.store in=\block@grid, grid={(1,1,1)},
% grid/.initial={(1,1,1)},
% grid/.default={(1,1,1)},
}
\pgfdeclareshape{base block}
{
\inheritsavedanchors[from=rectangle]
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{east}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{north east}
\inheritanchor[from=rectangle]{south west}
\inheritanchor[from=rectangle]{north west}
\inheritanchor[from=rectangle]{south east}
\saveddimen{\offset}{
\pgfmathsetlength\pgf@x{
sqrt(2)/8*\block@scale*\block@zcoordinate
}
}
\saveddimen{\grid@xsep}{
\expandafter\grid@parse@line\block@grid
\typeout{xtemp \grid@line@tempx}
\pgfmathsetlength\pgf@x{\block@scale/(\grid@line@tempx+1)*\block@xcoordinate}
}
\saveddimen{\grid@ysep}{
\expandafter\grid@parse@line\block@grid
\pgfmathsetlength\pgf@x{\block@scale/(\grid@line@tempy+1)*\block@ycoordinate}
}
\saveddimen{\grid@zsep}{
\expandafter\grid@parse@line\block@grid
\pgfmathsetlength\pgf@x{sqrt(2)/4*\block@scale/(\grid@line@tempz+1)*\block@zcoordinate}
}
\anchor{front}{
\pgf@process{\southwest}
\pgf@xa=.5\pgf@x
\pgf@ya=.5\pgf@y
\pgf@process{\northeast}
\pgf@x=.5\pgf@x
\pgf@y=.5\pgf@y
\advance \pgf@x by \pgf@xa
\advance \pgf@y by \pgf@ya
\advance \pgf@x by -\offset
\advance \pgf@y by -\offset
}
\anchor{back}{
\pgf@process{\southwest}
\pgf@xa=.5\pgf@x
\pgf@ya=.5\pgf@y
\pgf@process{\northeast}
\pgf@x=.5\pgf@x
\pgf@y=.5\pgf@y
\advance \pgf@x by \pgf@xa
\advance \pgf@y by \pgf@ya
\advance \pgf@x by \offset
\advance \pgf@y by \offset
}
\anchor{front south west}{
\pgf@process{\southwest}
\advance \pgf@x by -\offset
\advance \pgf@y by -\offset
}
\anchor{back south west}{
\pgf@process{\southwest}
\advance \pgf@x by \offset
\advance \pgf@y by \offset
}
\anchor{front north east}{
\pgf@process{\northeast}
\advance \pgf@x by -\offset
\advance \pgf@y by -\offset
}
\anchor{back north east}{
\pgf@process{\northeast}
\advance \pgf@x by \offset
\advance \pgf@y by \offset
}
\anchor{front south east}{
\pgf@process{\northeast}
\pgf@xa=\pgf@x
\advance \pgf@xa by -\offset
\pgf@process{\southwest}
\advance \pgf@y by -\offset
\pgf@x=\pgf@xa
}
\anchor{back south east}{
\pgf@process{\northeast}
\pgf@xa=\pgf@x
\advance \pgf@xa by \offset
\pgf@process{\southwest}
\advance \pgf@y by \offset
\pgf@x=\pgf@xa
}
\anchor{front north west}{
\pgf@process{\southwest}
\pgf@xa=\pgf@x
\advance \pgf@xa by -\offset
\pgf@process{\northeast}
\advance \pgf@y by -\offset
\pgf@x=\pgf@xa
}
\anchor{back north west}{
\pgf@process{\southwest}
\pgf@xa=\pgf@x
\advance \pgf@xa by \offset
\pgf@process{\northeast}
\advance \pgf@y by \offset
\pgf@x=\pgf@xa
}
% grid anchor
\expandafter\grid@parse@line\block@grid
%output is "expected:3, real:0"
\typeout{expected:3, real:\grid@line@tempx}
% \pgfmathsetlengthmacro\grid@xsep{\block@scale/(\grid@line@tempx+1)*\block@xcoordinate}
% \pgfmathsetlengthmacro\grid@ysep{\block@scale/(\grid@line@tempy+1)*\block@ycoordinate}
% \expandafter\grid@parse@anchor\block@grid
% \foreach \grid@i in {1, ...,\grid@anchor@tempx}{
% \foreach \grid@j in {1, ...,\grid@anchor@tempy}{
% \edef\make@anchor#1#2{
% \anchor{xy+\grid@i-\grid@j}{
% \typeout{xxi: \grid@i}
% \typeout{xxs: \grid@xsep}
% \pgf@process{\southwest}
% \advance \pgf@x by -\offset
% \advance \pgf@y by -\offset
% \pgfmathsetlength\pgf@x{\pgf@x+(\grid@i-1)*\grid@xsep}
% \pgfmathsetlength\pgf@y{\pgf@y+(\grid@i-1)*\grid@ysep}
% }
% }
% }
% }
\backgroundpath{
\pgf@process{\southwest}
\pgfmathsetlengthmacro\block@xa{\pgf@x}
\pgfmathsetlengthmacro\block@ya{\pgf@y}
\pgf@process{\northeast}
\pgfmathsetlengthmacro\block@xb{\pgf@x}
\pgfmathsetlengthmacro\block@yb{\pgf@y}
\def\block@add@offset##1{
\pgfpointadd{##1}{\pgfqpoint{\offset}{\offset}}
}
\def\block@sub@offset##1{
\pgfpointadd{##1}{\pgfqpoint{-\offset}{-\offset}}
}
\def\block@southwest{\pgfqpoint{\block@xa}{\block@ya}}
\def\block@southeast{\pgfqpoint{\block@xb}{\block@ya}}
\def\block@northeast{\pgfqpoint{\block@xb}{\block@yb}}
\def\block@northwest{\pgfqpoint{\block@xa}{\block@yb}}
\ifplane@block
% plane block in y-z plane, x = 0
\ifdim\block@xcoordinate=0pt
\pgfpathmoveto{\block@sub@offset{\block@southwest}}
\pgfpathlineto{\block@add@offset{\block@southwest}}
\pgfpathlineto{\block@add@offset{\block@northwest}}
\pgfpathlineto{\block@sub@offset{\block@northwest}}
\pgfpathclose
\fi
% plane block in x-z plane, y = 0
\ifdim\block@ycoordinate=0pt
\pgfpathmoveto{\block@sub@offset{\block@southwest}}
\pgfpathlineto{\block@sub@offset{\block@southeast}}
\pgfpathlineto{\block@add@offset{\block@southeast}}
\pgfpathlineto{\block@add@offset{\block@southwest}}
\pgfpathclose
\fi
% plane block in x-y plane, z = 0
\ifdim\block@zcoordinate=0pt
\pgfpathmoveto{\block@sub@offset{\block@southwest}}
\pgfpathlineto{\block@sub@offset{\block@southeast}}
\pgfpathlineto{\block@sub@offset{\block@northeast}}
\pgfpathlineto{\block@sub@offset{\block@northwest}}
\pgfpathclose
\fi
\else
% main path
\pgfpathmoveto{\block@sub@offset{\block@southwest}}
\pgfpathlineto{\block@sub@offset{\block@southeast}}
\pgfpathlineto{\block@add@offset{\block@southeast}}
\pgfpathlineto{\block@add@offset{\block@northeast}}
\pgfpathlineto{\block@add@offset{\block@northwest}}
\pgfpathlineto{\block@sub@offset{\block@northwest}}
\pgfpathclose
% other edge
\pgfpathmoveto{\block@sub@offset{\block@northeast}}
\pgfpathlineto{\block@sub@offset{\block@northwest}}
\pgfpathmoveto{\block@sub@offset{\block@northeast}}
\pgfpathlineto{\block@sub@offset{\block@southeast}}
\pgfpathmoveto{\block@sub@offset{\block@northeast}}
\pgfpathlineto{\block@add@offset{\block@northeast}}
\fi
}
\foregroundpath{
\def\back@plot@temp{
\pgfsetdash{{1mm}{1mm}}{0mm}
\pgfpathmoveto{\block@add@offset{\block@southwest}}
\pgfpathlineto{\block@sub@offset{\block@southwest}}
\pgfpathmoveto{\block@add@offset{\block@southwest}}
\pgfpathlineto{\block@add@offset{\block@northwest}}
\pgfpathmoveto{\block@add@offset{\block@southwest}}
\pgfpathlineto{\block@add@offset{\block@southeast}}
\pgfusepath{stroke}
}
\def\if@back@plot{0}
\ifback@plot
\def\if@back@plot{1}
\fi
%grid
\expandafter\grid@parse@line\block@grid
\def\grid@offset##1##2##3##4{
\pgfpointadd{\pgfqpoint{##1}{##2}}{\csname block@##3@offset\endcsname{\csname block@##4\endcsname}}
}
% x axis
\ifnum\grid@line@tempx>0
\foreach \grid@i in {1, ..., \grid@line@tempx}{
\pgfmathsetlengthmacro\grid@for@temp{\grid@i*\grid@xsep}
\pgfscope
\pgfsetlinewidth{.5\pgflinewidth}
\pgfpathmoveto{\grid@offset{\grid@for@temp}{0cm}{sub}{southwest}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{0cm}{sub}{northwest}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{0cm}{add}{northwest}}
\pgfusepath{stroke}
\endpgfscope
% back plot
\ifback@plot
\def\if@back@plot{1}
\pgfscope
\pgfsetlinewidth{.5\pgflinewidth}
\pgfsetdash{{1mm}{1mm}}{0mm}
\pgfpathmoveto{\grid@offset{\grid@for@temp}{0cm}{add}{northwest}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{0cm}{add}{southwest}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{0cm}{sub}{southwest}}
\pgfusepath{stroke}
\endpgfscope
\fi
}
\fi
% y axis
\ifnum\grid@line@tempy>0
\foreach \grid@i in {1, ..., \grid@line@tempy}{
\pgfmathsetlengthmacro\grid@for@temp{\grid@i*\grid@ysep}
\pgfscope
\pgfsetlinewidth{.5\pgflinewidth}
\pgfpathmoveto{\grid@offset{0cm}{\grid@for@temp}{sub}{southwest}}
\pgfpathlineto{\grid@offset{0cm}{\grid@for@temp}{sub}{southeast}}
\pgfpathlineto{\grid@offset{0cm}{\grid@for@temp}{add}{southeast}}
\pgfusepath{stroke}
\endpgfscope
% back plot
\ifback@plot
\def\if@back@plot{1}
\pgfscope
\pgfsetlinewidth{.5\pgflinewidth}
\pgfsetdash{{1mm}{1mm}}{0mm}
\pgfpathmoveto{\grid@offset{0cm}{\grid@for@temp}{add}{southeast}}
\pgfpathlineto{\grid@offset{0cm}{\grid@for@temp}{add}{southwest}}
\pgfpathlineto{\grid@offset{0cm}{\grid@for@temp}{sub}{southwest}}
\pgfusepath{stroke}
\endpgfscope
\fi
}
\fi
% z axis
\ifnum\grid@line@tempz>0
\foreach \grid@i in {1, ..., \grid@line@tempz}{
\pgfmathsetlengthmacro\grid@for@temp{\grid@i*\grid@zsep}
\pgfscope
\pgfsetlinewidth{.5\pgflinewidth}
\pgfpathmoveto{\grid@offset{\grid@for@temp}{\grid@for@temp}{sub}{northwest}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{\grid@for@temp}{sub}{northeast}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{\grid@for@temp}{sub}{southeast}}
\pgfusepath{stroke}
\endpgfscope
% back plot
\ifback@plot
\def\if@back@plot{1}
\pgfscope
\pgfsetlinewidth{.5\pgflinewidth}
\pgfsetdash{{1mm}{1mm}}{0mm}
\pgfpathmoveto{\grid@offset{\grid@for@temp}{\grid@for@temp}{sub}{southeast}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{\grid@for@temp}{sub}{southwest}}
\pgfpathlineto{\grid@offset{\grid@for@temp}{\grid@for@temp}{sub}{northwest}}
\pgfusepath{stroke}
\endpgfscope
\fi
}
\fi
\ifnum\if@back@plot=1
\back@plot@temp
\fi
}
}
\newcommand{\set@xy}[1]{%
\tikz@scan@one@point\pgfutil@firstofone(#1)\relax
}
% factor of length to z coordinate
\pgfmathsetmacro\fc@z{sqrt(2)/4}
\tikzset{
block/.code={\tikzset{/block plot/.cd, #1}
% scale
\pgfmathsetlengthmacro\scaled@xcoordinate{\block@scale*\block@xcoordinate}
\pgfmathsetlengthmacro\scaled@ycoordinate{\block@scale*\block@ycoordinate}
\pgfmathsetlengthmacro\scaled@zcoordinate{\block@scale*\block@zcoordinate}
% shift
% initial shift
\newdimen\block@xshift
\newdimen\block@yshift
\block@xshift=0pt \block@yshift=0pt
% shift in z axis
\pgfmathaddtolength\block@xshift{-\fc@z*\block@zshift}
\pgfmathaddtolength\block@yshift{-\fc@z*\block@zshift}
% pre
\ifx\block@pre\pgfutil@empty
\else
% define total xoffset and yoffset of previous and current node when
% applying alignment in different axis.
% ##1 pre, cur ##2 x, y, z axis ##3 x, y coordinate
\def\define@offset##1##2##3{
\expandafter\newdimen\csname ##1@offset@##2axis@##3\endcsname
}
% although some of them are not needed at all.
\define@offset{pre}{x}{x}
\define@offset{pre}{x}{y}% 0
\define@offset{pre}{y}{x}% 0
\define@offset{pre}{y}{y}
\define@offset{pre}{z}{x}
\define@offset{pre}{z}{y}
\define@offset{cur}{x}{x}
\define@offset{cur}{x}{y}% 0
\define@offset{cur}{y}{x}% 0
\define@offset{cur}{y}{y}
\define@offset{cur}{z}{x}
\define@offset{cur}{z}{y}
% start and end point of offset vector
\def\xaxis@start{back north west}
\def\xaxis@end{back north east}
\def\yaxis@start{back south east}
\def\yaxis@end{back north east}
\def\zaxis@start{front}
\def\zaxis@end{back}
% set total offset by coordinates.
% set offset of previous node
% ##1 x, y, z axis ##2 x, y coordinate
\def\calc@pre@shift##1##2{
\set@xy{\block@pre.\csname ##1axis@start\endcsname}
\csname pgf@##2a\endcsname=\csname pgf@##2\endcsname
\set@xy{\block@pre.\csname ##1axis@end\endcsname}
\advance \csname pgf@##2\endcsname by -\csname pgf@##2a\endcsname
\csname pre@offset@##1axis@##2\endcsname=\csname pgf@##2\endcsname
}
\calc@pre@shift{x}{x}
\calc@pre@shift{x}{y}
\calc@pre@shift{y}{x}
\calc@pre@shift{y}{y}
\calc@pre@shift{z}{x}
\calc@pre@shift{z}{y}
% set offset of current node
\pgfmathsetlength\cur@offset@xaxis@x{\scaled@xcoordinate}
\pgfmathsetlength\cur@offset@yaxis@y{\scaled@ycoordinate}
\pgfmathsetlength\cur@offset@zaxis@x{\fc@z*\scaled@zcoordinate}
\pgfmathsetlength\cur@offset@zaxis@y{\fc@z*\scaled@zcoordinate}
% \cur@offset@xaxis@x=\scaled@xcoordinate
% \cur@offset@yaxis@y=\scaled@ycoordinate
% \cur@offset@zaxis@x=\fc@z\scaled@zcoordinate
% \cur@offset@zaxis@y=\fc@z\scaled@zcoordinate
% x,y coordinates of shift vector (with factor 1)
% ##1 x, y, z axis ##2 x, y coordinate
\def\define@shift##1##2{
\expandafter\newdimen\csname shift@##1axis@##2\endcsname
}
\define@shift{x}{x}
\define@shift{x}{y}% 0
\define@shift{y}{x}% 0
\define@shift{y}{y}
\define@shift{z}{x}
\define@shift{z}{y}
% ##1 x, y, z axis ##2 x, y coordinate
\def\calc@shift##1##2{
\csname shift@##1axis@##2\endcsname=\csname pre@offset@##1axis@##2\endcsname
\advance \csname shift@##1axis@##2\endcsname by -\csname cur@offset@##1axis@##2\endcsname\relax
% \expandafter\pgfmathaddtolength\csname shift@##1axis@##2\endcsname{-\expandafter\the\csname cur@offset@##1axis@##2\endcsname}
}
\calc@shift{x}{x}
\calc@shift{x}{y}
\calc@shift{y}{x}
\calc@shift{y}{y}
\calc@shift{z}{x}
\calc@shift{z}{y}
% front of shift
\ifx\block@front\pgfutil@empty
\else
\pgfkeysalso{at=(\[email protected]), anchor=back}
\pgfmathaddtolength\block@xshift{-\fc@z*\block@front}
\pgfmathaddtolength\block@yshift{-\fc@z*\block@front}
\fi
% align shift
% align option has higher priority
% ##1 shift style ##2 hfactor ##3 vfactor
\def\shift@style##1##2##3{
\expandafter\def\csname block@shift@##1\endcsname{
\def\block@hfactor{##2}
\def\block@vfactor{##3}
}
}
\shift@style{left}{0}{0.5}
\shift@style{right}{1}{0.5}
\shift@style{down}{0.5}{0}
\shift@style{up}{0.5}{1}
\shift@style{upperleft}{0}{1}
\shift@style{upperright}{1}{1}
\shift@style{lowerleft}{0}{0}
\shift@style{lowerright}{1}{0}
\expandafter\ifcsname block@shift@\block@align\endcsname
\csname block@shift@\block@align\endcsname
\fi
% hshift and vshift in 3 directions
\pgfmathsetmacro\real@hfactor{\[email protected]}
\pgfmathsetmacro\real@vfactor{\[email protected]}
% ##1 x, y, z axis ##2 hvshift 3 4 shift x, y coordinate
\def\define@hv@shift##1##2##3##4{
\expandafter\newdimen\csname hshift@##1axis@##2\endcsname
\csname hshift@##1axis@##2\endcsname=\real@hfactor\csname shift@##3axis@##2\endcsname
\expandafter\newdimen\csname vshift@##1axis@##2\endcsname
\csname vshift@##1axis@##2\endcsname=\real@vfactor\csname shift@##4axis@##2\endcsname
}
\define@hv@shift{x}{x}{z}{y}
\define@hv@shift{x}{y}{z}{y}
\define@hv@shift{y}{x}{x}{z}
\define@hv@shift{y}{y}{x}{z}
\define@hv@shift{z}{x}{x}{y}
\define@hv@shift{z}{y}{x}{y}
\advance \block@xshift by \csname hshift@\block@align@axis axis@x\endcsname
\advance \block@xshift by \csname vshift@\block@align@axis axis@x\endcsname
\advance \block@yshift by \csname hshift@\block@align@axis axis@y\endcsname
\advance \block@yshift by \csname vshift@\block@align@axis axis@y\endcsname
\fi
% general
\pgfkeysalso{
shift={(\block@xshift, \block@yshift)},
inner sep=0,
base block, draw, fill opacity=.3, thick,
minimum height=\scaled@ycoordinate,
minimum width=\scaled@xcoordinate,
}
}
}
\def\block@label@upperleft@a{front north west}
\def\block@label@upperleft@b{back north west}
\def\block@label@upperright@a{front north east}
\def\block@label@upperright@b{back north east}
\def\block@label@lowerleft@a{front south west}
\def\block@label@lowerleft@b{back south west}
\def\block@label@lowerright@a{front south east}
\def\block@label@lowerright@b{back south east}
\def\block@label@frontwest@a{front south west}
\def\block@label@frontwest@b{front north west}
\def\block@label@fronteast@a{front south east}
\def\block@label@fronteast@b{front north east}
\def\block@label@backwest@a{back south west}
\def\block@label@backwest@b{back north west}
\def\block@label@backeast@a{back south east}
\def\block@label@backeast@b{back north east}
\def\block@label@frontsouth@a{front south west}
\def\block@label@frontsouth@b{front south east}
\def\block@label@frontnorth@a{front north west}
\def\block@label@frontnorth@b{front north east}
\def\block@label@backsouth@a{back south west}
\def\block@label@backsouth@b{back south east}
\def\block@label@backnorth@a{back north west}
\def\block@label@backnorth@b{back north east}
% #1 -- label position
% #2 -- node name
% #3 -- passed string
% #4 -- label text
% #5 -- edge specification
\newcommand{\block@label}[4]{
\path (#2.\csname block@label@#3@a\endcsname) --
node[#1] {#4}
(#2.\csname block@label@#3@b\endcsname);
}
\def\block@label@position@upperleft{left}
\def\block@label@position@upperright{right}
\def\block@label@position@lowerleft{left}
\def\block@label@position@lowerright{right}
\def\block@label@position@frontwest{left}
\def\block@label@position@fronteast{right}
\def\block@label@position@backwest{left}
\def\block@label@position@backeast{right}
\def\block@label@position@frontnorth{above}
\def\block@label@position@frontsouth{below}
\def\block@label@position@backnorth{above}
\def\block@label@position@backsouth{above}
% #1 -- label position, optional
% #2 -- node name
% #3 -- passed string
% #4 -- label text
\newcommand{\blocklabel}[4][]{
\ifcsname block@label@position@#3\endcsname
% \def\block@label@position{#1}
% use default position
% \ifx\block@label@position\pgfutil@empty
\def\block@label@position{\csname block@label@position@#3\endcsname}
% \fi
\block@label{\block@label@position, #1}{#2}{#3}{#4}
\fi
}
\makeatother