Atualizar

Atualizar

Estou tentando desenhar texto em formas (usando escala e caminho). Quero que o texto apareça assim:

Texto do Vale

Eu tentei vários métodos diferentes, mas estou tendo problemas para fazer isso. Posso chegar perto disso usando algo assim:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations.text}

\begin{document}
\pagenumbering{gobble}

\begin{tikzpicture}
\node (One) at (-15,0) {.}; 
\node (Two) at (15,0) {.};
\draw [decorate,decoration={text effects along path, 
                    text={TTTTTTTTTTTTTTTT},
                    text align=center,
                    text effects/.cd,
                    path from text,
                    character count=\i, character total=\n, 
                    characters= {text along path, scale=(2 + abs(\i - (\n / 2) - 0.5) * 1 )}}] (One) to (Two);

\end{tikzpicture}

\end{document}

O que resulta em :

Resultado

Quero que a parte superior do texto se curve como no exemplo mostrado.

Responder1

Acabei de inserir a \outlinemacro (requer pdflatex) para me divertir.

O \outlinematerial está no preâmbulo, enquanto o código de estreitamento está no documento principal. Eu originalmente roubei o código que compõe \outlineo Malipivo emTikZ: halo em torno do texto?

O que eu faço é criar uma caixa ( \mytext) com o texto (um pouco preenchido para que nada seja cortado posteriormente) e, em seguida, aplicar sucessivamente um \clipboxque corte verticalmente a caixa de texto \cuts. Em cada corte aplico a \scaleboxpara encolher o texto em função do número do corte e \dip, que representa a fração máxima de estreitamento. A função que escolho aqui é parabólica, embora outras também possam ser desenvolvidas.

