这是 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 中定义。这不是一个好主意,可能会导致意外问题。例如,将这些名称更改
edge
为myedge
等。 - 使用坐标计算。您声称使用坐标可以缩短编译时间,这似乎不正确。您只是将计算转移到坐标上。
- 使用
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