难以在“\path let ...”TikZ 结构中放置动态填充命令

难以在“\path let ...”TikZ 结构中放置动态填充命令

我想创建一系列显示菱形折叠的图像。我可以做我想做的事,但代码不太优雅。我最终(不必要地)重复了一大堆代码来获得我想要的效果。

代码如下:

\documentclass{article}
\usepackage[svgnames]{xcolor}
\usepackage[margin=0.35in]{geometry}
\usepackage{tikz}
\usepackage{tkz-euclide}
\usetikzlibrary{calc}
\usetikzlibrary{decorations}
\tikzset{rhombus fill/.style={fill=blue!\number\numexpr30+#1\relax},
         my arrow/.style={decorate,decoration={markings,mark=at position 1 with {\arrow[scale=2.25]{stealth};}}}}
\def\mystep{6}
\edef\myangle{0}
\def\stepmyangle#1{\xdef\myangle{\number\numexpr\myangle+#1\relax}}
\pagestyle{empty}
\setlength{\parindent}{0pt}
\begin{document}


%-@-(4)------------------------------------------------------------------------------------
\newcounter{currentstep}
\foreach \x/\y in {0/0,10/30,12/60,14/0,10/0,9/0}
  {\stepmyangle{\x}%%
   \begin{tikzpicture}
      \coordinate (W) at (0,2in);
      \coordinate (Y) at (0,-2in);
      \coordinate (X) at (1.14in,0);
      \coordinate (Z) at (-1.14in,0);

      \fill[rhombus fill=0] (W) -- (Z) -- (Y);

      \ifnum\x>0\relax
        \path let
                \p1=($(Y)-(X)$),
                \n1={atan2(\y1,\x1)},
                \n2={veclen(\y1,\x1)},
                \p2=($(Y)-(Z)$),
                \n3={atan2(\y2,\x2)}
              in
              coordinate (A) at ($(W)+(\n3-\myangle:\n2)$);
        \fill[rhombus fill=\y] (W) -- (A) -- (Y);
        \path let
                \p1=($(Y)-(X)$),
                \n1={atan2(\y1,\x1)},
                \n2={veclen(\y1,\x1)},
                \p2=($(Y)-(Z)$),
                \n3={atan2(\y2,\x2)}
              in
              coordinate (A) at ($(W)+(\n3-\myangle:\n2)$)
              %% Here results in an error message:  "Missing \endcsname insert"
              %%[fill,rhombus fill=\y] (W) -- (A) -- (Y)
              [draw,postaction={my arrow}] (A) arc (\n3-\myangle:\n1:\n2)
              ;
      \else
        \path let
                \p1=($(Y)-(X)$),
                \n1={atan2(\y1,\x1)},
                \n2={veclen(\y1,\x1)},
                \p2=($(Y)-(Z)$),
                \n3={atan2(\y2,\x2)}
              in
              coordinate (A) at ($(W)+(\n3:\n2)$)
              ;
      \fi
      %% Here doesn't work because it blocks the arrows.
      %%[fill,rhombus fill=\y] (W) -- (A) -- (Y)

      \draw[gray!20] (W) -- (X) -- (Y);

      \draw (W)
        \foreach \x in {A,Y,Z} { -- (\x) } -- cycle;
      \draw[dashed] (W) -- (Y);

    \ifnum\thecurrentstep>2\relax\draw[black,fill=black!20] (W) -- (A) -- (Y) -- cycle;\fi

    \end{tikzpicture}%%
    \ifnum\thecurrentstep=2\relax
      \vspace{2ex}\par
    \else
      \ifnum\thecurrentstep<5\relax
        \hspace*{\fill}%%
      \fi
    \fi
    \global\stepcounter{currentstep}%%
  } 

\end{document}

生成结果:

在此处输入图片描述

第一的问题是我重复了一段代码:

        \path let
                \p1=($(Y)-(X)$),
                \n1={atan2(\y1,\x1)},
                \n2={veclen(\y1,\x1)},
                \p2=($(Y)-(Z)$),
                \n3={atan2(\y2,\x2)}
              in ...;

如果我可以设置这些值一次,然后在需要时从路径外部调用它们,那就太好了。我尝试过类似

        \path let
                \p1=($(Y)-(X)$),
                \n1={atan2(\y1,\x1)},
                \n2={veclen(\y1,\x1)},
                \p2=($(Y)-(Z)$),
                \n3={atan2(\y2,\x2)}
              in \edef\myarclength{\n2};

但这导致了错误。

第二问题是我似乎不能只写

        \path let
                \p1=($(Y)-(X)$),
                \n1={atan2(\y1,\x1)},
                \n2={veclen(\y1,\x1)},
                \p2=($(Y)-(Z)$),
                \n3={atan2(\y2,\x2)}
              in
              coordinate (A) at ($(W)+(\n3-\myangle:\n2)$)
              [fill,rhombus fill=\y] (W) -- (A) -- (Y)
              [draw,postaction={my arrow}] (A) arc (\n3-\myangle:\n1:\n2)
              ;

并节省了我重新粘贴代码的时间。最后一个例子的结果是

Missing \endcsname insert

错误信息。

答案1

第二个问题出现是因为你同时使用了\y变量\foreachcalc的简写形式坐标值\p

\foreach \xValue/\yValue in … 当您使用时使用即可解决这个问题rhombus fill=\yValue

第一个问题稍微复杂一点。你实际上可以在路径上执行任意 TeX 操作。你可以使用

\path \pgfextra{<TeX stuff>};
\path \pgfextra<TeX stuff>\endpgfextra;

或者

\path [/utils/exec=<TeX stuff>];
%   or /utils/exec={<TeX stuff>} if <TeX stuff> contains , or =

\def但是用/定义的宏\edef只会在该路径上定义,并且不会在 中保留;。您需要在这里使用\gdef/ \xdef。(我不知道您想在哪里使用,\myarclength所以我不能说是否有其他方法可以解决这个问题。)

但我看到了第三个问题:
不能 draw路径的一部分和fill路径的另一部分(我敢说!弧也会有填充……)。

不过,在您的情况下,您可以保存坐标(A)并绘制圆弧,然后使用\fill已保存坐标的三角形的另一部分(A)

\path let
     \p1=($(Y)-(X)$),
     \n1={atan2(\y1,\x1)},
     \n2={veclen(\y1,\x1)},
     \p2=($(Y)-(Z)$),
     \n3={atan2(\y2,\x2)}
   in [draw, postaction=my arrow]
    ($(W)+(\n3-\myangle:\n2)$) coordinate (A) arc (\n3-\myangle:\n1:\n2);
\fill[rhombus fill=\yValue] (W) -- (A) -- (Y);

我意识到这没有帮助,因为您首先要填充该区域,然后绘制箭头(保存值以供日后使用会很方便\n)。

幸运的是,你 drawfill路径的各个部分分别;实际上,edge路径运算符创建了另一条路径,但我们可以使用它:

\path let
      \p1=($(Y)-(X)$),
      \n1={atan2(\y1,\x1)},
      \n2={veclen(\y1,\x1)},
      \p2=($(Y)-(Z)$),
      \n3={atan2(\y2,\x2)}
    in 
      (W) edge [rhombus fill=\yValue,
                to path={--($(W)+(\n3-\myangle:\n2)$) coordinate (A)--(Y)}] ()
      (A) edge [draw, postaction=my arrow,
                to path={arc (\n3-\myangle:\n1:\n2)}]                       ();

是的,我们只是忽略\tikztotarget并直接在中指定我们的路径to path

如果你看一下新的循环头:

\foreach \xValue/\yValue[
  evaluate={\myangle=\myangle+\xValue},
  remember=\myangle as \myangle (initially 0),
  count=\currentstep from 0] in {0/0, 10/30, 12/60, 14/0, 10/0, 9/0}{

我已将您的计数器和辅助宏纳入\foreach选项中。

此外,您也许可以尝试用一张(因此只有一张 TikZ 图片)来绘制图表\matrix,但我想这不再属于这个问题了。

代码

\documentclass{article}
\usepackage[svgnames]{xcolor}
\usepackage[margin=0.35in]{geometry}
\usepackage{tikz,tkz-euclide}
\usetikzlibrary{calc,decorations}
\tikzset{
  rhombus fill/.style={fill=blue!\number\numexpr30+#1\relax},
  my arrow/.style={
    decorate,
    decoration={markings,mark=at position 1 with {\arrow[scale=2.25]{stealth};}}}}
\begin{document}
\foreach \xValue/\yValue[
  evaluate={\myangle=\myangle+\xValue},
  remember=\myangle as \myangle (initially 0),
  count=\currentstep from 0] in {0/0, 10/30, 12/60, 14/0, 10/0, 9/0}{
   \begin{tikzpicture}
      \coordinate (W) at (0,2in);
      \coordinate (Y) at (0,-2in);
      \coordinate (X) at (1.14in,0);
      \coordinate (Z) at (-1.14in,0);

      \fill[rhombus fill=0] (W) -- (Z) -- (Y);

      \ifnum\xValue>0\relax
        \path let
                \p1=($(Y)-(X)$),
                \n1={atan2(\y1,\x1)},
                \n2={veclen(\y1,\x1)},
                \p2=($(Y)-(Z)$),
                \n3={atan2(\y2,\x2)}
              in 
              (W) edge [rhombus fill=\yValue,
                        to path={-- ($(W)+(\n3-\myangle:\n2)$) coordinate (A) -- (Y)}] ()
              (A) edge [draw, postaction=my arrow,
                        to path={arc (\n3-\myangle:\n1:\n2)}]                          ();
      \else
        \path let
                \p1=($(Y)-(X)$),
                \n1={atan2(\y1,\x1)},
                \n2={veclen(\y1,\x1)},
                \p2=($(Y)-(Z)$),
                \n3={atan2(\y2,\x2)}
              in coordinate (A) at ($(W)+(\n3:\n2)$);
      \fi

      \draw[gray!20] (W) -- (X) -- (Y);
      \draw (W) \foreach \x in {A,Y,Z} { -- (\x) } -- cycle;
      \draw[dashed] (W) -- (Y);

    \ifnum\currentstep>2\relax\draw[black,fill=black!20] (W) -- (A) -- (Y) -- cycle;\fi
    \end{tikzpicture}%
    \ifnum\currentstep=2\relax
      \vspace{2ex}\par
    \else
      \ifnum\currentstep<5\relax
        \hspace*{\fill}%%
      \fi
    \fi}
\end{document}

相关内容