% Copyright 2006 by Till Tantau and Mark Wibrow % % This file may be distributed and/or modified % % 1. under the LaTeX Project Public License and/or % 2. under the GNU Public License. % % See the file doc/generic/pgf/licenses/LICENSE for more details. \ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryshapes.geometric.code.tex,v 1.1 2007/06/08 11:24:59 tantau Exp $ \pgfdeclareshape{ellipse} % % Draws a circle around the text % { \savedanchor\centerpoint{% \pgf@x=.5\wd\pgfnodeparttextbox% \pgf@y=.5\ht\pgfnodeparttextbox% \advance\pgf@y by-.5\dp\pgfnodeparttextbox% } \savedanchor\radius{% % % Caculate ``height radius'' % \pgf@y=.5\ht\pgfnodeparttextbox% \advance\pgf@y by.5\dp\pgfnodeparttextbox% \pgfmathsetlength\pgf@yb{\pgfshapeinnerysep}% \advance\pgf@y by\pgf@yb% % % Caculate ``width radius'' % \pgf@x=.5\wd\pgfnodeparttextbox% \pgfmathsetlength\pgf@xb{\pgfshapeinnerxsep}% \advance\pgf@x by\pgf@xb% % % Adjust % \pgf@x=1.4142136\pgf@x% \pgf@y=1.4142136\pgf@y% % % Adjust hieght, if necessary % \pgfmathsetlength\pgf@yc{\pgfshapeminheight}% \ifdim\pgf@y<.5\pgf@yc% \pgf@y=.5\pgf@yc% \fi% % % Adjust width, if necessary % \pgfmathsetlength\pgf@xc{\pgfshapeminwidth}% \ifdim\pgf@x<.5\pgf@xc% \pgf@x=.5\pgf@xc% \fi% % % Add outer sep % \pgfmathsetlength{\pgf@xb}{\pgfshapeouterxsep}% \pgfmathsetlength{\pgf@yb}{\pgfshapeouterysep}% \advance\pgf@x by\pgf@xb% \advance\pgf@y by\pgf@yb% } % % Anchors % \anchor{center}{\centerpoint} \anchor{mid}{\centerpoint\pgfmathsetlength\pgf@y{.5ex}} \anchor{base}{\centerpoint\pgf@y=0pt} \anchor{north} { \pgf@process{\radius} \pgf@ya=\pgf@y% \pgf@process{\centerpoint} \advance\pgf@y by\pgf@ya } \anchor{south} { \pgf@process{\radius} \pgf@ya=\pgf@y% \pgf@process{\centerpoint} \advance\pgf@y by-\pgf@ya } \anchor{west} { \pgf@process{\radius} \pgf@xa=\pgf@x% \pgf@process{\centerpoint} \advance\pgf@x by-\pgf@xa } \anchor{mid west} {% \pgf@process{\radius} \pgf@xa=\pgf@x% \pgf@process{\centerpoint} \advance\pgf@x by-\pgf@xa% \pgfmathsetlength\pgf@y{.5ex} } \anchor{base west} {% \pgf@process{\radius} \pgf@xa=\pgf@x% \pgf@process{\centerpoint} \advance\pgf@x by-\pgf@xa% \pgf@y=0pt } \anchor{north west} { \pgf@process{\radius} \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgf@process{\centerpoint} \advance\pgf@x by-0.707107\pgf@xa \advance\pgf@y by0.707107\pgf@ya } \anchor{south west} { \pgf@process{\radius} \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgf@process{\centerpoint} \advance\pgf@x by-0.707107\pgf@xa \advance\pgf@y by-0.707107\pgf@ya } \anchor{east} {% \pgf@process{\radius} \pgf@xa=\pgf@x% \pgf@process{\centerpoint} \advance\pgf@x by\pgf@xa } \anchor{mid east} {% \pgf@process{\radius} \pgf@xa=\pgf@x% \pgf@process{\centerpoint} \advance\pgf@x by\pgf@xa% \pgfmathsetlength\pgf@y{.5ex} } \anchor{base east} {% \pgf@process{\radius} \pgf@xa=\pgf@x% \pgf@process{\centerpoint} \advance\pgf@x by\pgf@xa% \pgf@y=0pt } \anchor{north east} { \pgf@process{\radius} \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgf@process{\centerpoint} \advance\pgf@x by0.707107\pgf@xa \advance\pgf@y by0.707107\pgf@ya } \anchor{south east} { \pgf@process{\radius} \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgf@process{\centerpoint} \advance\pgf@x by0.707107\pgf@xa \advance\pgf@y by-0.707107\pgf@ya } \anchorborder{ \edef\pgf@marshal{% \noexpand\pgfpointborderellipse {\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} {\noexpand\radius}% }% \pgf@marshal% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \centerpoint% \advance\pgf@x by\pgf@xa% \advance\pgf@y by\pgf@ya% } % % Background path % \backgroundpath { \pgf@process{\radius}% \pgfutil@tempdima=\pgf@x% \pgfutil@tempdimb=\pgf@y% \pgfmathsetlength{\pgf@xb}{\pgfshapeouterxsep}% \pgfmathsetlength{\pgf@yb}{\pgfshapeouterysep}% \advance\pgfutil@tempdima by-\pgf@xb% \advance\pgfutil@tempdimb by-\pgf@yb% \pgfpathellipse{\centerpoint}{\pgfqpoint{\pgfutil@tempdima}{0pt}}{\pgfqpoint{0pt}{\pgfutil@tempdimb}}% } } % Set the recommended shape aspect ratio % % #1 = aspect ratio % % Example: % % \pgfsetshapeminwidth{1.5} \def\pgfsetshapeaspect#1{% \def\pgfshapeaspect{#1}% % Invert \pgfutil@tempdima=#1pt% \pgfutil@tempdima=.125\pgfutil@tempdima% \c@pgf@counta=\pgfutil@tempdima\relax% 8192*determinant \pgfutil@tempdima=8192pt% \divide\pgfutil@tempdima by\c@pgf@counta% \edef\pgfshapeaspectinverse{\pgf@sys@tonumber{\pgfutil@tempdima}} } \pgfsetshapeaspect{1} \pgfdeclareshape{diamond} { \savedanchor\outernortheast{% % % Calculate width and height of the inner rectangle % \pgf@xa=.5\wd\pgfnodeparttextbox% \pgfmathsetlength\pgf@xc{\pgfshapeinnerxsep}% \advance\pgf@xa by\pgf@xc% \pgf@ya=.5\ht\pgfnodeparttextbox% \advance\pgf@ya by.5\dp\pgfnodeparttextbox% \pgfmathsetlength\pgf@yc{\pgfshapeinnerysep}% \advance\pgf@ya by\pgf@yc% % % Calculate width and height of diamond % \pgf@x=\pgf@xa% \advance\pgf@x by\pgfshapeaspect\pgf@ya% \pgf@y=\pgfshapeaspectinverse\pgf@xa% \advance\pgf@y by\pgf@ya% % % Check against minimum height/width % \pgfmathsetlength\pgf@xb{\pgfshapeminwidth}% \ifdim\pgf@x<\pgf@xb% % yes, too small. Enlarge... \pgf@x=\pgf@xb% \fi% \pgfmathsetlength\pgf@yb{\pgfshapeminheight}% \ifdim\pgf@y<\pgf@yb% % yes, too small. Enlarge... \pgf@y=\pgf@yb% \fi% % % Add outer border % \pgfmathsetlength\pgf@xa{\pgfshapeouterxsep}% \advance\pgf@x by\pgf@xa% \pgfmathsetlength\pgf@ya{\pgfshapeouterysep}% \advance\pgf@y by\pgf@ya% } \savedanchor\text{% \pgf@x=-.5\wd\pgfnodeparttextbox% \pgf@y=-.5\ht\pgfnodeparttextbox% \advance\pgf@y by.5\dp\pgfnodeparttextbox% } % % Anchors % \anchor{text}{\text}% \anchor{center}{\pgfpointorigin}% \anchor{mid}{% \pgf@process{\text}% \pgf@x=0pt% \pgfmathsetlength\pgf@ya{.5ex} \advance\pgf@y by\pgf@ya% } \anchor{base}{\pgf@process{\text}\pgf@x=0pt } \anchor{north}{\pgf@process{\outernortheast}\pgf@x=0pt} \anchor{south}{\pgf@process{\outernortheast}\pgf@x=0pt\pgf@y=-\pgf@y} \anchor{west}{\pgf@process{\outernortheast}\pgf@x=-\pgf@x\pgf@y=0pt} \anchor{north west}{\pgf@process{\outernortheast}\pgf@x=-.5\pgf@x\pgf@y=.5\pgf@y} \anchor{south west}{\pgf@process{\outernortheast}\pgf@x=-.5\pgf@x\pgf@y=-.5\pgf@y} \anchor{east}{\pgf@process{\outernortheast}\pgf@y=0pt} \anchor{north east}{\pgf@process{\outernortheast}\pgf@x=.5\pgf@x\pgf@y=.5\pgf@y} \anchor{south east}{\pgf@process{\outernortheast}\pgf@x=.5\pgf@x\pgf@y=-.5\pgf@y} \anchorborder{% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgf@process{\outernortheast}% \ifdim\pgf@xa>0pt% \else% \pgf@x=-\pgf@x% \fi% \ifdim\pgf@ya>0pt% \else% \pgf@y=-\pgf@y% \fi% \edef\pgf@marshal{% \noexpand\pgfpointintersectionoflines {\noexpand\pgfpointorigin} {\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}} {\noexpand\pgfqpoint{\the\pgf@x}{0pt}} {\noexpand\pgfqpoint{0pt}{\the\pgf@y}}% }% \pgf@process{\pgf@marshal}% } % % Background path % \backgroundpath{ \pgf@process{\outernortheast}% \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% \pgfmathsetlength{\pgf@xa}{\pgfshapeouterxsep}% \pgfmathsetlength{\pgf@ya}{\pgfshapeouterysep}% \advance\pgf@xc by-1.414213\pgf@xa% \advance\pgf@yc by-1.414213\pgf@ya% \pgfpathmoveto{\pgfqpoint{\pgf@xc}{0pt}}% \pgfpathlineto{\pgfqpoint{0pt}{\pgf@yc}}% \pgfpathlineto{\pgfqpoint{-\pgf@xc}{0pt}}% \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@yc}}% \pgfpathclose% } } % \pgfsetstarpoints % % Set the number of points on a star. % \def\pgfsetstarpoints#1{% \pgfmathsetcounter{pgf@counta}{#1}% \edef\pgfstarpoints{\the\c@pgfmath@counta}} \pgfsetstarpoints{5} % \pgfsetstarpointheight % % Set the height of the points (this is the % distance between the outer and inner point % radii). % \def\pgfsetstarpointheight#1{% \pgfmathparse{#1}% \edef\pgfstarpointheight{\pgfmathresult pt}} \pgfsetstarpointheight{12pt} % \pgfsetstarpointratio % % Set the ratio between the outer and % inner point radii. % \def\pgfsetstarpointratio#1{% \pgfmathparse{#1}% \edef\pgfstarpointratio{\pgfmathresult}% \def\pgfstarpointheight{-16383pt}% If negative, the ratio is used. } \pgfsetstarpointratio{1.75} % \pgfsetstarrrotate % % Set the angle of rotation of the star % border. This can be decimal. % \def\pgfsetstarrotate#1{% \pgfmathparse{#1}% \edef\pgfstarrotate{\pgfmathresult}}% \pgfsetstarrotate{0} % Shape star. % \pgfdeclareshape{star}{% \saveddimen{\points}{\pgf@x\pgfstarpoints pt}% \saveddimen{\pointratio}{\pgf@x\pgfstarpointratio pt}% \saveddimen{\rotate}{\pgf@x\pgfstarrotate pt}% \saveddimen{\pointheight}{\pgf@x\pgfstarpointheight}% \saveddimen{\minimumsize}{% \pgfmathsetlength\pgf@x{\pgfshapeminwidth}% \pgfmathsetlength\pgf@y{\pgfshapeminheight}% \ifdim\pgf@y>\pgf@x% \pgf@x\pgf@y% \fi}% \saveddimen{\outersep}{% \pgfmathsetlength\pgf@x{\pgfshapeouterxsep}% \pgfmathsetlength\pgf@y{\pgfshapeouterysep}% \ifdim\pgf@y>\pgf@x% \pgf@x\pgf@y% \fi}% \savedanchor{\centerpoint}{% \pgf@x.5\wd\pgfnodeparttextbox% \pgf@y.5\ht\pgfnodeparttextbox% \advance\pgf@y-.5\dp\pgfnodeparttextbox% }% \saveddimen{\innerpointradius}{% % % The innerpoint radius is the radius of the circle which % can safely encompass the node textbox. % \pgfmathsetlength\pgf@x{\pgfshapeinnerxsep}% \advance\pgf@x.5\wd\pgfnodeparttextbox% \pgfmathsetlength\pgf@y{\pgfshapeinnerysep}% \advance\pgf@y.5\ht\pgfnodeparttextbox% \ifdim\pgf@y>\pgf@x% \pgf@x\pgf@y% \fi% \pgfmathveclen@{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@x}}% \pgf@x\pgfmathresult pt\relax% }% % \anchor{center}{\centerpoint}% \anchor{mid}{\centerpoint\pgfmathsetlength\pgf@y{.5ex}}% \anchor{base}{\centerpoint\pgf@y=0pt}% \anchor{north}{\pgf@anchor@star@border{\pgfpoint{+0pt}{+\outerpointradius}}}% \anchor{south}{\pgf@anchor@star@border{\pgfpoint{+0pt}{+-\outerpointradius}}}% \anchor{east}{\pgf@anchor@star@border{\pgfpoint{+\outerpointradius}{+0pt}}}% \anchor{west}{\pgf@anchor@star@border{\pgfpoint{+-\outerpointradius}{+0pt}}}% \anchor{north east}{\pgf@anchor@star@border{\pgfpoint{+\outerpointradius}{+\outerpointradius}}}% \anchor{north west}{\pgf@anchor@star@border{\pgfpoint{+-\outerpointradius}{+\outerpointradius}}}% \anchor{south east}{\pgf@anchor@star@border{\pgfpoint{+\outerpointradius}{+-\outerpointradius}}}% \anchor{south west}{\pgf@anchor@star@border{\pgfpoint{+-\outerpointradius}{+-\outerpointradius}}}% % \backgroundpath{% % % Redefine stuff for ease of use. % \pgf@x\points% \c@pgf@counta\pgf@x% \divide\c@pgf@counta65536\relax% \edef\points{\the\c@pgf@counta}% \pgf@x\rotate% \edef\rotate{\pgf@sys@tonumber{\pgf@x}}% \pgf@x\pointratio% \edef\pointratio{\pgf@sys@tonumber{\pgf@x}}% % % Calculate radii. % \pgf@x\innerpointradius\relax% \edef\innerradius{\the\pgf@x}% \pgf@xa\pointheight\relax% \ifdim\pgf@xa<0pt\relax% \pgf@x\pointratio\pgf@x% \else% \advance\pgf@x\pgf@xa% \fi% \pgf@xb\pgf@x% \pgf@xc\minimumsize\relax% \ifdim\pgf@x<.5\pgf@xc% \pgf@x.5\pgf@xc% \fi% \edef\outerradius{\the\pgf@x}% \ifdim\pgf@x>\pgf@xb% \ifdim\pgf@xa<0pt\relax% \pgfmathreciprocal{\pointratio}% \pgf@xc\pgfmathresult\pgf@x\relax% \edef\innerradius{\the\pgf@xc}% \else% \pgf@xc\pgf@x\relax% \advance\pgf@xc-\pointheight% \edef\innerradius{\the\pgf@xc}% \fi% \fi% % % Get the total number of points (inner + outer)... % \c@pgf@counta\points% \advance\c@pgf@counta\c@pgf@counta% \edef\numpoints{\the\c@pgf@counta}% % % ...and hence the angle between points. % \pgf@x360pt\relax% \divide\pgf@x\c@pgf@counta% \edef\staranglestep{\the\pgf@x}% % % Start at 90 degrees (star always points up)... % \pgf@x90pt\relax% % % ...unless rotation is applied. % \pgf@xa\rotate pt\relax% \advance\pgf@x\pgf@xa% \edef\starangle{\the\pgf@x}% \let\starradius=\outerradius% % % Move to first point. % \pgfpathmoveto{% \pgfpointadd{\centerpoint}% {\pgfpointpolar{+\starangle}{+\starradius}}% }% \def\staranchorname{pgf@anchor@star@outer point}% \pgfmathloop% % % Create anchors. Manually \xdef as \gdef is normally used by \anchor. % \c@pgf@counta\pgfmathcounter\relax% \advance\c@pgf@counta1\relax% \divide\c@pgf@counta2\relax% \expandafter\xdef\csname\staranchorname\space\the\c@pgf@counta\endcsname{% \noexpand\pgf@lib@shapesstaranchor{\pgfmathcounter}% }% \ifnum\pgfmathcounter=\numpoints\relax% Stop. \else% \ifodd\pgfmathcounter% \let\starradius\innerradius% \def\staranchorname{pgf@anchor@star@inner point}% \else% \let\starradius\outerradius% \def\staranchorname{pgf@anchor@star@outer point}% \fi% \pgf@x\starangle\relax% \advance\pgf@x\staranglestep\relax% \edef\starangle{\the\pgf@x}% \pgfpathlineto{% \pgfpointadd{\centerpoint}% {\pgfpointpolar{+\starangle}{+\starradius}}% }% \repeatpgfmathloop% \pgfpathclose% }% % \anchorborder{% % % Save x and y. % \pgf@xa\pgf@x% \pgf@ya\pgf@y% % % Redefine stuff for ease of use. % \pgf@x\points% \c@pgf@counta\pgf@x% \divide\c@pgf@counta65536\relax% \edef\points{\the\c@pgf@counta}% \pgf@x\rotate% \edef\rotate{\pgf@sys@tonumber{\pgf@x}}% \pgf@x\pointratio% \edef\pointratio{\pgf@sys@tonumber{\pgf@x}}% % % Calculate the location of the external % point relative to the node center. % \centerpoint% \advance\pgf@xa\pgf@x% \advance\pgf@ya\pgf@y% \edef\externalx{\the\pgf@xa}% \edef\externaly{\the\pgf@ya}% \pgf@process{\pgfpointdiff{\centerpoint}{\pgfpoint{+\externalx}{+\externaly}}}% % % First approximate the angle of the external point... % \pgf@xa\pgf@x% \pgf@ya\pgf@y% \pgf@xb\pgf@x% \pgf@yb\pgf@y% \ifdim\pgf@xa<0pt\relax% \pgf@xa-\pgf@xa% \fi% \ifdim\pgf@ya<0pt\relax% \pgf@ya-\pgf@ya% \fi% \ifdim\pgf@ya>\pgf@xa% \pgf@x\pgf@xa% \pgf@y\pgf@ya% \else% \pgf@x\pgf@ya% \pgf@y\pgf@xa% \fi% \ifdim\pgf@y=0pt\relax% \pgf@x0pt% \else% \pgfmathreciprocal@{\pgf@sys@tonumber{\pgf@y}}% \pgf@x\pgfmathresult\pgf@x% \fi% \multiply\pgf@x1000\relax% \afterassignment\pgfmath@gobbletilpgfmath@% \expandafter\c@pgf@counta\the\pgf@x\relax\pgfmath@% \expandafter\pgf@x\csname pgfmath@atan@\the\c@pgf@counta\endcsname pt\relax% \ifdim\pgfmath@ya>\pgfmath@xa\relax% \pgf@x-\pgf@x% \advance\pgf@x90pt% \fi% \ifdim\pgf@xb<0pt% \ifdim\pgf@yb>0pt% \pgf@x-\pgf@x% \fi% \advance\pgf@x180pt\relax% \else% \ifdim\pgf@yb<0pt% \pgf@x-\pgf@x% \advance\pgf@x360pt\relax% \fi\fi% % % ...then adjust, as star points start at 90 degrees... % \advance\pgf@x-90pt\relax% \ifdim\pgf@x<0pt\relax% \advance\pgf@x360pt\relax% \fi% % % ...and also for rotation. % \advance\pgf@x-\rotate pt\relax% \ifdim\pgf@x<0pt\relax% \advance\pgf@x360pt\relax% \fi% % % Now, locate the start and end points on the star border segment... % \c@pgf@counta\points\relax% \pgf@y180pt\relax% \divide\pgf@y\c@pgf@counta\relax% \pgfmathreciprocal@{\pgf@sys@tonumber{\pgf@y}}% \pgf@x\pgfmathresult\pgf@x% \afterassignment\pgfmath@gobbletilpgfmath@% \expandafter\c@pgf@counta\the\pgf@x\relax\pgfmath@% % % ...and hence, the start and end angles of the star border segment. % \pgf@x\pgf@y% \multiply\pgf@x\c@pgf@counta% \advance\pgf@x90pt% \advance\pgf@x\rotate pt\relax% \edef\firstangle{\the\pgf@x}% \advance\c@pgf@counta1\relax% \pgf@x\pgf@y% \multiply\pgf@x\c@pgf@counta% \advance\pgf@x\rotate pt\relax% \advance\pgf@x90pt% \edef\secondangle{\the\pgf@x}% % % Get the radii and add the outer sep... % \pgf@x\innerpointradius\relax% \edef\innerradius{\the\pgf@x}% \pgf@xa\pointheight\relax% \ifdim\pgf@xa<0pt\relax% \pgf@x\pointratio\pgf@x% \else% \advance\pgf@x\pgf@xa% \fi% \pgf@xb\pgf@x% \pgf@xc\minimumsize\relax% \ifdim\pgf@x<.5\pgf@xc% \pgf@x.5\pgf@xc% \fi% \edef\outerradius{\the\pgf@x}% \ifdim\pgf@x>\pgf@xb% \ifdim\pgf@xa<0pt\relax% \pgfmathreciprocal{\pointratio}% \pgf@xc\pgfmathresult\pgf@x\relax% \edef\innerradius{\the\pgf@xc}% \else% \pgf@xc\pgf@x\relax% \advance\pgf@xc-\pgf@xb% \edef\innerradius{\the\pgf@xc}% \fi% \fi% \pgf@xa\outersep\relax% \pgf@x\outerradius\relax% \advance\pgf@x\pgf@xa% \edef\outerradius{\the\pgf@x}% \pgf@x\innerradius\relax% \advance\pgf@x\pgf@xa% \edef\innerradius{\the\pgf@x}% \ifodd\c@pgf@counta% \let\firstradii\outerradius% \let\secondradii\innerradius% \else% \let\firstradii\innerradius% \let\secondradii\outerradius% \fi% % % ...and calculate the point on the intersection of % the line from the external point to \centerpoint and % the relevant segment of the star border. % \pgfpointintersectionoflines{\centerpoint}{\pgfpoint{+\externalx}{+\externaly}}% {% \pgfpointadd{\centerpoint}% {\pgfpointpolar{+\firstangle}{+\firstradii}}% }% {% \pgfpointadd{\centerpoint}% {\pgfpointpolar{+\secondangle}{+\secondradii}}% }% }% }% % \pgf@lib@shapesstaranchor % % Used internally to calculate inner point and % outer point anchor positions 'on line'. % \def\pgf@lib@shapesstaranchor#1{% % % Redefine stuff for ease of use. % \pgf@x\points% \c@pgf@counta\pgf@x% \divide\c@pgf@counta65536\relax% \edef\points{\the\c@pgf@counta}% \pgf@x\rotate% \edef\rotate{\pgf@sys@tonumber{\pgf@x}}% \pgf@x\pointratio% \edef\pointratio{\pgf@sys@tonumber{\pgf@x}}% % % Caculate radii. % \pgf@x\innerpointradius% \edef\innerradius{\the\pgf@x}% \pgf@xa\pointheight\relax% \ifdim\pgf@xa<0pt\relax% \pgf@x\pointratio\pgf@x% \else% \advance\pgf@x\pgf@xa% \fi% \pgf@xb\pgf@x% \pgf@xc\minimumsize\relax% \ifdim\pgf@x<.5\pgf@xc% \pgf@x.5\pgf@xc% \fi% \edef\outerradius{\the\pgf@x}% \ifdim\pgf@x>\pgf@xb% \ifdim\pgf@xa<0pt\relax% \pgfmathreciprocal{\pointratio}% \pgf@xc\pgfmathresult\pgf@x\relax% \edef\innerradius{\the\pgf@xc}% \else% \pgf@xc\pgf@x\relax% \advance\pgf@xc-\pgf@xb% \edef\innerradius{\the\pgf@xc}% \fi% \fi% % % Add the outer sep. % \pgf@xa\outersep% \pgf@x\outerradius\relax% \advance\pgf@x\pgf@xa% \edef\outerradius{\the\pgf@x}% \pgf@x\innerradius\relax% \advance\pgf@x\pgf@xa% \edef\innerradius{\the\pgf@x}% % % Calculate the angle. % \c@pgf@counta\points% \pgf@x180pt\relax% \divide\pgf@x\c@pgf@counta% \c@pgf@counta#1\relax% \advance\c@pgf@counta-1\relax% \multiply\pgf@x\c@pgf@counta% \pgf@xa\rotate pt\relax% \advance\pgf@x\pgf@xa% \advance\pgf@x90pt\relax% \edef\starangle{\the\pgf@x}% \ifodd\c@pgf@counta% \let\starradius\innerradius% \else% \let\starradius\outerradius% \fi% \pgfpointadd{\centerpoint}% {\pgfpointpolar{\starangle}{\starradius}}% }% % \pgfsetpolygonsides % % Set the number of sides on a polygon. % \def\pgfsetpolygonsides#1{% \pgfmathsetcounter{pgf@counta}{#1}% \edef\pgfpolygonsides{\the\c@pgfmath@counta}} \pgfsetpolygonsides{6} % \pgfsetpolygonrotate % % Set the angle of rotation of the polygon % border. This can be decimal. % \def\pgfsetpolygonrotate#1{% \pgfmathparse{#1}% \edef\pgfpolygonrotate{\pgfmathresult}}% \pgfsetpolygonrotate{0} % Regular polygon shape. % % \pgfdeclareshape{regular polygon}{% % % Saved dimensions. % \saveddimen{\sides}{\pgf@x\pgfpolygonsides pt}% \saveddimen{\rotate}{\pgf@x\pgfpolygonrotate pt}% \saveddimen{\minimumsize}{% \pgfmathsetlength\pgf@x{\pgfshapeminwidth}% \pgfmathsetlength\pgf@y{\pgfshapeminheight}% \ifdim\pgf@y>\pgf@x% \pgf@x\pgf@y% \fi}% \saveddimen{\outersep}{% \pgfmathsetlength\pgf@x{\pgfshapeouterxsep}% \pgfmathsetlength\pgf@y{\pgfshapeouterysep}% \ifdim\pgf@y>\pgf@x% \pgf@x\pgf@y% \fi}% \saveddimen{\radius}{% % % The radius calculated here is the radius of the circle which % can safely encompass the node textbox. This corresponds to the % distance from the centre of the polygon to the mid-point of the % of the sides of the polygon. The desired radius for the corners % of the polygon has to calculated `on-line' as the saved dimen % \sides is not available here. % \pgfmathsetlength\pgf@x{\pgfshapeinnerxsep}% \advance\pgf@x.5\wd\pgfnodeparttextbox% \pgfmathsetlength\pgf@y{\pgfshapeinnerysep}% \advance\pgf@y.5\ht\pgfnodeparttextbox% \ifdim\pgf@y>\pgf@x% \pgf@x\pgf@y% \fi% \pgfmathveclen@{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@x}}% \pgf@x\pgfmathresult pt\relax% }% % % Saved anchors. % \savedanchor{\centerpoint}{% \pgf@x.5\wd\pgfnodeparttextbox% \pgf@y.5\ht\pgfnodeparttextbox% \advance\pgf@y-.5\dp\pgfnodeparttextbox% }% % % Other anchors. % \anchor{center}{\centerpoint}% \anchor{mid}{\centerpoint\pgfmathsetlength\pgf@y{.5ex}}% \anchor{base}{\centerpoint\pgf@y=0pt}% \anchor{north}{\csname pgf@anchor@regular polygon@border\endcsname{\pgfpoint{+0pt}{+\radius}}}% \anchor{south}{\csname pgf@anchor@regular polygon@border\endcsname{\pgfpoint{+0pt}{+-\radius}}}% \anchor{east}{\csname pgf@anchor@regular polygon@border\endcsname{\pgfpoint{+\radius}{+0pt}}}% \anchor{west}{\csname pgf@anchor@regular polygon@border\endcsname{\pgfpoint{+-\radius}{+0pt}}}% \anchor{north east}{\csname pgf@anchor@regular polygon@border\endcsname{\pgfpoint{+\radius}{+\radius}}}% \anchor{north west}{\csname pgf@anchor@regular polygon@border\endcsname{\pgfpoint{+-\radius}{+\radius}}}% \anchor{south east}{\csname pgf@anchor@regular polygon@border\endcsname{\pgfpoint{+\radius}{+-\radius}}}% \anchor{south west}{\csname pgf@anchor@regular polygon@border\endcsname{\pgfpoint{+-\radius}{+-\radius}}}% % % Background path. % \backgroundpath{% % % Redefine some stuff for ease of use. % \pgf@x\sides% \c@pgf@counta\pgf@x% \divide\c@pgf@counta65536\relax% \edef\sides{\the\c@pgf@counta}% \pgf@x\rotate% \edef\rotate{\pgf@sys@tonumber{\pgf@x}}% % % Get the inner angle. % \pgf@y360pt\relax% \divide\pgf@y\sides% \edef\polygonanglestep{\the\pgf@y}% % % Now recalculate the polygon *corner* radius. % \pgf@y.5\pgf@y% \pgfmathcos@{\pgf@sys@tonumber{\pgf@y}}% \pgfmathreciprocal@{\pgfmathresult}% \pgf@x\radius\relax% \pgf@x\pgfmathresult\pgf@x% \pgf@xa\minimumsize\relax% \ifdim\pgf@x<.5\pgf@xa% \pgf@x.5\pgf@xa% \fi% \edef\polygonradius{\the\pgf@x}% % % Every polygon is drawn so that a side is at the bottom... % \pgf@x90pt\relax% \ifodd\sides% \else% \advance\pgf@x-\pgf@y% \fi% % % ...unless rotation is applied. % \pgf@xa\rotate pt\relax% \advance\pgf@x\pgf@xa% \edef\polygonangle{\the\pgf@x}% % % Move to first point. % \pgfpathmoveto{% \pgfpointadd{\centerpoint}% {\pgfpointpolar{+\polygonangle}{+\polygonradius}}% }% \pgfmathloop% % % Create anchors. Manually \xdef as \gdef is normally used by \anchor. % \expandafter\xdef\csname pgf@anchor@regular polygon@corner\space\pgfmathcounter\endcsname{% \noexpand\pgf@lib@shapescorneranchor{\pgfmathcounter}% }% \expandafter\xdef\csname pgf@anchor@regular polygon@side\space\pgfmathcounter\endcsname{% \noexpand\pgf@lib@shapessideanchor{\pgfmathcounter}% }% \ifnum\pgfmathcounter=\sides\relax% Stop. \else% \pgf@x\polygonangle\relax% \advance\pgf@x\polygonanglestep\relax% \edef\polygonangle{\the\pgf@x}% \pgfpathlineto{% \pgfpointadd{\centerpoint}% {\pgfpointpolar{+\polygonangle}{+\polygonradius}}% }% \repeatpgfmathloop% \pgfpathclose% }% % % Anchor border. % \anchorborder{% % % Save the external point. % \pgf@xa\pgf@x% \pgf@ya\pgf@y% \centerpoint% \advance\pgf@xa\pgf@x% \advance\pgf@ya\pgf@y% \edef\externalx{\the\pgf@xa}% \edef\externaly{\the\pgf@ya}% \pgf@process{\pgfpointdiff{\centerpoint}{\pgfpoint{+\externalx}{+\externaly}}}% % % Approximate the angle of the external point... % \pgf@xa\pgf@x% \pgf@ya\pgf@y% \pgf@xb\pgf@x% \pgf@yb\pgf@y% \ifdim\pgf@xa<0pt\relax% \pgf@xa-\pgf@xa% \fi% \ifdim\pgf@ya<0pt\relax% \pgf@ya-\pgf@ya% \fi% \ifdim\pgf@ya>\pgf@xa% \pgf@x\pgf@xa% \pgf@y\pgf@ya% \else% \pgf@x\pgf@ya% \pgf@y\pgf@xa% \fi% \ifdim\pgf@y=0pt\relax% \pgf@x0pt% \else% \pgfmathreciprocal@{\pgf@sys@tonumber{\pgf@y}}% \pgf@x\pgfmathresult\pgf@x% \fi% \multiply\pgf@x1000\relax% \afterassignment\pgfmath@gobbletilpgfmath@% \expandafter\c@pgf@counta\the\pgf@x\relax\pgfmath@% \expandafter\pgf@x\csname pgfmath@atan@\the\c@pgf@counta\endcsname pt\relax% \ifdim\pgfmath@ya>\pgfmath@xa\relax% \pgf@x-\pgf@x% \advance\pgf@x90pt% \fi% \ifdim\pgf@xb<0pt% \ifdim\pgf@yb>0pt% \pgf@x-\pgf@x% \fi% \advance\pgf@x180pt\relax% \else% \ifdim\pgf@yb<0pt% \pgf@x-\pgf@x% \advance\pgf@x360pt\relax% \fi\fi% % % ...(redefine stuff for ease of use)... % \pgf@y\sides% \c@pgf@counta\pgf@y% \divide\c@pgf@counta65536\relax% \edef\sides{\the\c@pgf@counta}% \pgf@y\rotate% \edef\rotate{\pgf@sys@tonumber{\pgf@y}}% % % ...now adjust angle, for the number of polygon sides... % \advance\pgf@x-90pt\relax% \pgf@xa180pt\relax% \divide\pgf@xa\sides% % % ...and for if the there is an even number of sides... % \ifodd\sides% \else% \advance\pgf@x\pgf@xa% \fi% \ifdim\pgf@x<0pt\relax% \advance\pgf@x360pt\relax% \fi% % % ...and also for rotation. % \advance\pgf@x-\rotate pt\relax% \ifdim\pgf@x<0pt\relax% \advance\pgf@x360pt\relax% \fi% % % Now, locate the start and end points on the polygon border segment... % \c@pgf@counta\sides\relax% \pgf@y360pt\relax% \divide\pgf@y\c@pgf@counta\relax% \pgfmathreciprocal@{\pgf@sys@tonumber{\pgf@y}}% \pgf@x\pgfmathresult\pgf@x% \afterassignment\pgfmath@gobbletilpgfmath@% \expandafter\c@pgf@counta\the\pgf@x\relax\pgfmath@% % % ...and hence, the start and end angles of the polygon border segment. % \pgf@x\pgf@y% \multiply\pgf@x\c@pgf@counta% \advance\pgf@x90pt% \ifodd\sides% \else% \advance\pgf@x-\pgf@xa% \fi% \advance\pgf@x\rotate pt\relax% \edef\firstangle{\the\pgf@x}% \advance\c@pgf@counta1\relax% \pgf@x\pgf@y% \multiply\pgf@x\c@pgf@counta% \advance\pgf@x\rotate pt\relax% \advance\pgf@x90pt% \ifodd\sides% \else% \advance\pgf@x-\pgf@xa% \fi% \edef\secondangle{\the\pgf@x}% % % Get the inner angle. % \pgf@y360pt\relax% \divide\pgf@y\sides% % % Now recalculate the polygon *corner* radius... % \pgf@y.5\pgf@y% \pgfmathcos@{\pgf@sys@tonumber{\pgf@y}}% \pgfmathreciprocal@{\pgfmathresult}% \pgf@x\radius\relax% \pgf@x\pgfmathresult\pgf@x% \edef\polygonradius{\the\pgf@x}% % % ...and add the outer sep to the corner radius... % \pgf@xa\minimumsize\relax% \ifdim\pgf@x<.5\pgf@xa% \pgf@x.5\pgf@xa% \fi% \pgf@xa\outersep\relax% \advance\pgf@x\pgf@xa% \edef\radius{\the\pgf@x}% % % ...and calculate the point on the intersection of % the line from the external point to \centerpoint and % the segment of the star border. % \pgfpointintersectionoflines{\centerpoint}{\pgfpoint{+\externalx}{+\externaly}}% {% \pgfpointadd{\centerpoint}% {\pgfpointpolar{+\firstangle}{+\radius}}% }% {% \pgfpointadd{\centerpoint}% {\pgfpointpolar{+\secondangle}{+\radius}}% }% }% }% % \pgf@lib@shapespolygoncorneranchor % % Used internally to calculate corner anchor positions. % \def\pgf@lib@shapescorneranchor#1{% % % Redefine stuff for ease of use. % \pgf@y\sides% \c@pgf@counta\pgf@y% \divide\c@pgf@counta65536\relax% \edef\sides{\the\c@pgf@counta}% \pgf@y\rotate% \edef\rotate{\pgf@sys@tonumber{\pgf@y}}% % % Get the inner angle. % \pgf@y360pt\relax% \divide\pgf@y\sides\relax% \edef\polgonanglestep{\pgf@sys@tonumber{\pgf@y}}% % % Recalculate the polygon corner radius... % \pgf@y.5\pgf@y% \pgfmathcos@{\pgf@sys@tonumber{\pgf@y}}% \pgfmathreciprocal@{\pgfmathresult}% \pgf@x\radius\relax% \pgf@x\pgfmathresult\pgf@x% \edef\polygonradius{\the\pgf@x}% % % ...adjust for minimum size... % \pgf@xa\minimumsize\relax% \ifdim\pgf@x<.5\pgf@xa% \pgf@x.5\pgf@xa% \fi% % % ...and add the outer sep. % \pgf@xa\outersep\relax% \advance\pgf@x\pgf@xa% \edef\polygonradius{\the\pgf@x}% % % Calculate the angle. % \c@pgf@counta#1\relax% \advance\c@pgf@counta-1\relax% \pgf@x2.0\pgf@y% \multiply\pgf@x\c@pgf@counta% \pgf@xa\rotate pt\relax% \advance\pgf@x\pgf@xa% \advance\pgf@x90pt\relax% \ifodd\sides% \else% \advance\pgf@x-\pgf@y% \fi% \edef\polygonangle{\the\pgf@x}% \pgfpointadd{\centerpoint}% {\pgfpointpolar{\polygonangle}{\polygonradius}}% }% % \pgf@lib@shapespolygonsideanchor % % Used internally to calculate side anchor positions. % \def\pgf@lib@shapessideanchor#1{% % % Redefine stuff for ease of use. % \pgf@y\sides% \c@pgf@counta\pgf@y% \divide\c@pgf@counta65536\relax% \edef\sides{\the\c@pgf@counta}% \pgf@y\rotate% \edef\rotate{\pgf@sys@tonumber{\pgf@y}}% % % Get the inner angle. % \pgf@y360pt\relax% \divide\pgf@y\sides\relax% \edef\polygonanglestep{\the\pgf@y}% % % Recalculate the polygon corner radius... % \pgf@y.5\pgf@y% \pgfmathcos@{\pgf@sys@tonumber{\pgf@y}}% \pgfmathreciprocal@{\pgfmathresult}% \pgf@x\radius\relax% \pgf@x\pgfmathresult\pgf@x% % % ...adjust for minimum size... % \pgf@xa\minimumsize\relax% \ifdim\pgf@x<.5\pgf@xa% \pgf@x.5\pgf@xa% \fi% % % and add the outer sep. % \pgf@xa\outersep\relax% \advance\pgf@x\pgf@xa% \edef\polygonradius{\the\pgf@x}% % % Calculate the angle. % \pgf@y\polygonanglestep% \c@pgf@counta#1\relax% \advance\c@pgf@counta-1\relax% \pgf@x\polygonanglestep pt\relax% \multiply\pgf@x\c@pgf@counta% \pgf@xa\rotate pt\relax% \advance\pgf@x\pgf@xa% \advance\pgf@x90pt\relax% \ifodd\sides% \else% \advance\pgf@x-.5\pgf@y% \fi% \edef\firstangle{\the\pgf@x}% \advance\pgf@x\pgf@y% \edef\secondangle{\the\pgf@x}% \pgfpointlineattime{0.5}{% \pgfpointadd{\centerpoint}{\pgfpointpolar{+\firstangle}{+\polygonradius}}% }{% \pgfpointadd{\centerpoint}{\pgfpointpolar{+\secondangle}{+\polygonradius}}% }% }% \endinput