A superellipse shape.
Keys:
superellipse x exponent
,superellipse y exponent
,superellipse step
(the stepwidth of the plot-loop) andsuperellipse exponent
(sets both x and y exponent).
The anchors on the border are found trough intersections
which takes a lot of time. However, there's room for improvement
- by not relying so much on PGFMath's parser
- by only creating a quadrant's plot for finding the intersections.
The radii evaluation is the same as for the ellipse
shape which multiplies the values with √2. To fit a lot of text on a page we use a text width of 1/√2 * \linewidth
and of that we subtract the inner xsep
s as well as the \pgflinewidth
(so that even the line of the shape doesn't protrude into the margin.
text width=text width=.70710678118\linewidth-\pgfkeysvalueof{/pgf/inner xsep}*2-\pgflinewidth
I've also set align=flush center
to get centered text that is not hyphenated.
Inside the node, the dimension \linewidth
is a long as the text width
is so we can use this directly for the horizontal \rule
.
Even though, the whole tikzpicture
is now as wide as \linewidth
I'll still put it into the center
environment which doesn't indent the line and is its own paragraph.
At the end of the preamble are some commands to show the vertical lines of the page. That's not needed otherwise.
Code
\documentclass{article}
\usepackage{tikz}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}
\usepgflibrary{shapes.geometric,intersections}
\pgfset{
superellipse x exponent/.initial=2.5,
superellipse y exponent/.initial=2.5,
superellipse step/.initial=4,
superellipse exponent/.style={/pgf/superellipse x exponent={#1},/pgf/superellipse y exponent={#1}}}
\makeatletter
\pgfdeclareshape{superellipse}{%
\inheritsavedanchors[from=ellipse]
\inheritanchor[from=ellipse]{text}\inheritanchor[from=ellipse]{center}
\inheritanchor[from=ellipse]{mid}\inheritanchor[from=ellipse]{base}
\inheritanchor[from=ellipse]{north}\inheritanchor[from=ellipse]{south}
\inheritanchor[from=ellipse]{west}\inheritanchor[from=ellipse]{east}
\inheritanchor[from=ellipse]{mid west}\inheritanchor[from=ellipse]{base west}
\inheritanchor[from=ellipse]{mid east}\inheritanchor[from=ellipse]{base east}
\anchor{north east}{%
\pgf@process{\radius}%
\pgfmathpow@{.70710678118}{\xexponent}%
\pgf@x=\pgfmathresult\pgf@x
\pgfmathpow@{.70710678118}{\yexponent}%
\pgf@y=\pgfmathresult\pgf@y
\pgfpointadd{}{\centerpoint}%
}
\anchor{north west}{%
\pgf@process{\radius}%
\pgfmathpow@{.70710678118}{\xexponent}%
\pgf@x=-\pgfmathresult\pgf@x
\pgfmathpow@{.70710678118}{\yexponent}%
\pgf@y=\pgfmathresult\pgf@y
\pgfpointadd{}{\centerpoint}%
}
\anchor{south west}{%
\pgf@process{\radius}%
\pgfmathpow@{.70710678118}{\xexponent}%
\pgf@x=-\pgfmathresult\pgf@x
\pgfmathpow@{.70710678118}{\yexponent}%
\pgf@y=-\pgfmathresult\pgf@y
\pgfpointadd{}{\centerpoint}%
}
\anchor{south east}{%
\pgf@process{\radius}%
\pgfmathpow@{.70710678118}{\xexponent}%
\pgf@x=\pgfmathresult\pgf@x
\pgfmathpow@{.70710678118}{\yexponent}%
\pgf@y=-\pgfmathresult\pgf@y
\pgfpointadd{}{\centerpoint}%
}
\savedmacro\xexponent{%
\pgfmathreciprocal{\pgfkeysvalueof{/pgf/superellipse x exponent}}%
\pgfmathmultiply@{\pgfmathresult}{2}%
\let\xexponent\pgfmathresult
}
\savedmacro\yexponent{%
\pgfmathreciprocal{\pgfkeysvalueof{/pgf/superellipse y exponent}}%
\pgfmathmultiply@{\pgfmathresult}{2}%
\let\yexponent\pgfmathresult
}
\savedmacro\step{%
\pgfmathsetmacro\step{\pgfkeysvalueof{/pgf/superellipse step}}}
\savedmacro\plothandler{\pgfkeysgetvalue{/pgf/superellipse smooth}\plothandler}
\backgroundpath{%
\pgf@process{\radius}%
\pgfmathsetlengthmacro\xradius{\pgf@x-\pgfkeysvalueof{/pgf/outer xsep}}%
\pgfmathsetlengthmacro\yradius{\pgf@y-\pgfkeysvalueof{/pgf/outer ysep}}%
\pgftransformshift{\centerpoint}%
\pgfplothandlerclosedcurve
\pgfplotfunction{\x}{0,\step,...,359}{%
\pgfmathsin@{\x}\let\sineofx\pgfmathresult
\pgfmathcos@{\x}\let\cosineofx\pgfmathresult
\pgfpoint{\xradius*abs(\cosineofx)^\xexponent*sign(\cosineofx)}
{\yradius*abs(\sineofx)^\yexponent*sign(\sineofx)}}
\pgftransformshift{\centerpoint\pgf@x=-\pgf@x\pgf@y=-\pgf@y}}
\anchorborder{%
\pgfextract@process\externalpoint{}%
\ifdim\pgf@x=0pt % catch special case x = 0
\ifdim\pgf@y<0pt \pgf@anchor@superellipse@south\else\pgf@anchor@superellipse@north\fi
\else
\ifdim\pgf@y=0pt % catch special case y = 0
\ifdim\pgf@x<0pt \pgf@anchor@superellipse@west\else\pgf@anchor@superellipse@east\fi
\else % both are not zero
\pgftransformreset % weird
\pgfintersectionofpaths{%
% line from center to rectangle encompassing superellipse
% \externalpoint might be only 1pt from center
\pgfpathmoveto{\centerpoint}%
\pgfpathlineto{\pgfpointborderrectangle{\externalpoint}{\radius}}%
}{%
\pgfpathmoveto{\centerpoint}%
\pgf@process{\radius}\pgfgetlastxy\xradius\yradius
\pgfplothandlerclosedcurve
\pgfplotfunction{\x}{0,\step,...,359}{%
% TODO: look for direction and only do quarter path
\pgfmathsin@{\x}\let\sineofx\pgfmathresult
\pgfmathcos@{\x}\let\cosineofx\pgfmathresult
\pgfpoint{\xradius*abs(\cosineofx)^\xexponent*sign(\cosineofx)}
{\yradius*abs(\sineofx)^\yexponent*sign(\sineofx)}}%
}%
\ifnum\pgfintersectionsolutions>0 % only if a solution was found
\pgfpointintersectionsolution{1}%
\pgfpointadd{}{\centerpoint}%
\else % other wise take the border on the rectangle (close enough?)
\pgfpointborderrectangle{\externalpoint}{\radius}%
\fi
\fi
\fi}}
% Begin: adjust frame of geometry
\usepackage[pass,showframe]{geometry}
\usepackage{etoolbox}
\preto\Gm@vrule{\color{red}}
\let\Gm@hrule\@empty
\let\Gm@hruled\@empty
% Begin: end frame of geometry
\makeatother
\tikzset{shape example/.style={color=black!30,draw,fill=yellow!30,line width=.5cm,inner xsep=2.5cm,inner ysep=0.5cm}}
\begin{document}
\begin{center}
\tikz\node (t) [
draw,
superellipse,
align=flush center, % or center (with hyphenation)
text width=.70710678118\linewidth-\pgfkeysvalueof{/pgf/inner xsep}*2-\pgflinewidth
]{
{\Huge\color{blue}Apunts de Matemàtiques per a l'Accés a la UIB per a majors de 25 anys\par}
{\color{gray}\rule[.5ex]{\linewidth}{1pt}\par}
{Teoria i exercicis per a la preparació de les ``Proves d'accés a la Universitat
de les Illes Balears per a majors de 25 anys i menors de 40 anys'' de l'assignatura de Matemàtiques\par}};
\end{center}
% \begin{tikzpicture}[opacity=.5,nodes={draw,superellipse,minimum size=+2cm,superellipse x exponent=5}]
% \node(t) at (-1,.5) {};
% \node(s) at (3,1) {};
% \draw[ultra thick] (s) -- (t);
% % This takes very long:
% % \foreach \ang in {0,5,...,359} \draw (s) -- +(\ang:1.4);
% \end{tikzpicture}
% \begin{tikzpicture}[superellipse step=1]\Huge
% \node[name=s,shape=superellipse,shape example] {Superellipse\vrule width 1pt height 2cm};
% \foreach \anchor/\placement in
% {north west/above left, north/above, north east/{red,above right},
% west/left, center/above, east/right,
% mid west/right, mid/above, mid east/left,
% base west/left, base/below, base east/right,
% south west/below left, south/below, south east/below right,
% text/left, 45/{red,above right}, 230/below}
% \draw[shift=(s.\anchor),style/.expanded=\placement] plot[mark=x] coordinates{(0,0)}
% node {\scriptsize\texttt{(s.\anchor)}};
% \end{tikzpicture}
\end{document}