14

Following @Alain Matthes's reply on this question, wa can get a picture like this:

enter image description here

I am not good enough to adapt the code to split the circle into 4 quarters. Can you help me?

\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\usetikzlibrary{shapes,backgrounds,calc}

% Two Colored Circle Split 
\makeatletter
\tikzset{circle split part fill/.style  args={#1,#2}{%
 alias=tmp@name, 
  postaction={%
    insert path={
     \pgfextra{% 
     \pgfpointdiff{\pgfpointanchor{\pgf@node@name}{center}}%
                  {\pgfpointanchor{\pgf@node@name}{east}}%            
     \pgfmathsetmacro\insiderad{\pgf@x}
      \fill[#1] (\pgf@[email protected]) ([xshift=-\pgflinewidth]\pgf@[email protected]) arc
                          (0:180:\insiderad-\pgflinewidth)--cycle;
      \fill[#2] (\pgf@[email protected]) ([xshift=\pgflinewidth]\pgf@[email protected])  arc
                           (180:360:\insiderad-\pgflinewidth)--cycle;            
         }}}}}  
 \makeatother  


\begin{document}

\begin{tikzpicture}
  \node[minimum size=4cm, 
    shape=circle split,
    draw=blue!70,line width=2mm,
    circle split part fill={blue!50, red!50}
    ] at (0.5, 1.5) {1\nodepart{lower} 2};
\end{tikzpicture}

\end{document}
3
  • 1
    Do you want/need a node shape with four node parts? Maybe Basic geometric shapes, sections, shading is related (my answer anyway). Commented Jun 29, 2013 at 14:39
  • @Qrrbrbirlbel:Yes, I would like a node shape with four node parts. I will have a look there. Thanks!
    – Marco
    Commented Jun 29, 2013 at 17:01
  • How should the text boxes be aligned horizontal? (Consider text boxed with different widths.) Commented Jun 29, 2013 at 20:39

2 Answers 2

16

The following code defines a circle cross split shape with the node parts and their short-hands

  • text,
  • two = tr,
  • three = br, and
  • four = bl.

It requires the shapes.multipart library (which also provides the PGF node part boxes which are \let to the corresponding short-hands) and needs:

  • the list processor \pgf@lib@sh@rs@process@list;
  • the macros \pgf@lib@sh@getalpha and \pgf@lib@sh@toalpha to convert 1, 2, … in one, two, …;
  • \pgf@lib@sh@rs@nonetext which simply contains none so that one can selectively disable the filling for one of the quarters.

The text boxes are “center-aligned”. This means that one of the corners of the text boxes will be stuffed in the center corner from the cross (the inner separators are included).

The two upper parts and the two lower parts are base-aligned respectively.

Further improvement:

  • Align options for node parts that are below/above each other.
  • The third example and the second example with inner sep=+0pt show that the dimension of the text boxes are not really correctly used in the calculation of the radius of the circle. With empty inner separators, the shape border will cross the boxes.
  • ?

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes.multipart}
\makeatletter
\let\pgfnodeparttrbox\pgfnodeparttwobox
\let\pgfnodepartblbox\pgfnodepartthreebox
\let\pgfnodepartbrbox\pgfnodepartfourbox
\newif\ifpgfcirclecrosssplitcustomfill
\tikzset{%
  circle cross split part fill/.code=%
    \def\pgf@lib@sh@ccs@list@fill{#1}\pgfcirclecrosssplitcustomfilltrue,%
  circle cross split uses custom fill/.is if=pgfcirclecrosssplitcustomfill}
\pgfdeclareshape{circle cross split}{%
  \nodeparts{text,two,three,four}%
  \savedanchor\centerpoint{%
    \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
    \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}%
    \pgf@x =\wd\pgfnodeparttextbox
    \pgf@yb=\dp\pgfnodeparttextbox
    \pgf@y=\dp\pgfnodeparttwobox
    \ifdim\pgf@yb>\pgf@y
      \pgf@y=\pgf@yb
    \fi
    \advance\pgf@x\pgf@xa
    \advance\pgf@y-\pgf@ya
    \advance\[email protected]\pgflinewidth
    \advance\[email protected]\pgflinewidth
  }%
  \savedanchor\twoanchor{%
    \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
    \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}%
    \advance\[email protected]\pgflinewidth
    \advance\pgf@x\pgf@xa
    \advance\[email protected]\pgflinewidth
    \advance\pgf@y\pgf@ya
    \pgf@yb\dp\pgfnodeparttextbox
    \pgf@yc\dp\pgfnodeparttwobox
    \ifdim\pgf@yb>\pgf@yc
      \pgf@yc\pgf@yb
    \fi
    \advance\pgf@y\pgf@yc
  }%
  \savedanchor\threeanchor{%
    \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}%
    \pgf@x\wd\pgfnodeparttextbox
    \pgf@yb\dp\pgfnodeparttextbox
    \pgf@yc\dp\pgfnodeparttwobox
    \ifdim\pgf@yb>\pgf@yc
      \pgf@yc\pgf@yb
    \fi
    \advance\pgf@y-\pgf@yc
    \advance\pgf@y-2\pgf@ya
    \advance\pgf@y-\pgflinewidth
    \pgf@yb\ht\pgfnodepartthreebox
    \pgf@yc\ht\pgfnodepartfourbox
    \ifdim\pgf@yb>\pgf@yc
      \pgf@yc\pgf@yb
    \fi
    \advance\pgf@y-\pgf@yc
    \advance\pgf@x-\wd\pgfnodepartthreebox
  }%
  \savedanchor\fouranchor{%
    \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
    \advance\pgf@x\wd\pgfnodepartthreebox
    \advance\pgf@x2\pgf@xa
    \advance\pgf@x\pgflinewidth
  }%
  \saveddimen\radius{%
    % height:
    \pgf@y\ht\pgfnodeparttextbox
    \pgf@yb\ht\pgfnodeparttwobox
    \ifdim\pgf@yb>\pgf@y
      \pgf@y\pgf@yb
    \fi
    \pgf@yc\dp\pgfnodeparttextbox
    \pgf@yb\dp\pgfnodeparttwobox
    \ifdim\pgf@yc>\pgf@yb
      \advance\pgf@y\pgf@yc
    \else
      \advance\pgf@y\pgf@yb
    \fi
    \pgf@yb\ht\pgfnodepartthreebox
    \ifdim\pgf@yb<\ht\pgfnodepartfourbox
      \pgf@yb\ht\pgfnodepartfourbox
    \fi
    \pgf@yc\dp\pgfnodepartthreebox
    \ifdim\pgf@yc<\dp\pgfnodepartfourbox
      \advance\pgf@yb\dp\pgfnodepartfourbox
    \else
      \advance\pgf@yb\pgf@yc
    \fi
    \ifdim\pgf@yc>\pgf@y
      \pgf@y\pgf@yc
    \fi
    \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}%
    \advance\pgf@y2\pgf@ya
    %
    \pgf@x\wd\pgfnodeparttextbox
    \pgf@xa\wd\pgfnodepartthreebox
    \pgf@xb\wd\pgfnodeparttwobox
    \pgf@xc\wd\pgfnodepartfourbox
    \ifdim\pgf@xa>\pgf@x
      \pgf@x\pgf@xa
    \fi
    \ifdim\pgf@xb>\pgf@x
      \pgf@x\pgf@xb
    \fi
    \ifdim\pgf@xc>\pgf@x
      \pgf@x\pgf@xc
    \fi
    \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
    \advance\pgf@x2\pgf@xa
    \ifdim\pgf@y>\pgf@x
      \pgf@x\pgf@y
    \fi
    \advance\[email protected]\pgflinewidth
    %
    \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/minimum width}}%
    \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/minimum height}}%
    \ifdim\pgf@x<.5\pgf@xb
        \pgf@x=.5\pgf@xb
    \fi
    \ifdim\pgf@x<.5\pgf@yb
        \pgf@x=.5\pgf@yb
    \fi
    %
    \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
    \ifdim\pgf@xb<\pgf@yb
      \advance\pgf@x\pgf@yb
    \else
      \advance\pgf@x\pgf@xb
    \fi
  }%
  \inheritanchorborder[from=circle]%
  \inheritanchor[from=circle]{north}%
  \inheritanchor[from=circle]{north west}%
  \inheritanchor[from=circle]{north east}%
  \inheritanchor[from=circle]{center}%
  \inheritanchor[from=circle]{west}%
  \inheritanchor[from=circle]{east}%
  \inheritanchor[from=circle]{mid}%
  \inheritanchor[from=circle]{mid west}%
  \inheritanchor[from=circle]{mid east}%
  \inheritanchor[from=circle]{base}%
  \inheritanchor[from=circle]{base west}%
  \inheritanchor[from=circle]{base east}%
  \inheritanchor[from=circle]{south}%
  \inheritanchor[from=circle]{south west}%
  \inheritanchor[from=circle]{south east}%
  \anchor{two}{\twoanchor}%
  \anchor{three}{\threeanchor}%
  \anchor{four}{\fouranchor}%
  \inheritbackgroundpath[from=circle]
  \beforebackgroundpath{%
    \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
    \advance\pgfutil@tempdima by-.5\pgflinewidth%
    \pgfsetshortenstart{0pt}%
    \pgfsetshortenend{0pt}%
    \pgfsetarrows{-}%
    \pgfpathmoveto
      {\pgfpointadd{\centerpoint}{\pgfqpoint{-\pgfutil@tempdima}{0pt}}}%
    \pgfpathlineto
      {\pgfpointadd{\centerpoint}{\pgfqpoint{\pgfutil@tempdima}{0pt}}}%
    \pgfpathmoveto
      {\pgfpointadd{\centerpoint}{\pgfqpoint{0pt}{-\pgfutil@tempdima}}}%
    \pgfpathlineto
      {\pgfpointadd{\centerpoint}{\pgfqpoint{0pt}{\pgfutil@tempdima}}}%
    \pgfusepathqstroke
  }%
  \behindbackgroundpath{%
    \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
    \advance\pgfutil@tempdima by-.5\pgflinewidth%
    \ifpgfcirclecrosssplitcustomfill%
      \pgf@lib@sh@rs@process@list{\pgf@lib@sh@ccs@list@fill}{4}%
      {%
        \pgfmathloop
           \ifnum\pgfmathcounter>4%
           \else%
             \pgf@lib@sh@getalpha\pgf@lib@sh@rs@number{\pgfmathcounter}%
              \edef\pgf@tempa
                {\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname}%
              \ifx\pgf@tempa\pgf@lib@sh@rs@nonetext\else
                \pgfsetfillcolor{\pgf@tempa}%
                \pgf@lib@sh@ccs@angles{\pgfmathcounter}%
                \pgfpathmoveto{\centerpoint}%
                \pgfpathlineto{\pgfpointadd{\centerpoint}
                  {\pgfqpointpolar{\pgf@lib@sh@ccs@angle}{\pgfutil@tempdima}}}%
                \pgfpatharc{\pgf@lib@sh@ccs@angle}{\pgf@lib@sh@ccs@angle@}
                  {\pgfutil@tempdima}%
                \pgfpathclose
                \pgfusepathqfill
              \fi
        \repeatpgfmathloop
      }%
    \fi}}
