早在 1979 年,Donald Knuth 就尝试使用越来越小的字体大小的无限序列来给人一种 π 是无理数的感觉,就像我在这里尝试使用 HTML 和 CSS 所做的那样。如何使用 LaTeX 实现同样的效果?
现在到了非常困难的部分,我如何以某种方式使用排版来创建 π 是超越数(不是任何具有整数系数的有限多项式的解)的感觉。
.pi sub { 垂直对齐:基线; 字体大小: 96%; }
π = 3.14159 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9 5 0 2 88419716939937510答案1
编辑以允许重复调用而无需重置参数,使用语法
\diminish[scale-down-ratio]{string}
的值\defaultstartht
设置了第一个字母的支柱高度(默认设置为\baselineskip
),缩小比例默认为 0.98,但可以作为可选参数提供。
请注意,如果事情变得足够小,可能会出现算术下溢。
请参阅附录以了解伪 3-D 效果:
\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}
附录
根据 Yori 想要看到更多“3-D”内容的愿望,我进行了编辑,加入了 Bruno 的\slantbox
的剪切变换一个“盒子”. 结合\raisebox
允许的效果相结合,一些可能查找更多 3-D。控制它的附加用户参数是\slantvalue
Bruno 的模型参数和\zshft
,这是每个字母增加的垂直移位。
\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}
虽然曲线尾部具有一定的风格淡化效果,但最好遵循透视规则,让数字沿着直线路径消失到消失点。这意味着,不是\zshft
每个字母都增加一个,而是\zshft
每个字母都变小,这样第 n 个字母(第一个字母之后)的总偏移量 (dZ) 应该是
dZ = dz + k dz + k^2 dz + ... + k^(n-1) dz
其中 dz 是指定的\zshft
,而 k 是 给出的缩小参数\dimfrac
。简单操作即可得出第 n 个字母(第一个字母之后)的移位为:
dZ = dz (1 - k^n)/(1-k)
这可以在 LaTeX 中计算,但需要计算量更大的fp
软件包。因此,以编译时间为代价,我们可以实现以下目标:
\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}
哎呀!洒在 1 号过道了!(编码留给学生)
答案2
Mark Wibrow 极大地增强了 TikZ 的文本装饰库,您可以根据字符数、单词总数等公式进行各种操作。
这是一个古怪的看法,(因此,沿路径进行简单的单调缩放非常简单,只需通过使用公式而scale
不是来实现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}
答案3
递归宏:
\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}
可以先计算数字的位数,然后确定最小值,以便调整减少的步长。我把这留作练习。
更新
另一个版本:
\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}
可选参数(默认 1)用于避免最后一位数字太小。
答案4
例如,在纯 TeX 中:
\input apnum
\apFRAC=80
\evaldef\Pi{\PI}
\evaldef\E{\EXP{1}}
\def\printsmaller#1{\ifx\end#1\else #1\pdfsetmatrix{.97 0 0 .97}%
\expandafter\printsmaller\fi}
\noindent\pdfsave\rlap{\expandafter\printsmaller\E\end}\pdfrestore
\bigskip
\noindent\pdfsave\rlap{\expandafter\printsmaller\Pi\end}\pdfrestore
\bye