使用分形图案切割字母

使用分形图案切割字母

如何使用 Tikz 获得如下照片中的效果?在此处输入图片描述

看看我使用 tikz 装饰库得到了什么 在此处输入图片描述

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.fractals}

\begin{document}
\usetikzlibrary {decorations.fractals}
\begin{tikzpicture}[line width=20pt, decoration=Cantor set]
{ \sffamily \bfseries \Huge
\begin{scope}[rotate=90]
  \clip (0,.5) rectangle +(1,-4.85);
  \draw decorate{ (0,0) -- (3,0) } node[white] at (0.5,0) { C};
  \draw decorate{ decorate{ (0,-.75) -- (3,-.75) }} node[white] at (0.5,-0.75) {A};
  \draw decorate{ decorate{ decorate{ (0,-1.5) -- (3,-1.5) }}} node[white] at (0.5,-1.5) {N};
  \draw decorate{ decorate{ decorate{ decorate{ (0,-2.25) -- (3,-2.25) }}}} node[white] at (0.5,-2.25) {T};
  \draw decorate{ decorate{ decorate{ decorate{ decorate{ (0,-3) -- (3,-3) }}}}} node[white] at (0.5,-3) {O};
  \draw decorate{ decorate{ decorate{ decorate{ decorate{ decorate { (0,-3.75) -- (3,-3.75) }}}}}} node[white] at (0.5,-3.75) {R};
\end{scope}
}
\end{tikzpicture}
\end{document}

这个解决方案似乎是蛮力型的。我问你是否存在其他类型的剪辑来实现这种效果。

答案1

这是一个递归剪辑解决方案。

似乎从第五次递归计算开始,TeX/PGFMath 的精度就不够了,或者我的渲染器不再喜欢它了。

对于行Xs,PDF 到 PNG 转换器的分辨率已经太低了。我已将巨大的添加M到示例中。


下面给出的解决方案单独剪辑每个字母。

如同dexteritas 的回答可以在整个区域安装一个剪辑,但这不会提高效率,因为剪辑掉的部分A也会被剪辑掉N。尽管此解决方案需要scope为每个字母安装一个,但似乎并不会减慢速度。

代码