\def\pgf@lib@sh@ccs@angles#1{%
  \ifcase#1\or\def\pgf@lib@sh@ccs@angle{90}%
           \or\def\pgf@lib@sh@ccs@angle{0}%
           \or\def\pgf@lib@sh@ccs@angle{180}%
           \else\def\pgf@lib@sh@ccs@angle{270}%
  \fi
  \edef\pgf@lib@sh@ccs@angle@{\number\numexpr\pgf@lib@sh@ccs@angle+90\relax}}
\makeatother
\begin{document}
\tikz {
  \node at (3,2) [
    line width=6pt,
    circle cross split,
    draw=gray!50,
    minimum size=5cm,
    circle cross split part fill={green,blue,red,yellow!90!black}
  ] (s) {text \nodepart{two} two \nodepart{three} three \nodepart{four} four};
\foreach \anchor/\placement in {
    north west/above left, north/above, north east/above right,
    west/left, center/left, east/right,
    mid west/left, mid/above, mid east/right,
    base west/left, base/below, base east/right,
    south west/below left, south/below, south east/below right,
    text/left, two/below right, three/below, four/below right}
  \draw[shift=(s.\anchor)] plot[mark=x] coordinates{(0,0)}
    node[\placement] {\scriptsize\texttt{(s.\anchor)}};
}

