將 TikZ Pics (\pic) 命名為節點

將 TikZ Pics (\pic) 命名為節點

我對 tikz 圖片感到困惑。我可以毫無問題地自由定義它們,甚至可以在其中添加坐標,這些坐標可以通過名稱繼承來使用,(-A)例如\pic (S) at (0,0) {myPic}; \draw (S-A) -- ++(0,0);.這一切都記錄在 p 左右。 pgf 手冊第 255 節。

但是我不明白為什麼如果內部沒有定義座標,就不可能為上面的圖片命名。預設情況下,如果它能夠像普通節點一樣運行,那就太好了。

微量元素:

\documentclass{minimal}
\usepackage{tikz}

\tikzset{
    myBlock/.pic = {
        \node[draw,minimum width=1cm,minimum height=0.5cm] at (0,0) {};
    },
    myBlockNamed/.pic = {
        \node[draw,minimum height=1cm,minimum width=0.5cm] (-m) at (0,0) {};
    },
}

\begin{document}
\begin{tikzpicture}
    \pic () at (0,0) {myBock}; % can't give it a name
    \pic (S) at (3,0) {myBlockNamed}; % can give it a name
    \draw (S-A) -- ++(2,0);
\end{tikzpicture}
\end{document}

根本點是我正在開發一個控制塊庫(這樣我們就可以停止下面與@Alenanno 的聊天)。例如,這是數學運算子的定義

\tikzset{
    mySum background/.style = {
        circle, minimum size=1.5em, fill=white,
    },
    mySum edge/.style = {
        draw=black, circle, minimum size=1.5em, line width=.5pt,
    },
    pics/bOp/.style = {
    code = {
      \node [mySum background] {};
      \foreach \t [count=\i] in {#1}{
        \pgfmathsetmacro{\angle}{\i*90}
        \node[anchor=center, font=\tiny] at (\angle:0.45em) {$\t$};
      }
      \node [mySum edge] {};
    },
  },
}

答案1

在某些情況下可以使用一個技巧,它利用了將 apic放入scope可以用local bounding box金鑰命名的 a 中的事實。請注意,這不適用於樹或圖表。

\documentclass[tikz,border=5]{standalone}
\tikzset{pics/.cd,
  pic a/.style={code={
      \node [fill=red!20, shape=circle] {A};
  }}
}

\begin{document}
\begin{tikzpicture}
\pic [local bounding box=A1] at (0,0) {pic a};
\pic [local bounding box=A2] at (3,0) {pic a};
\foreach \i in {0,15,...,345}{
  \draw [red, ->] (\i:1) -- (A1);
  \draw [blue, ->] (3,0)++(\i:1) -- (A2);
}
\end{tikzpicture}
\end{document}

在此輸入影像描述

也可以pic透過定義一個「包裝器」鍵來使用給定的名稱,該鍵明確地將範圍新增至程式碼:

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{fit}%
\makeatletter
\tikzset{pics/named scope code/.style={code={\tikz@fig@mustbenamed%
  \begin{scope}[local bounding box/.expanded=\tikz@fig@name]#1\end{scope}%
}}}
\makeatother

\tikzset{pics/.cd,
  pic a/.style={named scope code={
      \node [fill=red!20, shape=circle] {A};
  }}
}

\begin{document}
\begin{tikzpicture}
\pic (A1) at (0,0) {pic a};
\pic (A2) at (3,0) {pic a};
\foreach \i in {0,15,...,345}{
  \draw [red, ->] (\i:1) -- (A1);
  \draw [blue, ->] (3,0)++(\i:1) -- (A2);
}
\end{tikzpicture}
\end{document}

結果和以前一樣。

答案2

來自Pgf手冊(版本3.0.0),第 252 頁:

  1. 與節點不同,圖片不能在以後被引用。您可以引用圖片內的節點,但不能引用「圖片本身」。特別是,您不能像在節點之間繪製線條那樣在圖片之間繪製線條。一般來說,只要認為某些繪圖可以連接到其他類似節點的事物是有意義的,那麼節點就比圖片更好。

  2. 如果使用圖片來模擬節點的全部功能(原則上這是可能的),那麼它們的建構速度會比達到相同效果的節點慢,並且會佔用更多的記憶體。

