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

Example 1 (the anchors)
