考虑下面的代码。
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\newcommand{\newvar}{\pgfmathsetmacro}
\begin{document}
\begin{tikzpicture}[scale=1, transform shape]%, transparency group, blend mode = multiply]
\newvar{\num}{10}
\newvar{\val}{\num-1}
\newvar{\scale}{1}
\tikzset{
square/.pic={
\draw[line width=1mm, pic actions] (0, 0) -- (1, 0) -- (1, 1) -- (0, 1) -- cycle;
}
}
\tikzset{
scaledc/.pic={
\foreach \i in {(0, 0), (\scale, 0), (0, \scale), (0, 2*\scale), (\scale, 2*\scale)}{
\draw[line width=1mm] \i pic[fill=blue] {square};
}
}
}
\tikzset{
scaledd/.pic={
\foreach \i in {(0, 0), (-1*\scale, 0), (0, -1*\scale), (0, -2*\scale), (-1*\scale, -2*\scale)}{
\draw[line width=1mm] \i pic[fill=red] {square};
}
}
}
\begin{scope}[transparency group]
\begin{scope}[blend mode = multiply]
\foreach \i in {0,...,\num}{
\foreach \j in {0,...,\val}{
\path (3*\j+\i, -\j+3*\i) pic {scaledc};
\path (3*\j+\i+2, -\j+3*\i+1) pic {scaledd};
}
}
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}
上面的代码给出了一个由 C 形图块及其镜像组成的平面镶嵌图。当设置\scale
为 1 并将\num
设置为 10 时,输出如下(很漂亮):
但是我想设置得\scale
非常高,即53,而且\num
也非常高(至少40)。
Tikz 似乎并不关心是否\scale
高于 35。进一步增加时输出不会改变\scale
。
我只对原点周围的一小块区域(10 x 10)感兴趣。
我可以以某种方式告诉 tikz 忘记在这个区域之外做任何事情,以便它可以产生更丰富的输出吗?
编辑:
让我举个例子来解释我的观点。修复scale=11
。然后 c 形瓷砖变成
图像中心(原点)附近的很多方块未被覆盖。为了更好地研究镶嵌的行为,我们需要增加 的值\num
以获得更好的图像。以下是我们使用 看到的结果\num=20
。
这一切都很好。但如果我将值增加到\num
40,tikz 不会生成任何新数据,并且执行代码也需要很长时间。我的兴趣只在于原点周围的一个小窗口。
答案1
我测试了我在评论中提到的解决方案:这个想法是手动进行剪辑,因此对于每个方块,我们测试它是否在主区域。这可能不是最好的方法。它实际上可能是一个(非常)糟糕的答案,但因为我写了它,所以……发布它不需要任何费用!(如果有人认为这是一个糟糕的答案,请告诉我,我会删除它!)
为了对 4 个测试(-L < X < L 和 -L < Y < L)进行编码,我使用了四个差值的符号之和:LX、X-(-L)、LY 和 Y-(-L)。我不知道是否有更好、更优化的方法进行四次计算和四次测试,但它就是这样工作的,而且很容易编写!
(注意:sign(X) 等于 -1、0 或 1,因此如果所有不等式都成立,则总和应该为 4)
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\newcommand{\newvar}{\pgfmathsetmacro}
\begin{document}
\begin{tikzpicture}[scale=1, transform shape]%, transparency group, blend mode = multiply]
\newvar{\num}{50}
\newvar{\val}{\num-1}
\newvar{\scale}{11}
\newvar{\alimit}{10}
\newcommand{\drawsquare}[3]{
\pgfmathtruncatemacro\dum{sign(\alimit-(#1))+sign(#1+\alimit)+sign(\alimit-(#2))+sign(#2+\alimit)}
\ifnum\dum=4
\draw[fill=#3] (#1-.5,#2-.5) rectangle ++ (1,1);
\fi
}
\begin{scope}[transparency group]
\begin{scope}[blend mode = multiply]
\foreach \i in {0,...,\num}{
\message{\i,}
\foreach \j in {0,...,\val}{
\foreach \x/\y in {0/0, \scale/0, 0/\scale, 0/2*\scale, \scale/2*\scale}{
\drawsquare{3*\j+\i+\x}{-\j+3*\i+\y}{red}
}
\foreach \x/\y in {0/0, -\scale/0, 0/-\scale, 0/-2*\scale, -\scale/-2*\scale}{
\drawsquare{3*\j+\i+2+\x}{-\j+3*\i+1+\y}{blue}
}
}
}
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}
计算时间很大程度上取决于\limit
值,但对于较小的值,例如limit=10
和num=50
,在我的计算机上计算时间少于 30 秒。(我保留了\message{\i,}
用于评估这次的。)