\documentclass[varwidth, border=1pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc, chains}
\tikzset{
  cantor/start/.initial=0,
  cantor/picture/.style={
    start chain=going base right, node distance=+0mm, baseline=(chain-begin.base)},
  cantor/node/.style={
    text=black, inner sep=+0pt, outer sep=+0pt, node font=\sffamily\bfseries\Huge},
  cantor/cantor/.style n args={3}{insert path={
      coordinate (@1-#1) at ({$(#2)!.33333!(#3)$}-|#3)
      \ifnum#1=1 (#2) rectangle (@1-#1)
      \else      [cantor/cantor/.expanded={\pgfinteval{#1-1}}{#2}{@1-#1}] \fi
      coordinate (@2-#1) at ({$(#2)!.66667!(#3)$}-|#2)
      \ifnum#1=1 (@2-#1) rectangle (#3)
      \else      [cantor/cantor/.expanded={\pgfinteval{#1-1}}{@2-#1}{#3}] \fi}}}
\newcommand*\cantortext[2][]{%
  \begin{tikzpicture}[cantor/picture,#1]
  \foreach[count=\CNT from \pgfkeysvalueof{/tikz/cantor/start}]\LTR in{#2}{
    \node[cantor/node,on chain]{\phantom{\LTR}};
    \begin{scope}
      \ifnum\CNT>0 \clip[cantor/cantor={\CNT}{chain-end.south west}
                                             {chain-end.north east}];\fi
      \node[cantor/node]at(chain-end){\LTR};
    \end{scope}}
  \end{tikzpicture}}
\begin{document}
\Huge\bfseries\sffamily % just to have the same text in document as in TikZ
CANTOR\par
\cantortext{C, A, N, T, O, R}\par
\cantortext[cantor/start=3]{X, X, X, X, X, X}
%\cantortext[transform shape, scale=5, cantor/start=5]{M}
\end{document}

输出

在此处输入图片描述

在此处输入图片描述

答案2

我使用纯 pdfTeX 想出了这个解决方案。在我开始研究这个解决方案之前,我没有注意到您指定了 TikZ,而当我注意到时,我已经花了一些时间。如果这不能帮助回答您的问题,我很抱歉。

康托式康托

%% Useful TeX macros
\bgroup
    \lccode`\?=`\p \lccode`\!=`\t
    \lowercase{\egroup\def\rmpt#1?!{#1}}
% \idim{<dimension expression>} -> the evaluation of the expression without a dimension
\def\idim#1{\expandafter\rmpt\the\dimexpr #1\relax}

\def\gobble#1{}

% \map<\macro>{<general text>} -> applies \macro to every group in <general text>
\long\def\map#1#2{\mapA{#1}#2\nul}
\long\def\mapA#1#2{%
    \ifx\nul#2%
        \let\next=\gobble%
    \else%
        #1{#2}%
        \let\next=\mapA%
    \fi%
    \next{#1}%
}

%% Helper macros for \cantorize

\def\cantorizeA#1#2#3#4{%
    \ifnum#1>0 %
        #2 #3 \cantorwd, #4 re
        \cantorizeA{\the\numexpr #1-1\relax}%
                  {\idim{#2pt + \cantorwd,pt}}%
                  {#3}%
                  {\idim{#4pt / 3}}%
        \cantorizeA{\the\numexpr #1-1\relax}%
                  {\idim{#2pt + \cantorwd,pt}}%
                  {\idim{#3pt + #4pt * 2 / 3}}%
                  {\idim{#4pt / 3}}%
    \fi%
}

% Typeset character with width \cantorwd,
\def\cantorsetwidth#1{\hbox to\cantorwd,pt{\hss#1\hss}}
\newcount\cantorlen
% Update cantorlen and cantorwd
\def\cantorgetlen#1{%
    \advance\cantorlen by 1\relax%
    \setbox0=\hbox{#1}%
    \ifdim\wd0>\cantorwd,pt\relax%
        \edef\cantorwd,{\idim{\wd0}}%
    \fi%
}
% vertical buffer around text in \cantorize
\def\cantorbuf,{.2}

\def\cantorize#1{{%
    \setbox0=\hbox{#1}%
    \def\cantorwd,{0}%
    \edef\cantorht,{\idim{\ht0 + \cantorbuf,pt * 2}}%
    \cantorlen=0\relax%
    \map\cantorgetlen{#1}%
    \quitvmode\pdfsave%
        \pdfliteral{.96859 0 0 .96859 0 0 cm \cantorizeA{\cantorlen}{0}{-\cantorbuf,}{\cantorht,} W n}%
        \rlap{\map\cantorsetwidth{#1}}%
    \pdfrestore%
    \hskip\cantorlen\dimexpr\cantorwd,pt\relax%
}}

%% Showcasing \cantorize

% Bigger font for showcasing the macro
\font\bigss=cmssbx10 at 50pt

{\bigss\cantorize{CANTOR}}

这样就不会绘制白色矩形,而是剪切文本,因此如果您还想使用背景颜色,则无需更改任何内容。

答案3

描述

首先,每个字符都绘制在自己的节点中。由于我没有找到反转康托尔集装饰结果的方法,所以我从头开始并定义了一个递归函数\drawmiddleline。它在文本上绘制白线。它的四个参数在代码中描述。在下图中,我使用了不同的颜色(从浅红色到深红色)来展示它是如何一步一步绘制的。

在此处输入图片描述

我保存了当前级别,\cslet{dml-#2}{\level}因为第一次递归调用会改变变量\level,但第二次递归调用仍然需要该变量。

为了获得没有深度的字母高度,我使用了:

\settoheight{\myheight}{\huge A}%

\myspacing定义字符节点之间的空间。

当然,您可以将字体更改为其他字体,但我认为这不是主要问题。

结果

在此处输入图片描述

代码

\documentclass[margin=2mm]{standalone}
\usepackage{etoolbox}
\usepackage{tikz}

\newcommand{\drawmiddleline}[4]{
    % #1 = char index
    % #2 = current level
    % #3 = current width
    % #4 = current yshift
    \ifnumequal{#2}{1}{
%       \pgfmathsetmacro{\c}{20*#1}
%       \draw[red!\c!white, line width=#3/3] ([yshift=#4] c#1.west) -- ([yshift=#4] c\n.east);
        \draw[white, line width=#3/3] ([yshift=#4] c#1.west) -- ([yshift=#4] c\n.east);
    }{
        \pgfmathsetmacro{\level}{int(#2-1)}
        \cslet{dml-#2}{\level}
        \drawmiddleline{#1}{\csuse{dml-#2}}{#3/3}{#4+#3/3}
        \drawmiddleline{#1}{\csuse{dml-#2}}{#3/3}{#4-#3/3}
    }
}

\newcommand{\cantortext}[1]{
    \foreach \char [count=\i from 0] in {#1} {
        \node[anchor=south west, inner sep=.3pt, font=\huge] (c\i) at (\i*\myspacing,0) {\char};
        \xdef\n{\i}
    }
    
    \foreach \i in {1, ..., \n} {
        \drawmiddleline{\i}{\i}{\the\myheight}{0pt}
    }
}

\begin{document}
\newlength{\myheight}%
\settoheight{\myheight}{\huge A}%
\newlength{\myspacing}%
\setlength{\myspacing}{5mm}%
\begin{tikzpicture}
    \cantortext{C,A,N,T,O,R}
\end{tikzpicture}
\end{document}

相关内容