3

Consider the following code:

\documentclass[border=2mm]{standalone}

\usepackage{tikz}

\usepackage{xcolor}

\makeatletter \tikzset { myVSplitPlainVrtxStyle/.style args={#1,#2}{% circle, minimum size= 5mm, draw= #1!55!black!90, fill = #1, alias=tmp@name, postaction={% insert path={ \pgfextra{% \pgfpointdiff{\pgfpointanchor{\pgf@node@name}{center}}% {\pgfpointanchor{\pgf@node@name}{east}}% \pgfmathsetmacro\insiderad{\pgf@x} % } %The alternative bracket closing
\fill[#2] (\pgf@node@name.base) ([yshift=\pgflinewidth]\pgf@node@name.south) arc (-90:90:\insiderad-\pgflinewidth)--cycle; \draw[#2!55!black!90] (\pgf@node@name.base) ([yshift=\pgflinewidth/2]\pgf@node@name.south) arc (-90:90:\insiderad-\pgflinewidth/2); } } } } } \makeatother

\begin{document}

\begin{tikzpicture}
    \node[ myVSplitPlainVrtxStyle = {blue, lime} ] {};
\end{tikzpicture}

\end{document}

enter image description here

I have copy-pasted this code and modified it to my needs; however, there are parts that I do not understand. I would appreciate it you helping me understand what is going on. Also any improvements or seperate ideas are welcomed.

  1. alias = tmp@name

    • I have no idea why this is needed. I believed it is related to the fact that the style gets two input arguments. What does it do? Why is it necessary?
  2. postaction

    • I do not see the need for postaction. There is no need to say "do it later", and yet, when I remove it the code no longer function. What is happening?
  3. insert path

    • The manual says it is used to add something to the current path. I believe the only reason for its existence is to allow the use of \pgfextra. However, what is the current path in this context? Any other way to do this?
  4. \pgfextra

    • Why use this option? The manual says this command is used in path construction and temporary suspends that to have some TeX code executed first. More importantly, I am confused by the place the closing bracket } is placed. I have marked the more natural place for me, but that produces error. Why my intuition of the position of } is incorrect?
  5. (\pgf@node@name.base)

    • The original author have put this in the code. I don't understant the need of it. It works fine without it. Why was it done?
Aria
  • 393
  • It might be a good idea to link to the initial answer which provided this code, to make it more clear where it came from. – epR8GaYuh Jun 22 '21 at 05:59
  • \pgfextra has the following usage \draw (0,0)--(1,1) \pgfextra{LaTeX code such as \pgfmathsetmacro} (2,2)--(3,3). That is, it escapes back to the normal LaTeX context and lets you do arithmetics. – Symbol 1 Jun 22 '21 at 06:02
  • (\pgf@node@name.base) will move the "cursor"/"pen" to that point. Base is a rather bizarre anchor; it has something to do with the position of the text but there is no text here. You may delete it if that does not cause harm. – Symbol 1 Jun 22 '21 at 06:07
  • A \node ... ; is a shorthand of \draw node ... ;. The current path in this context is an empty path. So you need to add something (in your case, hemicircles) to have it drawn and filled. – Symbol 1 Jun 22 '21 at 06:11
  • alias=tmp@name is (probably) giving the concerned node a dummy name so that \pgf@node@name is nonempty. It cannot be name=tmp@name because that will override the name you gave. – Symbol 1 Jun 22 '21 at 06:13
  • postaction is to postpone the drawing until the node name is defined. – Symbol 1 Jun 22 '21 at 06:15
  • @Symbol1. Thanks for you comments. Three things:
    1. It is curious that pgf@node@name does not use "name" and will use the alias name (at least I think that is what is happening.) Just out of curiosity you know of any reason why?

    2. As it the case in your example and manual you put } after the computations like \pgfmathsetmacro is done. The placement of } is still curious for me, as it does not run properly in my placement.

    3. In this case it is logical (based on the objective) to have postaction; however, (again out of curiosity) why doesn't it run if you remove it.

    – Aria Jun 23 '21 at 01:05
  • 1
    (I didn't read the answers below so if there is contradiction trust other guys). For 1, the macro \pgf@node@name is probably accessed by both name and alias so either of them will make it nonempty. It doesn't matter if pgf@node@name ends up with being the alias because it still points to the name. For 2, the closing brace } is part of the \pgfextra{ ... } syntax. The correct syntax of the math macro is \pgfmathsetmacro\twenty{10+5*2}. (cont) – Symbol 1 Jun 23 '21 at 01:34
  • 1
    For 3, the node name will be available only after TikZ knows everything of the node: shape, content, position, width, height, anchor, etc. So it is logically impossible to assign circle and to access its anchors at the same moment. – Symbol 1 Jun 23 '21 at 01:35
  • Thank you. Everything is clear now. – Aria Jun 23 '21 at 01:42

2 Answers2

5

Another way to build a similar shape which I think it's easier to understand

\documentclass{article}
\usepackage{tikz}

