12

I have constructed a custom shape using pdfdeclareshape, and am using it in the following diagram

screenshot

I would like to rotate the border independently from the text so that ideally it will eventually look something like the image in this question.

Having studied the pgf manual and How to rotate a node and text independently in Tikz (for example), I think that I should be aiming to use shape border rotate, but not all shapes support it by default.

Can the border of my custom shape be rotated independently from its text? (If my custom shape can be improved upon, please feel free to let critique it.)

% arara: pdflatex
\documentclass[tikz]{standalone}

\makeatletter
\pgfdeclareshape{petal}
{
    \inheritsavedanchors[from=circle] % this is nearly a circle
    \inheritanchorborder[from=circle]
    \inheritanchor[from=circle]{center}
    \inheritanchor[from=circle]{base}
    \backgroundpath{
        % origin
        \centerpoint%
        \pgf@xc=\pgf@x%
        \pgf@yc=\pgf@y%
        \pgfutil@tempdima=\radius%
        \pgfpathmoveto{\pgfpointadd%
            {\pgfqpoint{\pgf@xc}{\pgf@yc}}
            {\pgfqpoint{-\pgfutil@tempdima}{0\pgfutil@tempdima}}}
        \pgfpatharc{180}{0}{\pgfutil@tempdima}
        \pgfpathcurveto{%
            \pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{0.9\pgfutil@tempdima}{-.9\pgfutil@tempdima}}}
            {\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{0.5\pgfutil@tempdima}{-.5\pgfutil@tempdima}}}
            {\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{0\pgfutil@tempdima}{-1.5\pgfutil@tempdima}}}
        \pgfpathcurveto{%
            \pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{0\pgfutil@tempdima}{-1.5\pgfutil@tempdima}}}
            {\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{-0.8\pgfutil@tempdima}{-.8\pgfutil@tempdima}}}
            {\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{-\pgfutil@tempdima}{0\pgfutil@tempdima}}}
    }
}
\makeatother

\begin{document}
\begin{tikzpicture}
    \foreach \i in {1,2,...,5}
    {
        \pgfmathparse{90-(\i-1)*360/5}
        \node[draw=black,anchor=base,rotate=-(\i-1)*360/5,petal,minimum width=1.5cm] at (\pgfmathresult:1.2cm)  {\i};
    }
\end{tikzpicture}

\end{document}

2 Answers 2

14

You can use a shape border rotate which exists for some shapes (or define your own special petal rotate key). When you define a new shape, however, you have to do all the work yourself. Drawing the shape border is straightforward, but you may want/have to manually define the anchors to reflect the value in this key (which isn't done here):

\documentclass[tikz]{standalone}

\makeatletter
\pgfkeys{/pgf/shape border rotate/.initial=0}

\pgfdeclareshape{petal}
{
    \inheritsavedanchors[from=circle] % this is nearly a circle
    \inheritanchorborder[from=circle]
    \inheritanchor[from=circle]{center}
    \inheritanchor[from=circle]{base}
    \savedmacro\petalparameters{%
      \pgfmathsetmacro\shapeborderrotate{\pgfkeysvalueof{/pgf/shape border rotate}}%
      \addtosavedmacro\shapeborderrotate%
    }
    \backgroundpath{
      % origin
      \petalparameters%
      {% Make sure transformations are  inside group.
         \pgftransformshift{\centerpoint}%
        \pgftransformrotate{\shapeborderrotate}%
        \pgfutil@tempdima=\radius%
        \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima}{0pt}}%
        \pgfpatharc{0}{180}{\pgfutil@tempdima}%
        \pgfpathcurveto{\pgfqpoint{-\pgfutil@tempdima}{-.5\pgfutil@tempdima}}%
          {\pgfqpoint{-.5\pgfutil@tempdima}{-.75\pgfutil@tempdima}}%
          {\pgfqpoint{0pt}{-1.5\pgfutil@tempdima}}
        \pgfpathcurveto{\pgfqpoint{0pt}{-.75\pgfutil@tempdima}}%
          {\pgfqpoint{\pgfutil@tempdima}{-.75\pgfutil@tempdima}}%
          {\pgfqpoint{\pgfutil@tempdima}{0pt}}%
      }%
   }
}
\makeatother

\begin{document}
\begin{tikzpicture}
    \foreach \i in {1,2,...,5}
    {
        \pgfmathparse{90-(\i-1)*360/5}
        \node[draw=black,anchor=base,shape border rotate=-(\i-1)*360/5,petal,minimum width=1.5cm] at (\pgfmathresult:1.25cm)  {\i};
    }
\end{tikzpicture}

\end{document}

enter image description here

2
  • Wonderful, thanks so much! I'm out of votes at the moment, but will return once they have recharged :) Is there a reference point in the manual (or somewhere else) that you could point me to as part of your answer? Thanks!
    – cmhughes
    Dec 31, 2013 at 20:39
  • @cmhughes Unfortunately the manual is a bit "thin" on creating new shapes. The best thing is to look at the code, but it isn't very well commented and some of my early shapes need an overhaul. Jan 3, 2014 at 14:41
0

With PSTricks.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{multido}
\psset{linejoin=1}
\SpecialCoor
\def\atom#1%
{
    \psccurve(0,0)(.3,.5)(1,1)(1,1.5)(0,2)(-1,1.5)(-1,1)
    \rput{*0}(0,1){#1}
}

\begin{document}
\begin{pspicture}[showgrid=false](-3,-3)(3,3)
    \multido{\ia=90+-72,\ib=0+-72,\in=1+1}{5}{\rput(.5;\ia){\rput{\ib}(0,0){\atom{\in}}}}
\end{pspicture}
\end{document}

enter image description here

You must log in to answer this question.

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