在我的插图中,我需要一个时钟的草图。为此,我使用了 TikZ 的图片功能。它运行良好,但有一个恼人的例外:图片中的时钟定位。如果我把时钟放在某个绝对坐标上,那么图片就会如预期的那样,但如果我把它放在相对坐标上,例如从某个坐标的左边,时钟就会搞砸。似乎在图片中,内部锚点声明错误。到目前为止,还没有弄清楚如何以正确的方式做到这一点。
我搜索了 SE,看是否有人遇到类似的问题。最接近的是锚定-tikz-图片,但那里的建议对我没有太大帮助(可能我没有完全理解它们)。
我的尝试是(不完全是)下面的 MWE:
\documentclass[12pt,tikz,border=3mm]{standalone}
\usetikzlibrary{arrows.meta,%
positioning,%
shapes
}
\begin{document}
\begin{tikzpicture}[
J/.style = {thick, bend left, shorten >=1mm, shorten <=1mm, -{Straight Barb[]}},
pics/ura/.style n args
= {3}{code={\node[name=ura,
circle, minimum width=21mm,fill=gray!50] {};
\foreach \i in {north,south,east,west,
north west,north east,south west,south east}
\coordinate (-\i) at (ura.\i);
%
\node[circle,draw=gray,thick, fill=#1!5, %%%%%%%%%
minimum width=20mm,inner sep=0pt,node contents={}];
\node[font=\tiny,
below=1mm of ura.center] {tik-tak};
\foreach \a/\label in {0/3, 30/2, 60/1,
90/12, 120/11, 150/10,
180/9, 210/8, 240/7,
270/6, 300/5, 330/4}
{\draw[very thick] (\a:8.2mm) -- (\a:9.9mm);
\draw (\a:7mm) node[font=\tiny] {\label};
}
\foreach \s in {1,2,...,60}\draw (6*\s:9mm) -- (6*\s:9.8mm);
\draw[line width=0.8mm,red,shorten <=-2mm,
{Round Cap[]-Kite[length=12pt,width=6pt,inset=5pt]}]
(ura.center) -- (#2,6mm); %%%%%%%%%hour
\begin{scope}[red,thick,opacity=0.6,
transparency group,{-Kite[]}]
\draw (#3-180:3mm) -- (ura.center) -- (#3:8mm); %%%%%%%% minute
\end{scope}
\node[circle,draw=red!80!black,
inner color=white,outer color=red!50,
inner sep=2pt] at (ura.center) {};
}
},
X/.style = {above=0mm of #1-north,
font=\footnotesize\sffamily\bfseries}
]
%-------
\pic (A) at (0, 0) {ura={teal}{0}{150}};\node[X=A] {ura A};
\pic (B) at (4, 0) {ura={yellow}{0}{120}};\node[X=B] {ura B};
\pic[below=2mm of A-south] (C) {ura={yellow}{0}{120}};\node[X=C] {ura C};
%-------
\draw[J] (A-east) to node[above,sloped] {11:50} (B-west);
\draw[J] (B-west) to node[below,sloped] {11:55} (A-east);
%----------------
\end{tikzpicture}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}
从下图可以看出,时钟(ura C)被分成三部分,基圆位于右侧位置(给定坐标的下方),其他组件的一部分以它为中心,另一部分位于两者之间。
答案1
这是一个可行的示例。我对其进行了重新格式化,并添加了一些样式,以帮助明确哪些操作是有效的。
\documentclass[12pt,tikz,border=3mm]{standalone}
\usetikzlibrary{arrows.meta,%
positioning,%
shapes,calc%%
}
\tikzset{%%
ura hub/.style={circle,
anchor=center,
draw=red!80!black,
inner color=white,
outer color=red!50,
inner sep=2pt},
ura hour hand/.style={line width=0.8mm,
red,
shorten <=-2mm,
{Round Cap[]-Kite[length=12pt,width=6pt,inset=5pt]},
},
ura minute hand/.style={red,
thick,
opacity=0.6,
transparency group,
{-Kite[]}},
ura matt/.style={circle,
draw=gray,
thick,
fill=#1!5,
minimum width=20mm,
inner sep=0pt,
anchor=center,
},
ura body/.style={circle,
minimum width=21mm,
fill=gray!50}
}
\begin{document}
\begin{tikzpicture}[
J/.style = {thick, bend left, shorten >=1mm, shorten <=1mm, -{Straight Barb[]}},
pics/ura/.style n args={3}{
code={\node[ura body] (ura) at (0,0) {};
\foreach \i in
{north,south,east,west,north west,north east,south west,south east}
{\coordinate (-\i) at (ura.\i);}
%%
\node[ura matt=#1] at (ura.center) {};
\node[font=\tiny,below=1mm of ura.center] {tik-tak};
%% minutes and hours on clock
\foreach \a/\label in
{0/3, 30/2, 60/1,
90/12, 120/11, 150/10,
180/9, 210/8, 240/7,
270/6, 300/5, 330/4}
{
\draw[very thick] ($(ura.center)+(\a:8.2mm)$) --
($(ura.center)+(\a:9.9mm)$);
\node[inner sep=0pt,anchor=center,font=\tiny] (N/\a) at ($(ura.center)+(\a:7mm)$) {\tiny\label};
%\draw ($(ura.center)+(\a:7mm)$) circle (1pt);
%\draw (N/\a) -- (ura.center);
}
%% minute tick marks
\foreach \s in {1,2,...,60}
{
\draw ($(ura.center)+(6*\s:9mm)$) -- ($(ura.center)+(6*\s:9.8mm)$);
}
\draw[ura hour hand] (ura.center) -- ($(ura.center)+(#2,6mm)$);
\draw[ura minute hand] ($(ura.center)+(#3-180:3mm)$) -- (ura.center) -- ($(ura.center)+(#3:8mm)$);
\node[ura hub] at (ura.center) {};
}
},
X/.style={above=0mm of #1-north,font=\footnotesize\sffamily\bfseries}
]
%-------
\pic (A) at (0, 0) {ura={teal}{0}{150}};
\node[X=A] {ura A};
\pic (B) at (4, 0) {ura={yellow}{0}{120}};
\node[X=B] {ura B};
\node[below=2mm of A-south] (myC) {};
\pic[anchor=north] (C) at (myC) {ura={yellow}{0}{120}};
\node[X=C] {ura C};
%-------
\draw[J] (A-east) to node[above,sloped] {11:50} (B-west);
\draw[J] (B-west) to node[below,sloped] {11:55} (A-east);
%----------------
\end{tikzpicture}
\end{document}
问题似乎是pic
问题似乎是获取走私进入您正在使用的节点的选项。因此,在每个节点中,我都指定锚点为anchor=center
。
我已经离开了
%\draw ($(ura.center)+(\a:7mm)$) circle (1pt);
%\draw (N/\a) -- (ura.center);
在那里你可以玩。anchor=center
从节点的选项中删除,这将显示\draw
一切正常,但node
s 则不然。
风格上\draw
我认为使用\node
当你正在做绘画。例如,对于双手的中心,不要写成
\node[ura hub] at (ura.center) {};
写得更有意义
\draw[ura hub] (ura.center) circle (2.5pt);
在这种情况下,我重新定义了钥匙“ura hub” 为:
ura hub/.style={red,
line width=1pt,
inner color=white,
outer color=red!50,
},
纯净版
这是我上面建议的关于如何使用\draw
和 的简洁版本\node
。此外,我删除了对 TikZ 库 的依赖calc
,并重命名了一些键,以明确哪些键用于节点,并明确其他键(以前是X
和J
)的功能。虽然设置时钟小时的方式遵循 TikZ 手册中的示例,但我以一种我认为更容易理解的方式重写了它。
\documentclass[12pt,tikz,border=3mm]{standalone}
\usetikzlibrary{arrows.meta,%
positioning,%
shapes,
}
\tikzset{%%
ura body for node/.style={circle,
minimum width=21mm,
fill=gray!50},
ura matt/.style={draw=gray,
thick,
fill=#1!5,
},
ura hour hand/.style={line width=0.8mm,
red,
shorten <=-2mm,
{Round Cap[]-Kite[length=12pt,width=6pt,inset=5pt]},
},
ura minute hand/.style={red,
thick,
opacity=0.6,
transparency group,
{-Kite[]}},
ura hours for node/.style={inner sep=0pt,anchor=center,font=\tiny,node contents=#1},
ura hub/.style={red,
line width=1pt,
inner color=white,
outer color=red!50,
},
}
\begin{document}
\begin{tikzpicture}[
arrow path between clocks/.style = {thick, bend left, shorten >=1mm, shorten <=1mm, -{Straight Barb[]}},
pics/ura/.style n args={3}{
code={\node[ura body for node] (ura) at (0,0) {};
\foreach \i in
{north,south,east,west,north west,north east,south west,south east}
{\coordinate (-\i) at (ura.\i);}
%%
\draw[ura matt=#1] (ura.center) circle (10mm);
\node[font=\tiny,below=1mm of ura.center] {tik-tak};
%% minutes and hours on clock
%% major tick marks
\foreach \myhour in {1,...,12}
{
\pgfmathsetmacro\myangle{int(90-\myhour*30)}
%% tick mark for hour
\draw[very thick] (ura.center) ++(\myangle:8.2mm) -- ++(\myangle:1.7mm);
%% place numbers for the hours
\path (ura.center) ++ (\myangle:7mm) node[ura hours for node=\myhour];
}
%% minor tick marks
\foreach \mysecond in {1,2,...,60}
{
\pgfmathsetmacro\myangle{int(6*\mysecond)}
%% tick marks for seconds
\draw (ura.center) ++ (\myangle:9mm) -- ++ (\myangle:0.8mm);
}
\draw[ura hour hand] (ura.center) -- ++(#2,6mm);
\draw[ura minute hand] (ura.center) ++ (#3-180:3mm) -- ++ (#3:11mm);
\draw[ura hub] (ura.center) circle (2.5pt);
}
},
position clock title at/.style={above=0mm of #1-north,font=\footnotesize\sffamily\bfseries}
]
%% the clocks:
%% clock A
\pic (A) at (0, 0) {ura={teal}{0}{150}};
\node[position clock title at=A] {ura A};
%% clock B
\pic (B) at (4, 0) {ura={yellow}{0}{120}};
\node[position clock title at=B] {ura B};
%% clock C
\node[below=4mm of A-south] (myC) {};
\pic[anchor=north] (C) at (myC) {ura={yellow}{0}{120}};
\node[position clock title at=C] {ura C};
%% Mapping between clocks
\draw[arrow path between clocks] (A-east) to node[above,sloped] {11:50} (B-west);
\draw[arrow path between clocks] (B-west) to node[below,sloped] {11:55} (A-east);
\end{tikzpicture}
\end{document}
最后一个例子
在最后一个示例中,您可以以更人性化的形式向时钟传递时间(而不必考虑角度和度数)。我还调整了时针以进行持续地根据小时和分钟全天候运行(就像真正的模拟时钟一样)。
\documentclass[12pt,tikz,border=3mm]{standalone}
\usetikzlibrary{arrows.meta,%
positioning,%
shapes,
}
\tikzset{%%
ura body for node/.style={circle,
minimum width=21mm,
fill=gray!50},
ura matt/.style={draw=gray,
thick,
fill=#1!5,
},
ura hour hand/.style={line width=0.8mm,
red,
shorten <=-2mm,
{Round Cap[]-Kite[length=12pt,width=6pt,inset=5pt]},
},
ura minute hand/.style={red,
thick,
opacity=0.6,
transparency group,
{-Kite[]}},
ura hours for node/.style={inner sep=0pt,anchor=center,font=\tiny,node contents=#1},
ura hub/.style={red,
line width=1pt,
inner color=white,
outer color=red!50,
},
}
\makeatletter
\def\ae@parse@hour@minutes#1:#2;{%%
\pgfmathsetmacro\my@hour{int(90-#1*30)-30/60*#2}%%
\pgfmathsetmacro\my@minu{int(90-#2*6)}}
\newcommand\aeUraCode[2]{%%
\ae@parse@hour@minutes#2;
\node[ura body for node] (ura) at (0,0) {};
\foreach \i in
{north,south,east,west,north west,north east,south west,south east}
{\coordinate (-\i) at (ura.\i);}
%%
\draw[ura matt=#1] (ura.center) circle (10mm);
\node[font=\tiny,below=1mm of ura.center] {tik-tak};
%% minutes and hours on clock
%% major tick marks
\foreach \myhour in {1,...,12}
{
\pgfmathsetmacro\myangle{int(90-\myhour*30)}
%% tick mark for hour
\draw[very thick] (ura.center) ++(\myangle:8.2mm) -- ++(\myangle:1.7mm);
%% place numbers for the hours
\path (ura.center) ++ (\myangle:7mm) node[ura hours for node=\myhour];
}
%% minor tick marks
\foreach \mysecond in {1,2,...,60}
{
\pgfmathsetmacro\myangle{int(6*\mysecond)}
%% tick marks for seconds
\draw (ura.center) ++ (\myangle:9mm) -- ++ (\myangle:0.8mm);
}
\draw[ura hour hand] (ura.center) -- ++(\my@hour:6mm);
\draw[ura minute hand] (ura.center) ++ (\my@minu-180:3mm) -- ++ (\my@minu:11mm);
\draw[ura hub] (ura.center) circle (2.5pt);
}
\makeatother
\begin{document}
\begin{tikzpicture}[
arrow path between clocks/.style = {thick, bend left, shorten >=1mm, shorten <=1mm, -{Straight Barb[]}},
pics/ura/.style n args={2}{code={\aeUraCode{#1}{#2}}},
position clock title at/.style={above=0mm of #1-north,font=\footnotesize\sffamily\bfseries}
]
%% the clocks:
%% clock A
\pic (A) at (0, 0) {ura={teal}{11:50}};
\node[position clock title at=A] {ura A};
%% clock B
\pic (B) at (4, 0) {ura={yellow}{11:55}};
\node[position clock title at=B] {ura B};
%% clock C
\node[below=4mm of A-south] (myC) {};
\pic[anchor=north] (C) at (myC) {ura={yellow}{12:45}};
\node[position clock title at=C] {ura C};
%% clock D
\node[below=4mm of B-south] (myD) {};
\pic[anchor=north] (D) at (myD) {ura={blue}{3:24}};
\node[position clock title at=D] {ura D};
%% Mapping between clocks
\draw[arrow path between clocks] (A-east) to node[above,sloped] {11:50} (B-west);
\draw[arrow path between clocks] (B-west) to node[below,sloped] {11:55} (A-east);
\end{tikzpicture}
\end{document}