TikZ 填充未使用命名坐标绘制

TikZ 填充未使用命名坐标绘制

这是 TikZ 中的错误吗?我正在完成一项包含许多彩色图形的作业,由于某种原因,以下代码无法按预期工作:

\RequirePackage{luatex85}
\documentclass[tikz]{standalone}

\usepackage{xcolor}
\definecolor{red}{HTML}{DC291E}
\definecolor{blue}{HTML}{04588A}
\definecolor{orange}{HTML}{FA6B00}

\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{decorations.pathmorphing}
\usetikzlibrary{positioning}
\usetikzlibrary{external}
\usepgflibrary{arrows.meta}
\usepackage{siunitx}

\begin{document}

\begin{tikzpicture}[
  axes/.style={node font=\small, every node/.style={fill=white, fill opacity=0.375, text opacity=1}},
  edge/.style={densely dashed, line width=0.5pt, shorten >= -2.5mm, color=black!75!white},
  dimension/.style={draw, line width=0.5pt, arrows = {Stealth-Stealth}, every node/.style={anchor=mid, midway, fill=white, node font=\footnotesize}},
  ]
  \begin{scope}[axes]
    \draw[->] (0, 0) -- (-4, -2) node[below left] {$x$} coordinate(x axis);
    \draw[->] (0, 0) -- (5, 0) node[right] {$z$} coordinate(y axis);
    \draw[->] (0, 0) -- (0, 5) node[above] {$y$} coordinate(z axis);
  \end{scope}

  \begin{scope}[name prefix = shape3-]
    \coordinate (bottom-right-front) at ({-12/sqrt(20) + 3}, {-6/sqrt(20)});
    \coordinate (bottom-left-front) at ({-12/sqrt(20)}, {-6/sqrt(20)});
    \coordinate (top-right-front) at ({-12/sqrt(20) + 3}, {-6/sqrt(20) + 1});
    \coordinate (top-left-front) at ({-12/sqrt(20)}, {-6/sqrt(20) + 1});
    \fill[fill=gray!70!white]
      (bottom-right-front) -- ++(0, 1) -- (3, 1) -- (3, 0) -- cycle;
    \fill[fill=gray!50!white] 
      (bottom-left-front) -- ++(3, 0) -- ++(0, 1) -- ++(-3, 0) -- cycle;
    \fill[fill=gray!30!white] 
      (top-left-front) -- ++(3, 0) -- (3, 1) -- (0, 1) -- cycle;
    \draw[line width=0.5pt, gray!10!white]
      (top-right-front) -- (3, 1)
      (top-left-front) -- ++(3, 0) -- ++(0, -1);
    \draw[line width=0.5pt, gray]
      (0, 1) -- (top-left-front) -- ++(0, -1) -- ++(3, 0) -- (3, 0) -- (3, 1);
  \end{scope}

  \begin{scope}[name prefix = shape2-]
    \coordinate (bottom-left-front) at ({-4/sqrt(20)}, {-2/sqrt(20) + 1});
    \coordinate (bottom-right-front) at ({-4/sqrt(20) + 3}, {-2/sqrt(20) + 1});
    \fill[fill=orange!80!white]
      (bottom-left-front) -- ++(3, 0) -- ++(0, 2) -- ++(-3, 0) -- cycle;
    \fill[fill=orange!60!gray]
      (bottom-right-front) -- ++(0, 2) -- (3, 3) -- (3, 1) -- cycle;
    \draw[line width=0.5pt, orange!50!black]
      (bottom-left-front) -- ++(3, 0) -- (3, 1)
      (bottom-left-front) -- ++(0, 2)
      (3, 1) -- (3, 3);
  \end{scope}
  \begin{scope}[name prefix = shape1-]
    \coordinate (bottom-left-front) at ({-4/sqrt(20)}, {-2/sqrt(20) + 3});
    \coordinate (bottom-right-front) at ({-4/sqrt(20) + 3}, {-2/sqrt(20) + 3});
    \coordinate (top-left-front) at ({-4/sqrt(20)}, {-2/sqrt(20) + 4.5});
    \coordinate (top-left-back) at (0, 4.4);
    \fill[fill=blue!80!white] (bottom-left-front) -- ++(3, 0) -- ++(-3, 1.5) -- cycle;

    % WHY YOU NO FILL?
    \fill[fill=blue!65!white] (3, 3) node {a} -- (top-left-back) node {b} -- (top-left-front) node {c} -- (bottom-right-front) node {d} -- cycle;

    % THIS WORKS BUT POINTS ARE SAME AS NAMED COORDINATES
    % \fill[fill=blue!65!white] (3, 3) node {a} -- (0, 4.4) node {b} -- ({-4/sqrt(20)}, {-2/sqrt(20) + 4.5}) node {c} -- (bottom-right-front) node {d} -- cycle;

    \draw[line width=0.5pt, blue!50!black]
      (3, 3) -- (0, 4.4) -- (top-left-front) -- ++(0, -2);
    \draw[line width=0.5pt, blue!50!orange!50!black]
      (bottom-left-front) -- ++(3, 0) -- (3, 3);
  \end{scope}

  \draw[edge] (shape3-bottom-right-front) -- ++(1, 0) coordinate (shape3-x);
  \draw[edge] (shape3-bottom-right-front) -- ({-16/sqrt(20) + 3}, {-8/sqrt(20)}) coordinate (shape3-y);
  \draw[edge] (shape3-top-left-front) -- ({-16/sqrt(20)}, {-8/sqrt(20) + 1}) coordinate (shape3-z);
  \draw[edge] (shape2-bottom-left-front) -- ++(-1, 0) coordinate (shape2-x);
  \draw[edge] (shape1-bottom-left-front) -- ++(-1, 0) coordinate (shape1-x);
  \draw[edge] (shape1-top-left-front) -- ++(-1, 0) coordinate (shape1-zf);
  \draw[edge] (shape1-top-left-back) -- ++(-1, 0) coordinate (shape1-zb);

  \draw[dimension] (shape3-x) -- (4, 0) node[inner xsep=0] {\SI{60}{\mm}};
  \draw[dimension] (shape3-y) -- ++(-3, 0) node {\SI{60}{\mm}};
  \draw[dimension] (shape3-z) -- ++(0, -1) node {\SI{20}{\mm}};
  \draw[dimension] (shape2-x) -- (shape1-x) node {\SI{40}{\mm}};
  \draw[dimension] (shape1-x) -- (shape1-zf) node {\SI{30}{\mm}};
  \draw[dimension] (shape1-zf) -- (shape1-zb) node[above=5pt] {\SI{20}{\mm}};

