3

I searched on the web and in this forum but I did not find a solution to my problem. I want to arrange text radially like rays of sunlight, coming out from a center. Something like that: image radial text

The code should be flexible (regarding to amount of lines and their length) and every line should be put on a separate sunbeam.

I created the example above with Inkscape and it was fairly easy to do so. But this would be a pain to do with 30 or more lines of text - and I would need to redo the whole thing whenever I add or remove a line.

Is there a way to automate that with LaTex?

I was fairly fluent in LaTex during my time at the university but did not use it recently... so therefore I don't know all the packages that are around. Maybe there is one which easily can do this ... ?

Further tuning would be to rotate some of the text by 180° (in my example 4th to 6th line) so that the text is not upside down.

2
5

A version that automatically does the counting and has a friendlier interface:

\documentclass[border=4]{standalone}
\usepackage{xparse,tikz}

\newcommand\textbeam[3]{%
  \node[anchor=west,rotate=#1] at (#1:#2) {#3};%
}
\NewDocumentCommand{\sunrays}{O{3mm}mm}
 {% optional argument = radius
  % first mandatory = initial angle
  % second mandatory = texts separated by \\
  \begin{tikzpicture}
  \fill (0,0) circle (#1);
  \makesunrays{#1}{#2}{#3}
  \end{tikzpicture}
 }

\ExplSyntaxOn
\NewDocumentCommand{\makesunrays}{mmm}
 {
  \seq_set_split:Nnn \l_atld_sunrays_text_seq { \\ } { #3 }
  \int_set:Nn \l_atld_sunrays_items_int { \seq_count:N \l_atld_sunrays_text_seq }
  \int_step_inline:nnnn { 0 } { 1 } { \l_atld_sunrays_items_int - 1 }
   {
    \textbeam
     { \fp_to_decimal:n { #2 - ##1*360/\l_atld_sunrays_items_int } }
     { #1 }
     { \seq_item:Nn \l_atld_sunrays_text_seq { ##1 + 1 } }
   }
 }
\seq_new:N \l_atld_sunrays_text_seq
\int_new:N \l_atld_sunrays_items_int
\ExplSyntaxOff

\begin{document}

\sunrays{60}{
  First line \\
  Second line, maybe longer \\
  Third line, maybe also long \\
  Fourth line, just text \\
  Fifth line, upside down \\
  Sixth line, I don't know how long
}

\end{document}

All the credit should go to StefanH, from whom I stole the TikZ code.

enter image description here

I used standalone to show the bounding box is correctly computed.

Here's the output of

\sunrays[1cm]{0}{AAA\\BBB\\CCC\\DDD\\EEE\\FFF\\GGG\\HHH\\III}

enter image description here

0
9

You can rotate lines using Tikz. In the below example I have a command textbeam that rotates the text a certain angle around a coordinate (the sun). That can be used to go through the text strings in a loop and position them around the sun.

For now I have not looked at the direction of the text (upside down problem). And the number of text lines is not automatically counted. But it might be a start.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
%%%%%%%
\newcommand\textbeam[4]{% {pos}{angle}{sep}{text}
  \node[anchor=west,rotate=#2] at ($(#1) + (#2:#3)$) {#4};
}
\newcommand\maketextsunbeams[4]{% {pos}{sep}{num}{text}
  \foreach \x [count=\xind from 0] in {#4}{
    \textbeam{#1}{\xind*360/#3}{#2}{\x}
  }  
}
\begin{document}

\begin{tikzpicture}
  \draw (1,0) circle (5mm);
  \maketextsunbeams{1,0}{7mm}{7}{%
    {First line}, 
    {Second line, maybe longer}, 
    {Third line, can also be long},
    {Fourth line},
    {Fifth line}, 
    {Sixth line}, 
    {Seventh line}}
\end{tikzpicture}
\end{document}

enter image description here

Edit

I updated the \textbeam command so that if the angle is between 90 and 270 degrees it turns it the other way (upside down):

\newcommand\textbeam[4]{% {pos}{angle}{sep}{text}
  \pgfmathparse{int(round(#2))}
  \edef\anglenum{\pgfmathresult}
  \ifnum\anglenum>90
    \ifnum\anglenum<270
      \node[anchor=east,rotate=#2+180] at ($(#1) + (#2:#3)$) {#4};
    \else
      \node[anchor=west,rotate=#2] at ($(#1) + (#2:#3)$) {#4};
    \fi
  \else
     \node[anchor=west,rotate=#2] at ($(#1) + (#2:#3)$) {#4};
  \fi
}

Then the same text-sun becomes

enter image description here

Edit 2

The automatic counting of text strings can be done using a recursive method. This changes also the command \maketextsunbeams so I give the full code.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
%%%%%%%
\newcommand\textbeam[4]{% {pos}{angle}{sep}{text}
  \pgfmathparse{int(round(#2))}
  \edef\anglenum{\pgfmathresult}
  \ifnum\anglenum>90
    \ifnum\anglenum<270
      \node[anchor=east,rotate=#2+180] at ($(#1) + (#2:#3)$) {#4};
    \else
      \node[anchor=west,rotate=#2] at ($(#1) + (#2:#3)$) {#4};
    \fi
  \else
     \node[anchor=west,rotate=#2] at ($(#1) + (#2:#3)$) {#4};
  \fi
}
\newcommand\maketextsunbeams[3]{% {pos}{sep}{text}
  \countargs{#3}
  \foreach \x [count=\xind from 0] in {#3}{
    \textbeam{#1}{\xind*360/\the\numargs}{#2}{\x}
  }  
}
%%%%
\newcount\numargs
\let\stop\empty
\newcommand\countargs[1]{%
  \numargs=0
  \reccountargs#1,\stop
}
\def\reccountargs#1,#2{%
  \advance\numargs 1
  \ifx\stop#2\relax
  \else
    \reccountargs{#2}
  \fi
}
%%%%
\begin{document}

\begin{tikzpicture}
  \draw (1,0) circle (5mm);
  \maketextsunbeams{1,0}{7mm}{%
    {One line}, 
    {A new line},
    {Another line},
    {Yet another line},    
    {A longer line, with a comma}, 
    {More lines},
    {Even more},
    {Next is an epty line}, 
    {}, 
    {More},
    {At last, the last line}}
\end{tikzpicture}
\end{document}

enter image description here

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.