\fboxsep=-.4pt
\fboxrule=.4pt
\tikz
  \node [
    circle cross split,
    draw,
    circle cross split part fill={green,blue,red,yellow!90!black},
%    inner sep=+0pt
  ] (s) {\fbox{text} \nodepart{tr} \fbox{two} \nodepart{bl} \fbox{three} \nodepart{br} \fbox{four}};

\tikz\node[opacity=.5,text=blue,draw,circle cross split,inner sep=+0pt] {
                \rule{4em}{4em}
  \nodepart{tr} \rule{4em}{4em}
  \nodepart{bl} \rule{4em}{4em}
  \nodepart{br} \rule{4em}{4em}};
\end{document}

Output

Example 2 and 3

enter image description here enter image description here

Example 1 (the anchors)

enter image description here

2
  • Using the exact code from the link but using \node at (4,,4) instead of just \node leads to the text node label not being shifted accordingly. In fact, the entire mid anchor refuses to get shifted. How do I correct this? Commented Mar 2, 2021 at 19:04
  • 1
    @TushantMittal I know it has been quite a while but I fixed the mistake. The dimension \pgf@y was never initialized inside the definition of \centerpoint. Commented Sep 9, 2022 at 15:32
6

PSTricks

\documentclass[pstricks,border=12pt]{standalone}
\begin{document}
\psset{dimen=medusa}
\begin{pspicture}(-3,-3)(3,3)
    \psclip{\pscircle{3}}
        \psframe*[linecolor=red](-3,0)(0,3)
        \psframe*[linecolor=green](0,0)(3,-3)
    \endpsclip
    \pscircle{3}
\end{pspicture}
\end{document}

Tikz

\documentclass[tikz,border=12pt]{standalone}
\begin{document}
\begin{tikzpicture}
    \clip (0,0) circle (3);
    \begin{scope}
        \fill[red] (-3,0) rectangle (0,3);
        \fill[green] (0,0) rectangle (3,-3);
    \end{scope}
    \draw (0,0) circle (3);
\end{tikzpicture}
\end{document}

enter image description here

2
  • 3
    Although this draws a circle with four parts, it doesn't really achieve the same thing as the original answer which creates a circle node with two parts, each of which is a node.
    – Alan Munn
    Commented Jun 29, 2013 at 14:07
  • Thanks, this looks great. However, @Alan is right. For the moment, I only upgrade, and I will accept your nice answer if nothing else really fits my request.
    – Marco
    Commented Jun 29, 2013 at 17:00

You must log in to answer this question.

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