\end{tikzpicture}
\end{document}

蓝色三角形的顶面应填充浅一点的色调,但当我使用命名坐标时,效果并不理想。渲染灰色框时,我遇到了类似的问题,但更改坐标顺序似乎可以解决这个问题。但是,我无法用蓝色形状解决这个问题。

我想通过尽可能少地进行数学运算来加快编译速度,命名坐标似乎是答案,特别是当绘图需要对所有形状进行尺寸标注时。

在此处输入图片描述

答案1

这是 TikZ 在确定节点是否为坐标时的一个错误。

如果一个节点是坐标,TikZ 会做一些稍微不同的事情。如果一个节点不是一个坐标,那么它就具有确定的大小,路径应该在其边界处断开(因此路径应该在节点的一侧停止,并在另一侧重新开始)。这会给move路径引入一个,从而影响其填充能力。如果节点是一个坐标,那么它的大小为零,因此路径没有断开 - 没有move- 这意味着路径可以按预期填充。

这里发生的事情是,节点是否为坐标的测试失败了,因为该测试没有考虑到设置name prefix。因此 TikZ 认为该节点不是坐标,并且会破坏路径(因为坐标节点的大小为零,所以您看不到这个中断,但它确实存在,并且会影响填充)。

如果您对序言中的\makeatletter小块感到满意,那么该错误的修复非常简单。\makeatother

\makeatletter
\def\tikz@parse@node#1(#2){%
  \pgfutil@in@.{#2}% Ok, flag this
  \ifpgfutil@in@
    \tikz@calc@anchor#2\tikz@stop%
  \else%
    \tikz@calc@anchor#2.center\tikz@stop% to be on the save side, in
                                % case iftikz@shapeborder is ignored...
% The next line is the fixed line with the addition of the `\tikz@pp@name`
    \expandafter\ifx\csname pgf@sh@ns@\tikz@pp@name{#2}\endcsname\tikz@coordinate@text%
    \else
      \tikz@shapebordertrue%
      \def\tikz@shapeborder@name{\tikz@pp@name{#2}}%
    \fi%
  \fi%
  \edef\tikz@marshal{\noexpand#1{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
  \tikz@marshal%
}
\makeatother

这应该被归类为 TikZ/PGF 中的错误。将其添加到您的示例中应该可以修复该特定问题。

(注意:我使用的是 Zarko 的 MWE,因为它比你的简单得多,但我检查了你的,发现同样的修复方法有效。只需确保上述内容\usepackage{tikz}在你的序言之后即可。)

答案2

您的 MWE 有更多问题:

  • 对于您的样式,您使用的名称已在 TikZ 中定义。这不是一个好主意,可能会导致意外问题。例如,将这些名称更改edgemyedge等。
  • 使用坐标计算。您声称使用坐标可以缩短编译时间,这似乎不正确。您只是将计算转移到坐标上。
  • 使用name prefix。乍一看你似乎发现了错误,然而,如果你稍微改变一下代码,问题就消失了。

解决方案是尝试重新排列您的 MWE,如下例所示:

\documentclass[tikz]{standalone}
\usepackage{xcolor}
\definecolor{red}{HTML}{DC291E}
\definecolor{blue}{HTML}{04588A}
\definecolor{orange}{HTML}{FA6B00}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,
                calc,
                decorations.markings,decorations.pathmorphing,
                external,
                positioning}
\usepackage{siunitx}

\begin{document}
    \begin{tikzpicture}
\pgfmathsetmacro{\SQ}{1/sqrt(20)}% <-- to for spare calculation time
    \begin{scope}[name prefix = S1-]
\coordinate (bl-front)  at (-4*\SQ,  -2*\SQ + 3.0);
\coordinate (br-front)  at (-4*\SQ+3,-2*\SQ + 3.0);
\coordinate (tl-front)  at (-4*\SQ,  -2*\SQ + 4.5);
\coordinate (tl-back)   at (0, 4.4);
    \end{scope}
% WHY YOU NO FILL? ... MOWED OUTSIDE OF "SCOPE", NOW FILL WORKS AS EXPECTED :-)
\draw[fill=gray] (3,3)  node[right] {a} 
    -- (S1-tl-back)     node[above] {b} 
    -- (S1-tl-front)    node[left]  {c} 
    -- (S1-br-front)    node[below] {d}    
    -- cycle;
    \end{tikzpicture}
\end{document}

在上面的 MWE 中,我引入了较短的坐标名称(对于较短的代码,这不会影响 MWE 的工作)。我还\pgfmathsetmacro' for calculate仅使用 sqrt`,然后在坐标中使用结果。

不幸的是,我在安装时遇到了一些问题LuaLaTeX,所以我用 pdfLateX 引擎进行了测试,结果出现了和你在问题中报告的相同的问题。因此,我得出结论,这个问题与使用的 TeX 引擎无关,建议的解决方案将适用于 LuaLaTeX

相关内容