\begin{document} \begin{tikzpicture}[ bicolor circle/.style 2 args={circle, fill=#1, path picture={\fill[#2] (path picture bounding box.north) rectangle (path picture bounding box.south east);}}, bicolor circle/.default={red}{green} ] \node[bicolor circle, draw, minimum size=3cm] {};

\node[bicolor circle={blue}{cyan}, draw=red, line width=1mm, minimum size=2cm] at (4,0) {}; \end{tikzpicture} \end{document}

enter image description here

Ignasi
  • 136,588
  • Thank man, very nice method! – Aria Jun 23 '21 at 01:09
  • @Ignasi: using path picture seems suitable only for this kind of shape (circle, left color, right color). How about more general shape? – Black Mild Jun 23 '21 at 04:46
  • @BlackMild path picture can be applied to any path or node. The path where is it applied acts as clipping path for the path picture drawn inside. If you apply it inside a node the text of the node is not covered by the path picture. Some examples: https://tex.stackexchange.com/a/497492/1952, https://tex.stackexchange.com/a/436272/1952 – Ignasi Jun 23 '21 at 08:59
3

@Ignasi command is simpler and clearer. Below, I try to answer the questions raised by @Aria.

  1. alias=tmp@name From the manual: This option allows you to provide another name for the node. It is later used in the coordinates computations through the postaction command.

  2. postaction= is needed for the node to exist, i.e. the main path operation to be completed (and so the computations for the coordinates to be performed). Note that preaction wouldn't do the job because the drawing (half-filled circle) would appear below the node.

  3. insert path Your explanation is correct. The added path is empty, but allowed the \pgfextra, as you have said. You might see, on the following simpler example, that a non-empty path introduced with insert path has no graphical effect; probably because the insert path is to be used as an option for a path and not for a node. From the manual: This option should be used with care, for instance, it should not be used as an argument of, say, a node.

enter image description here

The blue node has a non-empty added path, a circle of radius 1... In fact, there are some effects, due to the fill and opacity options!

Remark. Because the code is very simple, the circle around the node introduced inside \pgfextra is centered with respect to the node's label.

  1. (\pgf@node@name.base) I agree with @Symbol 1; it is not convincing. You can write the code without it and with the same effect.

enter image description here

The code for the first image

\documentclass[border=.5cm]{standalone}
\usepackage{tikz}

\begin{document} \tikzset{% tmpEmpty/.style={ rectangle, draw, fill=red, fill opacity=.3, text=black, text opacity=1, postaction={ insert path={% \pgfextra{% \draw[fill=yellow, fill opacity=.7] (0, 0) circle (.5); } } } }, tmpNEmpty/.style={ rectangle, draw, fill=red, fill opacity=.3, text=black, text opacity=1, postaction={ insert path={% [fill=green, opacity=1] \pgfextra{% \draw[fill=blue, fill opacity=.5] (0, 0) circle (.5); } circle[radius=1 cm] } } }
} \begin{tikzpicture} \draw (-1, -1) grid (2, 1);

\filldraw[red] (0, 0) circle (3pt); \path (0, 1) node[tmpEmpty] {center at $(0, 1)$}; \path (2, 1) node[tmpEmpty] {}; \draw (0, -1) node[tmpNEmpty] {};
\end{tikzpicture} \end{document}

The code for the second image

\documentclass[border=1cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document} \makeatletter \tikzset{% vsplit/.style args={#1, #2}{% circle, minimum size=5mm, draw=#1!70!black!90, fill=#1, alias=tmp@name, postaction={% insert path={ \pgfextra{% \pgfpointdiff{\pgfpointanchor{\pgf@node@name}{center}}% {\pgfpointanchor{\pgf@node@name}{east}}% \pgfmathsetmacro{\insiderad}{\pgf@x} \fill[#2] ([yshift=\pgflinewidth]\pgf@node@name.south) arc (-90:90:\insiderad pt-\pgflinewidth) -- cycle; \draw[#2!70!black!90] ([yshift=\pgflinewidth/2]\pgf@node@name.south) arc (-90:90:\insiderad-\pgflinewidth/2); } } } } } \makeatother

\begin{tikzpicture} \draw (-1, -1) grid (2, 1);

\path (0, 0) node[vsplit={red, blue}] {}; \path (1, 0) node[vsplit={yellow, blue}] {abc}; \end{tikzpicture} \end{document}

Peter Grill
  • 223,288
Daniel N
  • 5,687
  • Thank you. The reason postaction is necessary is not clear to me yet. Please see my comment to @Symbol1 for further explanaition and my other questions. – Aria Jun 23 '21 at 01:10
  • I think @Symbol1 explained the need of postaction (the node should exist before modifying it based on its coordinates). As for the position of the closing brace of \pgfextra, there are three paths involved here: the main one, the added one (introduced with insert path), and the glued one (I haven't found another name). The glued one is defined through a complete drawing instruction, and for this reason, it must appear inside \pgfextra; in particular, it fixes the position of the closing brace. Note that the added one (empty here) would not be a complete drawing command. – Daniel N Jun 23 '21 at 04:59