9

Is this a bug in TikZ? I'm working on an assignment which includes a number of colorful graphics, and for some reason the following code doesn't quite work as expected:

\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}

The blue triangular shape should be filled in a slightly lighter shade on its top surface, but when I use named coordinates it doesn't quite work. I had similar quirks rendering the gray box, but changing the order of the coordinates seemed to fix that. I can't fix it with the blue shape, however.

I wanted to speed up compilation by doing the mathematics as little as possible, and named coordinates seemed to be the answer, especially when the drawing requires dimensioning of all the shapes.

enter image description here

  • As first step change all your style names like "axes", "edge", which are already defined in TikZ. – Zarko Aug 29 '16 at 16:38
  • Problem is in use \begin{scope}[name prefix = ...]. This cause, that each line between given coordinates is drawn as separate line, consequently, you can not fill straight lines. If you delete name prefix = ... , then all works. I can't judge, if this is bug or intended feature. – Zarko Aug 29 '16 at 18:03
  • @Zarko are those words reserved words in TikZ? Could I use style names like "dimension edge" or should I avoid the word altogether? – Robbie Aug 30 '16 at 11:52
  • yes, it is used for line drawings between nodes/coordinates (drawing automaton, graphs etc). You can simple name as myedge what many people do (i prefer short names, because I'm lazy for typing :-( ). – Zarko Aug 30 '16 at 12:05
8

This is a bug in how TikZ determines whether a node is a coordinate or not.

TikZ does something slightly different if a node is a coordinate to if it is not. If a node is not a coordinate then it has a definite size and the path should be broken on its boundary (so the path should stop at one side of the node and restart at the other). This introduces a move to the path which affects its ability to be filled. If a node is a coordinate, then it has zero size and so the path is not broken - there is no move - and this means that the path can be filled as expected.

What is happening here is that the test for a node being a coordinate is failing because that test does not take into account the name prefix setting. So TikZ doesn't think the node is a coordinate and is breaking the path (as the coordinate node has zero size, you don't see this break but it is there and that affects the filling).

The fix for the bug is straightforward, if you're happy with a little \makeatletter-\makeatother block in your preamble.

\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

This should be filed as a bug in TikZ/PGF. Adding this to your example ought to fix that particular issue.

(Note: I was working from Zarko's MWE as that was far simpler than yours, but I checked with yours and the same fix works. Just ensure that the above is after \usepackage{tikz} in your preamble.)

  • This one I was tempted to try but LuaTeX completely fails on miktex for some reason not finding the right driver – percusse Aug 29 '16 at 20:52
  • 2
    @percusse Must admit I didn't try luatex. As Zarko said that the problem was also in pdftex, I stuck with that. Since I found the bug using that, I figured it would be engine independent. – Loop Space Aug 29 '16 at 20:54
  • I sow, that lines are not connected and concluded that this is source of OP problem. I also discover, that this is connected to use of name-prefix and show simple solution -- use defined coordinates outside of scope. This is (to me) some how logical use of name prefix (why ones use than, if is needed in coordinate position definition?). Anyway, thank you very much for bug fix! (+1). Hopefully it will be included in next TikZ release. – Zarko Aug 29 '16 at 21:02
  • @Zarko I agree that there may be other ways around this issue, but looking at the code there is definitely something happening that shouldn't be happening so it does qualify as a bug. I think the OP is using name prefix to "scope" the coordinates to ensure that they are kept separate. Thanks for the reduced MWE! – Loop Space Aug 29 '16 at 21:15
  • Update: this has been filed on the PGF/TikZ bug tracker. – Loop Space Aug 30 '16 at 8:52
4

Your MWE has more problems:

  • For your styles you use names which are already defined in TikZ. This is bad idea which can cause unexpected problems. Change this names, for example edge to myedge etc.
  • use of calculation of coordinates. Your claim, that with use of coordinates you shorten the compilation time, seems not to be true. You only move calculation to coordinates.
  • Use of name prefix. On the first sight seems that you find bug, however, if you slightly change your code, your problem disappear.

As solution try to rearrange your MWE as is shown on following example:

\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}

In above MWE I introduce shorter coordinate names (for shorter code, this will not influence to work of MWE). I also use \pgfmathsetmacro' for calculatesqrt` only ones and than use result in coordinates.

Unfortunately I have some problem with LuaLaTeX installation, so I made test with pdfLateX engine, which show the same problem as you reported in your question. So, I conclude, that problem is independed of used TeX engine and proposed solution will work with LuaLaTeX

  • if it is miktex I have also problems on my win machine – percusse Aug 29 '16 at 20:43
  • It's a bug! See my answer. (Thanks for your shortened MWE, that made it much easier to locate.) – Loop Space Aug 29 '16 at 20:49
  • Yes, I have MikTeX, recent 64-bit version. Error say: unrecognized option '--include-directory=C: <path to my file>'. Since for my needs I don't use LuaLaTeX (yet), this doesn't worry me much (for now). – Zarko Aug 29 '16 at 20:51
  • The updated version of LuaLaTeX in TeXLive 2016 is missing some macros which standalone needs, so adding \RequirePackage{luatex85} before \documentclass fixes that. – Robbie Aug 30 '16 at 11:47
  • At MikTeX this doesn't help, unfortunately :-( – Zarko Aug 30 '16 at 11:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.