
図形内にテキストを描画しようとしています (スケーリングとパスを使用)。テキストを次のように表示したいです:
いろいろな方法を試してみましたが、うまくいきませんでした。次のような方法を使えば、これに近づくことができます。
\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}
その結果は次のようになります:
示されている例のように、テキストの上部を上にカーブさせます。
答え1
\outline
楽しみのためにマクロ (pdflatex が必要)を投入しました。
内容\outline
はプリアンブルにありますが、ネックコードはメインドキュメントにあります。私はもともと\outline
Malipivoからコードを盗んだものです。TikZ: テキストの周りにハロー?
私がやっていることは、テキストを含むボックス ( \mytext
) を作成し (後で切り取られないように少しパディングする)、\clipbox
テキスト ボックスを垂直に 回スライスする を連続して適用することです。カットごとに、カット数の関数としてテキストを縮小するために を\cuts
適用し、最大のネッキング率を表す を適用します。ここで選択する関数は放物線型ですが、他の関数も開発できます。\scalebox
\dip
\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}
コードがなければ\outline
、コードはより管理しやすくなります。(編集済み) ここでは、\parabtext[<mode>]{<lift>}{<neck>}{<cuts>}{<content>}
上記のいくつかの追加を加えてマクロに変換します。
<mode>
中央が狭い場合は 0、両端が狭い場合は 1 です。
<lift>
変換中のベースラインの最大リフト率です
<neck>
首の部分での全高の減少率です。
<cuts>
ボックスに適用する垂直スライスの数です(小さすぎると階段状のように見えます)
<content>
箱に入れて変形させるものです。
\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}
最後に編集されたオプションは<mode>
、変換の形状関数を変更します。どちらのモードでも、関数が評価されます。
\FPeval{\myprod}{\NA*\NB*4/\cuts/\cuts}%
これは箱の両端で値が1、箱の中央で値が0の放物線です。モードが0の場合、変換は次のようになります。
\FPeval{\myprod}{1 - \neck*(\myprod)}%
一方、ゼロでない場合、変換は
\FPeval{\myprod}{1 - \neck*(1-\myprod)}%
この単純な違いにより、それぞれネック付きバージョンとバレル付きバージョンが生成されます。
提案された方法論
この方法は計算コストが多少高くなりますが、Wow! 効果を出すために控えめに使用することを目的としています。
まず、計算コストが少し高くなるかもしれませんが、実質的には前方差分から中心差分に移行する、わずかに修正されたコードを示します。
しかし、最も効果的だと思うのは、ユーザー定義変数のスライスの数をたとえば という低い数値に設定し、\def\slices{5}
それを基にドキュメントを開発することです。最終コンパイル時に、最終レイアウトですべてが設定されたら、\def\slices
を という望ましい数値に設定し{200}
、最後にもう一度再コンパイルします。
\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}
たとえば、低解像度コンパイルの場合に\slices
を設定した場合の出力は次のようになります。5
XeLaTeX ユーザーへの注意
OP は、このアプローチが XeLaTeX では機能しなかったと指摘しました。少し調べた後、私は問題をパッケージのバグに絞り込みましたtrimclip
(\scalebox の \clipbox が xelatex で正しく動作しないtrimclip
)。Joseph Wright 氏は親切にも、 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
答え2
アップデート
三角形メッシュを使用すると、任意の連続変換を近似できます。
\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}
古い回答
@Steven B. Segletes のアイデアをそのままコピーしただけです。グリッドは 2D で、PGF/Ti で作成されています。けZ.
% !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}
数学の話
私のコードでは変換は次のように定義されています
(x,y) |--> ( fxx(x)+fyx(y) 、 fxy(x)+fyy(y) )
ここで、fxx、fyx、fxy、fyyは良い関数。このような変換は正方形を平行四辺形に変換します。偶然にも、PDFはアフィン変換をサポートしており、これも正方形を平行四辺形に変換します。したがって、区分的アフィン変換を使用して元の変換を近似することができます。その結果、どの曲線も接続されたただし、微分可能ではありません。