纯净版

纯净版

在我的插图中,我需要一个时钟的草图。为此,我使用了 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一切正常,但nodes 则不然。

风格上\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,并重命名了一些键,以明确哪些键用于节点,并明确其他键(以前是XJ)的功能。虽然设置时钟小时的方式遵循 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}

在此处输入图片描述

相关内容