How do I display pi in LaTeX like Don?
EDITED to allow repeat invocations without having to reset parameters, using the syntax
\diminish[scale-down-ratio]{string}
The value of \defaultstartht
sets the strut height of the first letter (default is set to \baselineskip
), and the scale-down ratio defaults to 0.98, but may be supplied as an optional parameter.
Beware that arithmetic underflows are possible, if things get teeny enough.
See addendum for pseudo 3-D effect:
\documentclass{article}
\usepackage{scalerel}
\newlength\curht
\def\defaultdimfrac{.98}
\def\defaultstartht{\baselineskip}
\newcommand\diminish[2][\defaultdimfrac]{%
\curht=\defaultstartht\relax
\def\dimfrac{#1}%
\diminishhelpA{#2}%
}
\newcommand\diminishhelpA[1]{%
\expandafter\diminishhelpB#1\relax%
}
\def\diminishhelpB#1#2\relax{%
\scaleto{\strut#1}{\curht}%
\curht=\dimfrac\curht\relax%
\ifx\relax#2\relax\else\diminishhelpA{#2}\fi%
}
\begin{document}
\def\defaultstartht{14pt}
\def\pinum{3.14159265358979323846264338327950288419716939937510}
\diminish{\pinum}\par
\diminish[0.96]{\pinum}\par
\diminish[0.94]{\pinum}\par
\def\defaultstartht{38pt}
\diminish[0.92]{\pinum}
\end{document}
ADDENDUM
Based on Yori's desire to see something more "3-D", I have EDITED to incorporate Bruno's \slantbox
at Shear transform a "box". Combining that with a \raisebox
allows the effect which some may find more 3-D. The additional user parameters to control it are \slantvalue
which is Bruno's model parameter and \zshft
, which is an added vertical shift per letter.
\documentclass{article}
\usepackage{scalerel}
\newlength\curht
\newlength\zshft
\newcounter{letcount}
\def\defaultdimfrac{.98}
\def\slantvalue{0}
\zshft=0pt\relax
\def\defaultstartht{\baselineskip}
\newcommand\diminish[2][\defaultdimfrac]{%
\curht=\defaultstartht\relax
\def\dimfrac{#1}%
\setcounter{letcount}{0}
\diminishhelpA{#2}%
}
\newcommand\diminishhelpA[1]{%
\expandafter\diminishhelpB#1\relax%
}
\def\diminishhelpB#1#2\relax{%
\raisebox{\value{letcount}\zshft}{\scaleto{\strut\slantbox{#1}}{\curht}}%
\stepcounter{letcount}%
\curht=\dimfrac\curht\relax%
\ifx\relax#2\relax\else\diminishhelpA{#2}\fi%
}
\newsavebox{\foobox}
\newcommand{\slantbox}[2][\slantvalue]{\mbox{%
\sbox{\foobox}{#2}%
\hskip\wd\foobox
\pdfsave
\pdfsetmatrix{1 0 #1 1}%
\llap{\usebox{\foobox}}%
\pdfrestore
}}
\begin{document}
\def\pinum{3.14159265358979323846264338327950288419716939937510}
\def\defaultstartht{14pt}
\diminish{\pinum}\par
\def\slantvalue{.15}
\zshft=.1pt\relax
\diminish[0.96]{\pinum}\par
\diminish[0.94]{\pinum}\par
\def\slantvalue{.35}
\zshft=.4pt\relax
\def\defaultstartht{38pt}
\diminish[0.92]{\pinum}
\end{document}
While the curvy tail gives a certain stylistic fading, it might be preferable to follow the rules of perspective and have the numbers vanish along a linear path to the vanishing point. What this means is that rather than an additional \zshft
added for each letter, the \zshft
should also get smaller with each letter, so that the total shift (dZ) on the nth letter (after the 1st) should be
dZ = dz + k dz + k^2 dz + ... + k^(n-1) dz
where dz is the specified \zshft
, and k is the scale-down parameter given by \dimfrac
. Simple manipulation reveals that the shift for the nth letter (after the 1st) is:
dZ = dz (1 - k^n)/(1-k)
This can be calculated in LaTeX, but requires the much more computationally intensive fp
package. So, at the expense of compilation time, we can achieve the following:
\documentclass{article}
\usepackage{scalerel,fp}
\newlength\curht
\newlength\zshft
\newcounter{letcount}
\def\defaultdimfrac{.98}
\def\slantvalue{0}
\zshft=0pt\relax
\def\defaultstartht{\baselineskip}
\newcommand\diminish[2][\defaultdimfrac]{%
\curht=\defaultstartht\relax
\def\dimfrac{#1}%
\setcounter{letcount}{0}
\diminishhelpA{#2}%
}
\newcommand\diminishhelpA[1]{%
\expandafter\diminishhelpB#1\relax%
}
\def\diminishhelpB#1#2\relax{%
\FPpow\localshift{\dimfrac}{\theletcount}\unskip%
\FPsub\localshift{1}{\localshift}%
\FPsub\localdenom{1}{\dimfrac}%
\FPdiv\localshift{\localshift}{\localdenom}%
\raisebox{\localshift\zshft}{\scaleto{\strut\slantbox{#1}}{\curht}}%
\stepcounter{letcount}%
\curht=\dimfrac\curht\relax%
\ifx\relax#2\relax\else\diminishhelpA{#2}\fi%
}
\newsavebox{\foobox}
\newcommand{\slantbox}[2][\slantvalue]{\mbox{%
\sbox{\foobox}{#2}%
\hskip\wd\foobox
\pdfsave
\pdfsetmatrix{1 0 #1 1}%
\llap{\usebox{\foobox}}%
\pdfrestore
}}
\begin{document}
\def\pinum{3.14159265358979323846264338327950288419716939937510}
\def\defaultstartht{14pt}
\diminish{\pinum}\par
\def\slantvalue{.15}
\zshft=.3pt\relax
\diminish[0.96]{\pinum}\par
\diminish[0.94]{\pinum}\par
\def\slantvalue{.35}
\zshft=1.7pt\relax
\def\defaultstartht{38pt}
\diminish[0.92]{\pinum}
\end{document}
Oops!! Spill in aisle 1! (coding left to the student)
Mark Wibrow enhanced the text decoration library of TikZ greatly and you can do all kinds of stuff based on formulas regarding the character number and total count of words and so on.
Here is a wacky take on it, (thus a simple monotone scaling along a path is very simple and is possible just by playing with the formula with scale
instead of yscale
)
\documentclass[tikz]{standalone}
\usetikzlibrary{decorations.text}
\tikzset{pi decoration/.style={
decoration={text effects along path,
text={3.14159265358979323846264338327950288419716939937510},
text align=center,
text effects/.cd,
character total=\n,character count=\i,
path from text,
characters={yscale=10*sin(deg(5*\i/\n))-\i/\n,inner sep=0,anchor=base}
}}}
\begin{document}
\begin{tikzpicture}
\path[pi decoration,decorate] (0,0);
\end{tikzpicture}
\end{document}
A recursive macro:
\documentclass[border=2]{standalone}
\usepackage{mathptmx} % a scalable font is needed
\makeatletter
\def\makesmaller#1#2{%
\dimen0=\dimexpr\dimen0-.08pt\relax
\ifx#2\relax
\expandafter\@gobble
\else
{\fontsize{\dimen0}{0}\selectfont#1}%
\expandafter\@firstofone
\fi
{\makesmaller{#2}}%
}
\def\decreasingpi{%
{\dimen0=16pt\fontsize{\dimen0}{0}\selectfont
3.\makesmaller1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253
\relax}
}
\makeatletter
\begin{document}
\decreasingpi
\end{document}
One might first count the number of digits and decide the minimum size, so as to adjust the decrease step. I leave this as an exercise.
UPDATE
A different version:
\documentclass{article}
\usepackage{graphicx}
\ExplSyntaxOn
\NewDocumentCommand{\vanishing}{O{1}m}
{
\seq_set_split:Nnn \l_tmpa_seq { . } { #2 }
\seq_item:Nn \l_tmpa_seq { 1 } .
\seq_set_split:Nnx \l_tmpb_seq { } { \seq_item:Nn \l_tmpa_seq { 2 } }
\fp_set:Nn \l_tmpa_fp { \seq_count:N \l_tmpb_seq }
\seq_map_indexed_inline:Nn \l_tmpb_seq
{
\scalebox{\fp_eval:n { 1 - ##1/(\seq_count:N \l_tmpb_seq + #1) } } { ##2 }
}
}
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }
\ExplSyntaxOff
\begin{document}
$e=\vanishing[10]{2.71828 18284 59045 23536 02874 71352 66249 77572 47093 69995}$
$e=\vanishing{2.71828 18284 59045 23536 02874 71352 66249 77572 47093 69995}$
\end{document}
The optional argument (default 1) is for avoiding the last digit becomes too small.