12

I would like to define a node style, so that the node will look like the LaTeX symbol \oplus, i.e. a circle with lines from north to south, and east to west. (I also have more complicated examples in mind.)

I think that I should draw the lines in the execute at end node, or after mode path arguments, but nothing I have tried seems to work. The code I have in mind is something like this:

\tikzstyle{foo}=[circle,draw,execute at end node={\draw ??????}]

To rephrase the question: How can one do arbitrary drawing within a node, and define this as a style? In particular, how do you get the coordinates of the current node in a style?

1
  • 1
    a tip: you can use backticks ` to mark your inline code as I did in my edit. Feb 17, 2011 at 11:07

2 Answers 2

12

All TikZ node shapes are defined using lower-level PGF code. This is described in the pgfmanual in section 75.5 Declaring New Shapes, on page 625 of the v2.1 manual.

You can use the existing code of the circle shape as a base and add the lines to it. The code can be found in the file ${TEXMF}/tex/generic/pgf/modules/pgfmoduleshapes.code.tex.

Here the way I would do it:

Shape declaration:

\pgfdeclareshape{oplus}
%
% Shaped like '\oplus' math symbol. Based on 'circle' shape
%
{%
  % All anchors are taken from the 'circle' shape:
  \inheritsavedanchors[from={circle}]%
  \inheritanchor[from={circle}]{center}%
  \inheritanchor[from={circle}]{mid}%
  \inheritanchor[from={circle}]{base}%
  \inheritanchor[from={circle}]{north}%
  \inheritanchor[from={circle}]{south}%
  \inheritanchor[from={circle}]{west}%
  \inheritanchor[from={circle}]{east}%
  \inheritanchor[from={circle}]{mid west}%
  \inheritanchor[from={circle}]{mid east}%
  \inheritanchor[from={circle}]{base west}%
  \inheritanchor[from={circle}]{base east}%
  \inheritanchor[from={circle}]{north west}%
  \inheritanchor[from={circle}]{south west}%
  \inheritanchor[from={circle}]{north east}%
  \inheritanchor[from={circle}]{south east}%
  \inheritanchorborder[from={circle}]%
  %
  % Only the background path is different
  %
  \backgroundpath{%
    % First the existing 'circle' code:
    \pgfutil@tempdima=\radius%
    \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
    \ifdim\pgf@xb<\pgf@yb%
      \advance\pgfutil@tempdima by-\pgf@yb%
    \else%
      \advance\pgfutil@tempdima by-\pgf@xb%
    \fi%
    \pgfpathcircle{\centerpoint}{\pgfutil@tempdima}%
    %
    % Now the | and -- lines:
    \pgfmoveto{\pgfpointadd{\centerpoint}{\pgfpoint{0pt}{\pgfutil@tempdima}}}%
    \pgflineto{\pgfpointadd{\centerpoint}{\pgfpoint{0pt}{-\pgfutil@tempdima}}}%
    \pgfmoveto{\pgfpointadd{\centerpoint}{\pgfpoint{\pgfutil@tempdima}{0pt}}}%
    \pgflineto{\pgfpointadd{\centerpoint}{\pgfpoint{-\pgfutil@tempdima}{0pt}}}%
  }%
}

Usage example:

\documentclass{standalone}

\usepackage{tikz}
\usepackage{pgfshape_oplus}

\begin{document}
\begin{tikzpicture}
  \node [draw=blue,shape=oplus] {Test};
\end{tikzpicture}
\end{document}

Result:

Result

You might also want to draw the additional lines in the \foregroundpath instead. For this see the forbidden sign shape in the file pgflibraryshapes.symbols.code.tex is an good example.

11
  • very good answer: the right method, the right code. But note the forbidden sign shape is backwards! Feb 17, 2011 at 13:05
  • @Matthew: You mean the line is drawn in the wrong angle, do you? That's something which should be reported to the PGF/TikZ author. Nevertheless the code of it is a good example for having a circle as background path and the other lines in the foreground. Feb 17, 2011 at 13:29
  • Yes, that's what I meant. I did report it to the mailing list a while back (google tells me it was Feb 2009). Maybe I should follow up on that since it's just a one-line patch—unless now you want it to be an option to have it backwards! Feb 17, 2011 at 13:35
  • @Matthew: Yeah, backwards compatibility (wow what a pun! :-) ) is always an issue even with smaller stuff like this. Feb 17, 2011 at 13:48
  • @Martin: Tell me about it. The new pgfmath engine has introduced bugs in lots of the graphs that I use for teaching. :-( Feb 17, 2011 at 14:17
7

A possibility :

 \begin{tikzpicture}
   \tikzset{oplus/.style={path picture={% 
      \draw[black]
       (path picture bounding box.south) -- (path picture bounding box.north) 
       (path picture bounding box.west) -- (path picture bounding box.east);
      }}} 
    \node[oplus,fill=blue!10,draw=blue,thick,circle] {};
    \end{tikzpicture}

oplus

It's possible to send the cross in the background and to change the color

\begin{tikzpicture}
 \tikzset{oplus/.style={path picture={%
 \begin{pgfonlayer}{background} 
 \draw[red,opacity=.5]
  (path picture bounding box.south) -- (path picture bounding box.north) 
  (path picture bounding box.west) -- (path picture bounding box.east);
\end{pgfonlayer}}}
}
\node[oplus,draw=blue,thick,circle](a) {TEST}; 
\end{tikzpicture}

oplus 2

Now your code execute at end node is not good in this case. This code modifies the content of the node. You can try the next code :

 \begin{tikzpicture}
    \tikzset{foo/.style ={circle,draw, execute at end node={\ #1}}} 
    \node[foo=bad](A) at (2,3){good};
 \end{tikzpicture}

Interesting is execute at begin node=$ and execute at end node=$

Now if my answer is not what you want, you can define new shape like shape =oplus like in the other answer from Martin.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .