我正在尝试绘制一个旋转对称的形状,而不必写出重复的点。这样,我可以改变一个点,整个形状就会改变。然而,发生了一些非常错误的事情,看看四尖图形上的点的尖端。它们不应该看起来像那样,它们应该看起来像右边手动创建的那个。
这个问题似乎是由于线条粗细完全在指定点的外部造成的。这意味着当它们通过 xscale=-1 翻转时,它们无法正确居中。我该如何解决这个问题?也许有完全不同的方法可以完成我正在尝试做的事情?您可以看到第一个绘图的代码比第二个短得多,而第二个绘图的代码仅为其完整代码的四分之一,仅用于此示例。
\documentclass[crop, border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows,automata,positioning,calc}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\getlinecolor}{m}{
\int_compare:nNnTF {#1} = {1} {black}{}
\int_compare:nNnTF {#1} = {2} {white}{}
\int_compare:nNnTF {#1} = {3} {black}{}
}
\NewExpandableDocumentCommand{\getlinethickness}{m}{
\int_compare:nNnTF {#1} = {1} {1.5pt}{}
\int_compare:nNnTF {#1} = {2} {0.5pt}{}
\int_compare:nNnTF {#1} = {3} {0.1pt}{}
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}
\foreach \c in {1, 2, 3}{%draw first with a black thick line, draw next with a medium white line, draw again with a black thin line
\foreach \k in {-1, 1}{%draw the actual and mirror of the shape
\foreach \i in {0, 90, 180, 270}{%draw the shape radially four times
\draw[xscale=\k,rotate=\i,line width=\getlinethickness{\c},color=\getlinecolor{\c},fill=black,anchor=center]
(0,1) --
(0.2,0.4) --
(0.2,0) --
(0,0) --
cycle;
}}}%
\draw[color=red, line width=0.05pt] (0,-1.2) -- (0,1.2);
\draw[color=red, line width=0.05pt] (-1.2,0) -- (1.2,0);
\draw[color=blue, line width=0.05pt] (-1.2,1) -- (1.2,1);
\end{tikzpicture}
\vspace{0.25in}
\begin{tikzpicture}
%draw the black outline
\draw[line width=\getlinethickness{1},color=\getlinecolor{1},fill=black,anchor=center]
(0,1) --
(0.2,0.4) --
(0.2,0) --
(0,0) --
(-0.2,0) --
(-0.2,0.4) --
(0,1) --
cycle;
%draw a white hairline
\draw[line width=\getlinethickness{2},color=\getlinecolor{2},fill=black,anchor=center]
(0,1) --
(0.2,0.4) --
(0.2,0) --
(0,0) --
(-0.2,0) --
(-0.2,0.4) --
(0,1) --
cycle;
%used to cover up middle seams
\draw[line width=\getlinethickness{3},color=\getlinecolor{3},fill=black,anchor=center]
(0,1) --
(0.2,0.4) --
(0.2,0) --
(0,0) --
(-0.2,0) --
(-0.2,0.4) --
(0,1) --
cycle;
\draw[color=red, line width=0.05pt] (0,-1.2) -- (0,1.2);
\draw[color=red, line width=0.05pt] (-1.2,0) -- (1.2,0);
\draw[color=blue, line width=0.05pt] (-1.2,1) -- (1.2,1);
\end{tikzpicture}
\end{document}
此外,独立版 tikz 裁剪效果不佳,因此我不得不指定手动边框。如果没有它,形状的尖端将被剪掉。如果有人知道解决方案,那就太好了。
答案1
我的spath3
TikZ 库可能对你有用。它允许你操纵路径,包括转换它们并重新连接它们。
以下是我对形状进行编码的方法,从基本路径开始。
\documentclass{article}
%\url{https://tex.stackexchange.com/q/582869/86}
\usepackage{tikz}
\usetikzlibrary{spath3}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\getlinecolor}{m}{
\clist_item:nn {black, white, black} {#1}
}
\NewExpandableDocumentCommand{\getlinethickness}{m}{
\clist_item:nn {1.5pt, 0.5pt, 0.1pt} {#1}
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}
% Save the basic shape
\path[spath/save=path] (.2,.2) -- (.2,.4) -- (0,1);
\tikzset{
% Clone it for the next piece
spath/clone={reflected path}{path},
% Reflect it in the y-axis
spath/transform={reflected path}{xscale=-1},
% Reverse the reflected path
spath/reverse={reflected path},
% Join it to the original path
spath/join with={path}{reflected path},
% Clone the combined path for rotating
spath/clone={path 90}{path},
% Rotate the new clone
spath/transform={path 90}{rotate=90},
% Join it to the original path
spath/join with={path}{path 90},
% Clone the newly combined path
spath/clone={path 180}{path},
% Rotate it 180
spath/transform={path 180}{rotate=180},
% Join it to the original path
spath/join with={path}{path 180},
% Weld all the components together so that they join nicely
spath/spot weld={path},
% Close the path
spath/close={path}
}
\foreach \c in {1, 2, 3}{
\draw[
line width=\getlinethickness{\c},
color=\getlinecolor{\c},
fill=black,
spath/restore=path
];
}
\end{tikzpicture}
\end{document}
我添加了关于每个键的作用的注释。您可以查看文档以了解更多详细信息(尽管我似乎忘记记录键join with
- 它只是将一个路径放在另一个路径后面)。
生成的结果如下:
我还稍微改变了您的\getlinewidth
和颜色宏,以在内部使用逗号分隔的列表,这可能使其更易于维护。
问题standalone
是大概因为尖角突出的距离比边界框计算的距离要远。当它添加路径来计算边界框时,TikZ/PGF 会考虑当前线宽并添加一些额外的线宽,但这对于尖角来说还不够(因为这些尖角可能会突出到任意远)。您可以相当自动地在 tikzpicture 末尾的边界框中添加一点,或者只需border
像在原始代码中一样添加到选项中。
答案2
也许有完全不同的方法可以实现我想要做的事情?
当你在等待 TikZ 团队的时候,这里有一些完全不同的东西。如果你愿意尝试,lualatex
你可以使用元帖子而是。这是制作通过反射和旋转创建的形状的一种方法。您需要使用 编译此示例lualatex
。
\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);
path unit, cross;
unit = ((1,0) -- (0.4, 0.2) -- (0.2, 0.2)) scaled 42;
cross = for i = 0 upto 3:
unit rotated 90i &
reverse unit reflectedabout (origin, point infinity of unit) rotated 90i &
endfor cycle;
% linejoin := mitered;
filldraw cross withpen pencircle scaled 1.8;
draw cross withcolor white;
path axis;
axis = (left--right) scaled 50;
draw axis withpen pencircle scaled 1/4 withcolor 3/4 red;
draw axis rotated 90 withpen pencircle scaled 1/4 withcolor 3/4 red;
draw axis shifted 42 up withpen pencircle scaled 1/4 withcolor 3/4 blue;
endfig;
\end{mplibcode}
\end{document}
笔记
MP 中的运算符用于连接事物。在这里我使用它从旋转和反射的路径
&
构造路径。cross
unit
在 MP 中,你可以将循环“排成一行”——Scala 等语言也可以这样做
我使用的唯一技巧是用
filldraw
一支大而粗的笔描绘形状,然后用默认笔用白色再次绘制它以创建内部边框。如果您喜欢末端尖锐而不是圆形,请取消注释
linejoin := mitered
。