因此,如果您正在做節點做得很好的事情,並且沒有特殊原因使用pic,那麼您最好使用節點。問題的答案中有一個解決方法“如何為 \pic 命名”,但這正是一個解決方法。

但是,如果您希望能夠將節點放置在另一個節點周圍,您可以檢查我不久前問過的這個問題(如何在 TiKZ 中將節點定位在另一個節點周圍?)或者您將 Tikz foreach 與常規節點一起使用。

更新的答案

現在我知道您需要什麼,這是 Tikz 的解決方案。 new指令\mySumn(您可以重新命名它)採用兩個參數,例如\mySumn{#1}{#2},其中#1是節點的名稱,#2是位置。

我嘗試使用添加可選參數above of但沒有成功。但是,您可以使用此程式碼以不同的方式執行相同的操作。考慮以下:

\mySumn{p1}{0,0};
\mySumn{p2}{$(p1.north east)+(1em,1em)$};

它將p1在座標處放置一個節點(0,0),然後將另一個節點放置p2在 x 軸和 y 軸上 p1 的東北 +1em 處(右側對角線上方)。

當然,您仍然可以從一個節點到另一個節點繪製邊。

輸出

圖1

程式碼

\documentclass[margin=10pt]{standalone}
\usepackage{tikz}
\usepackage{xparse}

\usetikzlibrary{calc,arrows.meta,positioning}

\tikzset{
    mySumbk/.style = {
        draw, circle, minimum size=1.5em, fill=white,
    },
}

\newcommand{\mySumn}[2]{
    \node[mySumbk,fill=white] (#1) at (#2) {};
        \foreach \angle/\maop in {
        90/+,
        180/-
        }{
   \node[anchor=center, font=\tiny] at ($(#1)+(\angle:.45em)$) {$\maop$};
}}

\begin{document}
\begin{tikzpicture}[>=latex]

\mySumn{p1}{0,0};
\mySumn{p2}{$(p1.north east)+(1em,1em)$};

\draw (p1) -- (3,0);
\draw (p1) edge[out=90,in=180] (p2);
\end{tikzpicture}
\end{document}

答案3

老問題,但我對解決方案不滿意,local bounding box因為我找不到更好的方法來控制它(例如,到內部內容的距離)。

我的解決方案是在 , 中使用嵌套圖片pic以及remember picture選項。這些名稱作為參數以級聯方式傳遞。這樣,您不僅可以將 引用pic為節點(因為實際上它是一個節點),還可以引用其內容。

另一點是,使用此解決方案, a 的內容pic始終是集中的,這也是我在處理此程式碼時一直在尋找的。

意識到:

  • 你必須編譯該文檔兩次,因為remember picture.
  • 由於繼承,嵌套節點可能會很棘手。

在此輸入影像描述

這是代碼:

\documentclass[tikz]{standalone}

\usetikzlibrary{positioning}

\begin{document}
\begin{tikzpicture}[remember picture]
  \tikzset{
    mine/.pic={
      \node[draw](#1){
        \begin{tikzpicture}[remember picture]
          \node[draw](#1-1){#1-1};          
          \node[draw, right=of #1-1](#1-2){#1-2};
        \end{tikzpicture}
      };
    },
  }

  \pic{mine=a};
  \pic[right=of a]{mine=b};

  \draw[thick, blue, <->](a-1)to[out=90, in=90](b-1);
  \draw[thick, blue, <->](a-2)to[out=-90, in=-90](b-2);
  \draw[thick, red](a)to(b);
\end{tikzpicture}
\end{document}

答案4

看來,如果我為我的操作員定義一個命令:

\tikzset{
    mySum background/.style = {
        circle, minimum size=1.5em, fill=white,
    },
    mySum edge/.style = {
        draw=black, circle, minimum size=1.5em, line width=.5pt,
    },
}
\newcommand{\bOp}[1]{
  \tikz[outer sep=0pt]{
    \node [mySum background] {};
    \foreach \t [count=\i] in {#1}{
      \pgfmathsetmacro{\angle}{\i*90}
      \node[anchor=center, font=\tiny] at (\angle:0.45em) {$\t$};
    }
    \node [mySum edge] {};
  }
}

然後可以建立一個包含假圖片的節點,因為上面的內容正是人們用來定義圖片的內容。

\node (1) at (0,0) {\bOp{+,-,,}};
\draw (4,0) -- (1);

相關內容