TikZ Pics (\pic) をノードのように命名する

TikZ Pics (\pic) をノードのように命名する

tikz pics について混乱しています。問題なく自由に定義でき、たとえば のように名前の継承で使用できる座標を内部に追加することもできます(-A)\pic (S) at (0,0) {myPic}; \draw (S-A) -- ++(0,0);これはすべて、pgf マ​​ニュアルの 255 ページあたりに記載されています。

しかし、座標が定義されていない場合、上記のような画像に名前を付けることができないのはなぜか理解できません。デフォルトでは、通常のノードのように動作できれば素晴らしいと思います。

MWE:

\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

状況によっては、キーで名前を付けることができるpica の中に a が配置されるという事実を利用するトリックが使用できます。ただし、これはツリーやグラフでは機能しないことに注意してください。scopelocal bounding box

\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. ノードとは異なり、pic は後で参照できません。pic 内のノードは参照できますが、「pic 自体」は参照できません。特に、ノード間で線を引くのと同じように、pic 間に線を引くことはできません。一般に、何らかの描画が他のノードのようなものと接続される可能性がある場合は、pic よりもノードの方が適しています。

  2. ノードの全機能をエミュレートするために pics が使用される場合 (原理的には可能です)、同じ効果を実現するノードよりも構築に時間がかかり、多くのメモリを消費します。

したがって、ノードが得意とする処理を行っていて、 を使用する特別な理由がない場合はpic、ノードを使用する方がよいでしょう。質問の回答に回避策があります。\picに名前を付ける方法「」ですが、それはまさに回避策です。

ただし、ノードを別のノードの周りに配置できるようにしたい場合は、以前私が尋ねたこの質問を確認してください(TiKZ で別のノードの周囲にノードを配置するにはどうすればよいですか?) または、通常のノードで Tikz foreach を使用します。

更新された回答

必要なものがわかったので、Tikz を使用したソリューションを示します。新しいコマンド\mySumn(名前を変更できます) は、 などの 2 つの引数を取ります。\mySumn{#1}{#2}ここで、#1はノードの名前、 は#2位置です。

を使用してオプションの引数を追加しようとしましたabove ofが、成功しませんでした。ただし、このコードを使用して、別の方法で同じことを行うことができます。次のことを考慮してください。

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

p1座標にノードを配置し、次にx 軸と y 軸上の p1 の北東 +1em (右上の斜め上) に(0,0)別のノードを配置します。p2

もちろん、あるノードから別のノードにエッジを描くこともできます。

出力

図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ノードとして参照できるだけでなく (実際にはノードであるため)、その内容も参照できます。

もう 1 つのポイントは、このソリューションでは、コンテンツがpic常に集中管理されることです。これは、このコードで作業しているときに私が求めていたことでもありました。

注意してください:

  • のため、ドキュメントを 2 回コンパイルする必要があります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] {};
  }
}

上記の内容はまさに pic を定義するために使用するものであるため、偽の pic を含むノードを作成することが可能です。

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

関連情報