\documentclass{article}
\usepackage{ifthen,trimclip,calc,fp,graphicx,xcolor}
%%%%% FOR TEXT OUTLINING
\input pdf-trans
\newbox\qbox
\def\usecolor#1{\csname\string\color@#1\endcsname\space}
\newcommand\bordercolor[1]{\colsplit{1}{#1}}
\newcommand\fillcolor[1]{\colsplit{0}{#1}}
\newcommand\outline[1]{\leavevmode%
  \def\maltext{#1}%
  \setbox\qbox=\hbox{\maltext}%
  \boxgs{Q q 2 Tr \thickness\space w \fillcol\space \bordercol\space}{}%
  \copy\qbox%
}
\newcommand\colsplit[2]{\colorlet{tmpcolor}{#2}\edef\tmp{\usecolor{tmpcolor}}%
  \def\tmpB{}\expandafter\colsplithelp\tmp\relax%
  \ifnum0=#1\relax\edef\fillcol{\tmpB}\else\edef\bordercol{\tmpC}\fi}
\def\colsplithelp#1#2 #3\relax{%
  \edef\tmpB{\tmpB#1#2 }%
  \ifnum `#1>`9\relax\def\tmpC{#3}\else\colsplithelp#3\relax\fi
}
\bordercolor{blue}
\fillcolor{yellow}
\def\thickness{.5}
%%%%%
\begin{document}
\Huge
\edef\dip{.5}% percent to depress the amplitude
\def\cuts{200}% Number of cuts
\newsavebox\mytext
\savebox{\mytext}{\kern.3pt\textbf{\textsf{\outline{Valley Text}}}\kern.3pt}% TEXT
\newlength\clipsize
\FPeval{\myprod}{1/cuts}
\clipsize=\myprod\wd\mytext\relax
\newcounter{mycount}
\whiledo{\value{mycount}<\cuts}{%
  \stepcounter{mycount}%
  \edef\NA{\themycount}%
  \edef\NB{\the\numexpr\cuts-\themycount\relax}%
  \FPeval{\myprod}{1 - \dip*\NA*\NB*4/\cuts/\cuts}%
  \clipbox{%
    \value{mycount}\clipsize\relax{} %
    -1pt %
    \wd\mytext-\value{mycount}\clipsize-\clipsize\relax{} %
    -1pt%
  }{\scalebox{1}[\myprod]{\usebox{\mytext}}}%
}
\end{document}

insira a descrição da imagem aqui

Sem o \outlinecódigo, o código é mais gerenciável. (EDITADO) Aqui eu converto em uma macro \parabtext[<mode>]{<lift>}{<neck>}{<cuts>}{<content>}com vários acréscimos acima:

<mode>é 0 para meio estreito e 1 para extremidades estreitas;

<lift>é o levantamento máximo fracionário da linha de base durante a transformação

<neck>é a redução fracionária da altura total no pescoço;

<cuts>são o número de fatias verticais a serem aplicadas à caixa (muito pequenas e parecerão escalonadas)

<content>é o material para colocar em uma caixa e transformar.

\documentclass{article}
\usepackage{ifthen,trimclip,calc,fp,graphicx,xcolor}
\newsavebox\mytext
\newcounter{mycount}
\newlength\clipsize
\newcommand\parabtext[5][0]{%
  \edef\neck{#3}% percent to depress the amplitude
  \def\cuts{#4}% Number of cuts
  \savebox{\mytext}{\kern.2pt#5\kern.2pt}% TEXT
  \FPeval{\myprod}{1/cuts}%
  \clipsize=\myprod\wd\mytext\relax%
  \setcounter{mycount}{0}%
  \whiledo{\value{mycount}<\cuts}{%
    \stepcounter{mycount}%
    \edef\NA{\themycount}%
    \edef\NB{\the\numexpr\cuts-\themycount\relax}%
    \FPeval{\myprod}{\NA*\NB*4/\cuts/\cuts}%
    \ifnum0#1=0\relax%
      \FPeval{\myprod}{1 - \neck*(\myprod)}%
    \else%
      \FPeval{\myprod}{1 - \neck*(1-\myprod)}%
    \fi%
    \clipbox{%
      \value{mycount}\clipsize\relax{} %
      -1pt %
      \wd\mytext-\value{mycount}\clipsize-\clipsize\relax{} %
      -1pt%
    }{\raisebox{#2\dimexpr\ht\mytext-\myprod\ht\mytext}{%
        \scalebox{1}[\myprod]{\usebox{\mytext}}}}%
  }%
}
\begin{document}
\Huge\centering\def\X{\textbf{XXX}}%
\parabtext{0}{.7}{200}{\textbf{\textcolor{brown}{Valley Text}}}\par
\X\parabtext{0}{.7}{200}{\X}\parabtext[1]{0}{.7}{200}{\X}\X\par
\X\parabtext{1}{.7}{200}{\X}\parabtext[1]{1}{.7}{200}{\X}\X\par
\X\parabtext{.425}{.7}{200}{\X}\parabtext[1]{.425}{.7}{200}{\X}\X
\end{document}

insira a descrição da imagem aqui

A opção EDITADA mais recentemente, <mode>, altera a função de forma da transformação. Em ambos os modos, uma função é avaliada

\FPeval{\myprod}{\NA*\NB*4/\cuts/\cuts}%

Essa é uma parábola com valor 1 em ambas as extremidades da caixa e valor 0 no meio da caixa. Então, se a moda for 0, a transformação é

\FPeval{\myprod}{1 - \neck*(\myprod)}%

enquanto que, se não for zero, a transformação é

\FPeval{\myprod}{1 - \neck*(1-\myprod)}%

Essa simples diferença produzirá as versões com pescoço e cano, respectivamente.


METODOLOGIA PROPOSTA

O método é um tanto caro do ponto de vista computacional, mas deve ser usado com moderação para o Wow! efeito.

Primeiro, mostrarei um código ligeiramente modificado que leva, na verdade, de uma diferença direta para uma diferença central, embora possa custar um pouco mais em cálculo.

Mas o que acho que funciona melhor é definir o número de fatias em uma variável definida pelo usuário para um número baixo, digamos, \def\slices{5}e desenvolver seu documento com base nisso. Na compilação final, quando tudo estiver definido no layout final, volte \def\slicespara o número desejado, digamos {200}, e recompile uma última vez.

\documentclass{article}
\usepackage{ifthen,trimclip,calc,fp,graphicx,xcolor}
\newsavebox\mytext
\newcounter{mycount}
\newlength\clipsize
\newcommand\parabtext[5][0]{%
  \edef\neck{#3}% percent to depress the amplitude
  \def\cuts{#4}% Number of cuts
  \savebox{\mytext}{\kern.2pt#5\kern.2pt}% TEXT
  \FPeval{\myprod}{1/cuts}%
  \clipsize=\myprod\wd\mytext\relax%
  \setcounter{mycount}{0}%
  \whiledo{\value{mycount}<\cuts}{%
    \stepcounter{mycount}%
    \edef\NA{\themycount}%
    \edef\NB{\the\numexpr\cuts-\themycount\relax}%
    \FPeval{\myprod}{(\NA-.5)*(\NB+.5)*4/\cuts/\cuts}%
    \ifnum0#1=0\relax%
      \FPeval{\myprod}{1 - \neck*(\myprod)}%
    \else%
      \FPeval{\myprod}{1 - \neck*(1-\myprod)}%
    \fi%
    \clipbox{%
      \value{mycount}\clipsize-\clipsize\relax{} %
      -1pt %
      \wd\mytext-\value{mycount}\clipsize\relax{} %
      -1pt%
    }{\raisebox{#2\dimexpr\ht\mytext-\myprod\ht\mytext}{%
        \scalebox{1}[\myprod]{\usebox{\mytext}}}}%
  }%
}
\begin{document}
\def\slices{200}
\Huge\centering\def\X{\textbf{XXX}}%
\parabtext{0}{.7}{\slices}{\textbf{\textcolor{brown}{Valley Text}}}\par
\X\parabtext{0}{.7}{\slices}{\X}\parabtext[1]{0}{.7}{\slices}{\X}\X\par
\X\parabtext{1}{.7}{\slices}{\X}\parabtext[1]{1}{.7}{\slices}{\X}\X\par
\X\parabtext{.425}{.7}{\slices}{\X}\parabtext[1]{.425}{.7}{\slices}{\X}\X
\end{document}

Aqui está, por exemplo, a saída \slicesdefinida como 5para a compilação em baixa resolução:

insira a descrição da imagem aqui

NOTA PARA USUÁRIOS XeLaTeX

O OP observou que esta abordagem não funcionou no XeLaTeX. Depois de algum estudo, resumi o problema a um bug no trimclippacote (\clipbox de um \scalebox não funciona corretamente no xelatex). Joseph Wright teve a gentileza de diagnosticar o problema e fornecer um patch para o trimclipcódigo, quando executado no XeLaTeX.

\makeatletter
\ifdefined\XeTeXversion
  \def\@cliptoboxdim#1{%
    \setbox #1=\hbox{%
      \Gin@defaultbp\WIDTH{\wd #1}%
      \Gin@defaultbp \DEPTH {\dp #1}%
      \@tempdima \ht #1%
      \advance\@tempdima\dp#1%
      \Gin@defaultbp \TOTALHEIGHT {\@tempdima }%
      \special{pdf:literal q}% 
      \special{pdf:literal 0 -\DEPTH \space \WIDTH \space \TOTALHEIGHT \space re W n }%
      \rlap{\copy #1}%
      \special {pdf:literal Q}%
      \hskip\wd#1%
    }%
  }
\fi
\makeatother

Responder2

Atualizar

Usando malha triangular, podemos aproximar qualquer transformação contínua.

\documentclass[border=9,tikz]{standalone}
\begin{document}

\pgfmathdeclarefunction{fx}{2}{\pgfmathparse{#1*(3+cos(#2*20))/3}}
\pgfmathdeclarefunction{fy}{2}{\pgfmathparse{#2*(3-cos(#1*20))/3}}
\pgfmathdeclarefunction{fxx}{2}{\pgfmathparse{fx(#1+1,#2)-fx(#1,#2)}}
\pgfmathdeclarefunction{fxy}{2}{\pgfmathparse{fy(#1+1,#2)-fy(#1,#2)}}
\pgfmathdeclarefunction{fyx}{2}{\pgfmathparse{fx(#1,#2+1)-fx(#1,#2)}}
\pgfmathdeclarefunction{fyy}{2}{\pgfmathparse{fy(#1,#2+1)-fy(#1,#2)}}

\tikz{
    \path(-15,-15)(15,15);
    \foreach\i in{-10,...,9}{
        \foreach\j in{-10,...,9}{
            \pgfmathsetmacro\aa{fxx(\i,\j)}
            \pgfmathsetmacro\ab{fxy(\i,\j)}
            \pgfmathsetmacro\ba{fyx(\i,\j)}
            \pgfmathsetmacro\bb{fyy(\i,\j)}
            \pgfmathsetmacro\xx{fx (\i,\j)}
            \pgfmathsetmacro\yy{fy (\i,\j)}
            \pgflowlevelobj{
                \pgfsettransformentries{\aa}{\ab}{\ba}{\bb}{\xx cm}{\yy cm}
            }{
                \fill[black!10](1,0)--(0,0)--(0,1);
                \clip(1,0)--(0,0)--(0,1)--cycle;
                \tikzset{shift={(-\i,-\j)}}
                \path(0,0)node{\includegraphics[width=20cm]{lena.png}};
            }
            \pgfmathsetmacro\aa{fxx(\i  ,\j+1)}
            \pgfmathsetmacro\ab{fxy(\i  ,\j+1)}
            \pgfmathsetmacro\ba{fyx(\i+1,\j  )}
            \pgfmathsetmacro\bb{fyy(\i+1,\j  )}
            \pgfmathsetmacro\xx{fx (\i+1,\j+1)}
            \pgfmathsetmacro\yy{fy (\i+1,\j+1)}
            \pgflowlevelobj{
                \pgfsettransformentries{\aa}{\ab}{\ba}{\bb}{\xx cm}{\yy cm}
            }{
                \clip(0,0)--(-1,0)--(0,-1)--cycle;
                \tikzset{shift={(-\i-1,-\j-1)}}
                \path(0,0)node{\includegraphics[width=20cm]{lena.png}};
            }
        }
    }
}

\end{document}

Resposta Antiga

Apenas copiando a ideia do @Steven B. Segletes, só que a grade é 2D, e é feita em PGF/TikZ.

% !TEX program = XeLaTeX
% !TEX encoding = UTF-8 Unicode

\documentclass[border=9,tikz]{standalone}
\usepackage{fontspec}\setmainfont{Arial Unicode MS}

\begin{document}

\pgfmathdeclarefunction{fxx}{1}{\pgfmathparse{#1}}
\pgfmathdeclarefunction{fxy}{1}{\pgfmathparse{sin(222+30*#1)}}
\pgfmathdeclarefunction{fyx}{1}{\pgfmathparse{sin(20*#1)}}
\pgfmathdeclarefunction{fyy}{1}{\pgfmathparse{#1}}
\pgfmathdeclarefunction{gxx}{1}{\pgfmathparse{fxx(#1+1)-fxx(#1)}}
\pgfmathdeclarefunction{gxy}{1}{\pgfmathparse{fxy(#1+1)-fxy(#1)}}
\pgfmathdeclarefunction{gyx}{1}{\pgfmathparse{fyx(#1+1)-fyx(#1)}}
\pgfmathdeclarefunction{gyy}{1}{\pgfmathparse{fyy(#1+1)-fyy(#1)}}

\tikz{
    \path(-2,-2)(103,23);
    \foreach\i in{0,...,100}{
        \foreach\j in{0,...,20}{
            {
                \pgfmathsetmacro\aa{gxx(\i)}
                \pgfmathsetmacro\ab{gxy(\i)}
                \pgfmathsetmacro\ba{gyx(\j)}
                \pgfmathsetmacro\bb{gyy(\j)}
                \pgfmathsetmacro\xx{fxx(\i)+fyx(\j)}
                \pgfmathsetmacro\yy{fxy(\i)+fyy(\j)}
                \pgflowlevelobj{
                    \pgfsettransformentries{\aa}{\ab}{\ba}{\bb}{\xx cm}{\yy cm}
                }{
                    \clip(0,0)--(1,0)--(1,1)--(0,1)--cycle;
                    \draw[gray](1,0)--(0,0)--(0,1);
                    \path(-\i,-\j)+(50,10)node{\fontsize{500pt}{0}\selectfont Valley Text};
                }
            }
        }
    }
}

\end{document}

Um pouco de matemática

No meu código, uma transformação é definida por

(x,y) |--> ( fxx(x)+fyx(y) , fxy(x)+fyy(y) )

onde fxx, fyx, fxy, fyy estãobomfunções. Tal transformação enviará um quadrado a um paralelogramo. Coincidentemente, o PDF suporta transformação afim, que também envia um quadrado para um paralelogramo. Assim, posso usar a transformação afim por partes para aproximar a transformação original. O resultado é que qualquer curva permaneceráconectado, embora não seja diferenciável.

informação relacionada